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(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?
Best Answer
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 '='