Hello All,
I've developed customized LPC1768 board & want PWM 4 & 6 in Double Edge mode. However it is not working. Can you please guide after looking into my code as below. O/p pins of PWM3,4,5 & 6 all shows always HIGH. One more observation is that in the simulator mode the PWM works fine.
I've tested the respective Pins by configuring them as GPIO & LED toggle it works. But the PWM mode is not working.
Thanks & Regards Raj
pwm.c
#include "lpc17xx.h" #include "type.h" #include "datatype.h" #include "pwm.h"
#define PWM_RATE 10000
volatile uint32_t Pwm_Match0_counter;
/****************************************************************************** ** Function name: PWM1_IRQHandler ** ** Descriptions: PWM1 interrupt handler ** For now, it only deals with PWM1 match 0 ** ** parameters: None ** Returned value: None ** ******************************************************************************/ void PWM1_IRQHandler (void) { uint8 regVal;
regVal = LPC_PWM1->IR; if ( regVal & MR0_INT ) { Pwm_Match0_counter++; } LPC_PWM1->IR |= regVal; /* clear interrupt flag on match 0 */ return; }
/****************************************************************************** ** Function name: PWM_Init ** ** Descriptions: PWM initialization, setup all GPIOs to PWM0~6, ** reset counter, all latches are enabled, interrupt ** on PWMMR0, install PWM interrupt to the VIC table. ** ** parameters: None ** Returned value: true or false, if VIC table is full, return false ** ******************************************************************************/ void PWM_Init(void) { Pwm_Match0_counter = 0; LPC_PINCON->PINSEL4 = 0x05500550; /* select PWM3,4,5 & 6 func and P2.10 to 13 as interrupt */
LPC_PWM1->TCR = TCR_RESET; /* Counter Reset */ LPC_PWM1->PR = 0x00; /* count frequency:Fpclk */ LPC_PWM1->MCR = PWMMR0I | PWMMR0R; /* interrupt on PWMMR0, reset on PWMMR0, reset TC if PWM matches */
LPC_PWM1->PCR = PWMSEL3 | PWMSEL4 | PWMSEL5 | PWMSEL6; /* Double Edge selection */ LPC_PWM1->MR0 = PWM_RATE; /* set PWM cycle */
/* all PWM latch enabled */ LPC_PWM1->LER = LER0_EN;
NVIC_EnableIRQ(PWM1_IRQn); return; }
/****************************************************************************** ** Function name: PWM_Set ** ** Descriptions: PWM cycle setup ** ** parameters: Channel number, PWM cycle, and offset ** Returned value: None ** ******************************************************************************/ uint8 PWM_Set(uint8 channelnum, uint32 on_period, uint32 off_period) { switch(channelnum) { case PWM4: LPC_PWM1->MR3 = on_period; /* ON time */ LPC_PWM1->MR4 = off_period; /* OFF time */ LPC_PWM1->LER = LER3_EN | LER4_EN; /* latch new ON/OFF period */ break; case PWM6: LPC_PWM1->MR5 = on_period; /* ON time */ LPC_PWM1->MR6 = off_period; /* OFF time */ LPC_PWM1->LER = LER5_EN | LER6_EN; /* latch new ON/OFF period */ break; default: channelnum = ERROR; /* return ERROR incase wrong channalnum */ break; } return(channelnum); }
/****************************************************************************** ** Function name: PWM_Start ** ** Descriptions: Enable PWM by setting the PCR, PTCR registers ** ** parameters: channel number ** Returned value: None ** ******************************************************************************/ uint8 PWM_Start(uint8 channelnum) { switch(channelnum) { case PWM4: LPC_PWM1->PCR |= PWMENA4; /* Start PWM4 */ break; case PWM6: LPC_PWM1->PCR |= PWMENA6; /* Start PWM6 */ break; default: channelnum = ERROR; /* return ERROR incase wrong channalnum */ break; } LPC_PWM1->TCR = TCR_CNT_EN | TCR_PWM_EN; /* counter enable, PWM enable */ //???? return(channelnum); }
/****************************************************************************** ** Function name: PWM_Stop ** ** Descriptions: Stop PWM channel ** ** parameters: channel number ** Returned value: None ** ******************************************************************************/ uint8 PWM_Stop(uint8 channelnum) { switch(channelnum) { case PWM4: LPC_PWM1->PCR = PWM_DIS4; /* Stop PWM4 */ break; case PWM6: LPC_PWM1->PCR = PWM_DIS6; /* Stop PWM6 */ break; default: channelnum = ERROR; /* return ERROR incase wrong channalnum */ break; } return(channelnum); }
/****************************************************************************** ** End Of File ******************************************************************************/
----------------------------------------------------------------------------------------------
main.c
#include "lpc17xx.h" #include "datatype.h" #include "pwm.h"
extern volatile uint32_t Pwm_Match0_counter;
int main (void) { /* SystemClockUpdate() updates the SystemFrequency variable */ SystemClockUpdate();
PWM_Init(); PWM_Set(PWM4, 3000, 9000); PWM_Set(PWM6, 2000, 8000); PWM_Start(PWM4); PWM_Start(PWM6);
while(1) { if(Pwm_Match0_counter != 0) { Pwm_Match0_counter = 0; PWM_Set(PWM4, 3000, 7000); PWM_Set(PWM6, 5000, 8000); } } }
So read the text information you have available directly above the message input box. Don't you notice teh "Place source code ..." part?
/****************************************************************************** ** Start Of main.c File ******************************************************************************/ #include "lpc17xx.h" #include "datatype.h" #include "pwm.h" extern volatile uint32_t Pwm_Match0_counter; int main (void) { /* SystemClockUpdate() updates the SystemFrequency variable */ SystemClockUpdate(); PWM_Init(); PWM_Set(PWM4, 3000, 9000); PWM_Set(PWM6, 2000, 8000); PWM_Start(PWM4); PWM_Start(PWM6); while(1) { if(Pwm_Match0_counter != 0) { Pwm_Match0_counter = 0; PWM_Set(PWM4, 3000, 7000); PWM_Set(PWM6, 5000, 8000); } } } /****************************************************************************** ** End Of main.c File ******************************************************************************/ /****************************************************************************** ** Start Of pwm.c File ******************************************************************************/ #include "lpc17xx.h" #include "type.h" #include "datatype.h" #include "pwm.h" #define PWM_RATE 10000 volatile uint32_t Pwm_Match0_counter; /****************************************************************************** ** Function name: PWM1_IRQHandler ** ** Descriptions: PWM1 interrupt handler ** For now, it only deals with PWM1 match 0 ** ** parameters: None ** Returned value: None ** ******************************************************************************/ void PWM1_IRQHandler (void) { uint8 regVal; regVal = LPC_PWM1->IR; if ( regVal & MR0_INT ) { Pwm_Match0_counter++; } LPC_PWM1->IR |= regVal; /* clear interrupt flag on match 0 */ return; } /****************************************************************************** ** Function name: PWM_Init ** ** Descriptions: PWM initialization, setup all GPIOs to PWM0~6, ** reset counter, all latches are enabled, interrupt ** on PWMMR0, install PWM interrupt to the VIC table. ** ** parameters: None ** Returned value: true or false, if VIC table is full, return false ** ******************************************************************************/ void PWM_Init(void) { Pwm_Match0_counter = 0; LPC_PINCON->PINSEL4 = 0x05500550; /* select PWM3,4,5 & 6 func and P2.10 to 13 as interrupt */ LPC_PINCON->PINMODE4 = 0x00000AA0; /* No Pull-up/down for PWM3,4,5 & 6*/ LPC_PWM1->TCR = TCR_RESET; /* Counter Reset */ LPC_PWM1->PR = 0x00; /* count frequency:Fpclk */ LPC_PWM1->MCR = PWMMR0I | PWMMR0R; /* interrupt on PWMMR0, reset on PWMMR0, reset TC if PWM matches */ LPC_PWM1->PCR = PWMSEL3 | PWMSEL4 | PWMSEL5 | PWMSEL6; /* Double Edge selection */ LPC_PWM1->MR0 = PWM_RATE; /* set PWM cycle */ /* all PWM latch enabled */ LPC_PWM1->LER = LER0_EN; NVIC_EnableIRQ(PWM1_IRQn); return; } /****************************************************************************** ** Function name: PWM_Set ** ** Descriptions: PWM cycle setup ** ** parameters: Channel number, PWM cycle, and offset ** Returned value: None ** ******************************************************************************/ uint8 PWM_Set(uint8 channelnum, uint32 on_period, uint32 off_period) { switch(channelnum) { case PWM4: LPC_PWM1->MR3 = on_period; /* ON time */ LPC_PWM1->MR4 = off_period; /* OFF time */ LPC_PWM1->LER = LER3_EN | LER4_EN; /* latch new ON/OFF period */ break; case PWM6: LPC_PWM1->MR5 = on_period; /* ON time */ LPC_PWM1->MR6 = off_period; /* OFF time */ LPC_PWM1->LER = LER5_EN | LER6_EN; /* latch new ON/OFF period */ break; default: channelnum = ERROR; /* return ERROR incase wrong channalnum */ break; } return(channelnum); } /****************************************************************************** ** Function name: PWM_Start ** ** Descriptions: Enable PWM by setting the PCR, PTCR registers ** ** parameters: channel number ** Returned value: None ** ******************************************************************************/ uint8 PWM_Start(uint8 channelnum) { switch(channelnum) { case PWM4: LPC_PWM1->PCR |= PWMENA4; /* Start PWM4 */ break; case PWM6: LPC_PWM1->PCR |= PWMENA6; /* Start PWM6 */ break; default: channelnum = ERROR; /* return ERROR incase wrong channalnum */ break; } LPC_PWM1->TCR = TCR_CNT_EN | TCR_PWM_EN; /* counter enable, PWM enable */ //???? return(channelnum); } /****************************************************************************** ** Function name: PWM_Stop ** ** Descriptions: Stop PWM channel ** ** parameters: channel number ** Returned value: None ** ******************************************************************************/ uint8 PWM_Stop(uint8 channelnum) { switch(channelnum) { case PWM4: LPC_PWM1->PCR = PWM_DIS4; /* Stop PWM4 */ break; case PWM6: LPC_PWM1->PCR = PWM_DIS6; /* Stop PWM6 */ break; default: channelnum = ERROR; /* return ERROR incase wrong channalnum */ break; } return(channelnum); } /****************************************************************************** ** End Of pwm.c File ******************************************************************************/