Help on PWM basic code

Started by madbaxyh April 18, 2012
Hello everyone!

i'm testing PWM single edge of my LPC2148, after reading the user manual i came up with this code. It should work at 1KHz with duty 50% (XTALMHz,MSEL=6, PSEL=1) but it doesn't. i've watched the behavior through PWM module of KEIL uVision simulator and it seems to work, but in real, nothing appears in the osciloscope.

can someone tell me what I'm missing?

#include
int main(void){
//#1: Define the pins as PWM outputs:

PINSEL0 = 0x8000;// Enable PWM2
PINSEL1 = 0x300;// Enable PWM5

//#2: Inititialize the PWM registers:

PWMPR = 0; // PWM prescal register - divide peripheral clock
PWMMCR = 0x2; // PWM match control - reset PMWTC at Match 0
PWMMR0 = 60000; // PWM match register 0 - determines PWM frequency
PWMPCR = 0x2400; // PWM control - PWM2/PWM5 single edge | PWM2/PWM5 enabled
PWMTCR = 0x9; // PWM timer control: counters enabled, PWM enabled

//#3 Write to the PWM buffers and then latch into PWM registers each time you want to update the PWM output.

PWMMR2 = 30000; //set the match register for the PWM output.
PWMMR5 = 30000; //set the match register for the PWM output.
PWMLER = 0x24;// Latch PWM registers

while(1){
}
}

PS: sorry about my bad english.

An Engineer's Guide to the LPC2100 Series

I'm not completely familiar with the LPC21xx, but other LPC devices tend to
use the same peripherals and general device architecture.

From the code all I see is setup for the PWM peripheral and the IO, but no
code to initialize the clocks or enable the blocks power.

Have you checked that the block is actually powered up and the top level
clock enables set.

Regards

Phil.

From: l... [mailto:l...] On Behalf Of
madbaxyh
Sent: 19 April 2012 00:04
To: l...
Subject: [lpc2000] Help on PWM basic code

Hello everyone!

i'm testing PWM single edge of my LPC2148, after reading the user manual i
came up with this code. It should work at 1KHz with duty 50%
(XTALMHz,MSEL=6, PSEL=1) but it doesn't. i've watched the behavior
through PWM module of KEIL uVision simulator and it seems to work, but in
real, nothing appears in the osciloscope.

can someone tell me what I'm missing?

#include
int main(void){
//#1: Define the pins as PWM outputs:

PINSEL0 = 0x8000;// Enable PWM2
PINSEL1 = 0x300;// Enable PWM5

//#2: Inititialize the PWM registers:

PWMPR = 0; // PWM prescal register - divide peripheral clock
PWMMCR = 0x2; // PWM match control - reset PMWTC at Match 0
PWMMR0 = 60000; // PWM match register 0 - determines PWM frequency
PWMPCR = 0x2400; // PWM control - PWM2/PWM5 single edge | PWM2/PWM5 enabled
PWMTCR = 0x9; // PWM timer control: counters enabled, PWM enabled

//#3 Write to the PWM buffers and then latch into PWM registers each time
you want to update the PWM output.

PWMMR2 = 30000; //set the match register for the PWM output.
PWMMR5 = 30000; //set the match register for the PWM output.
PWMLER = 0x24;// Latch PWM registers

while(1){
}
}

PS: sorry about my bad english.



I'm not sure what you mean. I added a file to the project(startup.s) that configures PLL, MAM and many other registers.

--- In l..., "Phil Young" wrote:
>
> I'm not completely familiar with the LPC21xx, but other LPC devices tend to
> use the same peripherals and general device architecture.
>
>
>
> From the code all I see is setup for the PWM peripheral and the IO, but no
> code to initialize the clocks or enable the blocks power.
>
>
>
> Have you checked that the block is actually powered up and the top level
> clock enables set.
>
>
>
> Regards
>
>
>
> Phil.
>

On most platforms Startup.s only configures the basic required for getting a
system able to run code, I haven't viewed the default starup.s file for the
LPC21xx devices.

This usually leaves most of the peripheral clocks unaltered so they retain
their powerup status, which is usually disabled.

Generally these devices have boot code which executes from ROM before your
code so usually Uarts etc are clocked, but the other peripherals are usually
not.

Did you modify startup.s to explicitly enable these clocks / power domains.

Also do you know that your code is actually running, for example try
toggling a bit in SW to verify this or single stepping the code with the
debugger.

If you are using a jtag interface for debugging then you can manually try
writing the values to the registers using the debugger, if the clocks are
not enabled then you should be able to tell, either the debugger will
generate a warning message unable to write to the location, or reading back
the value will show that the register didn't actually get written.

