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 Olieman

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:
jocis
Date:
Thu May 23 10:39:29 2013 +0000
Revision:
4:923b54e7c2c1
based on FastPWM, changed double calculation to int calculation for most functions

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jocis 4:923b54e7c2c1 1 #ifndef HighPWM_H
jocis 4:923b54e7c2c1 2 #define HighPWM_H
jocis 4:923b54e7c2c1 3
jocis 4:923b54e7c2c1 4 #include "mbed.h"
jocis 4:923b54e7c2c1 5
jocis 4:923b54e7c2c1 6 #ifndef F_CLK
jocis 4:923b54e7c2c1 7 #define F_CLK 96000000
jocis 4:923b54e7c2c1 8 #endif
jocis 4:923b54e7c2c1 9
jocis 4:923b54e7c2c1 10 #define us_2_F_CLK (F_CLK/1000000)
jocis 4:923b54e7c2c1 11 #define ms_2_F_CLK (F_CLK/1000)
jocis 4:923b54e7c2c1 12 #define s_2_F_CLK (F_CLK)
jocis 4:923b54e7c2c1 13
jocis 4:923b54e7c2c1 14 /** Library that allows faster and/or higher resolution PWM output
jocis 4:923b54e7c2c1 15 *
jocis 4:923b54e7c2c1 16 * This library is based original on FastPWM by Erik Olieman but without floating point (double) calculation in each call of pulsewidth_xx.
jocis 4:923b54e7c2c1 17 * This change was nessecary to get a performant motion controller.
jocis 4:923b54e7c2c1 18 *
jocis 4:923b54e7c2c1 19 * Library can directly replace standard mbed PWM library. Only limitation is that the maximum PWM period is four times shorter
jocis 4:923b54e7c2c1 20 * The maximum achievable period is roughly 40 seconds, I dont think that should be a problem.
jocis 4:923b54e7c2c1 21 * Do take into account all PWM objects (based on defailt PWM lib) will run four times faster than default.
jocis 4:923b54e7c2c1 22 *
jocis 4:923b54e7c2c1 23 * Contrary to the default mbed library, this library takes doubles instead of floats. The compiler will autocast if needed,
jocis 4:923b54e7c2c1 24 * but do take into account it is done for a reason, your accuracy will otherwise be limitted by the floating point precision.
jocis 4:923b54e7c2c1 25 *
jocis 4:923b54e7c2c1 26 * Using this library for a RC servo the resolution of steps (min to max) is increased from 1000 to 96000.
jocis 4:923b54e7c2c1 27 *
jocis 4:923b54e7c2c1 28 * 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.
jocis 4:923b54e7c2c1 29 *
jocis 4:923b54e7c2c1 30 * In your program you can define F_CLK if you use a different clock frequency than the default one.
jocis 4:923b54e7c2c1 31 *
jocis 4:923b54e7c2c1 32 * 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.
jocis 4:923b54e7c2c1 33 */
jocis 4:923b54e7c2c1 34 class HighPWM {
jocis 4:923b54e7c2c1 35 public:
jocis 4:923b54e7c2c1 36 /**
jocis 4:923b54e7c2c1 37 * Create a HighPWM object connected to the specified pin
jocis 4:923b54e7c2c1 38 *
jocis 4:923b54e7c2c1 39 * @param pin - PWM pin to connect to
jocis 4:923b54e7c2c1 40 */
jocis 4:923b54e7c2c1 41 HighPWM(PinName pin);
jocis 4:923b54e7c2c1 42
jocis 4:923b54e7c2c1 43 /**
jocis 4:923b54e7c2c1 44 * Set the PWM frequency, specified in Hz (double), keeping the duty cycle the same.
jocis 4:923b54e7c2c1 45 */
jocis 4:923b54e7c2c1 46 void frequency(double frq);
jocis 4:923b54e7c2c1 47
jocis 4:923b54e7c2c1 48 /**
jocis 4:923b54e7c2c1 49 * Set the PWM period, specified in seconds (double), keeping the duty cycle the same.
jocis 4:923b54e7c2c1 50 */
jocis 4:923b54e7c2c1 51 void period(double seconds);
jocis 4:923b54e7c2c1 52
jocis 4:923b54e7c2c1 53 /**
jocis 4:923b54e7c2c1 54 * Set the PWM period, specified in micro-seconds (double), keeping the duty cycle the same.
jocis 4:923b54e7c2c1 55 */
jocis 4:923b54e7c2c1 56 void period_us(double us);
jocis 4:923b54e7c2c1 57
jocis 4:923b54e7c2c1 58 /**
jocis 4:923b54e7c2c1 59 * Set the PWM period, specified in milli-seconds (int), keeping the duty cycle the same.
jocis 4:923b54e7c2c1 60 */
jocis 4:923b54e7c2c1 61 void period_ms(unsigned int ms);
jocis 4:923b54e7c2c1 62
jocis 4:923b54e7c2c1 63 /**
jocis 4:923b54e7c2c1 64 * Set the PWM period, specified in micro-seconds (int), keeping the duty cycle the same.
jocis 4:923b54e7c2c1 65 */
jocis 4:923b54e7c2c1 66 void period_us(unsigned int us);
jocis 4:923b54e7c2c1 67
jocis 4:923b54e7c2c1 68 /**
jocis 4:923b54e7c2c1 69 * Set the PWM period, specified in cpu ticks based on 96MHz (int), keeping the duty cycle the same.
jocis 4:923b54e7c2c1 70 */
jocis 4:923b54e7c2c1 71 void period_ticks(unsigned int ticks);
jocis 4:923b54e7c2c1 72
jocis 4:923b54e7c2c1 73 /**
jocis 4:923b54e7c2c1 74 * Set the PWM pulsewidth, specified in seconds (double), keeping the period the same.
jocis 4:923b54e7c2c1 75 */
jocis 4:923b54e7c2c1 76 void pulsewidth(double seconds);
jocis 4:923b54e7c2c1 77
jocis 4:923b54e7c2c1 78 /**
jocis 4:923b54e7c2c1 79 * Set the PWM pulsewidth, specified in micro seconds (double), keeping the period the same.
jocis 4:923b54e7c2c1 80 */
jocis 4:923b54e7c2c1 81 void pulsewidth_us(double us);
jocis 4:923b54e7c2c1 82
jocis 4:923b54e7c2c1 83 /**
jocis 4:923b54e7c2c1 84 * Set the PWM pulsewidth, specified in milli-seconds (int), keeping the period the same.
jocis 4:923b54e7c2c1 85 */
jocis 4:923b54e7c2c1 86 void pulsewidth_ms(unsigned int ms);
jocis 4:923b54e7c2c1 87
jocis 4:923b54e7c2c1 88 /**
jocis 4:923b54e7c2c1 89 * Set the PWM pulsewidth, specified in micro-seconds (int), keeping the period the same.
jocis 4:923b54e7c2c1 90 */
jocis 4:923b54e7c2c1 91 void pulsewidth_us(unsigned int us);
jocis 4:923b54e7c2c1 92
jocis 4:923b54e7c2c1 93 /**
jocis 4:923b54e7c2c1 94 * Set the PWM pulsewidth, specified in cpu ticks based on 96MHz (int), keeping the period the same.
jocis 4:923b54e7c2c1 95 */
jocis 4:923b54e7c2c1 96 void pulsewidth_ticks(unsigned int ticks);
jocis 4:923b54e7c2c1 97
jocis 4:923b54e7c2c1 98 /**
jocis 4:923b54e7c2c1 99 * Set the ouput duty-cycle, specified as a percentage (double)
jocis 4:923b54e7c2c1 100 *
jocis 4:923b54e7c2c1 101 * @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%).
jocis 4:923b54e7c2c1 102 */
jocis 4:923b54e7c2c1 103 void write(double duty);
jocis 4:923b54e7c2c1 104
jocis 4:923b54e7c2c1 105 /**
jocis 4:923b54e7c2c1 106 * Return the ouput duty-cycle, specified as a percentage (double)
jocis 4:923b54e7c2c1 107 *
jocis 4:923b54e7c2c1 108 * @param return - A double value representing the output duty-cycle, specified as a percentage.
jocis 4:923b54e7c2c1 109 */
jocis 4:923b54e7c2c1 110 double read( void );
jocis 4:923b54e7c2c1 111
jocis 4:923b54e7c2c1 112 /**
jocis 4:923b54e7c2c1 113 * An operator shorthand for write()
jocis 4:923b54e7c2c1 114 */
jocis 4:923b54e7c2c1 115 HighPWM& operator= (double value);
jocis 4:923b54e7c2c1 116
jocis 4:923b54e7c2c1 117 /**
jocis 4:923b54e7c2c1 118 * An operator shorthand for read()
jocis 4:923b54e7c2c1 119 */
jocis 4:923b54e7c2c1 120 operator double();
jocis 4:923b54e7c2c1 121
jocis 4:923b54e7c2c1 122 private:
jocis 4:923b54e7c2c1 123 PwmOut PWMObject;
jocis 4:923b54e7c2c1 124 //double _duty;
jocis 4:923b54e7c2c1 125 int _period;
jocis 4:923b54e7c2c1 126 int _pulsewidth;
jocis 4:923b54e7c2c1 127 unsigned int PWMUnit;
jocis 4:923b54e7c2c1 128
jocis 4:923b54e7c2c1 129 __IO uint32_t *MR;
jocis 4:923b54e7c2c1 130
jocis 4:923b54e7c2c1 131 };
jocis 4:923b54e7c2c1 132 #endif