Assuming you are using an LPC1768, I'm afraid you cannot generate a precisely 5 MHz clock from the PWM. Even if you don't use the current library, and drive the PWM yourself, you are constrained by integers.
The LPC1768 clocks at 96MHz. 96e6 / 5e6 gives 19.2. The PWM block counts off of the system clock, so your period counter would have to be either 19 or 20. 19 gives you a frequency of just over 5.052MHz, and 20 gives you 4.8 MHz. (Note, to get these frequencies, you have to bypass the library).
Assuming that the 5.052andabit is good enough, here's how you get there. I'll use the library object as a starting point, as it does a load of the pin connection setup, enabling the block and all that for us. I'll just go and trample over some of its settings afterwards. I'm going to use pin 21 of the mbed, which is PWM output 6.
The PWM block has a match register 0, which is used as the period counter. Then, each of the PWM outputs (1 through to 6) have their own match counters, which are used to determine when to change the output level. We're using the block in a simple "output high, until match counter matched, then output low" mode. Thus our value of MR0 is going to be 18 (we count from zero, match at 18), and our value of MR6 (if using p21) is going to be 9. These counters are derived from the system clock, through a peripheral clock divider and a prescaler. So what we need to do is:
- Reset the PWM block
- Set the peripheral clock divider to /1 (the library sets the prescaler to /1 for us)
- Load the match registers
- Tell the block to start at next match
- Re-start the PWM block
#include "mbed.h"
DigitalOut myled(LED1);
PwmOut fmclck(p21);
int main() {
LPC_PWM1->TCR = (1 << 1); // Reset counter, disable PWM
LPC_SC->PCLKSEL0 &= ~(0x3 << 12);
LPC_SC->PCLKSEL0 |= (1 << 12); // Set peripheral clock divider to /1, i.e. system clock
LPC_PWM1->MR0 = 18; // Match Register 0 is shared period counter for all PWM1
LPC_PWM1->MR6 = 9; // Pin 21 is PWM output 6, so Match Register 6
LPC_PWM1->LER |= 1; // Start updating at next period start
LPC_PWM1->TCR = (1 << 0) || (1 << 3); // Enable counter and PWM
while(1);
}
I'd like to have precisely 5 MHz clock signal. mbed PWM seems to be able to give 1MHz (with 1 us period). Is there an easy way to do this, instead of buying a 5 MHz crystal oscillator.