It's also quite common that a program will fail at startup if you just
include the default startup.s without specifying a heap size, at least with
Keil, since the heap is required for the semi-hosting libraries which are
included by default unless you explicitly specify not to use semi-hosting.

Regards

Phil.

From: l... [mailto:l...] On Behalf Of
madbaxyh
Sent: 19 April 2012 01:21
To: l...
Subject: [lpc2000] Re: Help on PWM basic code

I'm not sure what you mean. I added a file to the project(startup.s) that
configures PLL, MAM and many other registers.

--- In l... , "Phil
Young" wrote:
>
> I'm not completely familiar with the LPC21xx, but other LPC devices tend
to
> use the same peripherals and general device architecture.
>
> From the code all I see is setup for the PWM peripheral and the IO, but no
> code to initialize the clocks or enable the blocks power.
>
> Have you checked that the block is actually powered up and the top level
> clock enables set.
>
> Regards
>
> Phil.
>



PINSEL1 = 0x300;// Enable PWM5

The above is not correct , the value 0x300 sets P0.20 to EINT3.
For P0.21 set to PWM5 use PINSEL1=0x00000400;

I would suggest you download ARMwizard to avoid such mistakes
http://alexan.edaboard.eu/

The power control for PWM can be enabled using:
PCONP = (PCONP & 0x801817BE) | (1UL<<5); /* Enable peripheral clock for
PWM0 (default is enabled) */

Alex

madbaxyh wrote:
>
> Hello everyone!
>
> i'm testing PWM single edge of my LPC2148, after reading the user
> manual i came up with this code. It should work at 1KHz with duty 50%
> (XTALMHz,MSEL=6, PSEL=1) but it doesn't. i've watched the behavior
> through PWM module of KEIL uVision simulator and it seems to work, but
> in real, nothing appears in the osciloscope.
>
> can someone tell me what I'm missing?
>
> #include
> int main(void){
> //#1: Define the pins as PWM outputs:
>
> PINSEL0 = 0x8000;// Enable PWM2
> PINSEL1 = 0x300;// Enable PWM5
>
> //#2: Inititialize the PWM registers:
>
> PWMPR = 0; // PWM prescal register - divide peripheral clock
> PWMMCR = 0x2; // PWM match control - reset PMWTC at Match 0
> PWMMR0 = 60000; // PWM match register 0 - determines PWM frequency
> PWMPCR = 0x2400; // PWM control - PWM2/PWM5 single edge | PWM2/PWM5
> enabled
> PWMTCR = 0x9; // PWM timer control: counters enabled, PWM enabled
>
> //#3 Write to the PWM buffers and then latch into PWM registers each
> time you want to update the PWM output.
>
> PWMMR2 = 30000; //set the match register for the PWM output.
> PWMMR5 = 30000; //set the match register for the PWM output.
> PWMLER = 0x24;// Latch PWM registers
>
> while(1){
> }
> }
>
> PS: sorry about my bad english.

Be careful with using PINSEL1=0x00000400;
you might accidentally set or reset the functions on other pins as well.

--- In l..., Alexan_e wrote:
>
> PINSEL1 = 0x300;// Enable PWM5
>
> The above is not correct , the value 0x300 sets P0.20 to EINT3.
> For P0.21 set to PWM5 use PINSEL1=0x00000400;
>
> I would suggest you download ARMwizard to avoid such mistakes
> http://alexan.edaboard.eu/
>
> The power control for PWM can be enabled using:
> PCONP = (PCONP & 0x801817BE) | (1UL<<5); /* Enable peripheral clock for
> PWM0 (default is enabled) */
>
> Alex
>

--- In l..., "Kevin" wrote:
>
> Be careful with using PINSEL1=0x00000400;
> you might accidentally set or reset the functions on other pins as well.
In other words, always use something like:
PINSEL1 |= 0x00000400;

Check out the demo code at www.jcwren.com/arm Everything you could possibly want to know about the LPC2148 is contained in that demo code.

There is a simple example of PWM on the PWM5 output.

I didn't look at the startup code but it will very likely set the peripheral clock. This clock will be the source for the PWM module so understanding the setup is important. The clock setup may be done somewhere other than in the startup file so make sure you track it down.

Richard

I gave a try to ARMwizard and it looks so useful but although I
configured PWM module it doesn't work yet.
here is the code generated + PWMLER that didn't apare.
/***********************************************************************\
************* Code created using the ARMwizard, visit
http://alexan.edaboard.eu
************************************************************************\
************/
#include

