2
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ You really expect us to understand fuse bits from a hex value? Also add comments to your code what each register setting is supposed to do. \$\endgroup\$ – jippie Nov 8 '15 at 7:59
  • \$\begingroup\$ @jippie: Fuse settings are shown here: eleccelerator.com/fusecalc/… The parameters are explained here: martyncurrey.com/arduino-atmega-328p-fuse-settings In short: external 16Mhz crystal is used, bootloader is disabled, Brown Out Detection is disabled. \$\endgroup\$ – Igor Liferenko Nov 8 '15 at 13:25
  • \$\begingroup\$ You are aware that you are the one asking for help, not me? \$\endgroup\$ – jippie Nov 8 '15 at 14:41
  • \$\begingroup\$ @jippie: I'm not asking for help at all - I just propose an interesting problem to think over, for those who are interested... \$\endgroup\$ – Igor Liferenko Nov 8 '15 at 15:01
  • \$\begingroup\$ @IgorLiferenko ... But you ARE asking for help by posting here. Also, your fuses are wrong. You claim to be using an external 16MHz crystal, but the fuses you are using for are for an external 8MHz oscillator. \$\endgroup\$ – Kurt E. Clothier Nov 8 '15 at 22:03
1
\$\begingroup\$

Most of your code and post has absolutely nothing to do with the watchdog timer.

In the comments above, you note using an external 16MHz oscillator, but your fuses set up the chip for an external 8MHz oscillator. Are you actually using a crystal with capacitors, or a ceramic resonator?

Is this a custom PCB? Are you using Arduino or some other Development board? If so, which one? How are you communicating with this chip... over the serial port from a computer? What is your setup? You haven't explained anything about what you are actually trying to do. If you are using Arduino, say so.. and probably ask this on the Arduino channel instead.

The code used to enable and use the USART is not very good, but that's a different conversation to be had. Header files (.h) should never be included in the middle of code, they should all be included at the top of the file. You also need to include avr/interrupt.h to use any ISR vectors.


The AVR watchdog timer has specific register bits that must be set.

Rather than post a long answer, I will direct you to this question about the WDT that I previously answered with details on starting and operating the WDT.

Any other details you might need can be found in the datasheet for the ATmegax8 series microcontrollers, specifically section 10.8.

\$\endgroup\$
  • \$\begingroup\$ This code from the topic which you referred to seems to disable the blinking: MCUSR &= ~_BV(WDRF); WDTCSR |= (_BV(WDCE) | _BV(WDE)); WDTCSR = 0x00; But why and when does WDT get started in the first place? NOTE: I do not use the bootloader at all. \$\endgroup\$ – Igor Liferenko Nov 8 '15 at 12:21
  • \$\begingroup\$ That's the thing, you aren't doing anything to start the WDT. The blinking has nothing to do with the WDT. The chip is resetting due to a register memory error or other timing issue. \$\endgroup\$ – Kurt E. Clothier Nov 8 '15 at 22:06
  • \$\begingroup\$ The solution was found on arduino.SX - see arduino.stackexchange.com/questions/17585/… \$\endgroup\$ – Igor Liferenko Nov 10 '15 at 1:45
  • \$\begingroup\$ So I was mostly correct, it just wasn't what you wanted to hear. I thought about suggesting you use a Makefile to do all of the Compiling and Linking, but I hand't thought to check those actual commands. \$\endgroup\$ – Kurt E. Clothier Nov 10 '15 at 2:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.