Take the 2-minute tour ×
Electrical Engineering Stack Exchange is a question and answer site for electronics and electrical engineering professionals, students, and enthusiasts. It's 100% free, no registration required.

I was using ATmega32A before and now I am migrating to ATmega324PA just to enhance power management. Now I am testing the new controller in every aspect. This is a simple code to check the watchdog timer but it keeps resetting the controller.

Code:

int main(void)
{
  uart_init();
  PORTA|=(1<<PORTA1);
  _delay_ms(1500);
  PORTA&=~(1<<PORTA1);
  _delay_ms(2000);
  uart_array("FFFFFFFFFFFFFFFFFF");
  wdt_enable(WDTO_2S);
  _delay_ms(5000);
}

void uart_init()
{
 /*set PinA1 as output for LED*/
 DDRA|=(1<<1);

 /*set PinD3 as output for UART*/
 DDRD|=(1<<3);

 /*set pinD2 as input for UART*/
 DDRD&=~(1<<2);

 /*enabling TX and RX*/
 UCSR1B |=(1<<TXEN1) | (1<<RXEN1);

 /*asynchronous mode selection*/
 UCSR1C&=~(1<<UMSEL11);
 UCSR1C&=~(1<<UMSEL10);

 /*setting data format to 8 bit*/
 UCSR1B &=~(1<<UCSZ12);
 UCSR1C|=(1<<UCSZ11)|(1<<UCSZ10);

 /* setting one bit as stop bit*/
 UCSR1C &=~(1<<USBS1);

 /*Disabling parity*/
 UCSR1C &= ~((1<<UPM11) | (1<<UPM10));

 /* loading 8 LSB to UBRRL*/
 UBRR1L = UBRRL_VALUE;

 /* loading 4 MSB to UBRRH*/
 UBRR1H = UBRRH_VALUE;
}

The code works well for the first time, but after that, LED keeps blinking.

Note: watchdog (WDTON) fuse bit is disabled.

share|improve this question

2 Answers 2

up vote 3 down vote accepted

Yeah, that is because after the watchdog fires, you have to reset the corresponding flag before main starts again (there is a register where you can read out, what caused the reset) and to disable the watchdog from firing over and over.

This code will fix your problem:

    // This function is called upon a HARDWARE RESET:
void reset(void) __attribute__((naked)) __attribute__((section(".init3")));

/*! Clear SREG_I on hardware reset. */
void reset(void)
{
     cli();
    // Note that for newer devices (any AVR that has the option to also
    // generate WDT interrupts), the watchdog timer remains active even
    // after a system reset (except a power-on condition), using the fastest
    // prescaler value (approximately 15 ms). It is therefore required
    // to turn off the watchdog early during program startup.
    MCUSR = 0; // clear reset flags
    wdt_disable();
}

This .init3 thing is a special code section where you can put code that is run before main starts. Here is a link that describes that, but you shouldn't worry too much about it, the code above will work just fine when put into the main.c.

share|improve this answer
    
It did work without adding .init3 stuff.. Thanks alot –  gzix Jul 1 at 6:32
    
what do you mean, without init stuff? Did you just put the code at the beginning of main? If so, thats a bit unsafe, since you do not know how long it will take to enter main (there are some other inits that do sth before main) so you better put it as far forward as possible. This ensures you don't get unexpected behaviour. –  jjstcool Jul 1 at 6:50
    
After wdt_enable, i checked the watchdog interrupt value. It has been disabled only. So from where the continuous reset came from? –  gzix Jul 1 at 7:00
1  
what do you mean with wdt interrupt value? Anyway: The watchdog stays enabled after a wdt reset, but the time after which it will trigger is set to 15 ms! So you have to disable it very fast, otherwise it will trigger over and over again. So the way to go is to disable it before main and enable it as you want it to work in the main. –  jjstcool Jul 1 at 7:14

Beyond previous reset() function advice you need disable watchdog in bootloader (if used of course). There is/was e.g. known bug of original Arduino bootloader which did not disable watchdog.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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