Uses trigonometry to produce high quality 3 phase sinewave output waveworms on the PWM. Tested from 30 to 100Hz at 10kHz modulation. Changes frequency glitch free. Amplitude is scalable. Could be used as a basic invertor back-end. Not optimised for processor overhead, could be modified to use lookup tables if less accuracy required. Oscilloscope trace here: http://mbed.org/users/waynemcl/notebook/sine3-v2/
main.cpp
- Committer:
- waynemcl
- Date:
- 2010-11-28
- Revision:
- 0:d040778370fc
File content as of revision 0:d040778370fc:
#include "mbed.h" #include "stdio.h" #define PI 3.1416 // License: You may copy or modify and re-use this code, but you MUST credit me: // Wayne McLachlan, www.embeddedengineering.co.nz // You may add your name to the author list if you have done significant modifications or improvements PwmOut chA(p21); PwmOut chB(p22); PwmOut chC(p23); Serial pc(USBTX, USBRX); Ticker sine3ticker; #define SINE3_PWM_FREQ 10000 unsigned char sine3freq; float sine3mag; float sine3theta; void sine3tick() { // offset PWM for bipolar: 0.5 => 0V chA = 0.5 + (sine3mag * sinf(sine3theta) /2); chB = 0.5 + (sine3mag * sinf(sine3theta + 2*PI /3)/2); // + 120 degrees chC = 0.5 + (sine3mag * sinf(sine3theta + 2*PI*2/3)/2); // + 240 degrees => - 120 degrees sine3theta += 2*PI / (SINE3_PWM_FREQ / sine3freq); // one cycle / steps per cycle if (sine3theta >= 2*PI) { sine3theta = 0; } } void sine3_init() { chA.period_us( 1000000 / SINE3_PWM_FREQ ); // period in uS. Common to all PWM chA = 0.5; chB = 0.5; chC = 0.5; sine3mag = 0.9; // prevent overmodulation sine3freq = 55; // compromise between 50Hz and 60Hz sine3theta = 0; sine3ticker.attach_us(&sine3tick, (1000000 / SINE3_PWM_FREQ) ); // period in uS //pc.printf("\n\r init "); } int main() { sine3_init(); while (1) { sine3freq++; if (sine3freq > 100) { sine3freq = 30; pc.printf("\n\r"); } wait(0.2); pc.printf("%d ",sine3freq); } }