EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

[LPC2148] R/C Servo's and PWM/Timers

Started by gussy_27 September 19, 2008
Hi All!

I am a long time user of Atmels 8bit AVR range, but only recently have
jumped into the wold of ARM, the LPC2xxx range specifically.

I am having a little bit of trouble deciphering the NXP datasheet and
understanding the match, capture and pwm functions.

What I want to do is to capture 6 R/C Servo inputs (PPM) and then
control 4 R/C servos (a 1ms to 2ms pulse every 20ms).
If a "passthrough" flag is set the 4 outputs will be exactly the same
as 4 of the inputs, if not they 4 outputs will reflect a value which
is set to them.

I am having trouble understanding firstly the hardware side and
secondly the software side.
My current setup is the 6 servo inputs all on a CAPx.x pin, and the 4
outputs on a PWMx pin.
Does this sound right? I am wondering if I should be just using GPIO's
for the outputs.

Does anyone have any examples of PWM capture and output similar to
what I am trying to achieve, that I can look over and get a better
understanding on how it works?

I am using the WinARM GCC compiler if it helps.

Regards,
Angus

An Engineer's Guide to the LPC2100 Series

--- In l..., "gussy_27" wrote:
>
> Hi All!
>
> I am a long time user of Atmels 8bit AVR range, but only recently have
> jumped into the wold of ARM, the LPC2xxx range specifically.
>
> I am having a little bit of trouble deciphering the NXP datasheet and
> understanding the match, capture and pwm functions.
>
> What I want to do is to capture 6 R/C Servo inputs (PPM) and then
> control 4 R/C servos (a 1ms to 2ms pulse every 20ms).
> If a "passthrough" flag is set the 4 outputs will be exactly the same
> as 4 of the inputs, if not they 4 outputs will reflect a value which
> is set to them.
>
> I am having trouble understanding firstly the hardware side and
> secondly the software side.
> My current setup is the 6 servo inputs all on a CAPx.x pin, and the 4
> outputs on a PWMx pin.
> Does this sound right? I am wondering if I should be just using GPIO's
> for the outputs.
>
> Does anyone have any examples of PWM capture and output similar to
> what I am trying to achieve, that I can look over and get a better
> understanding on how it works?
>
> I am using the WinARM GCC compiler if it helps.
>
> Regards,
> Angus
>

So I spent the afternoon writing code, but I have no hardware to test
it on at the moment so not sure if I am on the right track. Looking
for some advice and tips.

Here's what I came up with, it's mostly mine with a bit of structure
influence from an example I found on the googles. I haven't started on
the PWM capture yet. Cross one bridge at a time ;-)

#include "LPC214x.h"
#include
#include "Pins.h"
#include "servos.h"

// Usage: Servos_Init();
// Inputs: none
void Servos_Init(void)
{
/*
Getting prescaler value with a 60MHz clock and 1000 servo resolution
Calculations:
60,000,000Hz / 60
= 1MHz
1MHz / (10*2000)
= 50Hz
1(second) / 50Hz
= 20ms

(@1024res 59 .14ms or 58.80ms)
*/
PWMPR = 60; //Set prescaler to 60

//Set all servos at center
SetServo(0, 500);
SetServo(1, 500);
SetServo(2, 500);
SetServo(3, 500);

//Resolution is 1000
//1000 MR0 ticks = 1ms, total count has to be 20ms
//Therefore MR0 should have 10*2000 ticks
PWMMR0 = 10*2000;

PWMMR2 = ServoValue[0];
PWMMR4 = ServoValue[1];
PWMMR5 = ServoValue[2];
PWMMR6 = ServoValue[3];

PWMPCR = 0x00007400; //Enable PWM2, PWM4, PWM5 and PWM6
PWMLER = 0x1E; //Enable latch for M1, M2, M3 and M4
PWMIR = 0x01; //Enable interrupt for M0

//Setup the PWM Pins
PINSEL0 |= 0x000A8000; //P0.7=PWM2, P0.8=PWM4, P0.9=PWM5
PINSEL1 |= 0x00000400; //P0.21=PWM6

//Setup the interrupt for Match0 (Interrupt 8)
VICIntSelect |= ~(1<<8);
VICVectCntl3 = 0x20 | 8;
VICVectAddr3 = (unsigned int)ServoISR;

PWMTCR = 0x0B; //Enable Counter, Counter Reset, PWM Enable
}

// Usage: SetServo(1, 500);
// Inputs: servo, val
// servo = servo number from 0 to 3
// value = Servo position from 0 to 1000 where 500 is center
void SetServo(int servo, unsigned int value)
{
ServoValue[servo] = 1000 + value; //val=0 needs to be 1ms so add 1000
}