int main(void){/* P0.0: PORT0.0 (General purpose I/O) Input
P0.1: PORT0.1 (General purpose I/O) Input P0.2: PORT0.2 (General
purpose I/open-drain O) Input P0.3: PORT0.3 (General purpose
I/open-drain O) Input P0.4: PORT0.4 (General purpose I/O) Input
P0.5: PORT0.5 (General purpose I/O) Input P0.6: PORT0.6 (General
purpose I/O) Input P0.7: PWM2 (Pulse Width Modulator output 2)
P0.8: PORT0.8 (General purpose I/O) Input P0.9: PORT0.9 (General
purpose I/O) Input P0.10: PORT0.10 (General purpose I/O) Input
P0.11: PORT0.11 (General purpose I/O) Input P0.12: PORT0.12
(General purpose I/O) Input P0.13: PORT0.13 (General purpose I/O)
Input P0.14: PORT0.14 (General purpose I/O) Input P0.15:
PORT0.15 (General purpose I/O) Input P0.16: PORT0.16 (General
purpose I/O) Input P0.17: PORT0.17 (General purpose I/O) Input
P0.18: PORT0.18 (General purpose I/O) Input P0.19: PORT0.19
(General purpose I/O) Input P0.20: PORT0.20 (General purpose I/O)
Input P0.21: PWM5 (Pulse Width Modulator output 5) P0.22:
PORT0.22 (General purpose I/O) Input P0.23: PORT0.23 (General
purpose I/O) Input P0.25: PORT0.25 (General purpose I/O) Input
P0.28: PORT0.28 (General purpose I/O) Input P0.29: PORT0.29
(General purpose I/O) Input P0.30: PORT0.30 (General purpose I/O)
Input P0.31: PORT0.31 (General purpose O) Output P1.16:
PORT1.16 (General purpose I/O) Input P1.17: PORT1.17 (General
purpose I/O) Input P1.18: PORT1.18 (General purpose I/O) Input
P1.19: PORT1.19 (General purpose I/O) Input P1.20: PORT1.20
(General purpose I/O) Input P1.21: PORT1.21 (General purpose I/O)
Input P1.22: PORT1.22 (General purpose I/O) Input P1.23:
PORT1.23 (General purpose I/O) Input P1.24: PORT1.24 (General
purpose I/O) Input P1.25: POR11.25 (General purpose I/O) Input
P1.26: PORT1.26 (General purpose I/O) Input P1.27: PORT1.27
(General purpose I/O) Input P1.28: PORT1.28 (General purpose I/O)
Input P1.29: PORT1.29 (General purpose I/O) Input P1.30:
PORT1.30 (General purpose I/O) Input P1.31: PORT1.31 (General
purpose I/O) Input*/
PINSEL0=0x00008000; /* binary:
00000000_00000000_10000000_00000000 */ IO0DIR=0x80000000; /*
binary: 10000000_00000000_00000000_00000000 */ PINSEL1=0x00000400;
/* binary: 00000000_00000000_00000100_00000000 */ PINSEL2=0x00000000;
/* binary: 00000000_00000000_00000000_00000000 */ IO1DIR=0x00000000;
/* binary: 00000000_00000000_00000000_00000000 */
/***********************************************************************\
*******
PWM*********************************************************************\
********** Counter Enabled, Counter Reset=0, PWM mode enabled
Counter clk: 7.5 MHz, Counts every: 133.33 ns (calculated with
peripheral clock: 60MHz) MCR0.0 : reset, on compare match PWM
frequency: 1 KHz PWM1: Single edge, set by MR0, reset by MR1, output
disabled PWM2: Single edge, set by MR0, reset by MR2, output enabled
PWM3: Single edge, set by MR0, reset by MR3, output disabled PWM4:
Single edge, set by MR0, reset by MR4, output disabled PWM5: Single
edge, set by MR0, reset by MR5, output enabled PWM6: Single edge, set
by MR0, reset by MR6, output disabled*/PCONP = (PCONP & 0x801817BE) |
0x20; /* Enable peripheral clock for PWM0 (default is enabled)
*/PWMTC=0x00000000; /* decimal 0 */PWMPR=0x00000007; /* decimal
7 */PWMMCR=0x00000002; /* binary:
00000000_00000000_00000000_00000010 */PWMMR0=0x00001D4C; /* decimal
7500 */PWMMR1=0x00000000; /* decimal 0 */PWMMR2=0x00000EA6; /*
decimal 3750 */PWMMR3=0x00000000; /* decimal 0 */PWMMR4=0x00000000;
/* decimal 0 */PWMMR5=0x00000EA6; /* decimal 3750
*/PWMMR6=0x00000000; /* decimal 0 */PWMPCR=0x00002400; /*
binary: 00000000_00000000_00100100_00000000 */PWMTCR=0x09; /*
binary: 00001001 */PWMLER=0x24; while(1) { }
}
--- In l..., Alexan_e wrote:
>
> PINSEL1 = 0x300;// Enable PWM5
>
> The above is not correct , the value 0x300 sets P0.20 to EINT3.
> For P0.21 set to PWM5 use PINSEL1=0x00000400;
>
> I would suggest you download ARMwizard to avoid such mistakes
> http://alexan.edaboard.eu/
>
> The power control for PWM can be enabled using:
> PCONP = (PCONP & 0x801817BE) | (1UL<<5); /* Enable peripheral clock
for
> PWM0 (default is enabled) */
>
> Alex
>



