I want to generate waveform with f = 196 Hz using only normal mode. Here is the code I use. Whenever the timer overflows TOV1 is set and PIND0 will toggle. TOV1 is cleared after that and I wait for another overflown to happen so PIND0 will toggle again.

I tried my code, with PIND0 connected to the LED. On power up, the LED turned on and off a short time after that but it didn't turn on again. Because it had turned off means that the overflown happened so PIND is toggled but I don't know why it didn't turn on again. I even tried to not clear TOV1 but get the same result as TOV1 is cleared.

#include <avr/io.h>
#define F_CPU 25690112UL
int main(void)
    TIFR1 |= (1<<TOV1); // clear timer 1 overflown flag
    DDRD = 0xFF; // set port D as output
    TCCR1B = 0b00000001; // using internal I/O clock with prescaler 1
        while(TIFR1 & (1<<TOV1)){
            PIND ^= (1<<PD0); // toggle bit 0 on port D
            TIFR1 |= (1<<TOV1); // clear TOV1 by adding 1 to TOV1

Can anyone see an error in my code?

  • \$\begingroup\$ Can you try using if instead of while(TIFR1 & (1<<TOV1)){ \$\endgroup\$ – Swanand Dec 21 '15 at 7:43

The PIND ^= (1 << PD0) line is off.

The PIN register holds the actual physical state pins, and would not normally be written. The PORT register sets the state of the pin drivers.

However, as a common read-only register is a waste of I/O address space, Atmel added a neat feature to the pin register: Writing a bit mask to PIN will toggle the corresponding bits in PORT. The line 'PIND ^= mask' is then approximately the same as PORTD XOR PIND XOR mask. Since PIND reads the pins PORTD drives, PIND is usually = PORTD, which results in this being equivalent to 'PORTD = mask'.

Try substituting 'PIND' with 'PORTD', -or- '^=' with just '='


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.