LPC2129 PWM Modified rate not working properly

Started by "ana...@yahoo.com [lpc2000]" May 11, 2014
Hi all
I am working on single edge PWM generation on LPC 2129 .The summary o my work is as below
1)I am able to see PWM output on Pin 33(PWM 4).it is as per my clock settings.No problem still here.
2)In the PWM ISR,I am setting 2 flags and in the main loop of the code ,and based on these flag values I am dynamically changing PWM4 rate by changing PWMMR0 ;PWMMR4 PWMLER registers.
3)These above mentioned changes are not reflected in the scope output.I dont see my modified rate settings on the scope.

Regards
Anand

int main(void)
{

systemInit(); // PLL, MAM etc.
gpioInit();
enableIRQ();
init_PWM();

while (1) { /* Loop forever */

if (count10flag == 1)
{
count10flag = 0;
PWMMR0 = 4000;
PWMMR4 = 500;
PWMLER = 0x7f;
//PWMTCR = 0x09; // Counter Enable, PWM Mode Enabled(bit0, bit3)
}
else if (count20flag == 1)
{
count20flag = 0;
PWMMR0 = 4000;
PWMMR4 = 1500;
PWMLER = 0x7f;
}
;
}

return 0; /* never reached */
}
//*******************************************************////
pwm.C
void PWM0_isr (void) __attribute__ ((naked));
static int count = 0;
int count10flag = 0;
int count20flag = 0;
void PWM0_isr (void)
{

ISR_ENTRY();

PWMIR |= 0x00000001; /* Clear match0 interrupt */
VICVectAddr = 0x00000000;
count++;

if (count == 10) //LED Blinks at every 4 * 10 = 40 seconds
{
IOSET1 = LED3BITY; // enable LED3
count10flag = 1;
}
else if (count == 20)//LED Blinks off at every 4 * 10 = 40 seconds
{
IOCLR1 = LED3BITY; // disable LED3
count = 0;
count20flag = 1;
}
ISR_EXIT();
}

void init_PWM (void) {
VICIntSelect = 0x00000000;
VICIntEnable = 0x00000100; /* Enable the interrupt */
VICVectCntl8 = 0x00000028; /* Set channel */
VICVectAddr8 = (unsigned)(void *)PWM0_isr; /* Set the PWM ISR vector address */

PINSEL0 |= 0x00020000; // Change GPIO P0.8 to PWM4
PWMPR = 23999;// Set Pre Scale to 23999 -Here formula is given by Delay = (Y/(X*10^6)) .Here if Pclk = 24 Mhz then X = 24 And here we want a delay of 1 ms /Therefore Pr = 23999 which gives 24000 / 24 Mhz = 1ms;
PWMPCR = 0x00001000; // Enable PWM4 Output (bit12)
// 1 tick = 1ms;
PWMMR0 = 4000;// Max Value of Pulse Width for 4000 ticks --- total pulse width at PWM4 pin no 33 = 4 seconds (4000 * 1ms))
PWMMR4 = 2500;// PWM4 Match Value for 2500 ticks pulse width at PWM4 pin no 33 = 2.5 seconds (2500 * 1ms).
PWMMCR = 0x00000003; // Reset PWMTC and interrupt PWMMTC when Matched with PWMMR0
PWMLER = 0x7F; // Latch in all PWMMMR's
PWMTCR = 0x02; // Reset PWMMTC, (bit1)
PWMTCR = 0x09; // Counter Enable, PWM Mode Enabled(bit0, bit3)

}


An Engineer's Guide to the LPC2100 Series

First why are you latching all the possible PWM's where you are only
using 1 (PWM4).

Why are you reloading the PWM0 over again. It has not changed since
you initialized it.

If you just latch the PWM4 ONLY and remove the load for PWM0 in your
routine.

PWMLER = BIT_4;

I'm using a 2136 and a 2148 with no problems.

