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