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:
Thu Jul 12 11:20:09 2012 +0000
Revision:
0:f8c1b0ad5371
Child:
1:1aed61747ed6
v1.0, seems completely functional

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 0:f8c1b0ad5371 1 #include "mbed.h"
Sissors 0:f8c1b0ad5371 2
Sissors 0:f8c1b0ad5371 3
Sissors 0:f8c1b0ad5371 4 #ifndef FASTPWM_H
Sissors 0:f8c1b0ad5371 5 #define FASTPWM_H
Sissors 0:f8c1b0ad5371 6
Sissors 0:f8c1b0ad5371 7 #ifndef F_CLK
Sissors 0:f8c1b0ad5371 8 #define F_CLK 96000000
Sissors 0:f8c1b0ad5371 9 #endif
Sissors 0:f8c1b0ad5371 10
Sissors 0:f8c1b0ad5371 11 /** Library that allows faster and/or higher resolution PWM output
Sissors 0:f8c1b0ad5371 12 *
Sissors 0:f8c1b0ad5371 13 * Library can directly replace standard mbed PWM library. Only limitation is that the maximum PWM period is four times shorter
Sissors 0:f8c1b0ad5371 14 * The maximum achievable period is roughly 40 seconds, I dont think that should be a problem.
Sissors 0:f8c1b0ad5371 15 * Do take into account all PWM objects will run four times faster than default.
Sissors 0:f8c1b0ad5371 16 *
Sissors 0:f8c1b0ad5371 17 * Contrary to the default mbed library, this library takes doubles instead of floats. The compiler will autocast if needed,
Sissors 0:f8c1b0ad5371 18 * 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 19 *
Sissors 0:f8c1b0ad5371 20 * In your program you can define F_CLK if you use a different clock frequency than the default one.
Sissors 0:f8c1b0ad5371 21 *
Sissors 0:f8c1b0ad5371 22 * 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 23 */
Sissors 0:f8c1b0ad5371 24 class FastPWM {
Sissors 0:f8c1b0ad5371 25 public:
Sissors 0:f8c1b0ad5371 26 /**
Sissors 0:f8c1b0ad5371 27 * Create a FastPWM object connected to the specified pin
Sissors 0:f8c1b0ad5371 28 *
Sissors 0:f8c1b0ad5371 29 * @param pin - PWM pin to connect to
Sissors 0:f8c1b0ad5371 30 */
Sissors 0:f8c1b0ad5371 31 FastPWM(PinName pin);
Sissors 0:f8c1b0ad5371 32
Sissors 0:f8c1b0ad5371 33 /**
Sissors 0:f8c1b0ad5371 34 * Set the PWM period, specified in seconds (double), keeping the duty cycle the same.
Sissors 0:f8c1b0ad5371 35 */
Sissors 0:f8c1b0ad5371 36 void period(double seconds);
Sissors 0:f8c1b0ad5371 37
Sissors 0:f8c1b0ad5371 38 /**
Sissors 0:f8c1b0ad5371 39 * Set the PWM period, specified in milli-seconds (int), keeping the duty cycle the same.
Sissors 0:f8c1b0ad5371 40 */
Sissors 0:f8c1b0ad5371 41 void period_ms(int ms);
Sissors 0:f8c1b0ad5371 42
Sissors 0:f8c1b0ad5371 43 /**
Sissors 0:f8c1b0ad5371 44 * Set the PWM period, specified in micro-seconds (int), keeping the duty cycle the same.
Sissors 0:f8c1b0ad5371 45 */
Sissors 0:f8c1b0ad5371 46 void period_us(int us);
Sissors 0:f8c1b0ad5371 47
Sissors 0:f8c1b0ad5371 48 /**
Sissors 0:f8c1b0ad5371 49 * Set the PWM period, specified in micro-seconds (double), keeping the duty cycle the same.
Sissors 0:f8c1b0ad5371 50 */
Sissors 0:f8c1b0ad5371 51 void period_us(double us);
Sissors 0:f8c1b0ad5371 52
Sissors 0:f8c1b0ad5371 53 /**
Sissors 0:f8c1b0ad5371 54 * Set the PWM pulsewidth, specified in seconds (double), keeping the period the same.
Sissors 0:f8c1b0ad5371 55 */
Sissors 0:f8c1b0ad5371 56 void pulsewidth(double seconds);
Sissors 0:f8c1b0ad5371 57
Sissors 0:f8c1b0ad5371 58 /**
Sissors 0:f8c1b0ad5371 59 * Set the PWM pulsewidth, specified in milli-seconds (int), keeping the period the same.
Sissors 0:f8c1b0ad5371 60 */
Sissors 0:f8c1b0ad5371 61 void pulsewidth_ms(int ms);
Sissors 0:f8c1b0ad5371 62
Sissors 0:f8c1b0ad5371 63 /**
Sissors 0:f8c1b0ad5371 64 * Set the PWM pulsewidth, specified in micro-seconds (int), keeping the period the same.
Sissors 0:f8c1b0ad5371 65 */
Sissors 0:f8c1b0ad5371 66 void pulsewidth_us(int us);
Sissors 0:f8c1b0ad5371 67
Sissors 0:f8c1b0ad5371 68 /**
Sissors 0:f8c1b0ad5371 69 * Set the PWM pulsewidth, specified in micro-seconds (double), keeping the period the same.
Sissors 0:f8c1b0ad5371 70 */
Sissors 0:f8c1b0ad5371 71 void pulsewidth_us(double us);
Sissors 0:f8c1b0ad5371 72
Sissors 0:f8c1b0ad5371 73 /**
Sissors 0:f8c1b0ad5371 74 * Set the ouput duty-cycle, specified as a percentage (double)
Sissors 0:f8c1b0ad5371 75 *
Sissors 0:f8c1b0ad5371 76 * @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 77 */
Sissors 0:f8c1b0ad5371 78 void write(double duty);
Sissors 0:f8c1b0ad5371 79
Sissors 0:f8c1b0ad5371 80 /**
Sissors 0:f8c1b0ad5371 81 * Return the ouput duty-cycle, specified as a percentage (double)
Sissors 0:f8c1b0ad5371 82 *
Sissors 0:f8c1b0ad5371 83 * @param return - A double value representing the output duty-cycle, specified as a percentage.
Sissors 0:f8c1b0ad5371 84 */
Sissors 0:f8c1b0ad5371 85 double read( void );
Sissors 0:f8c1b0ad5371 86
Sissors 0:f8c1b0ad5371 87 /**
Sissors 0:f8c1b0ad5371 88 * An operator shorthand for write()
Sissors 0:f8c1b0ad5371 89 */
Sissors 0:f8c1b0ad5371 90 FastPWM& operator= (double value);
Sissors 0:f8c1b0ad5371 91
Sissors 0:f8c1b0ad5371 92 /**
Sissors 0:f8c1b0ad5371 93 * An operator shorthand for read()
Sissors 0:f8c1b0ad5371 94 */
Sissors 0:f8c1b0ad5371 95 operator double();
Sissors 0:f8c1b0ad5371 96
Sissors 0:f8c1b0ad5371 97 private:
Sissors 0:f8c1b0ad5371 98 PwmOut PWMObject;
Sissors 0:f8c1b0ad5371 99 double _duty;
Sissors 0:f8c1b0ad5371 100 double _period;
Sissors 0:f8c1b0ad5371 101
Sissors 0:f8c1b0ad5371 102 __IO uint32_t *MR;
Sissors 0:f8c1b0ad5371 103
Sissors 0:f8c1b0ad5371 104 };
Sissors 0:f8c1b0ad5371 105 #endif