Ganesh S
Ganesh S

Reputation: 21

AVR (debugging) PWM generation

I wrote a simple program to generate PWM wave with 50% duty cycle. Then I went for debugging in AtmelStudio. All registers except OCR0 were assigned there respective values. Why OCR0 not assigned any value. ATmega32, Fast PWM.

#include <avr/io.h>
int main(void)
{
DDRB = (1 << PB3);
TCCR0 |= (1 << WGM01) | (1 << WGM00) | (1 << COM01);
OCR0 = 127;
TCCR0 |= (1 << CS02);
return 0;
}

Upvotes: 0

Views: 222

Answers (1)

spectras
spectras

Reputation: 13542

So anyway.

You're using the 8-bit counter0 on your Atmega32. Let's see how you set it up:

// Set Pin B3 as output, others as input
DDRB = (1 << PB3);

// Set Clear on compare match + Fast PWM mode + Counter stopped
TCCR0 |= (1 << WGM01) | (1 << WGM00) | (1 << COM01);

// Set comparator value to 127
OCR0 = 127;

// Enable clkIO/256 from prescaler, turning on the counter
TCCR0 |= (1 << CS02);

Okay. First, a few things:

  • On initial setup, you usually want to assign the value and not or it, to be certain of its state.
  • Even after, setting it instead of or-ing it avoids a useless read. No impact on behavior for this register, but might be a bit better for performance.
  • The documentation recommends only enabling the output after you have set it up properly, to avoid spurious output. So you should move the first line last.

I'll be reading from that version of the datasheet.

Now, in fast PWM mode, according to table 38, and 40, the counter behaves like this:

  • It counts from BOTTOM to MAX (0 to 0xFF).
  • OCR0 is only used to toggle OC0 pin, not to reset the counting.
  • OCR0 has double-buffering. Its actual value is not updated until next cycle.

This might be your issue. If any of those are true:

  • Counter doesn't start properly (could happen if CS2-0 are not correct due to or-ing them instead of setting them).
  • Counter is stopped early (because your program ends and if the studio detects it, it could disable it at that point - I d'ont use the studio so I cannot really tell).

Then it is possible the value you write to the double buffer never makes it to the actual register. Alas the datasheet doesn't explain in detail how this is handled. Nor does it tell whether reading OCR0 while double buffering is active returns current value or awaiting value.

Upvotes: 1

Related Questions