Varying the pwm frequency for timer 0 or timer 2?

There is more info on atemag1280 datasheet (chapter 19. Ouput Modulator (OCM1COA) giving details how pin 13 on mega board is shared by timer0 and timer1.

As stated before & this can be seen on the schematic, if one fully disable timer0 then timer1 recovers full potential of OC1A, OC1B & OC1C and three pins outputs. If you need to use timer0, then only OC1A & OC1B outputs hence only two pins are controlled by timer1.

Timer0 is used by millis and delay so it can't be disabled without disturbing these core functions.

OK the idea here is to have full potentiality of timer1 in mega board hence have control of OC1A, OC1B & OC1C. I could be wrong be feel then to preventing timer0 from writing to OC0A which is shared by OC1C (same pin 13 on mega) will leave intact millis() and delays(). For example, this code will block COM0A1 & COMA0 so partially disable timer0:

TCCR0A = TCCR0A & 0x3F;

Looks promising, have you tried it and does the PWM work on timer1 without disturbing millis timing?

There is no need to try because millis() does not use OC0A which happens to be connected to pin 13. Any project can use pin13 without corrupting millis() having in mind that pin13 happens to be the unique pin with a led inside mega board. My code just disable any output on pin13 coming from OC0A of timer0 so pin13 will be only modulated by OC1C of timer1.

There is no need to try because ...

It's been my experience that what one expects to happen based on interpreting a datasheet and what actually happens is not always as expected. :wink:

Ok, just done the test with this code and for me it works fine

#include <util/delay_basic.h>

int outputPsuB = 12;  // Timer1-B
int outputPsuC = 13;  // Timer1-C

unsigned long time;

void setup()
{
  Serial.begin(9600);
  
// PSU outputs via timer1
  pinMode(outputPsuB, OUTPUT);  // select Pin as ch-B
  pinMode(outputPsuC, OUTPUT);  // select Pin as ch-C

  TCCR1A = B00101001; // Phase and frequency correct PWM change at OCRA
  TCCR1B = B10101;  // System clock / 1024 from prescaler
  OCR1A = 10000; // 0.78125 Hz
  OCR1B = 7500; // 75% PWM
  OCR1C = 500; // 5% PWM
  
  TCCR0A = TCCR0A & 0x3F; // disable OC0A from timer0
}

void loop()
{
  Serial.print("Time: ");
  time = millis();
  //prints time since program started
  Serial.println(time);
  // wait a second so as not to send massive amounts of data
  delay(1000);
}

The terminal gives these values and I have correct PWM on pin 12 & 13:

Time: 4
Time: 1012
Time: 2023
Time: 3034
Time: 4045
Time: 5056
Time: 6067
Time: 7078
Time: 8090
Time: 9101
Time: 10113
Time: 11125
Time: 12137

Now if I remove the timer1 & timer0 specific initialization in setup(), I get same Time code log computed by millis() except there will be no PWM modulating pin 12 & pin 13.

Let me know if this fits what you wanted to test !

On second thought about OC1C output of timer1 on mega, it works fine but there might be a little problem because the shared pin13 is wired with a LED on the board. This will somehow alter or degrade the bandwith of fast PW as well as when using OC0A of timer0 so the problem i snot only with timer1. Worthwhile noting the presence of this led will also degrade the inner Atmega1280 Output Compare Modulator (see section 19) :-/

It would have been best arduino designer connect the mega board LED to pin not connected to any timer as it is done with duamilanove.

Hi,

Sorry if this is a dupe, but I can't seem to find this info anywhere else. Here are the PWM pin <-> TCCR register values to change PWM freuquencies on the Arduino Mega. These values were measured for each pin by going through the different TCCRXB values (from X=0 to 5) and measuring the pin output on an oscilloscope.

As above, the code used to set the prescaler in each case was

TCCRXB = TCCRXB & 0b11111000 |

e.g. to set the PWM freq on pin 5 to 31.25 kHz:
TCCR3B = TCCR3B 0b11111000 | 0x01

Frequencies are truncated at the decimal point. I have to admit, I didn't check every single setting, but just checked the pattern and then filled in the blanks from previous pwm divisor data. However, at least two setting values were checked for each pin, so this data should be reliable, barring a strange deviation from the divisors used in previous arduinos.

PIN TIMER Freq. at setting = 0x01 0x02 0x03 0x04

2 TCCR3B 31250 3906 488 122
3 TCCR3B 31250 3906 488 122
4 TCCR0B 62500 7812 976 244
5 TCCR3B 31250 3906 488 122
6 TCCR4B 31250 3906 488 122
7 TCCR4B 31250 3906 488 122
8 TCCR4B 31250 3906 488 122
9 TCCR2B 31250 3906 976 488
10 TCCR2B 31250 3906 976 488
11 TCCR1B 31250 3906 488 122
12 TCCR1B 31250 3906 488 122
13 TCCR0B 62500 7812 976 244
45 TCCR5B 31250 3906 488 122
46 TCCR5B 31250 3906 488 122

--

Hope this is useful.

-- Mark

Gah, I see this information has indeed already been posted! My apologies. Believe it or not, I didn't notice that this thread had two pages so I missed mem's post above. It would have saved me an hour of checking if I had seen it. Hopefully the redundancy means that there is more chance of people finding the answer.

  • Mark

I'm slightly confused. In the code:

int outputPsuB = 45;  // Timer5-B

void setup()
{
// PSU outputs via timer5
  pinMode(outputPsuB, OUTPUT);  // select Pin as ch-B
  
  TCCR5A = B00100010; // Phase correct PWM change at OCR5A
  TCCR5B = B10010;  // prescaling by 8 the system clock
  OCR5A = 14970; // 66,8002672Hz
  OCR5B = 1497; // 10% PWM
  }

We set pin 45 as output. How would this actually run? If I do analogWrite(outputPsuB, 25) it gives me a distorted sine wave. I don't understand this and nobody can seem to explain this stuff to me... :frowning:

please read my answer on

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1252073278/15#15

I would also like to know how to change the frequencies on the Arduino Mega....

I have changed them on my regular Arduino with good success, but the Mega has more timers and I am having trouble linking how MaceGR came up with the commands to change the frequencies from the Atmega168 datasheet.

Has anyone done this yet?

So I am trying to create PWM using Timer4 on the Arduino Mega. I know that Timer4 uses pins 6, 7, and 8 on the Mega, and I'm trying to use output pin 7.
I want to use Fast PWM mode with a frequency of 62.5 kHz. (Ideally I would like 80kHz, but it seemed easier to get 62.5kHz by setting the clock prescale value to 1.)
Here is my code:

void setup()

{
  pinMode(7, OUTPUT);
 //Within the TCCR4A register:
 //COM4A1:0 = 10 for non-inverted output
 //WGM41:0 = 11 for the LSBs of WGM setting to fast PWM mode
  TCCR4A = _BV(COM4A1) | _BV(WGM41) | _BV(WGM40);
 //Within the TCCR4B register:
 //CS42:0 = 001 for clock prescale of 1, which should make a frequency of 62.5 kHz
 //WGM43:2 = 01 for the MSBs of WGM setting to fast PWM mode
  TCCR4B = _BV(CS40) | _BV(WGM42);
  OCR4A = 14970;          // change the frequency by some (arbitrary) amount
  OCR4B = 819;              // set 80% duty cycle on channel 4B (this is supposed to show up on output pin 7!)
}

void loop()
{
}

I don't completely understand how to use the OCR registers, but from what I've seen it seems like you use OCR4A to set the timer compare value to determine the frequency you want. Then, you use the OCR4B and OCR4C registers to set the values for the duty cycles of your respective output channels.

BUT, this code just gives me a noisy sine wave on output pin 7. What am I doing wrong?