0

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;
}
Lundin
220k47 gold badges281 silver badges446 bronze badges
asked Oct 6, 2017 at 5:53
15
  • 2
    Where is your never ending loop? Commented Oct 6, 2017 at 6:10
  • What makes you think that your attempt to write a value did not succeed? Does the hardware specification describe the OCR0 register as readable? Is it perhaps write-only? Commented Oct 6, 2017 at 6:31
  • @tilz0R Please elaborate. What is a never ending loop needed for? Commented Oct 6, 2017 at 6:32
  • 1
    @Lundin> that very compiler (namely avr-gcc) uses int main(void) and return0; in its documentation. It does make sense on a microcontroller, it has whatever sense its C runtime library gives it. On large systems it's "cleanup and terminate process with that error code", but a runtime library could perfectly define "exit main with non-zero and I shall blink some red led furiously". Commented Oct 6, 2017 at 8:15
  • 1
    Don't get me wrong, I don't like seeing that either, even if I do want to freeze the device I'd rather put it in standby/sleep mode. I simply wanted to point out it is valid and it makes sense as long as the platform documentation says so. And it generates the exact same binary you would with a manual for(;;) {}. So there is no reason to call him out on that. Actually there is one thing it does better when using c++: it invokes destructors of objects in main()'s scope, which the manual infinite loop does not do. Commented Oct 6, 2017 at 9:32

1 Answer 1

1

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.

answered Oct 6, 2017 at 9:11
Sign up to request clarification or add additional context in comments.

Comments

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.