## frequency and OCR0A value

7 posts / 0 new
Author
Message

Hi,

I have the following code where I wanted to set the frequency by loading the corresponding value needed to be loaded into OCR0A channel A using equation but it gives incorrect frequency output. But when I calculate OCR0A value for frequency and directly put it it gives correct frequency output. I think, something is wrong while converting the equation to OCR0A value. Can anybody tell me what I am doing wrong? thanks

```
#define F_CPU 16000000UL

#include <avr/io.h>
#include <avr/interrupt.h>

ISR(TIMER0_COMPA_vect){
PORTD ^= (1<<PD2);
}
uint16_t Freq;

int main()
{

DDRD |= (1<<PD2);

TCCR0A |= (1<<WGM01);	//prescalar set to 256, CTC mode 2
TCCR0B |= (1<<CS02);
TIMSK0 = (1<<OCIE0A);	//set interrupt on A

Freq = 1000;
OCR0A = ((F_CPU / (2*256*Freq) - 1));
sei();

while (1);

return 0;
}```

Last Edited: Sat. Jul 31, 2021 - 01:13 PM

You have overflow in the (2*256*Freq) expression, it's computed using 16 bits. Try

`	OCR0A = ((F_CPU / (2*256UL*Freq) - 1));`

/Lars

Lajon wrote:

You have overflow in the (2*256*Freq) expression, it's computed using 16 bits. Try

`	OCR0A = ((F_CPU / (2*256UL*Freq) - 1));`

/Lars

hi,

I tried but didn't give right output frequency. I tried casting too such as OCR0A = (int)(equation) and OCR0A=(uint8_t)(equation) but didn't work too.

Last Edited: Sat. Jul 31, 2021 - 01:43 PM

avr101 wrote:
I tried but didn't give right output frequency.

What output frequency do you get?

note: you can get close to 1000Hz, but dividing a 16MHz clock down to exactly 1000Hz using an 8 bit counter is not possible.

Jim

Keys to wealth:

Invest for cash flow, not capital gains!

Wealth is attracted, not chased!

Income is proportional to how many you serve!

ki0bk wrote:

avr101 wrote:
I tried but didn't give right output frequency.

What output frequency do you get?

note: you can get close to 1000Hz, but dividing a 16MHz clock down to exactly 1000Hz using an 8 bit counter is not possible.

Jim

hi,

from the code I have posted, I get frequency of around 1.68Khz. With OCR0A=30 direct input I get 1000Hz. I could not figure out how to make the equation come close to the value of 30 or for other frequency input as well. It is same for other frequencies, the equation that I posted just calculates some other value instead of value expected. I think it has to do with rounding and casting value. I also tried round() function but could not make it work.

Last Edited: Sat. Jul 31, 2021 - 02:11 PM

Tested on real hardware...

`	OCR0A = ((F_CPU / (2*256*(uint32_t)Freq) - 1));`

...gives 1008Hz.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

`OCR0A = ((F_CPU / (2*256UL*Freq) - 1));`