Philip,
I had a similar need to drive peripherals with a clock signal in the 4-8Mhz range and wanted to use a PWMout channel to do so however, the mbed API is limited to 1Mhz maximum. In my investigations I found some useful information regarding manipulating the hardware registers directly to alter the pre-scaler blocks that 'divide-by' to reduce the 96Mhz system clock down to a lower frequency to drive the PWM hardware.
Refer to forum called "5 MHz clock signal" /forum/mbed/topic/733/?page=1#comment-3597
and also a good blog link for LPC1768 PWM is: http://msys-mv.blogspot.com/2011/01/using-pwm-on-lpc17xx.html
I put together a simple snippet of code to collect my thoughts for self tutorial for my future reference:
#include "mbed.h"
PwmOut oscillator(p21); // using hardware channel PWM_6
int main() {
/* Here we maniplulate the LPC1768 hardware registers directly. Due to the 96Mhz system
clock and the design of the PWMout library function to achieve waveform periods on exact
settings on exact frequency stops in S, ms & us, it is limited to 1Mhz output maximum. We
use PWMout to do the legwork of setup, pin assignment & starting the PWM, then we access
the hardware registers directly to achieve a PWM output greater than the 1Mhz library limitation.
Refer to forum called "5 MHz clock signal" and also a good blog link for LPC1768 PWM is:
http://msys-mv.blogspot.com/2011/01/using-pwm-on-lpc17xx.html
*/
LPC_SC->PCLKSEL0 &= ~(3<<12); //manipulate LPC1768 peripheral master PCLK_PWM1 clock pre-scaler register and
LPC_SC->PCLKSEL0 |= (1<<12); //set to divide by /1 (ie: system clock 96Mhz) rather than default /4
//should now output 4-times the 1Mhz inherent maximum rate of PWMout, or 4Mhz
//refer to LPC17xx manual, table 40 and 42, pg 56 and 57
LPC_PWM1->MR0 = 23; //Match Register 0 is shared period counter for all PWM outputs
//system clock 96Mhz divided by 24 less one (because counts from zero)
//96Mhz / 24 = exactly 4Mhz period
LPC_PWM1->MR6 =12; //Pin 21 is PWM output 6, so Match Register 6 determines pulse width
//pulse width would be half of 23 for 50% duty cycle but because register
//only accepts integers we'll use 12
while (1) {}
}
When you make the adjustments to the clock pre-scaler and match register MR0 (period counter), they will affect all six PWMout channels in the same way being all six share and are dependent on these two hardware registers. The duty cycle or pulse width are each independently adjustable and specific to each PWMout channel by the respective match register:
- MR1 is for PWM output 1
- MR2 is for PWM output 2
- MR3 is for PWM output 3
- MR4 is for PWM output 4
- MR5 is for PWM output 5
- MR6 is for PWM output 6
I hope you find this helpful. It helped me learn how to achieve the output I needed.
Dave
Hello all I was searching the forum for instructions on how to access function source code. Say for example I'm interested in the functions located here: http://mbed.org/handbook/PwmOut
I'd like to look at the code for the function PwmOut or period_us. How can I do this?
Thank you Scott