Problem with setting OCR1A on Atmega16

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

After doing the USART and the AVR timers tutorials, I decided to combine them. The idea is to control how many time a second an LED blinks. It works fine except when I enter a new value there is a delay of about 5 second where the LED is either on or off before it starts to blink with the new value. Is this normal or did I do something wrong with the timer? How can I get rid of this delay ?

The Atmega16 is running from STK500 clock at 3.686MHz. There is another file that handles the USART, it sends the new values to parceInput.
here is the code

#include "PC_comm.h"

#define Hertz 14398

int main(void)

{
	initUSART();
	Initializer(); //run initializing rutine
	for(;;)
	{

	}

}

void Initializer()
{
	
	
	sendString("\nInitializer Running\r\n");
		
	DDRD |= (1<<5); //LED for output
	TCCR1B |= (1<<WGM12);	//Set up timer in CTC mode
	TCCR1A |= (1 << COM1A0);//Enable timer1 Compare Output Channel A in toggle mode 
	OCR1A = 14398; //Set timer compare value to 1 second
	TCCR1B |= (1 << CS12); // Start timer at Fcpu/256 

	sendString("PrecisionBlinking on\r\n");

}

void parceInput(char s[])
{
	unsigned int freq;
	freq = atoi( s );
	// set new compare calue
	OCR1A = Hertz/freq;
}

thanks in advance

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

A typical mistake when operating timers is that you change the upper limit to a number which is less than the present value of the counter (assuming you're counting up). What happens then is that the counter has to roll all the way up to an overflow and then from 0 up to the limit you just set.

The workaround is to set the counter value to a known good number (between the upper and lower limit) when you change the limits. It is also a good thing to disable the timer interrupt while you are modifying the limits and the counter, and then re-enable it when you're done.

Hope this helped!

Børge

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

try this...

void parceInput(char s[]) 
{ 
   unsigned int freq; 
   freq = atoi( s ); 

   //stop timer
   TCCR1B &= ~((1 << CS12) | (1 << CS11) | (1 << CS10));

   // set new compare value 
   OCR1A = Hertz/freq; 

  //reset counter
  TCNT1 = 0;

  //Start Timer again
  TCCR1B |= (1 << CS12);


}