Varying the pwm frequency for timer 0 or timer 2?

I don't know of other side effects...the ones you mentioned were enough make me avoid changing the TCCR0B register.

Pins 5 and 6:
Setting Divisor Frequency
0x03 64 976.5625
TCCR0B = TCCR0B & 0b11111000 | ;

Pins 11 and 3:
Setting Divisor Frequency
0x04 64 488.28125
TCCR2B = TCCR2B & 0b11111000 | ;

Does timer2 really run half the frequency of timer0 with the same prescaler? I coudn’t find anything obvious to account for such a discrepancy in the AVR datasheet, although it matches observations. What am I missing?

thanks a lot! I'll try this out today. I'm pulsing some solenoid valves to control a pair of air muscles, and they just arrived!

westfw, start with the first section on page 136 of the atmega168 datasheet. I am not able to fully make sense of it all, but it looks like timers 0 and 1 source from different clock inputs (one 8bit vs one 16bit), so even with the shared prescaler logic and settings, they have different frequency outputs; timer 2 is more independent. I wonder what the design considerations were, but I think they were going for maximum variation between the three, while sharing a lot of logic.

macegr: I’m afraid that the frequencies in your post for pins 3, 9, 10 and 11 are a little of. The correct formula is f = clock/(510 N), where N is the divisor (prescaler) and clock = 16,000,000. That gives f = 490.196 Hz for the default setting. But close enough. See the ATmega168 datasheet.

westfw: The reason is that Timer0 runs in the FastPWM mode to feed the millis() function. That gives a frequency f = clock / (256 N), N = 64 by default. In FastPWM, the counter is always incrementing until it reaches 256 when it overflows to 0. The frequency f = 976.563 that is close enough to generate milliseconds.
Timers 1 and 2 run in the Phase correct PWM, which is apperently better for motors. Then the counter increments until it reaches the top 255 and then starts decrementing until it reaches 0. And then again incrementing… Thus for each cycle it has to go through 255 + 255 = 510 steps, hence the frequency clock/ (510 N), N = 64. That gives you ~~ 490Hz.

If you change TCCR0B, it affects millis() and delay(). They will count time faster or slower than normal if you change the TCCR0B settings. Below is the adjustment factor to maintain consistent behavior of these functions:

Default: delay(1000) or 1000 millis() ~ 1 second

0x01: delay(64000) or 64000 millis() ~ 1 second 0x02: delay(8000) or 8000 millis() ~ 1 second 0x03: is the default 0x04: delay(250) or 250 millis() ~ 1 second 0x05: delay(62) or 62 millis() ~ 1 second (Or 63 if you need to round up. The number is actually 62.5)

Also, the default settings for the other timers are: TCCR1B: 0x03 TCCR2B: 0x04

There may be other side effects from changing TCCR0B. For example my project would not properly run with TCCR0B set to 0x02 or 0x01. But it worked fine at 0x03 and higher. YMMV


Does anyone know which timer (TCCR**) that controls which pins on a Arduino Mega? I would like to change the pwm frequency on to of the pins.


I posted a spreadsheet here that has that information:

Very helpful document mem.

Do you know why timer2 on mega board has no OC2C output aka PWM T2C since all 16bit-timers on mega have three registers: OCRnA, OCRnB and OCRnC ?

Do you know when timer5 will be supported by IDE ?

Hi, selfonlypath, I am not aware of how the Arduino designers chose which resources to expose.

But looking at the source code, I think PWM A and B on Timer5 may actually work. Try doing an analogWrite on pins 45 and 46. Let me know if it works and I will update the spreadsheet.

hello mem,

Just done the test with mega board and version 15 running on my Macintosh.

I confirm timer5 works perfect, here is my code where I generate 799,92Hz freq, PWM of 75% on OC5B and PWM of 1% on OC5C with clock system, phase & freq correct PWM

int outputPsuB = 45;  // Timer5-B
int outputPsuC = 44;  // Timer5-C

void setup()
// PSU outputs via timer5
  pinMode(outputPsuB, OUTPUT);  // select Pin as ch-B
  pinMode(outputPsuC, OUTPUT);  // select Pin as ch-C
  TCCR5A = B00101001; // Phase and frequency correct PWM change at OCRA
  TCCR5B = B10001;  // System clock
  OCR5A = 10000; // 799,92Hz
  OCR5B = 7500; // 75%
  OCR5C = 100; // 1%

i've tried pre-scaling to diminish frequency and works perfect.

For me it looks 16-bits timer3, timer4 & timer5 are fully compatible with version 15 on Macintosh.

I'll look later on timer1 issue you've raised on your doc :-/

hello again mem,

Ok just made some test on timer1 which as you wisely mention on your doc can only have 2 pins outputs (11 and 12).

Well, it is a bit more tricky when reading atmega1280 spec because pin13 is SHARED by timer0 and timer1 so it can either be related to OCOA or OC1C.

If one make sure to only use timer1 and NOT use timer0, then timer1 becomes a full 16bit timer as timer3, timer4 and timer5 with three PW outputs.

Don't know what is best on how to describe this on your doc but with the above restriction, pin13 can be either TOA (as you have it now) and T1C :P

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. ;)

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()
// 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
  // wait a second so as not to send massive amounts of data

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.