Phase and Frequency correct PWM doesn't working. ATmega32u4.

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

Hello every one! I'm trying to turn on PFC PWM on timer 3 on ATmega32u4. But my code doesn't work. OC3A pin is always at HIGH level. Maybe I misunderstood something or was mistaken?

My code example:

 

#include <avr/io.h>

#define F_CPU 16000000UL

#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	DDRC = 1 << 6;												//	Set OC3A as an output
//	sei();

	uint16_t frequency = 1;
	uint8_t dutyCycle = 20;

	TCCR3A = 1 << COM3A1 | 0 << COM3A0 | 1 << WGM30;			//	Turn on PFC PWM mode with TOP = OCR3A
	TCCR3B = 1 << WGM33 | 1 << CS32 | 0 << CS31 | 1 << CS30;	//	Prescaler = 1024
	OCR3A = (F_CPU / (2 * 1024 * frequency));					//	Set the frequency, i.e. TOP value
	uint16_t temp = OCR3A;
	OCR3B = (temp * dutyCycle) / 100;							//	Set the duty cycle

    while (1)
    {

    }
}

 

Ruslan

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

Ah-ha.   I thought that I would just run it through the Simulator in AS7.

Unfortunately,  the Simulator is not available for the 32U4.   So I built for the 1284P which also has a Timer3

 

You have selected PWM#9 which uses OCR3A as TOP.

And the PWM would only be available on the (non-existent) OC3B pin.

 

If you use PWM#8 you can set the TOP with ICR3 register.

And would get output on OC3A pin (PC6).

 

Life would be much simpler if the Simulator worked on 32U4.   I have an Arduino Leonardo.   So I could try it on real hardware but am too lazy.

 

Yes,  it would be fairly logical for the non-existent OC3B pin to "appear" on OC3A pin.   The only way to find out is to try it.

You could also experiment with the COM3B and COM3C bits.

 

My datasheet is (c) 2010.  So a modern version might be less obtuse.

 

David.

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

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

Last Edited: Sun. Mar 4, 2018 - 06:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

David, thank you very much! Everything is working!

Ruslan

Last Edited: Sun. Mar 4, 2018 - 09:13 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

First off.   Larry's link did not work.   This one should be ok http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7766-8-bit-AVR-ATmega16U4-32U4_Datasheet.pdf

 

From a brief glance at the "up to date" datasheet it is equally confusing.

 

I suggest that you do your own experiments to see exactly what COM3C does.   And whether OC3B and OC3C are actually connected to the outside world.

 

This family is 8 years old.   I would have thought the COM3C OC3B functionality has been discussed by now.

 

Mind you,   anyone using PWM on Timer3 is unlikely to want Input Capture at the same time.  i.e. just use PWM#8

 

David.

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

david.prentice wrote:
First off.   Larry's link did not work.
Edited the broken link, see the EDIT.

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius