Library that allows for higher resolution and speed than standard mbed PWM library. Based on FastPWM without floating point calculation in most functions

Fork of FastPWM by Erik -

Library that allows faster and/or higher resolution PWM output.

This library is based original on FastPWM by Erik Olieman but without floating point (double) calculation in each call of pulsewidth_xx. This change was nessecary to get a performant motion controller.

Library can directly replace standard mbed PWM library. Only limitation is that the maximum PWM period is four times shorter The maximum achievable period is roughly 40 seconds, I dont think that should be a problem. Do take into account all PWM objects (based on defailt PWM lib) will run four times faster than default.

Contrary to the default mbed library, this library takes doubles instead of floats. The compiler will autocast if needed, but do take into account it is done for a reason, your accuracy will otherwise be limitted by the floating point precision.

Using this library for a RC servo the resolution of steps (min to max) is increased from 1000 to 96000.

This library can be also used as a analoge output (with external low-pass filter) with a frequency of e.g. 20kHz and a resolution 4800 steps (similar to a 12 bit DAC) instead of 50 steps (similar to a 5 bit DAC) on original PWM lib.

In your program you can define F_CLK if you use a different clock frequency than the default one.

Only works on LPC1768 for now. If you want support for the other one, send a PM and I will have a look, but I cannot even compile for it.

Committer:
Sissors
Date:
Wed Jul 25 07:14:39 2012 +0000
Revision:
3:3094d3806cfc
Parent:
1:1aed61747ed6
Fixed clk_sel, latch registers and constant duty when changing period

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 1:1aed61747ed6 1 /*
Sissors 1:1aed61747ed6 2 .---. _....._
Sissors 1:1aed61747ed6 3 / p `\ .-""`: :`"-.
Sissors 1:1aed61747ed6 4 |__ - | ,' . ' ',
Sissors 1:1aed61747ed6 5 ._> \ /: : ; :,
Sissors 1:1aed61747ed6 6 '-. '\`. . : ' \
Sissors 1:1aed61747ed6 7 `. | .'._.' '._.' '._.'. |
Sissors 1:1aed61747ed6 8 `;-\. : : ' '/,__,
Sissors 1:1aed61747ed6 9 .-'`'._ ' . : _.'.__.'
Sissors 1:1aed61747ed6 10 ((((-'/ `";--..:..--;"` \
Sissors 1:1aed61747ed6 11 .' / \ \
Sissors 1:1aed61747ed6 12 jgs ((((-' ((((-'
Sissors 1:1aed61747ed6 13
Sissors 1:1aed61747ed6 14 Yeah ASCII art turtle more fun than copyright stuff
Sissors 1:1aed61747ed6 15 */
Sissors 1:1aed61747ed6 16
Sissors 1:1aed61747ed6 17
Sissors 0:f8c1b0ad5371 18 #include "mbed.h"
Sissors 0:f8c1b0ad5371 19
Sissors 0:f8c1b0ad5371 20
Sissors 0:f8c1b0ad5371 21 #ifndef FASTPWM_H
Sissors 0:f8c1b0ad5371 22 #define FASTPWM_H
Sissors 0:f8c1b0ad5371 23
Sissors 0:f8c1b0ad5371 24 #ifndef F_CLK
Sissors 0:f8c1b0ad5371 25 #define F_CLK 96000000
Sissors 0:f8c1b0ad5371 26 #endif
Sissors 0:f8c1b0ad5371 27
Sissors 0:f8c1b0ad5371 28 /** Library that allows faster and/or higher resolution PWM output
Sissors 0:f8c1b0ad5371 29 *
Sissors 0:f8c1b0ad5371 30 * Library can directly replace standard mbed PWM library. Only limitation is that the maximum PWM period is four times shorter
Sissors 0:f8c1b0ad5371 31 * The maximum achievable period is roughly 40 seconds, I dont think that should be a problem.
Sissors 0:f8c1b0ad5371 32 * Do take into account all PWM objects will run four times faster than default.
Sissors 0:f8c1b0ad5371 33 *
Sissors 0:f8c1b0ad5371 34 * Contrary to the default mbed library, this library takes doubles instead of floats. The compiler will autocast if needed,
Sissors 0:f8c1b0ad5371 35 * but do take into account it is done for a reason, your accuracy will otherwise be limitted by the floating point precision.
Sissors 0:f8c1b0ad5371 36 *
Sissors 0:f8c1b0ad5371 37 * In your program you can define F_CLK if you use a different clock frequency than the default one.
Sissors 0:f8c1b0ad5371 38 *
Sissors 0:f8c1b0ad5371 39 * Only works on LPC1768 for now. If you want support for the other one, send a PM and I will have a look, but I cannot even compile for it.
Sissors 0:f8c1b0ad5371 40 */
Sissors 0:f8c1b0ad5371 41 class FastPWM {
Sissors 0:f8c1b0ad5371 42 public:
Sissors 0:f8c1b0ad5371 43 /**
Sissors 0:f8c1b0ad5371 44 * Create a FastPWM object connected to the specified pin
Sissors 0:f8c1b0ad5371 45 *
Sissors 0:f8c1b0ad5371 46 * @param pin - PWM pin to connect to
Sissors 0:f8c1b0ad5371 47 */
Sissors 0:f8c1b0ad5371 48 FastPWM(PinName pin);
Sissors 0:f8c1b0ad5371 49
Sissors 0:f8c1b0ad5371 50 /**
Sissors 0:f8c1b0ad5371 51 * Set the PWM period, specified in seconds (double), keeping the duty cycle the same.
Sissors 0:f8c1b0ad5371 52 */
Sissors 0:f8c1b0ad5371 53 void period(double seconds);
Sissors 0:f8c1b0ad5371 54
Sissors 0:f8c1b0ad5371 55 /**
Sissors 0:f8c1b0ad5371 56 * Set the PWM period, specified in milli-seconds (int), keeping the duty cycle the same.
Sissors 0:f8c1b0ad5371 57 */
Sissors 0:f8c1b0ad5371 58 void period_ms(int ms);
Sissors 0:f8c1b0ad5371 59
Sissors 0:f8c1b0ad5371 60 /**
Sissors 0:f8c1b0ad5371 61 * Set the PWM period, specified in micro-seconds (int), keeping the duty cycle the same.
Sissors 0:f8c1b0ad5371 62 */
Sissors 0:f8c1b0ad5371 63 void period_us(int us);
Sissors 0:f8c1b0ad5371 64
Sissors 0:f8c1b0ad5371 65 /**
Sissors 0:f8c1b0ad5371 66 * Set the PWM period, specified in micro-seconds (double), keeping the duty cycle the same.
Sissors 0:f8c1b0ad5371 67 */
Sissors 0:f8c1b0ad5371 68 void period_us(double us);
Sissors 0:f8c1b0ad5371 69
Sissors 0:f8c1b0ad5371 70 /**
Sissors 0:f8c1b0ad5371 71 * Set the PWM pulsewidth, specified in seconds (double), keeping the period the same.
Sissors 0:f8c1b0ad5371 72 */
Sissors 0:f8c1b0ad5371 73 void pulsewidth(double seconds);
Sissors 0:f8c1b0ad5371 74
Sissors 0:f8c1b0ad5371 75 /**
Sissors 0:f8c1b0ad5371 76 * Set the PWM pulsewidth, specified in milli-seconds (int), keeping the period the same.
Sissors 0:f8c1b0ad5371 77 */
Sissors 0:f8c1b0ad5371 78 void pulsewidth_ms(int ms);
Sissors 0:f8c1b0ad5371 79
Sissors 0:f8c1b0ad5371 80 /**
Sissors 0:f8c1b0ad5371 81 * Set the PWM pulsewidth, specified in micro-seconds (int), keeping the period the same.
Sissors 0:f8c1b0ad5371 82 */
Sissors 0:f8c1b0ad5371 83 void pulsewidth_us(int us);
Sissors 0:f8c1b0ad5371 84
Sissors 0:f8c1b0ad5371 85 /**
Sissors 0:f8c1b0ad5371 86 * Set the PWM pulsewidth, specified in micro-seconds (double), keeping the period the same.
Sissors 0:f8c1b0ad5371 87 */
Sissors 0:f8c1b0ad5371 88 void pulsewidth_us(double us);
Sissors 0:f8c1b0ad5371 89
Sissors 0:f8c1b0ad5371 90 /**
Sissors 0:f8c1b0ad5371 91 * Set the ouput duty-cycle, specified as a percentage (double)
Sissors 0:f8c1b0ad5371 92 *
Sissors 0:f8c1b0ad5371 93 * @param duty - A double value representing the output duty-cycle, specified as a percentage. The value should lie between 0.0 (representing on 0%) and 1.0 (representing on 100%).
Sissors 0:f8c1b0ad5371 94 */
Sissors 0:f8c1b0ad5371 95 void write(double duty);
Sissors 0:f8c1b0ad5371 96
Sissors 0:f8c1b0ad5371 97 /**
Sissors 0:f8c1b0ad5371 98 * Return the ouput duty-cycle, specified as a percentage (double)
Sissors 0:f8c1b0ad5371 99 *
Sissors 0:f8c1b0ad5371 100 * @param return - A double value representing the output duty-cycle, specified as a percentage.
Sissors 0:f8c1b0ad5371 101 */
Sissors 0:f8c1b0ad5371 102 double read( void );
Sissors 0:f8c1b0ad5371 103
Sissors 0:f8c1b0ad5371 104 /**
Sissors 0:f8c1b0ad5371 105 * An operator shorthand for write()
Sissors 0:f8c1b0ad5371 106 */
Sissors 0:f8c1b0ad5371 107 FastPWM& operator= (double value);
Sissors 0:f8c1b0ad5371 108
Sissors 0:f8c1b0ad5371 109 /**
Sissors 0:f8c1b0ad5371 110 * An operator shorthand for read()
Sissors 0:f8c1b0ad5371 111 */
Sissors 0:f8c1b0ad5371 112 operator double();
Sissors 0:f8c1b0ad5371 113
Sissors 0:f8c1b0ad5371 114 private:
Sissors 0:f8c1b0ad5371 115 PwmOut PWMObject;
Sissors 0:f8c1b0ad5371 116 double _duty;
Sissors 0:f8c1b0ad5371 117 double _period;
Sissors 3:3094d3806cfc 118 unsigned int PWMUnit;
Sissors 0:f8c1b0ad5371 119
Sissors 0:f8c1b0ad5371 120 __IO uint32_t *MR;
Sissors 0:f8c1b0ad5371 121
Sissors 0:f8c1b0ad5371 122 };
Sissors 0:f8c1b0ad5371 123 #endif