I gave a try to ARMwizard and it looks so useful but although I
configured PWM module it doesn't work yet.
here is the code generated + PWMLER that didn't apare.

/*********************************************************
Code created using the ARMwizard, visit http://alexan.edaboard.eu
***********************************************************/

#include
int main(void)
{
PINSEL0=0x00008000;/* binary: 00000000_00000000_10000000_00000000 */
IO0DIR=0x80000000;/* binary: 10000000_00000000_00000000_00000000 */
PINSEL1=0x00000400;/* binary: 00000000_00000000_00000100_00000000 */
PINSEL2=0x00000000;/* binary: 00000000_00000000_00000000_00000000 */
IO1DIR=0x00000000;/* binary: 00000000_00000000_00000000_00000000 */

PCONP = (PCONP & 0x801817BE) | 0x20;
PWMTC=0x00000000; /* decimal 0 */
PWMPR=0x00000007; /* decimal 7 */
PWMMCR=0x00000002;
PWMMR0=0x00001D4C; /* decimal 7500 */
PWMMR1=0x00000000; /* decimal 0 */
PWMMR2=0x00000EA6; /* decimal 3750 */
PWMMR3=0x00000000; /* decimal 0 */
PWMMR4=0x00000000; /* decimal 0 */
PWMMR5=0x00000EA6; /* decimal 3750 */
PWMMR6=0x00000000; /* decimal 0 */
PWMPCR=0x00002400;
PWMTCR=0x09; /* binary: 00001001 */
PWMLER=0x24;
while(1)
{

}

}
--- In l..., "Kevin" wrote:
>
> Be careful with using PINSEL1=0x00000400;
> you might accidentally set or reset the functions on other pins as well.
>
> --- In l..., Alexan_e wrote:
> >
> > PINSEL1 = 0x300;// Enable PWM5
> >
> > The above is not correct , the value 0x300 sets P0.20 to EINT3.
> > For P0.21 set to PWM5 use PINSEL1=0x00000400;
> >
> > I would suggest you download ARMwizard to avoid such mistakes
> > http://alexan.edaboard.eu/
> >
> > The power control for PWM can be enabled using:
> > PCONP = (PCONP & 0x801817BE) | (1UL<<5); /* Enable peripheral clock for
> > PWM0 (default is enabled) */
> >
> > Alex
> >
> >
>
Apart from the wrong setting for the PWM5 pin everything was already correct.
Your code works fine in KEIL simulation so there is something wrong with the hardware.

Are you sure that the mcu is programmed properly?
Have you tried a simple blinky application to see if you can upload and execute some code?
How fo you check the PWM output , do you have something connected to the pins?

Alex
----- Original Message -----
From: madbaxyh
To: l...
Sent: Friday, April 20, 2012 2:12 AM
Subject: [lpc2000] Re: Help on PWM basic code

I gave a try to ARMwizard and it looks so useful but although I
configured PWM module it doesn't work yet.
here is the code generated + PWMLER that didn't apare.
/***********************************************************************\
************* Code created using the ARMwizard, visit
http://alexan.edaboard.eu
************************************************************************\
************/
#include

