The goal is to generate and output square wave via pin 0 on port C and be able to change the frequency of the signal while running.
I used the 16 bit Timer1 on an ATMega16. The compare interrupt is enabled. The interrupt routine handles toggling the output pin high and low. The frequency is varied by changing the compare value OCR1A.
This works but periodically, it appears that the interrupt is not called for about 8.5ms and then continues. I observed this behavior with a logic analyzer on the output pin.
I have been through the datasheet carefully, but did not find any solution or explanation. Can anyone explain this?
Here is a simple bit of code that exhibits the behavior:
uint16_t step = 0; void main(void) { uint16_t j = 256; // Step PC0 to output DDRC |= BV(PC0); // Enable CTC mode and set Prescaler to 1 TCCR1B |= (1 << CTC1) | (0 << CS12) | (0 << CS11) | (1 << CS10); // Enable Timer1 compare interrupt TIMSK |= (1 << OCIE1A); // Set compare value OCR1A = 256; asm("sei"); while (1) { delay_ms(2); OCR1A = j; if (j == 256) j = 512; else j = 256; }; } #pragma interrupt_handler TIMER1Handler:iv_TIMER1_COMPA void TIMER1Handler(void) { PORTC ^= BV(PC0); }
The code simple changes the compare value OCR1A back and forth from 512 to 256 every 2 milliseconds. The interrupt handle toggles the output pin (PC0).