// Usage: None. Called by FW
void ServoISR(void)
{
PWMMR2 = ServoValue[0];
PWMMR4 = ServoValue[1];
PWMMR5 = ServoValue[2];
PWMMR6 = ServoValue[3];

//Reset the PWM timer counter
PWMTC = 0x00;

VICVectAddr = 0x00; //Update the VIC priorities
}
Hi Angus,

This is exactly the same thing i wanted to do and i was wondering if
you got any further on this part?

I want to capture the rc signals from my rc reciever and route them
forward to the servo's using the 2148.

When i engage a certain switch the rc remote gets disabled and the
autopilot (which i'm trying to build) takes over.

Hope we can get in contact about this.

Gr,

Ernst
--- In l..., "gussy_27" wrote:
>
> --- In l..., "gussy_27" wrote:
> >
> > Hi All!
> >
> > I am a long time user of Atmels 8bit AVR range, but only recently have
> > jumped into the wold of ARM, the LPC2xxx range specifically.
> >
> > I am having a little bit of trouble deciphering the NXP datasheet and
> > understanding the match, capture and pwm functions.
> >
> > What I want to do is to capture 6 R/C Servo inputs (PPM) and then
> > control 4 R/C servos (a 1ms to 2ms pulse every 20ms).
> > If a "passthrough" flag is set the 4 outputs will be exactly the same
> > as 4 of the inputs, if not they 4 outputs will reflect a value which
> > is set to them.
> >
> > I am having trouble understanding firstly the hardware side and
> > secondly the software side.
> > My current setup is the 6 servo inputs all on a CAPx.x pin, and the 4
> > outputs on a PWMx pin.
> > Does this sound right? I am wondering if I should be just using GPIO's
> > for the outputs.
> >
> > Does anyone have any examples of PWM capture and output similar to
> > what I am trying to achieve, that I can look over and get a better
> > understanding on how it works?
> >
> > I am using the WinARM GCC compiler if it helps.
> >
> > Regards,
> > Angus
> > So I spent the afternoon writing code, but I have no hardware to test
> it on at the moment so not sure if I am on the right track. Looking
> for some advice and tips.
>
> Here's what I came up with, it's mostly mine with a bit of structure
> influence from an example I found on the googles. I haven't started on
> the PWM capture yet. Cross one bridge at a time ;-)
>
> #include "LPC214x.h"
> #include
> #include "Pins.h"
> #include "servos.h"
>
> // Usage: Servos_Init();
> // Inputs: none
> void Servos_Init(void)
> {
> /*
> Getting prescaler value with a 60MHz clock and 1000 servo resolution
> Calculations:
> 60,000,000Hz / 60
> = 1MHz
> 1MHz / (10*2000)
> = 50Hz
> 1(second) / 50Hz
> = 20ms
>
> (@1024res 59 .14ms or 58.80ms)
> */
> PWMPR = 60; //Set prescaler to 60
>
> //Set all servos at center
> SetServo(0, 500);
> SetServo(1, 500);
> SetServo(2, 500);
> SetServo(3, 500);
>
> //Resolution is 1000
> //1000 MR0 ticks = 1ms, total count has to be 20ms
> //Therefore MR0 should have 10*2000 ticks
> PWMMR0 = 10*2000;
>
> PWMMR2 = ServoValue[0];
> PWMMR4 = ServoValue[1];
> PWMMR5 = ServoValue[2];
> PWMMR6 = ServoValue[3];
>
> PWMPCR = 0x00007400; //Enable PWM2, PWM4, PWM5 and PWM6
> PWMLER = 0x1E; //Enable latch for M1, M2, M3 and M4
> PWMIR = 0x01; //Enable interrupt for M0
>
> //Setup the PWM Pins
> PINSEL0 |= 0x000A8000; //P0.7=PWM2, P0.8=PWM4, P0.9=PWM5
> PINSEL1 |= 0x00000400; //P0.21=PWM6
>
> //Setup the interrupt for Match0 (Interrupt 8)
> VICIntSelect |= ~(1<<8);
> VICVectCntl3 = 0x20 | 8;
> VICVectAddr3 = (unsigned int)ServoISR;
>
> PWMTCR = 0x0B; //Enable Counter, Counter Reset, PWM Enable
> }
>
> // Usage: SetServo(1, 500);
> // Inputs: servo, val
> // servo = servo number from 0 to 3
> // value = Servo position from 0 to 1000 where 500 is center
> void SetServo(int servo, unsigned int value)
> {
> ServoValue[servo] = 1000 + value; //val=0 needs to be 1ms so add 1000
> }
>
> // Usage: None. Called by FW
> void ServoISR(void)
> {
> PWMMR2 = ServoValue[0];
> PWMMR4 = ServoValue[1];
> PWMMR5 = ServoValue[2];
> PWMMR6 = ServoValue[3];
>
> //Reset the PWM timer counter
> PWMTC = 0x00;
>
> VICVectAddr = 0x00; //Update the VIC priorities
> }
>


The 2024 Embedded Online Conference