2
\$\begingroup\$

I'm using an ATtiny85 to generate a PWM output (using Timer0 in OCR mode), and this PWM output is being switched on and off at regular intervals. I am finding that when switching on the PWM output, there is a delay before it actually starts outputting.

Look at the screenshot below, the green line shows the state I am putting the PWM into (either on or off via TCCR1) and yet there is a delay of what looks like one full cycle before it starts. I've tried also resetting TCNT0 to 0, but this had no effect.

Enter image description here

(Timebase is 20 μs.)

SET(DDRB, PB1);
SET(DDRB, PB2);
// Set up PWM for 460 kHz with 8 MHz clock
TCCR1 = (1<<PWM1A) | (1<<COM1A1) | (1<<COM1A0) | (1<<CS10); // Prescaler = none;
GTCCR = (1<<FOC1A);
OCR1A = 9; // 460.750 kHz
OCR1C = 18;
#define BIT_DELAY ((1000000/38400))
while(1) {
 SET(TCCR1, PWM1A);
 SET(PORTB, PB2);
 _delay_us(BIT_DELAY);
 CLR(TCCR1, PWM1A);
 CLR(PORTB, PB2);
 _delay_us(BIT_DELAY);
}
Peter Mortensen
1,6973 gold badges17 silver badges23 bronze badges
asked Mar 5, 2016 at 16:10
\$\endgroup\$
2
  • \$\begingroup\$ Can you please share the code snippet \$\endgroup\$ Commented Mar 5, 2016 at 16:16
  • \$\begingroup\$ yep added, thanks! One pin is the green and the other is the timer output \$\endgroup\$ Commented Mar 5, 2016 at 16:23

1 Answer 1

2
\$\begingroup\$

Disabling the PWM mode of TIMER1 does not stop TCNT from counting - it only stops the PWM from being output.

So when you disable the output using CLR(TCCR1, PWM1A), TCNT1 keeps merrily counting along and does not reset to 0 when it hits OCR1C since it is not in PWM mode anymore. It runs right past OCR1C and will keep on counting up to 255 when it rolls over.

The delay you are seeing is the time it take TCNT1 to count from where ever it happens to be when you enable PWM mode back to OCR1C, at which time it will reset to 0 and start doing a normal PWM cycle.

One way to control when the PWM cycle starts after you enable PWM mode is to preload the counter such that it will not have to do a wrap around before starting the normal PWM compare points in OCR1A and then OCR1C. For example...

 while(1) {
 TCNT1=254;
 SET(TCCR1, PWM1A);
 SET(PORTB, PB2);
 _delay_us(BIT_DELAY);
 CLR(TCCR1, PWM1A);
 CLR(PORTB, PB2);
 _delay_us(BIT_DELAY);
 }

... generates this waveform...

enter image description here

Note that this approach seems like a hack to me and that there are probably better ways to gate the PWM signal that would more straightforward, but the best choice would depend on your application.

answered Mar 6, 2016 at 15:33
\$\endgroup\$
1
  • \$\begingroup\$ thanks. Would have never noticed the ocr1c compare was being disabled too! \$\endgroup\$ Commented Mar 19, 2016 at 21:40

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.