PWM frequency

How do I change the frequency period to something over 5ms? I need to control servos without worrying about some functions which may take over 20ms to execute.

I’m pouring over the register descriptions in the atmega168 datasheet and it’s not clear what I have to change.

I can’t lower my clock rate. An external servo controller is also an option but I really don’t like the idea.

EDIT:
I found this:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1170282999

Thanks for your hints, Mellis.

After some hours of diggin’ in datasheets and webpages i finally came up with a solution that works:
(hope it’s of any interest)

/* ServoPWM

*/

int val = 0;

void setup(void) {
pinMode(9,OUTPUT); // Servo Pin
Serial.begin(9600);

TCCR1A = 0x00; // sets timer control bits to PWM Phase and Frequency Correct mode
TCCR1B = 0x12; // sets timer control bits to Prescaler N = 8
ICR1 = 0x0FA0; // Upper Timer Limit = 4000 (in hex) equals 4ms => 1/5 of servo frequency

}

void loop(void) {
val = analogRead(0); // read potentiometer
val = (val * 1.76) + 600; // convert potentiometer reading to value in microseconds (my servo responds to signals in the 600us - 2400us range)
analogWrite(9,val); // pulse servo
Serial.println(val); // output servo value

}

what it does:

  • it initializes the PWM timer so its frequency is 4ms - 1/5 of the servo’s frequency of 20ms
    (as all of the servo’s signals fall in between the 0.5ms - 2.5ms range).
  • analogWrite now takes values from 0 to 4000 (for us = 0.001ms)

EDIT:

it currently only works on pins 9 and 10 as Timer1 only drives these two.

best regards,
Moe

What about timer0 and timer2? I know they are 8 bits, so do I do this?

TCCR0A = 0x00;
TCCR0B = 0x12;
TCCR2A = 0x00;
TCCR2B = 0x12;

Thanks