Hi all, I have an olimex lpc2106-mt pcb and try to program a PWM without success. The Docu is not especially detailed (I think). I tried a lot of register settings(for hours). All I get is a single 88.64 ms pulse on PWM4 at reset that does not change with the match register or pre- scaler value. This code is one example that illustrates my understanding of that thing: //testing PWM4 PINSEL0 |= 0x20000; // select pin 0.08 PWM4 function PWM_PR = 0x0000; // max prescale counter value PWM_MCR = 0x0002; // reset when PWMMR0 matches PWM_PCR = 0x1000; // PWM4 enable, single edge PWM_MR0 = 0x0f00; // match register trigger value PWM_TCR = 0x0009; // set the TC counter and enable the PWMs I would expect a 1.92 kHz frequency from that... Obviously I do something completly wrong. Any help is really apreciated Cheers, Kurt. |
|
PWM with olimex lpc2106-mt pcb - how to?
Started by ●July 20, 2004
Reply by ●July 20, 20042004-07-20
--- In , "killtheclock" <kurt.westphal@g...> wrote: > I have an olimex lpc2106-mt pcb and try to program a PWM without > success. The Docu is not especially detailed (I think). I tried a lot > of register settings(for hours). All I get is a single 88.64 ms pulse > on PWM4 at reset that does not change with the match register or pre- > scaler value. > > This code is one example that illustrates my understanding of that > thing: > //testing PWM4 > PINSEL0 |= 0x20000; // select pin 0.08 PWM4 function > PWM_PR = 0x0000; // max prescale counter value > PWM_MCR = 0x0002; // reset when PWMMR0 matches > PWM_PCR = 0x1000; // PWM4 enable, single edge > PWM_MR0 = 0x0f00; // match register trigger value > PWM_TCR = 0x0009; // set the TC counter and enable the PWMs > > I would expect a 1.92 kHz frequency from that... > Obviously I do something completly wrong. You also need to set PWM_MR4, and then PWM_LER before the PWM_MRx values take effect. Karl Olsen |
|
Reply by ●July 21, 20042004-07-21
I still can't get it running. Karl showed me the way to understand the docu - at least I felt like understanding it... Current code status: //testing PWM4 PINSEL0 |= 0x20000; // select pin 0.08 PWM4 function PWM_PR = 0x0000; // max prescale counter value PWM_MCR = 0x0002; // reset TC when PWMMR0 matches PWM_PCR = 0x7E00; // enable all PWM just to get the right one PWM_TCR = 0x000A; // reset TC counter (not yet needed?!) PWM_MR0 = 0x0400; // match register 0 trigger value PWM_LER |= BIT0; PWM_MR4 = 0x0150; // match register 4 trigger value PWM_LER |= BIT4; PWM_TCR = 0x0009; // set the TC counter and enable the PWMs But still getting the single 88.64 ms pulse. Any idea? Cheers, Kurt. --- In , "Karl Olsen" <kro@p...> wrote: > --- In , "killtheclock" <kurt.westphal@g...> > wrote: > > > I have an olimex lpc2106-mt pcb and try to program a PWM without > > success. The Docu is not especially detailed (I think). I tried a > lot > > of register settings(for hours). All I get is a single 88.64 ms > pulse > > on PWM4 at reset that does not change with the match register or > pre- > > scaler value. > > > > This code is one example that illustrates my understanding of that > > thing: > > //testing PWM4 > > PINSEL0 |= 0x20000; // select pin 0.08 PWM4 function > > PWM_PR = 0x0000; // max prescale counter value > > PWM_MCR = 0x0002; // reset when PWMMR0 matches > > PWM_PCR = 0x1000; // PWM4 enable, single edge > > PWM_MR0 = 0x0f00; // match register trigger value > > PWM_TCR = 0x0009; // set the TC counter and enable the PWMs > > > > I would expect a 1.92 kHz frequency from that... > > Obviously I do something completly wrong. > > You also need to set PWM_MR4, and then PWM_LER before the PWM_MRx > values take effect. > > Karl Olsen |
|
Reply by ●July 21, 20042004-07-21
> I still can't get it running. Karl showed me the way to understand
> the docu - at least I felt like understanding it... > Current code status: > > //testing PWM4 > PINSEL0 |= 0x20000; // select pin 0.08 PWM4 function > > PWM_PR = 0x0000; // max prescale counter value > PWM_MCR = 0x0002; // reset TC when PWMMR0 matches > PWM_PCR = 0x7E00; // enable all PWM just to get the right one > PWM_TCR = 0x000A; // reset TC counter (not yet needed?!) > > PWM_MR0 = 0x0400; // match register 0 trigger value > PWM_LER |= BIT0; > > PWM_MR4 = 0x0150; // match register 4 trigger value > PWM_LER |= BIT4; > > PWM_TCR = 0x0009; // set the TC counter and enable the PWMs > > But still getting the single 88.64 ms pulse. > Any idea? > > Cheers, Kurt. Hi Kurt, I think the main problem is that you have to wait until you get the Match _before_ the PWM cycle is actually written. This would explain why you only get a single pulse. Follow this procedure I use : /* Setting the PWM cycle */ /*******************/ PWMTCR = 0x0B; // Hold TC in reset while altering Cycle PWMMR0 = CYCLE; // Write the new PWM period PWMMCR = 0x01; // Allow the INT flag for MR0 PWMTCR = 0x09; // Restart PWM PWMIR |= 0x01; // Reset MR0 Int flag PWMLER = 0x01; // Enable PWM0 latch while ( ! (PWMIR & 0x01)); // Wait for match -> new cycle complete PWMMCR = 0; // Disable MR0 Int flagging /* Setting , for example, PWM5 */ /***********************/ PWMMR5 = DUTY; // write duty cycle PWMLER = 0x20; // enable PWM5 Latch Obviously CYCLE is the total PWM cycle and PERIOD makes the PWM's dutycycle as = DUTY / CYCLE So if you eg. set CYCLE to 1000 and DUTY to 150 you would get a 15% dutycycle with a frequency of PCLK / 1000 (cycle), providing Prescaler is set to ONE (=0). There might be better ways of doing this, but this way ensures you wait long enough for the PWM period cycle to update, but no longer than necessary...... B rgds and good luck, Kris |
|
Reply by ●July 23, 20042004-07-23
Now I got it: It is really simple. The only problem was that I inited P0.8 to be used as TxD UART 1, PINSEL P0.8 bits set to 01. Then in the main program I set the bits to 10. PINSEL0 |= 0x20000; That resulted in both bits set for P0.8, wich is undefined and does not work. This code does work: //setup PWM4 PINSEL0 &= ~BIT16; // deselect pin 0.08 GPIO function PINSEL0 |= BIT17; // select pin 0.08 PWM4 function PWM_PCR = BIT12; //PWM4 enable, single edge PWM_PR = 0x0000; // max prescale counter value PWM_MR0 = 0x400; // MR0 must be set prior to enabling // the PWM PWM_MCR = 0x02; // enable reset on MR0 PWM_TCR = 0x09; // PWM enable and counter start PWM_MR4 = 0x0200; // match register 4 trigger value PWM_LER |= 0x10; // latch MR4 Kris, there is no need to poll the interrupt flag when you init MR0 before enabling PWM mode. The docu says (UM_LPC2106_2105_2104_1.pdf, p.152, table 117): "Note that the PWM Match register that determines the PWM rate (PWM Match 0) must be set up prior to the PWM being enabled. Otherwise a Match event will not occur to cause shadow register contents to become effective." Thank you Kris and Karl, regards, Kurt. --- In , "microbit" <microbit@c...> wrote: > > I still can't get it running. Karl showed me the way to understand > > the docu - at least I felt like understanding it... > > Current code status: > > > > //testing PWM4 > > PINSEL0 |= 0x20000; // select pin 0.08 PWM4 function > > > > PWM_PR = 0x0000; // max prescale counter value > > PWM_MCR = 0x0002; // reset TC when PWMMR0 matches > > PWM_PCR = 0x7E00; // enable all PWM just to get the right one > > PWM_TCR = 0x000A; // reset TC counter (not yet needed?!) > > > > PWM_MR0 = 0x0400; // match register 0 trigger value > > PWM_LER |= BIT0; > > > > PWM_MR4 = 0x0150; // match register 4 trigger value > > PWM_LER |= BIT4; > > > > PWM_TCR = 0x0009; // set the TC counter and enable the PWMs > > > > But still getting the single 88.64 ms pulse. > > Any idea? > > > > Cheers, Kurt. > > Hi Kurt, > > I think the main problem is that you have to wait until you get the Match _before_ > the PWM cycle is actually written. This would explain why you only get a single pulse. > > Follow this procedure I use : > > /* Setting the PWM cycle */ > /*******************/ > PWMTCR = 0x0B; // Hold TC in reset while altering Cycle > PWMMR0 = CYCLE; // Write the new PWM period > PWMMCR = 0x01; // Allow the INT flag for MR0 > PWMTCR = 0x09; // Restart PWM > PWMIR |= 0x01; // Reset MR0 Int flag > PWMLER = 0x01; // Enable PWM0 latch > while ( ! (PWMIR & 0x01)); // Wait for match -> new cycle complete > PWMMCR = 0; // Disable MR0 Int flagging > > /* Setting , for example, PWM5 */ > /***********************/ > PWMMR5 = DUTY; // write duty cycle > PWMLER = 0x20; // enable PWM5 Latch > > Obviously CYCLE is the total PWM cycle and PERIOD makes the > PWM's dutycycle as = DUTY / CYCLE > > So if you eg. set CYCLE to 1000 and DUTY to 150 you would get a 15% dutycycle > with a frequency of PCLK / 1000 (cycle), providing Prescaler is set to ONE (=0). > > There might be better ways of doing this, but this way ensures you wait long enough > for the PWM period cycle to update, but no longer than necessary...... > > B rgds and good luck, > Kris > |