Proble extraño al ejecutar atmega328 de forma independiente

0

Tengo dos ATMEGA328 y estoy experimentando un problema muy extraño. Tengo un código muy simple para parpadear un LED:

    #define F_CPU 8000000UL

    #include <avr/io.h>
    #include <util/delay.h>
    #include <stdlib.h>

    void delayms( uint16_t millis ) 
    {
            while ( millis ) 
            {
                    _delay_ms( 1 );
                    millis--;
            }
    }

    int main( void ) 
    {
            DDRD = 0b11111111;

            int interval = 1000;

            while ( 1 ) 
            {
                    PORTD = 0b11111111;
                    delayms( interval );
                    PORTD = 0b00000000;
                    delayms( interval );
            }

            return 0;
    }

Y aquí está el Makefile:

    CC=/usr/bin/avr-gcc
    MEGA=328p
    CFLAGS=-g -Os -Wall -mcall-prologues -mmcu=atmega$(MEGA)
    OBJ2HEX=/usr/bin/avr-objcopy 
    PROG=/usr/bin/avrdude
    TARGET=blink

    program : $(TARGET).hex
            $(PROG) -c avrispv2 -p m$(MEGA) -P /dev/ttyACM2 -e
            $(PROG) -c avrispv2 -p m$(MEGA) -P /dev/ttyACM2 -U flash:w:$(TARGET).hex

    %.obj : %.o
            $(CC) $(CFLAGS) $< -o $@

    %.hex : %.obj
            $(OBJ2HEX) -R .eeprom -O ihex $< $@

    clean :
            rm -f *.hex *.obj *.o

El código funciona perfectamente, pero aquí está la parte extraña:

ATMEGA # 1:

  • Funciona como se espera cuando se conecta directamente a la fuente de 5V. Lo que significa que ejecuta el último código, que fue escrito en él.
  • No se puede programar. avrdude: stk500v2_command (): el comando falló. No se puede conectar.

ATMEGA # 2:

  • Funciona solo a través del caso Arduino. Cuando se conecta directamente a la fuente de 5V, PORTD no genera nada.
  • Se puede programar.

Este misterio ha sucedido tantas veces antes. Todo lo que puedo pensar es que tiene algo que ver con los bits de fusible o, posiblemente, la frecuencia está "codificada" para un chip a 8Mhz y 16Mhz para el otro. Esperaba que F_CPU definiera eso y avrdude usa esa definición para configurar los fusibles correctamente.

No quiero usar un oscilador externo. ¿Alguna pista sobre lo que está pasando?

ACTUALIZACIÓN: Esta es la salida de una de las ATMEGA que no se pudo programar.

/usr/bin/avrdude -c avrispv2 -p m328p -P /dev/ttyACM0 -e -U lfuse:w:0xe2:m -B 250.0 -U hfuse:w:0xd9:m

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.07s

avrdude: Device signature = 0x1e950f
avrdude: erasing chip
avrdude: reading input file "0xe2"
avrdude: writing lfuse (1 bytes):

Writing | ################################################## | 100% 0.07s

avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0xe2:
avrdude: load data lfuse data from input file 0xe2:
avrdude: input file 0xe2 contains 1 bytes
avrdude: reading on-chip lfuse data:

Reading | ################################################## | 100% 0.02s

avrdude: verifying ...
avrdude: 1 bytes of lfuse verified
avrdude: reading input file "0xd9"
avrdude: writing hfuse (1 bytes):

Writing | ################################################## | 100% 0.02s

avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0xd9:
avrdude: load data hfuse data from input file 0xd9:
avrdude: input file 0xd9 contains 1 bytes
avrdude: reading on-chip hfuse data:

Reading | ################################################## | 100% 0.02s

avrdude: verifying ...
avrdude: 1 bytes of hfuse verified

avrdude: safemode: Fuses OK (E:07, H:D9, L:E2)

avrdude done.  Thank you.

/usr/bin/avrdude -c avrispv2 -p m328p -P /dev/ttyACM0 -U flash:w:serial.hex

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.07s

avrdude: Device signature = 0x1e950f
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "serial.hex"
avrdude: input file serial.hex auto detected as Intel Hex
avrdude: writing flash (912 bytes):

Writing |                                                    | 0% 0.00s
avrdude: stk500v2_ReceiveMessage(): timeout
Writing | ######                                             | 12% 2.84s
avrdude: stk500v2_ReceiveMessage(): timeout
Writing | #############                                      | 25% 5.68s
avrdude: stk500v2_ReceiveMessage(): timeout
Writing | ###################                                | 37% 8.52s
avrdude: stk500v2_ReceiveMessage(): timeout
Writing | ###############################                    | 62% 14.20s
avrdude: stk500v2_ReceiveMessage(): timeout
Writing | ######################################             | 75% 17.04s
avrdude: stk500v2_ReceiveMessage(): timeout
Writing | ############################################       | 87% 19.89s
avrdude: stk500v2_ReceiveMessage(): timeout
Writing | ################################################## | 100% 22.73s

