Timer Halt/delay when changing OCR1A value

Last post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi

im having some problems with some delay or halt of the timer when a change the OCR1A value.

this is what happens.

1: the timer runs fine
2: i change OCR1A to a minor change in value
3: timer seems to stop for a little time, but much longer then the timer trigger time.

using AVRGCC and Mega 328p 20Mhz with Timer1


void init_Timer1(void)
{


   	TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode

   	TIMSK1 |= (0 << OCIE1A); // disable CTC interrupt

   	OCR1A   = 0x01F0; // 
   	
   	TCCR1B |= ((1 << CS10) |(0 << CS10) | (1 << CS11)); // Start timer at Fcpu/8

	TIMSK1 |= (1 << OCIE1A); // Enable CTC interrupt

}

if i only change OCR1A value, the halt time is changing time to time, some time no halt is noticed.

		// Set OCR1A / Speed Settings
		OCR1A = MainSpeedValue / MainMicrostepValue;

MainMicrostepValue = 0 or 1 or 2

but if i resets timer before, the Halt time is always the same

		// Set OCR1A / Speed Settings
		TCNT1L = 0x00;									// Reset Counter
		TCNT1H = 0x00;
		OCR1A = MainSpeedValue / MainMicrostepValue;

if i dont change value of OCR1A in my code, there is no delay, so it have to do with this part of the code.

Much grateful for any help :D

Thanks // Micke

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

data sheet section 15.9.2 wrote:
If the new value written to OCR1A or ICR1 is lower than the current value of TCNT1, the counter will miss the compare match. The counter will then have to count to its maximum value (0xFFFF) and wrap around starting at 0x0000 before the compare match can occur. In many cases this feature is not desirable. An alternative will then be to use the fast PWM mode using OCR1A for defining TOP (WGM13:0 = 15) since the OCR1A then will be double buffered.

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

well the problem is you're in CTC mode, and you're asynchronously changing the compare value. Updates are immediate, but if you change to a value that is less than the current count, the timer will need to overflow before it reaches your compare value, thus creating a delay. Change your code to use an interrupt, and update the compare value at the compare match point. This will guarantee that the timer will always be starting over from 0 just as you're setting the value.

Also note that:

TIMSK1 |= (0 << OCIE1A); // disable CTC interrupt 

does not disable anything.

0 OR 0 = 0
1 OR 0 = 1
0 OR 1 = 1
1 OR 1 = 1

as you are ORing a 0 in, the result will be whatever value that bit had going into that line.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

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

Quote:

OCR1A = MainSpeedValue / MainMicrostepValue;

MainMicrostepValue = 0 or 1 or 2


Dividing by 0 should give some interesting results. ;)

Youd division by a small number will result in fairly large changes to OCR1A. Example: If MainSpeedValue is 10000, /1 gives 10000, /2 gives 5000, and /0 gives who-knows-what.

If you change the value from 10000 to 5000 when the count is, say, 7000 then it needs to count up to 65k, wrap, and then count to 5000 before it "trips". I suspect that is what you are seeing. If you are in a CTC mode that resets TCNT1 at compare match, then using compare match or overflow (if that mode supports it) interrupt (either ISR or polling) to change the value when TCNT1 is a very small number and you shouldn't lose any periods.

We'll assume your compiler does the proper write of OCR1A.

Either change after a compare match and reset of TCNT, or use phase-and-frequency-correct mode(s) and update both TOP and the "trip" point at an appropriate time.

Lee

You can put lipstick on a pig, but it is still a pig.

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

Sorry my bad , its divided by 1,2,4,16

and by doing this its working quite fine

// Set OCR1A / Speed Settings
TCNT1 = (MainSpeedValue / MainMicrostepValue) - (MainSpeedValue*0.1);									

OCR1A = MainSpeedValue / MainMicrostepValue;

is this a good solution ??

Thanks :)

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

if your app is fine with the jitter introduced, and the addition of the floating point libraries, then sure.

Writing code is like having sex.... make one little mistake, and you're supporting it for life.