regards,
Charles
On 5/11/2014 3:04 PM, a...@yahoo.com [lpc2000] wrote:
> Hi all
> I am working on single edge PWM generation on LPC 2129 .The summary o my work is as below
> 1)I am able to see PWM output on Pin 33(PWM 4).it is as per my clock settings.No problem still here.
> 2)In the PWM ISR,I am setting 2 flags and in the main loop of the code ,and based on these flag values I am dynamically changing PWM4 rate by changing PWMMR0 ;PWMMR4 PWMLER registers.
> 3)These above mentioned changes are not reflected in the scope output.I dont see my modified rate settings on the scope.
> Regards
> Anand
> int main(void)
> {
>
> systemInit(); // PLL, MAM etc.
> gpioInit();
> enableIRQ();
> init_PWM();
>
> while (1) { /* Loop forever */
>
> if (count10flag == 1)
> {
> count10flag = 0;
> PWMMR0 = 4000;
> PWMMR4 = 500;
> PWMLER = 0x7f;
> //PWMTCR = 0x09; // Counter Enable, PWM Mode Enabled(bit0, bit3)
> }
> else if (count20flag == 1)
> {
> count20flag = 0;
> PWMMR0 = 4000;
> PWMMR4 = 1500;
> PWMLER = 0x7f;
> }
> ;
> }
>
>
> return 0; /* never reached */
> }
> //*******************************************************////
> pwm.C
> void PWM0_isr (void) __attribute__ ((naked));
> static int count = 0;
> int count10flag = 0;
> int count20flag = 0;
> void PWM0_isr (void)
> {
>
> ISR_ENTRY();
> PWMIR |= 0x00000001; /* Clear match0 interrupt */
> VICVectAddr = 0x00000000;
> count++;
>
> if (count == 10) //LED Blinks at every 4 * 10 = 40 seconds
> {
> IOSET1 = LED3BITY; // enable LED3
> count10flag = 1;
> }
> else if (count == 20)//LED Blinks off at every 4 * 10 = 40 seconds
> {
> IOCLR1 = LED3BITY; // disable LED3
> count = 0;
> count20flag = 1;
> }
> ISR_EXIT();
> }
> void init_PWM (void) {
> VICIntSelect = 0x00000000;
> VICIntEnable = 0x00000100; /* Enable the interrupt */
> VICVectCntl8 = 0x00000028; /* Set channel */
> VICVectAddr8 = (unsigned)(void *)PWM0_isr; /* Set the PWM ISR vector address */
>
> PINSEL0 |= 0x00020000; // Change GPIO P0.8 to PWM4
> PWMPR = 23999;// Set Pre Scale to 23999 -Here formula is given by Delay = (Y/(X*10^6)) .Here if Pclk = 24 Mhz then X = 24 And here we want a delay of 1 ms /Therefore Pr = 23999 which gives 24000 / 24 Mhz = 1ms;
> PWMPCR = 0x00001000; // Enable PWM4 Output (bit12)
> // 1 tick = 1ms;
> PWMMR0 = 4000;// Max Value of Pulse Width for 4000 ticks --- total pulse width at PWM4 pin no 33 = 4 seconds (4000 * 1ms))
> PWMMR4 = 2500;// PWM4 Match Value for 2500 ticks pulse width at PWM4 pin no 33 = 2.5 seconds (2500 * 1ms).
> PWMMCR = 0x00000003; // Reset PWMTC and interrupt PWMMTC when Matched with PWMMR0
> PWMLER = 0x7F; // Latch in all PWMMMR's
> PWMTCR = 0x02; // Reset PWMMTC, (bit1)
> PWMTCR = 0x09; // Counter Enable, PWM Mode Enabled(bit0, bit3)
>
> }
>
>
>
On 05/11/2014 10:04 PM, a...@yahoo.com [lpc2000] wrote:
> 3)These above mentioned changes are not reflected in the scope output.I
> dont see my modified rate settings on the scope.

Are you sure, that your "if" sentences in the main loop are firing as
expected? To be sure, try to blink your LED there.

It may be, that the compiler is not aware that the value of the
countx0flags may be changed during the main loop. Use volatile qualifiers.

--

Timo



>On 05/11/2014 10:04 PM, a...@yahoo.com [lpc2000] wrote:
>> 3)These above mentioned changes are not reflected in the scope output.I
>> dont see my modified rate settings on the scope.
>
>Are you sure, that your "if" sentences in the main loop are firing as
>expected? To be sure, try to blink your LED there.
>
>It may be, that the compiler is not aware that the value of the
>countx0flags may be changed during the main loop. Use volatile qualifiers.
>
>--
>
>Timo
>
>I will try using volatile qualifiers and latch only PWM4 and remove PWM0 duty cylce updation from the main loop code and try and will let u know

if there is any errata related to PWM dynamic duty cycle modification on LPC 2129.Any idea ,any of the group members do have ,please guide me

regards
Anand
>


