OC2A and OC2B on ATMEGA328 not completely off in Fast PWM

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

Hi,

I am learning Fast PWM with ATMEGA328 with 4 LEDs connected to OC1A, OC2A, OC1B, and OC2B. The following is the relevant code:


void setFast_PWM()
{
//Atmega328 two fast PWM channels from OC1x
	set_output(DDRB,PB1); //OC1A
	set_output(DDRB,PB2); //OC1B
	TCCR1A=0;
	TCCR1A  |= _BV(WGM12) | _BV(WGM10);//set fast PWM mode
	TCCR1A |=_BV(COM1A1) | _BV(COM1B1); //non-inverting for both OC1A and OC1B
	TCCR1B |= _BV(CS11);	//prescaler=8

//Atmega328 two fast PWM channels from OC2x
	set_output(DDRB,PB3); //OC2A
	set_output(DDRD,PD3); //OC2B

	TCCR2A=0;//reset?
	TCCR2A |= _BV(WGM21) | _BV(WGM20); // set fast PWM Mode
	TCCR2A |= _BV(COM2A1) | _BV(COM2B1); //set non-inverting mode for both OC2A and OC2B.
	TCCR2B |= _BV(CS21); // set prescaler to 8 and starts PWM
}

int main(void)
{
	set_output(DDRB,PB1); //OC1A
	set_output(DDRB,PB2); //OC1B
	set_output(DDRB,PB3); //OC2A
	set_output(DDRD,PD3); //OC2B

	//setFP_PWM();
	setFast_PWM(); //use fast PWM for all 4 PWM channels

//turn off all 4 LEDs	
		OCR1A=0; 
		OCR2A=0;
		OCR1B=0;
		OCR2B=0;
}

I found that OC2A and OC2B are not completely turned off when they are set to 0 (see above code). The LEDs show a very faint light and when I measured the voltage on PB3 and PD3, there is about 0.014v. This is in contrast to the 0.002v for OC1A and OC1B which are both off. The VCC is powered at 3.3v.

What am I doing wrong? Thanks.

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

Quote:
What am I doing wrong?
Nothing. There is always a brief (less than a clock tick) time when the output is high. You can switch to inverted signals, then you will get full off, but instead you will never have exactly full on. I believe that this is not a problem with phase correct mode.

Regards,
Steve A.

The Board helps those that help themselves.

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

Koshchi wrote:
I believe that this is not a problem with phase correct mode.
It isn't. You get full off, full on, and 254 steps in-between. The catch is the timer's max resolution is not a power-of-two. That's not usually a problem.

One way to deal with Fast PWM is to trap the zero case and disable the COMxn outputs and use the pin's PORT register to drive the pin low. That's how Arduino does it for OC0A/B on TIMER0, which is configured for single-slope fast PWM for easier use as a basis for millis() and the other timing functions.

The catch there is that you 'lose' a step in the available duty cycles. You get full off, full on, and 2/256 through 255/256, but not 1/256.

JJ

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

Isn't there a solution involving:

Invert the output and count 255 as "off" and 0 as "full on?" Hmm, I don't think that's what it was. Maybe somebody less ADD will chime in.

What I just did is turn off the high-side driver when I set the speed to 0, and on when the speed != 0.

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

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

Quote:
Isn't there a solution involving:

Invert the output and count 255 as "off" and 0 as "full on?"

But as I said above, 255 (or rather, TOP since it might not be 8 bit PWM) would be full off, but 0 would not be full on.

Regards,
Steve A.

The Board helps those that help themselves.

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

All, just tested and inverting worked. Thanks to all.

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

terrapin8 wrote:
All, just tested and inverting worked. Thanks to all.
So, I guess you don't need 'full-on' then?

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

0 then is "Full on."

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

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

Torby wrote:
0 then is "Full on."
Nope.

In inverting mode '0' is a duty cycle of 255/256, 'almost' full on. For an LED, it doesn't matter, but it will in other circumstances.

Fast PWM available Duty cycles (at full 8 bits):
------------------------------------------------
Non-inverting:  1/256 through 256/256
Inverting:      255/256 through 0/256

JJ

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

Oh. I see. Yea, for a motor, 255/256ths is pretty much on too.

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut.