frequency and OCR0A value

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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

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

/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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!

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Tested on real hardware...

 

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

...gives 1008Hz.

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

#2 Hardware Problem? Read AVR042.

#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."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avr101 wrote:
I think it has to do with rounding and casting value. I also tried round() function but could not make it work.

I already wrote what the reason is in post #2, with the code 

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

you will get 30 in OCR0A. I get 1005 Hz on a Arduino UNO.

/Lars