6
\$\begingroup\$

I'm currently using an ATmega32 to keep time, so I carefully read the datasheet and configured the Timer 1 to generate an interrupt each second.

According to the following formula on the datasheet, using a 16 MHz clock, a prescaler of 256, and OCR1A = 31249, I should get a frequency of 1 Hz in CTC mode:

\$ f_{OCnA} = \frac{f_{clk\_I/O}}{2\: \cdot \: N \cdot \: (1 \: + \: OCRnA)} \$

This formula is available on page 99 of the ATmega32 datasheet.

I've configured Timer 1 as follows:

TCCR1A = 0;
TCCR1B = (1<<WGM12)|(1<<CS12);
OCR1A = 31249;
TIMSK = (1<<OCIE1A);

Here is the interrupt code

ISR(TIMER1_COMPA_vect){
    sec++;
}

Then, I use an LCD to continuously print the value of sec, and I get a timing of 0.5 seconds. In other words, for each second that passes, the timer generates two interrupts.

At first I thought maybe I got the fuses wrong, but that doesn't seem to be the case, as delays work just fine. Anyway, here's how I configured the fuses:

-U lfuse:w:0xff:m -U hfuse:w:0x99:m

I have absolutely no idea of what's going on, I've double checked everything, tried another ATmega32, tried another 16 MHz crystal oscillator, and I still get the same result.

Is the datasheet wrong, or am I missing something here?

\$\endgroup\$
1
  • \$\begingroup\$ TL;DR Answer: No. No it's not. ;-) \$\endgroup\$ Dec 4, 2015 at 0:29

2 Answers 2

14
\$\begingroup\$

If the system clock is 16 MHz and the prescaler is 256, you timer will run on \$ \large \frac{16\,MHz}{256} = \small 62500\,Hz \$ , so there will be an increment in every \$ \large \frac{1}{62500\,Hz} = \small 16\, \mu s \$. An interrupt will be generated when the counter's value is 31249. If we calculate this time: \$ \small 16\, \mu s \times 31250\, ticks = 0.5\, s\$, which is exactly the same result you have.

The equation in the datasheet is for a different purpose:

For generating a waveform output in \$ \small CTC\$ mode, the \$ \small OC1A\$ output can be set to toggle its logical level on each compare match by setting the compare output mode bits to toggle mode \$ \small (COM1A1:0 = 1)\$. The \$ \small OC1A\$ value will not be visible on the port pin unless the data direction for the pin is set to output \$ \small (DDR_{OC1A} = 1)\$. The waveform generated will have a maximum frequency of \$ \small fOC1A = fclk_{I/O}/2 \$ when \$ \small OCR1A\$ is set to zero \$(0x0000)\$. The waveform frequency is defined by the following equation: (...)

If you would measure the frequency of specific pin, I think it would be 1 Hz.


To achieve an 1 s, \$ \small 16\, \mu s \times 62500 = 1\,s\$ interrupt generation you need 62500 ticks and as the counter starts from 0, set OCR1A to \$ \small 31250 \times 2 - 1= 62499\$, and since Timer1 is a 16 bit timer this value is not too high (<65535, \$ 2^{16}-1 \$).

\$\endgroup\$
2
  • 4
    \$\begingroup\$ It's actually 62499, and you need to add 1 before multiplying by the clock period. \$\endgroup\$ Dec 4, 2015 at 0:10
  • 2
    \$\begingroup\$ Oh! I feel so dumb right now, I didn't notice that it toggled the pin, so I just assumed it was the same formula!! So, if I want precisely 1 second (as precise as the crystal is), I should use OCR1A = 62499, right? According to the formula (now dropping the 2), that should give me precisely 1 second. \$\endgroup\$
    – Chi
    Dec 4, 2015 at 0:30
5
\$\begingroup\$

That formula is for the output frequency of the OCnA pin ("For generating a waveform output in CTC mode, the OC1A output can be set to toggle its logical level on each compare match by setting the compare output mode bits to toggle mode (COM1A1:0 = 1). [...] The waveform frequency is defined by the following equation:"). Since you're using the interrupt instead you will receive two compares per period. Drop the 2 from the denominator to calculate the interrupt frequency.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.