>On 05/11/2014 10:04 PM, a...@yahoo.com [lpc2000] wrote:
>> 3)These above mentioned changes are not reflected in the scope output.I
>> dont see my modified rate settings on the scope.
>
>Are you sure, that your "if" sentences in the main loop are firing as
>expected? To be sure, try to blink your LED there.
>
>It may be, that the compiler is not aware that the value of the
>countx0flags may be changed during the main loop. Use volatile qualifiers.
>
>--
>
>Timo
>
Thanks Timo for your valuable help.I am using volatile qualifiers in both of my files(pwm.c and blinky.c --here extern volatile),It is taking my modified PWM Duty cycles and scope o/p is as expected.

Thanks again


On 14.05.2014 21:33, a...@yahoo.com [lpc2000] wrote:
> Thanks Timo ...

You're welcome.

--

Timo



count10flag and count20flag are modified in the main loop and in the IRQ thread without guarding in the main loop. This is a problem which you may not see rigtht now but it is very unsafe to do that.

regards















 









Hi all



I am working on single edge PWM generation on LPC 2129 .The
summary o my work is as below



1)I am able to see PWM output on Pin 33(PWM 4).it is as per
my clock settings.No problem still here.



2)In the PWM ISR,I am setting 2 flags and in the main loop
of the code ,and based on these flag values I am dynamically
changing PWM4 rate by changing PWMMR0 ;PWMMR4 PWMLER
registers.



3)These above mentioned changes are not reflected in the
scope output.I dont see my modified rate settings on the
scope.



Regards

Anand



int main(void)

{



systemInit(); // PLL, MAM etc.

gpioInit();

enableIRQ();

init_PWM();



while (1) { /* Loop forever
*/



if (count10flag == 1)

{

count10flag = 0;

PWMMR0 = 4000;

PWMMR4 = 500;

PWMLER = 0x7f;

//PWMTCR = 0x09; // Counter Enable, PWM Mode Enabled(bit0,
bit3)

}

else if (count20flag == 1)

{

count20flag = 0;

PWMMR0 = 4000;

PWMMR4 = 1500;

PWMLER = 0x7f;

}

;

}





return 0; /* never reached */

}



//*******************************************************////

pwm.C



void PWM0_isr (void) __attribute__ ((naked));

static int count = 0;

int count10flag = 0;

int count20flag = 0;



void PWM0_isr (void)

{



ISR_ENTRY();





PWMIR |= 0x00000001; /* Clear match0
interrupt */

VICVectAddr = 0x00000000;

count++;



if (count == 10) //LED Blinks at every 4 * 10 = 40
seconds

{

IOSET1 = LED3BITY; // enable LED3

count10flag = 1;

}

else if (count == 20)//LED Blinks off at every 4 * 10 =
40 seconds

{

IOCLR1 = LED3BITY; // disable LED3

count = 0;

count20flag = 1;

}

ISR_EXIT();

}



void init_PWM (void) {



VICIntSelect = 0x00000000;

VICIntEnable = 0x00000100; /* Enable the
interrupt */

VICVectCntl8 = 0x00000028; /* Set channel
*/

VICVectAddr8 = (unsigned)(void *)PWM0_isr; /* Set
the PWM ISR vector address */







PINSEL0 |= 0x00020000; // Change GPIO P0.8 to PWM4

PWMPR = 23999;// Set Pre Scale to 23999 -Here formula is
given by Delay = (Y/(X*10^6)) .Here if Pclk = 24 Mhz then X
= 24 And here we want a delay of 1 ms /Therefore Pr =
23999 which gives 24000 / 24 Mhz = 1ms;

PWMPCR = 0x00001000; // Enable PWM4 Output (bit12)

// 1 tick = 1ms;

PWMMR0 = 4000;// Max Value of Pulse Width for 4000 ticks
--- total pulse width at PWM4 pin no 33 = 4 seconds (4000 *
1ms))

PWMMR4 = 2500;// PWM4 Match Value for 2500 ticks pulse
width at PWM4 pin no 33 = 2.5 seconds (2500 * 1ms).

PWMMCR = 0x00000003; // Reset PWMTC and interrupt PWMMTC
when Matched with PWMMR0

PWMLER = 0x7F; // Latch in all PWMMMR's

PWMTCR = 0x02; // Reset PWMMTC, (bit1)

PWMTCR = 0x09; // Counter Enable, PWM Mode Enabled(bit0,
bit3)



}