PWM Servo center issue lpc2149 (solved)

I’m having a kind of a nightmare here to get my servo centered when i boot.

    IODIR0 |= 0x00403000;       //buzz1 & buzz2 & P0.22 as output
    PINSEL1 = 0x10000400;       //p0.21 = PWM5 - p0.30 = AD0.3
    PWMTCR = 0x02;              //pwm reset
    PWMPR = 0;                  //prescaler disable
    PWMPCR = 0x2000;            //PWM5 enabled - single edge
    PWMMCR = 0x00000002;        //reset on PWMMR0
    PWMMR0 = 0x00124F80;        //set PWM frequency to 50Hz
    //PWMMR5 = 50000;             //set pwm5 duty cycle
    PWMLER = 0x20;              //latch new match entries
    PWMTCR = 0x09;              //enable PWM

so i calculated the PWM frequency by 60.000.000 (cpu speed) / 50 = 0x00124F80 (this is right though?)

For centering i need a 1,5ms puls every 20ms google told me 8)

How do i calculate the value to put in PWMMR5 to center it?

Tnx

Ernst

The PWM is based on the pclk (peripheral clock), so this depends on what you have VPVDIV set at for your pclk. So, assuming your pclk is not running at the same speed as the processor, you’ll need to redo the math for your PWMMR0 AND PWMMR5 accordingly.

In my application, I initialize PWMPC and PWMTC to both equal 0 but I don’t know if that is necessary or not.

One thing you might want to consider is setting the prescaler to a number that makes the pwm periods seem more intuitive. In my case, I use 4 for VPBDIV, which makes my pclck run at approx 15MHz. I then use 15 for the prescaler (PWMPR) to further reduce the timing down to approx 1MHz. I use 10000 for the PWMMR0 period and 1400 for PWMMR1 (yours is PWMMR5). This roughly relates to 10ms between pulses and 1.4ms for the servo pulse, which for me is near center. For me, using numbers like these, makes it much easier to keep track of what I want the servos to do without having to continuously do math to convert a strange number to servo numbers.

You can use 20000 for PWMMR0 to approximate 20ms between pulses but I’ve found they work with 10 as well. If you are using cheap servos, you should probably go with the higher number for PWMMR0. Either way, the PWMMR1 (or PWMMR5 for you) would not change from about 1400. I need to go back and refine my numbers so they are more intuitive but that’s what I’m doing.

I didn’t check your pin assignments, so hopefully they are correct. If you need to run the pclk at a higher rate, just adjust the PWM prescaler to compensate if you try my method. Don’t forget to un-comment your PWMMR5 assignment.

My PCLK is synced with the CCLK and both running at 60Mhz

I set the PWMMR0 to 50Hz

To calculate the LEFT(1ms), CENTER(1,5)ms and RIGHT(2ms) i devided 60.000.000 per sencond by 1000 (for ms).

This results in that a:

  • 1ms puls being 60.000 cycles

  • 1,5ms puls being 90.000 cycles

  • 2ms puls being 120.000 cycles

The servo is now moving without a problem only i had to thinker a bit with the values a little to really move it 180 degrees

One thing you might want to consider is setting the prescaler to a number that makes the pwm periods seem more intuitive. In my case, I use 4 for VPBDIV, which makes my pclck run at approx 15MHz. I then use 15 for the prescaler (PWMPR) to further reduce the timing down to approx 1MHz. I use 10000 for the PWMMR0 period and 1400 for PWMMR1 (yours is PWMMR5). This roughly relates to 10ms between pulses and 1.4ms for the servo pulse, which for me is near center

So if i get this right: If your prescaler is set to 15 it devides the speed of the PCLK by 15 (so in my case this would be 60Mhz / 15 = 4MHz)

So what doest the PWMMR0 do in that case?


I found out that in ARM land the PWMMR0 is not the frequency but the PWM period

I calculate PWMMR0 as follows:

1st way:

60.000.000 = PCLK = 60Mhz for 1sec = 1000ms

60.000 = 1ms so a 20ms cycle = 60.000 x 20 = 1.200.000(dec) = 00124f80(hex)

2nd way:

60.000.000 / 50(Hz) = 1.200.000(dec) = 00124f80 (hex)

same result but different way of calculating