Good day everyone!
I'm facing a problem while I'm trying to set the ATmeag8aTIMER2 in CTC mode, the problem is when I'm giving OCR2 some value it doesn't affect the TIMER2, the timer doesn't give me the result I want,
I set fuses to internal 8MHZ oscillator
and I'm using external 32.768Khz crystal and this code:
void setup() {
cli();
ASSR = 0x08; // set clockSource to external crystal
TCNT2 = 0;
OCR2 = 32; // compare register
TCCR2 = 0b10001111; // CTC, no port output, 1024 prescaler
while ((ASSR & 0x07)); // Wait until updating of the Above 3 register completes
sei();
TIMSK |= (1 << OCIE2); // activate compare match interrupt.
pinMode(13,OUTPUT);
}
volatile bool a;
ISR(TIMER2_COMP_vect) {
a=!a;
}
void loop{
digitalWrite(13,a);
}
What I expect is to toggle the LED on 13 pin every exactly 1 second, what I get is a very speed flashing LED,
but if add this inside the ISR:
OCR2=32;
it gives me what I want but freezes for a second every approximately 5 minutes,
I read in datasheet and internet and found some examples they set OCR2 value only in the setup{}
why it doesn't work with me, what should I do ?
why OCR2 forgets its value ? or there is another issue ?
How that? 32kHz and a prescaler of 1024 yields about 1kHz, and OCR of 32 yields 1/32 kHz or about 33 Hz and a blink rate of 16 Hz. Isn't this what you really get?
oscillator freq. / prescaler = output timer frequencey 32768 / 1024 = 32Hz
so if I set OCR2=32 I should get 1Hz flashing LED
is that right ?
anyway, if I set OCR2 = 1 or OCR2= 200 nothing changes
the led flashes at same speed (as I see)
I would say -- yes, it is right! Then where is the problem?
37.768 kHz/1024 = 32 Hz
The driving clock for TCCR2 (clkTc2) is : 32 Hz, which means that the TCNT2 will count 32 clock pulses in 1-sec. If OCR2 is loaded with 32, then the COMP flag (OCF2) will set 1-sec point which can be used to interrupt the MCU. The timing is shown below (Fig-1):
Figure-1:
2. Kindly, re-arrange your setup codes as follows and re-run the sketch. You should not start TC2 until initialization is done.
One possibility is that the registers are busy when you update them. I would check the busy flags after setting AS2 and before writing to the registers:
ASSR = 0x08; // set clockSource to external crystal
while (ASSR & 0x07); // Wait until the registers are not updating.
TCNT2 = 0;
OCR2 = 32; // compare register
TCCR2 = 0b10001111; // CTC, no port output, 1024 prescaler
while (ASSR & 0x07); // Wait until updating of the Above 3 register completes
I would NOT set the Force Output Compare bit in TCCR2: TCCR2 = 0b00001111; // CTC, no port output, 1024 prescaler
Note: You should set OCR2 to 31 to get 32 counts.
That's all I can suggest for now.
Do you have an oscilloscope you could use to check the clock frequency?
Note: If the 8 MHz clock is leaking through you'll get about 244 Hz interrupt (instead of 1 Hz) for an output frequency of 122 Hz (two octaves below middle B).
Needs clarification as to why the OCR2 register should be loaded with 31 and not 32 for the OCF2 flag to get set at every 1-sec interval in CTC-2 mode operation of TC2 of ATmega8A MCU.
If we solve the following equation, then it comes 31--
f = 32768/(2*N*(1+OCR2))
==> 0.5 = 32768/(2*1024*(1+OCR2)) //period = 2 sec; so f = 0.5 Hz
==> 1+OCR2 = 32768/(2*1024*0.5)
==> OCR2 = 32 -1 = 31
The counter starts at zero and counts up to and including TOP. The first state is zero, the second one is 1, and the N-th state is N-1. For 32 states the last one is 31, followed by 0.
1. Initially, TCNT2 contains 0. After that and at the very first start, the TCNT2 must count 32 pulses (RE, HIGH, FE or LOW) to spend 1-sec time -- is this correct?
2. If Step-1 is correct, then OCR2 must be loaded with 32 to make an equality comparison at 1-sec -- is this correct?
3. At the equality point, the TCNT2 goes to BOTTOM (due to CTC Mode) and this transition from TOP to BOTTOM requires 1 clock pulse -- is this correct?
4. So, excluding the beginning compare phase, the remaining compare phases does include this transition time: 1x1/32-sec
5. Therefore, at steady-state operation, the OCR2 must be loaded with 31 which being added with the transition clock gives 32.
6. My stand is: the count should be 32 to measure 1-sec time when the driving clock for TCN2 is 32.768 kHz/1024. For steady-state operation, OCR2 should be loaded with 31 for the reason described in Step-5.
but now I still facing a problem,
the frequancy is precise 1HZ, but I'm losing some seconds in an hour..
it looks like the interrupt doesn't occur for some reason every 10 or 15 minutes, it's not periodic, it happens randomly.
There is nothing nearby that make noise or something similar
and I programmed CKOPT fuse that activated internal capacitors and make oscillator Full swing
can the code affect the interrupt ? or the interrupt must occur whatever the processor is doing ?