First we set fuse bits:
avrdude -c usbasp -p atmega328p -U lfuse:w:0xFF:m -U hfuse:w:0xDF:m -U efuse:w:0x07:m # same for atmega168
In the following examples we use the following commands to compile and burn all the programs:
avr-gcc -Os -mmcu=atmega328p -c -o serial.o serial.c
avr-ld -o serial.elf serial.o
avr-objcopy -O ihex serial.elf serial.hex
avrdude -c usbasp -p atmega328p -U flash:w:serial.hex
Let us burn the following program:
#define F_CPU 16000000UL
#include <avr/io.h>
void main (void) {
DDRB |= (1<<PB5); // enable output on pin PB5 (default led on arduino)
PORTB |= (1<<PB5); // set the led on
while (1);
}
It makes the led to be on constantly. And it stays so for infinite period of time.
Then we burn the following program:
#define F_CPU 16000000UL
#include <avr/io.h>
char data = 0;
void main(void) {
// Initialize USART:
UBRR0H = 0x00; // set the speed (Higher bit)
UBRR0L = 0x67; // set the speed (Lower bit)
UCSR0B = 0x10; // enable receiver
UCSR0C = 0x06; // set mode (8N1)
DDRB |= (1<<PB5); // enable output on pin PB5 (default led on arduino)
while(1) {
while(!(UCSR0A&(1<<RXC0))); // wait until a byte is received
data = UDR0; // read it
if (data) PORTB |= (1<<PB5); // set the led on
}
}
Then we open a terminal (9600,8N1) and press several keys, until the led turns off. Now we burn the first program again and the led is constantly blinking. The reason for this is that watchdog times gets started when we press the keys in terminal. But why and when WDT gets started? How to make so that it will not start?
It should be noted also that we can disable the blinking only with complete poweroff/poweron - only after that the led lights constantly without blinking, as necessary.
This happens on atmega168 and atmega328p, 100% reproducible.
avr-gcc version 4.8.1 avrdude version 6.1
NOTE: bootloader is not used at all.