Forums

PWM on LPC24xx

Started by Herbert Demmel September 1, 2008
Hi,

I seem to have problems to understand the PWM (although it's not the
first time I've set one up for the LPC2xxx family).

I run the uC with 72MHz and have set the PCLK for PWM0 to divide by
8. So I would expect to get a 300 Hz signal (with a duty cycle of
50%) out of P3.16, but in fact I get 290 (???) Hz, I don't understand
why. In the specific case it's not a problem not to have exactly 300
Hz, but I simply want to understand what I'm doing wrong. Please see
my test code below.

I've measured the XTAL frequency, it *is* 12.00 MHz and the uC *does*
run with 72 MHz (LPC2478's LCD controller clock is divided by 3 and
*does* give the expected 24MHz).

Any idea is appreciated. Thanks for your help in advance.

Herbert
// Enable PWM on P3.16 = PWM0[1]
PINSEL7 |= (0x02 << 0);

// Leave PWM0CCR as it is (no capture)
// Leave PWM0LER as it is (no latch enable)

// Enable PWM0[1]
PWM0PCR |= (1 << 9);

// Input frequency is 72 / 8 MHz = 9 MHz, we want to have 300 * 1000
Hz, so the prescaler is set as follows:
PWM0PR = 72000000 / 8 / 300 / 1000;

// Reset after 1000 counts
PWM0MR0 = 1000;

// reset on match of PWM0MR0
PWM0MCR |= (1 << 1);

// Set duty cycle of 50%
PWM0MR1 = PWM0MR0 / 2;

// PWM Count Control Register
PWM0CTCR = 0;

// Counter Enable & PWM0 enable
PWM0TCR = (1 << 0) | (1 << 3);

An Engineer's Guide to the LPC2100 Series

do PWM0PR = (72000000 / 8 / 300 / 1000) - 1;
PR = 0 means 1 count per 1 clock, 1 count per 0 clocks makes no sense...
so if u want 1 count per x clocks, make PR = x-1.

2008/9/1 Herbert Demmel

> Hi,
>
> I seem to have problems to understand the PWM (although it's not the
> first time I've set one up for the LPC2xxx family).
>
> I run the uC with 72MHz and have set the PCLK for PWM0 to divide by
> 8. So I would expect to get a 300 Hz signal (with a duty cycle of
> 50%) out of P3.16, but in fact I get 290 (???) Hz, I don't understand
> why. In the specific case it's not a problem not to have exactly 300
> Hz, but I simply want to understand what I'm doing wrong. Please see
> my test code below.
>
> I've measured the XTAL frequency, it *is* 12.00 MHz and the uC *does*
> run with 72 MHz (LPC2478's LCD controller clock is divided by 3 and
> *does* give the expected 24MHz).
>
> Any idea is appreciated. Thanks for your help in advance.
>
> Herbert
>
> // Enable PWM on P3.16 = PWM0[1]
> PINSEL7 |= (0x02 << 0);
>
> // Leave PWM0CCR as it is (no capture)
> // Leave PWM0LER as it is (no latch enable)
>
> // Enable PWM0[1]
> PWM0PCR |= (1 << 9);
>
> // Input frequency is 72 / 8 MHz = 9 MHz, we want to have 300 * 1000
> Hz, so the prescaler is set as follows:
> PWM0PR = 72000000 / 8 / 300 / 1000;
>
> // Reset after 1000 counts
> PWM0MR0 = 1000;
>
> // reset on match of PWM0MR0
> PWM0MCR |= (1 << 1);
>
> // Set duty cycle of 50%
> PWM0MR1 = PWM0MR0 / 2;
>
> // PWM Count Control Register
> PWM0CTCR = 0;
>
> // Counter Enable & PWM0 enable
> PWM0TCR = (1 << 0) | (1 << 3);
>
>
>

Because the actual value used in the hardware is the value of PR + 1.

Baldur

On Mon, Sep 01, 2008 at 09:57:55PM +0200, Herbert Demmel wrote:
> Hi,
>
> I seem to have problems to understand the PWM (although it's not the
> first time I've set one up for the LPC2xxx family).
>
> I run the uC with 72MHz and have set the PCLK for PWM0 to divide by
> 8. So I would expect to get a 300 Hz signal (with a duty cycle of
> 50%) out of P3.16, but in fact I get 290 (???) Hz, I don't understand
> why. In the specific case it's not a problem not to have exactly 300
> Hz, but I simply want to understand what I'm doing wrong. Please see
> my test code below.
>
> I've measured the XTAL frequency, it *is* 12.00 MHz and the uC *does*
> run with 72 MHz (LPC2478's LCD controller clock is divided by 3 and
> *does* give the expected 24MHz).
>
> Any idea is appreciated. Thanks for your help in advance.
>
> Herbert
> // Enable PWM on P3.16 = PWM0[1]
> PINSEL7 |= (0x02 << 0);
>
> // Leave PWM0CCR as it is (no capture)
> // Leave PWM0LER as it is (no latch enable)
>
> // Enable PWM0[1]
> PWM0PCR |= (1 << 9);
>
> // Input frequency is 72 / 8 MHz = 9 MHz, we want to have 300 * 1000
> Hz, so the prescaler is set as follows:
> PWM0PR = 72000000 / 8 / 300 / 1000;
>
> // Reset after 1000 counts
> PWM0MR0 = 1000;
>
> // reset on match of PWM0MR0
> PWM0MCR |= (1 << 1);
>
> // Set duty cycle of 50%
> PWM0MR1 = PWM0MR0 / 2;
>
> // PWM Count Control Register
> PWM0CTCR = 0;
>
> // Counter Enable & PWM0 enable
> PWM0TCR = (1 << 0) | (1 << 3);
>
Dear All,

one should really avoid to work more than 16 hours a day ...
thanks a lot for the rather obvious I could not see anymore; I go to
bed now (it's 11:30 pm here ..)

Herbert

At 17:15 01.09.2008 -0300, you wrote:
>do PWM0PR = (72000000 / 8 / 300 / 1000) - 1;
>PR = 0 means 1 count per 1 clock, 1 count per 0 clocks makes no sense...
>so if u want 1 count per x clocks, make PR = x-1.
>
>2008/9/1 Herbert Demmel > Hi,
> >
> > I seem to have problems to understand the PWM (although it's not the
> > first time I've set one up for the LPC2xxx family).
> >
> > I run the uC with 72MHz and have set the PCLK for PWM0 to divide by
> > 8. So I would expect to get a 300 Hz signal (with a duty cycle of
> > 50%) out of P3.16, but in fact I get 290 (???) Hz, I don't understand
> > why. In the specific case it's not a problem not to have exactly 300
> > Hz, but I simply want to understand what I'm doing wrong. Please see
> > my test code below.
> >
> > I've measured the XTAL frequency, it *is* 12.00 MHz and the uC *does*
> > run with 72 MHz (LPC2478's LCD controller clock is divided by 3 and
> > *does* give the expected 24MHz).
> >
> > Any idea is appreciated. Thanks for your help in advance.
> >
> > Herbert
> >
> > // Enable PWM on P3.16 = PWM0[1]
> > PINSEL7 |= (0x02 << 0);
> >
> > // Leave PWM0CCR as it is (no capture)
> > // Leave PWM0LER as it is (no latch enable)
> >
> > // Enable PWM0[1]
> > PWM0PCR |= (1 << 9);
> >
> > // Input frequency is 72 / 8 MHz = 9 MHz, we want to have 300 * 1000
> > Hz, so the prescaler is set as follows:
> > PWM0PR = 72000000 / 8 / 300 / 1000;
> >
> > // Reset after 1000 counts
> > PWM0MR0 = 1000;
> >
> > // reset on match of PWM0MR0
> > PWM0MCR |= (1 << 1);
> >
> > // Set duty cycle of 50%
> > PWM0MR1 = PWM0MR0 / 2;
> >
> > // PWM Count Control Register
> > PWM0CTCR = 0;
> >
> > // Counter Enable & PWM0 enable
> > PWM0TCR = (1 << 0) | (1 << 3);
> >
> >
> >
>
>