Hello,
The following code is taken from the example code of AVR Butterfly.
void RTC_init(void) { Delay(1000); // wait for 1 sec to let the Xtal stabilize after a power-on, __disable_interrupt(); // disabel global interrupt cbi(TIMSK2, TOIE2); // disable OCIE2A and TOIE2 ASSR = (1<<AS2); // select asynchronous operation of Timer2 TCNT2 = 0; // clear TCNT2A TCCR2A |= (1<<CS22) | (1<<CS20); // select precaler: 32.768 kHz / 128 = 1 sec between each overflow while((ASSR & (0x01 | 0x04))); // wait for TCN2UB and TCR2UB to be cleared TIFR2 = 0xFF; // clear interrupt-flags sbi(TIMSK2, TOIE2); // enable Timer2 overflow interrupt OCR2A = 200; // set timer2 compare value while(ASSR & 0x02); // wait for OCR2UB to be cleared __enable_interrupt(); // enable global interrupt }
It is to achieve an interrupt every second to wake the system up with a 32.768kHz crystal oscillator. My question is, if it is better to put these two lines in the ISR:
TCCR2A = TCCR2A; // dummy write while(ASSR & 0x01); // wait for TCR2UB to be cleared
because of the following description from the data sheet:
Reading of the TCNT2 Register shortly after wake-up from Power-save may give an incorrect
result. Since TCNT2 is clocked on the asynchronous TOSC clock, reading TCNT2 must be
done through a register synchronized to the internal I/O clock domain. Synchronization takes
place for every rising TOSC1 edge. When waking up from Power-save mode, and the I/O clock
(clkI/O) again becomes active, TCNT2 will read as the previous value (before entering sleep)
until the next rising TOSC1 edge. The phase of the TOSC clock after waking up from Power-
save mode is essentially unpredictable, as it depends on the wake-up time. The recommended
procedure for reading TCNT2 is thus as follows:
1. Write any value to either of the registers OCR2A or TCCR2A.
2. Wait for the corresponding Update Busy Flag to be cleared.
3. Read TCNT2.
Thank
Owen