int main(void){/* P0.0: PORT0.0 (General purpose I/O) Input
P0.1: PORT0.1 (General purpose I/O) Input P0.2: PORT0.2 (General
purpose I/open-drain O) Input P0.3: PORT0.3 (General purpose
I/open-drain O) Input P0.4: PORT0.4 (General purpose I/O) Input
P0.5: PORT0.5 (General purpose I/O) Input P0.6: PORT0.6 (General
purpose I/O) Input P0.7: PWM2 (Pulse Width Modulator output 2)
P0.8: PORT0.8 (General purpose I/O) Input P0.9: PORT0.9 (General
purpose I/O) Input P0.10: PORT0.10 (General purpose I/O) Input
P0.11: PORT0.11 (General purpose I/O) Input P0.12: PORT0.12
(General purpose I/O) Input P0.13: PORT0.13 (General purpose I/O)
Input P0.14: PORT0.14 (General purpose I/O) Input P0.15:
PORT0.15 (General purpose I/O) Input P0.16: PORT0.16 (General
purpose I/O) Input P0.17: PORT0.17 (General purpose I/O) Input
P0.18: PORT0.18 (General purpose I/O) Input P0.19: PORT0.19
(General purpose I/O) Input P0.20: PORT0.20 (General purpose I/O)
Input P0.21: PWM5 (Pulse Width Modulator output 5) P0.22:
PORT0.22 (General purpose I/O) Input P0.23: PORT0.23 (General
purpose I/O) Input P0.25: PORT0.25 (General purpose I/O) Input
P0.28: PORT0.28 (General purpose I/O) Input P0.29: PORT0.29
(General purpose I/O) Input P0.30: PORT0.30 (General purpose I/O)
Input P0.31: PORT0.31 (General purpose O) Output P1.16:
PORT1.16 (General purpose I/O) Input P1.17: PORT1.17 (General
purpose I/O) Input P1.18: PORT1.18 (General purpose I/O) Input
P1.19: PORT1.19 (General purpose I/O) Input P1.20: PORT1.20
(General purpose I/O) Input P1.21: PORT1.21 (General purpose I/O)
Input P1.22: PORT1.22 (General purpose I/O) Input P1.23:
PORT1.23 (General purpose I/O) Input P1.24: PORT1.24 (General
purpose I/O) Input P1.25: POR11.25 (General purpose I/O) Input
P1.26: PORT1.26 (General purpose I/O) Input P1.27: PORT1.27
(General purpose I/O) Input P1.28: PORT1.28 (General purpose I/O)
Input P1.29: PORT1.29 (General purpose I/O) Input P1.30:
PORT1.30 (General purpose I/O) Input P1.31: PORT1.31 (General
purpose I/O) Input*/
PINSEL0=0x00008000; /* binary:
00000000_00000000_10000000_00000000 */ IO0DIR=0x80000000; /*
binary: 10000000_00000000_00000000_00000000 */ PINSEL1=0x00000400;
/* binary: 00000000_00000000_00000100_00000000 */ PINSEL2=0x00000000;
/* binary: 00000000_00000000_00000000_00000000 */ IO1DIR=0x00000000;
/* binary: 00000000_00000000_00000000_00000000 */
/***********************************************************************\
*******
PWM*********************************************************************\
********** Counter Enabled, Counter Reset=0, PWM mode enabled
Counter clk: 7.5 MHz, Counts every: 133.33 ns (calculated with
peripheral clock: 60MHz) MCR0.0 : reset, on compare match PWM
frequency: 1 KHz PWM1: Single edge, set by MR0, reset by MR1, output
disabled PWM2: Single edge, set by MR0, reset by MR2, output enabled
PWM3: Single edge, set by MR0, reset by MR3, output disabled PWM4:
Single edge, set by MR0, reset by MR4, output disabled PWM5: Single
edge, set by MR0, reset by MR5, output enabled PWM6: Single edge, set
by MR0, reset by MR6, output disabled*/PCONP = (PCONP & 0x801817BE) |
0x20; /* Enable peripheral clock for PWM0 (default is enabled)
*/PWMTC=0x00000000; /* decimal 0 */PWMPR=0x00000007; /* decimal
7 */PWMMCR=0x00000002; /* binary:
00000000_00000000_00000000_00000010 */PWMMR0=0x00001D4C; /* decimal
7500 */PWMMR1=0x00000000; /* decimal 0 */PWMMR2=0x00000EA6; /*
decimal 3750 */PWMMR3=0x00000000; /* decimal 0 */PWMMR4=0x00000000;
/* decimal 0 */PWMMR5=0x00000EA6; /* decimal 3750
*/PWMMR6=0x00000000; /* decimal 0 */PWMPCR=0x00002400; /*
binary: 00000000_00000000_00100100_00000000 */PWMTCR=0x09; /*
binary: 00001001 */PWMLER=0x24; while(1) { }
}
--- In l..., Alexan_e wrote:
>
> PINSEL1 = 0x300;// Enable PWM5
>
> The above is not correct , the value 0x300 sets P0.20 to EINT3.
> For P0.21 set to PWM5 use PINSEL1=0x00000400;
>
> I would suggest you download ARMwizard to avoid such mistakes
> http://alexan.edaboard.eu/
>
> The power control for PWM can be enabled using:
> PCONP = (PCONP & 0x801817BE) | (1UL<<5); /* Enable peripheral clock
for
> PWM0 (default is enabled) */
>
> Alex
>