avrdude: 912 bytes of flash written
avrdude: verifying flash memory against serial.hex:
avrdude: load data flash data from input file serial.hex:
avrdude: input file serial.hex auto detected as Intel Hex
avrdude: input file serial.hex contains 912 bytes
avrdude: reading on-chip flash data:

Reading |                                                    | 0% 0.00s
avrdude: stk500v2_ReceiveMessage(): timeout
Reading | ######                                             | 12% 2.80s
avrdude: stk500v2_ReceiveMessage(): timeout
Reading | ###################                                | 37% 8.39s
avrdude: stk500v2_ReceiveMessage(): timeout
Reading | #########################                          | 50% 11.18s
avrdude: stk500v2_ReceiveMessage(): timeout
Reading | ###############################                    | 62% 13.98s
avrdude: stk500v2_ReceiveMessage(): timeout
Reading | ############################################       | 87% 19.57s
avrdude: stk500v2_ReceiveMessage(): timeout
Reading | ################################################## | 100% 22.37s

avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x0000
         0x80 != 0x0c
avrdude: verification error; content mismatch

avrdude: safemode: Fuses OK (E:07, H:D9, L:E2)

avrdude done.  Thank you.

Makefile:9: recipe for target 'program' failed
make: *** [program] Error 1
    
pregunta 0x29a

1 respuesta

2

Tu configuración me confundió mucho: creo que siempre colocaste el ATmega328 en una placa de creación de prototipos (por ejemplo, placa de soldadura sin soldadura ), e intentabas programar el ATmega con un programador de estilo stk500v2 independiente. Si bien mencionó que el chip # 2 funciona cuando se coloca en un "estuche de arduino", pensé que se refería a un gabinete de electrónica destinado a un arduino, no a un verdadero arduino PCB .

Creo que finalmente he entendido lo que has intentado hacer:

  • Tienes dos chips ATmega328, una placa Arduino Uno y un Pololu PGM03A en el circuito Programador serie (que es muy similar al programador STK500V2 original de Atmel).

  • Para programar un ATmega328, conectó el PGM03A al encabezado de programación ICSP del Arduino Uno y colocó el chip en el zócalo del Arduino.

  • Para usar un ATmega328, lo quitaste de la PCB de Arduino y lo colocaste en un tablero de prototipos para ver si funciona sin el arduino.

Mi hipótesis sobre por qué los dos chips no funcionan:

ATmega # 2 es el que vino con el arduino. Como la placa arduino tiene un cristal de 16 MHz, los bits de fusible de chip se programaron en la fábrica para que el ATmega funcione a 16 MHz utilizando el oscilador de cristal integrado. Por lo tanto, el ATmega funciona bien y se programa correctamente cuando se coloca en la placa arduino (cristal presente), pero no se inicia en una placa separada (que no tiene un cristal) debido a que no tiene ninguna fuente de reloj .

ATmega # 1 está programado para usar el oscilador RC interno en alguna frecuencia (muy probablemente 8 MHz, posiblemente 1MHz, 128 kHz o 16 kHz), por lo que funciona como se espera tanto en la placa arduino como en una placa separada sin un cristal.
Al programar un ATmega328 con un programador en serie, la velocidad de reloj del ATmega debe ser al menos cuatro veces la velocidad de reloj de los datos en serie. Que yo sepa, la frecuencia de reloj SPI predeterminada del PGM03A es de 4 MHz, mientras que se requiere un máximo de 2 MHz para programar con éxito un ATmega que funcione a 8 MHz. Por lo tanto, el ICSP está intentando enviar datos demasiado rápido para que el ATmega los reciba .

Para que ATmega # 2 se ejecute de forma independiente, tiene dos opciones:

  • Agrega un cristal a tu tablero

  • Programe los bits de fusible para que ATmega use el oscilador RC interno. Por ejemplo, ejecutar avrdude con las opciones -U lfuse:w:0xe2:m -U hfuse:w:0xd9:m configurará el chip para que funcione a 8 MHz con el oscilador RC. Hay ingeniosas herramientas en línea para calcular la configuración de fusibles correcta, e incluso generan directamente las opciones de línea de comandos de avrdude.

Para que ATmega # 1 pueda programar, necesita reducir la frecuencia SPI de los programadores, lo que se puede hacer con la opción -B bitclock de avrdude (donde bitclock es el período de un ciclo de reloj en microsegundos). Por ejemplo, para programar un chip que funcione a 1 MHz, debe configurar la frecuencia en un cuarto de la frecuencia de reloj (250 kHz) o menos. Como 250 kHz implica un período de 4 microsegundos (1/250 kHz = 4 µs), le daría a avrdude la opción de línea de comando -B 4.0

    
respondido por el jms

Lea otras preguntas en las etiquetas