Author Topic: Atmega2560 PWM  (Read 4897 times)

0 Members and 1 Guest are viewing this topic.

Offline dan3460Topic starter

  • Frequent Contributor
  • **
  • Posts: 326
  • Country: us
Atmega2560 PWM
« on: May 07, 2017, 02:35:46 am »
I'm a little confused when setting up a PMW on a pin. I was trying to setup a 50% duty cycle on PB5 which is OC1A, I was not able to get any signal on that port (I'm using an Arduino mega that is on port 11), check the code several times then I noticed that the LED that is pegged to PB7 which is OC1C (Arduino port 13) was steady but a dimmed. I put the scope there and there was the PWM. See note below
Here is the setup code:
Code: [Select]
PSUFan::PSUFan()
{
freqSet = 0;

DDRB |= (1<<PB7);
setDutyCycle(80);
TCCR0A |= (1<<WGM01)|(1<<WGM00)|(1<<COM0A1);
TCCR0B |= (1<<CS02)|(1<<CS00);

} //PSUFan

I'm very confused on how to setup PWM. Can I have different waves on each pin? how do you control each pin? Sorry, may be i'm just too old to understand.

Thanks for the help.

Note, I notice that because I have the led blinking to indicate that the program is working. That is why I put PB7 on the code, originally I had PB5.
 
« Last Edit: May 07, 2017, 02:38:22 am by dan3460 »
 

Offline FreddyVictor

  • Regular Contributor
  • *
  • Posts: 164
  • Country: gb
Re: Atmega2560 PWM
« Reply #1 on: May 07, 2017, 07:05:43 am »
I'm a little confused when setting up a PMW on a pin. I was trying to setup a 50% duty cycle on PB5 which is OC1A, I was not able to get any signal on that port (I'm using an Arduino mega that is on port 11), check the code several times then I noticed that the LED that is pegged to PB7 which is OC1C (Arduino port 13) was steady but a dimmed. I put the scope there and there was the PWM. See note below
Here is the setup code:
Code: [Select]
PSUFan::PSUFan()
{
freqSet = 0;

DDRB |= (1<<PB7);
setDutyCycle(80);
TCCR0A |= (1<<WGM01)|(1<<WGM00)|(1<<COM0A1);
TCCR0B |= (1<<CS02)|(1<<CS00);

} //PSUFan
obvious issue: OC1A
and: TCCR0A TCCR0B
0 is Timer0, 1 is Timer1
I'm very confused on how to setup PWM. Can I have different waves on each pin? how do you control each pin? Sorry, may be i'm just too old to understand.
You can have different duty cycles for each pin, but the frequency is set for each Timer so this remains constant across the pins attached to that Timer
 

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 2416
  • Country: us
Re: Atmega2560 PWM
« Reply #2 on: May 07, 2017, 07:57:58 am »
It gets complicated if you can't use a library for easymode. But don't forget that library source can provide valuable clues on how to do it yourself. The atmel datasheet has all the info, but is heavy reading because there are so many ways to set it up. Try this for a decent intro to the subject: http://www.righto.com/2009/07/secrets-of-arduino-pwm.html.
 

Offline dan3460Topic starter

  • Frequent Contributor
  • **
  • Posts: 326
  • Country: us
Re: Atmega2560 PWM
« Reply #3 on: May 07, 2017, 01:02:43 pm »
Thanks for the answers, but sorry still confused.
I'm getting and I can control PWM on PB7 which is OC1C, how do I output on pin PB5 which is OC1A?
Freddy, are you saying that OC1A is associated with TCCR1A and B and timer 1? So then, why is the code posted is outputting on OC1C?
By the way the function setdutycicle() is setting OCR0A.
Nusa, I'm guessing that the library you mention is the used by Arduino. I understand how the wave is created and control, my problem is how to control the individual outputs?
 

Offline Nusa

  • Super Contributor
  • ***
  • Posts: 2416
  • Country: us
Re: Atmega2560 PWM
« Reply #4 on: May 07, 2017, 02:51:03 pm »
Your answer suggests you either didn't look at my prior link, or didn't get skim past the intro stuff to the hardware and register setting details.
A key concept is that there are a number of counter/timers that are tied to specific hardware pins. You can configure a timer frequency, but they'll affect all the pins that are making use of that timer.

As to why you got activity on PB7: it's because that pin happens to be special on the 2560, in that that OC0A and OC1C outputs can be enabled individually or together for a modulated output (The atmel datasheet has a nice section that explains the the two-timer modulation case output). In your code fragment, you enabled the OC0A output when you set up the timer 0 registers.

PB5, on the other hand, has a OC1A output, which only has pwm controlled only by timer 1 registers. You didn't set any timer 1 registers, so of course it didn't work.

So, what Freddy said is correct. Understand the nomenclature: TCCRxA, TCCRxB, OCxA, OCxB, OCxC, OCRxA, etc, where "x" refers to the timer number associated with that registers functions.

Atmel datasheet: http://www.atmel.com/Images/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf
« Last Edit: May 07, 2017, 02:57:45 pm by Nusa »
 

Offline dan3460Topic starter

  • Frequent Contributor
  • **
  • Posts: 326
  • Country: us
Re: Atmega2560 PWM
« Reply #5 on: May 07, 2017, 04:05:57 pm »
Thanks, that makes it clear. And by taking a closer look at the mapping of pins for the Arduino platform I can see that way on the right of the description for pin 13 is the OC0A I didn't see it, I see my mistake now.

Now if I can ask one more question, if I'm using the 0 register and outputting a wave on OC0B, can I still use PB7 as a blinker?

Thanks very much for the help.

I answer my own questions by actually trying, yes you can have a PWM on OC0B and use pin 13 as a blinker.

Thanks again.
« Last Edit: May 07, 2017, 07:58:36 pm by dan3460 »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf