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/

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "stdio.h"
00003 
00004 #define PI 3.1416
00005 
00006 // License: You may copy or modify and re-use this code, but you MUST credit me:
00007 // Wayne McLachlan, www.embeddedengineering.co.nz
00008 // You may add your name to the author list if you have done significant modifications or improvements
00009 
00010 PwmOut chA(p21);
00011 PwmOut chB(p22);
00012 PwmOut chC(p23);
00013 
00014 Serial pc(USBTX, USBRX);
00015 Ticker sine3ticker;
00016 
00017 #define SINE3_PWM_FREQ 10000
00018 
00019 unsigned char   sine3freq;
00020 float           sine3mag;
00021 float           sine3theta;
00022 
00023 void sine3tick() {
00024         // offset PWM for bipolar: 0.5 => 0V
00025         chA = 0.5 + (sine3mag * sinf(sine3theta) /2);
00026         chB = 0.5 + (sine3mag * sinf(sine3theta + 2*PI  /3)/2);   // + 120 degrees
00027         chC = 0.5 + (sine3mag * sinf(sine3theta + 2*PI*2/3)/2);   // + 240 degrees => - 120 degrees
00028                 
00029         sine3theta +=  2*PI / (SINE3_PWM_FREQ / sine3freq); // one cycle / steps per cycle
00030         if (sine3theta >=  2*PI) {
00031             sine3theta = 0;
00032         }
00033 }
00034 
00035 
00036 void sine3_init() {
00037     chA.period_us( 1000000 / SINE3_PWM_FREQ );   // period in uS. Common to all PWM
00038     chA = 0.5;
00039     chB = 0.5;
00040     chC = 0.5;
00041     
00042     sine3mag = 0.9;                             // prevent overmodulation
00043     sine3freq = 55;                             // compromise between 50Hz and 60Hz
00044     sine3theta = 0;
00045     sine3ticker.attach_us(&sine3tick, (1000000 / SINE3_PWM_FREQ) ); // period in uS
00046     //pc.printf("\n\r init ");
00047 }
00048 
00049 
00050 int main() {
00051     sine3_init();
00052     while (1) {
00053         sine3freq++;
00054         if (sine3freq > 100) {
00055             sine3freq = 30;
00056             pc.printf("\n\r");
00057         }
00058         wait(0.2);
00059         pc.printf("%d ",sine3freq);
00060     }
00061 }