Hiroki Mori / 3PhasePWM
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers 3PhasePWM.cpp Source File

3PhasePWM.cpp

00001 #include "3PhasePWM.h"
00002 
00003 #include "mbed.h"
00004 
00005 ThreePhasePWM::ThreePhasePWM(PinName upper_U, PinName upper_V, PinName upper_W,
00006           PinName lower_U, PinName lower_V, PinName lower_W,
00007           float Frequency, float DeadTime):
00008           pwm_upper_U(upper_U), pwm_upper_V(upper_V), pwm_upper_W(upper_W),
00009           pwm_lower_U(lower_U), pwm_lower_V(lower_V), pwm_lower_W(lower_W)  
00010 {
00011     pwm_upper_U = 0;
00012     pwm_upper_V = 0;
00013     pwm_upper_W = 0;
00014     pwm_lower_U = 0;
00015     pwm_lower_V = 0;
00016     pwm_lower_W = 0;
00017 
00018     Frequency_ = Frequency;
00019     DeadTime_  = DeadTime;
00020 }
00021 
00022 
00023 #ifdef TOOTHWAVE
00024 void ThreePhasePWM::PwmUout(void) {
00025     unsigned char i = 0;//i=0のときU相
00026     uvw[i].mode += 1;   //チョッピングのオンオフを決定するモードを1増やす
00027 
00028     if(uvw[i].mode == 1) { // モードが1のとき、Tonの状態をつくる
00029         pwm_upper_U = 1; //上アームUuをON
00030         pwm_lower_U = 0; //下アームUdをOFF
00031 
00032         // モード1の時間幅 T1 = Ton-Tdt を計算
00033         uvw[i].upper_us = uvw[i].duty * 1000000 / Frequency_ - DeadTime_;
00034         // 時間幅が小さいときはTMINにする
00035         if( uvw[i].upper_us < TMIN ) uvw[i].upper_us = TMIN;
00036 
00037         // T1[μs]経過してからタイムアウトでこの関数自身をコール
00038         pwm[i].attach_us(this, &ThreePhasePWM::PwmUout, uvw[i].upper_us);
00039 
00040         // モード3の時間幅 T3=Toff-Tdt=Tpwm-(T1+Tdt)-Tdtを計算
00041         uvw[i].lower_us = 1000000 / Frequency_ - uvw[i].upper_us - 2 * DeadTime_;
00042         // 時間幅が小さいときはTMINにする
00043         if( uvw[i].lower_us < TMIN ) uvw[i].lower_us = TMIN;
00044     }
00045     else if(uvw[i].mode == 2) { // モードが2のとき、デッドタイムをつくる
00046         // Tdt[μs]経過してからタイムアウトでこの関数自身をコール
00047         pwm[i].attach_us(this, &ThreePhasePWM::PwmUout, DeadTime_);
00048 
00049         pwm_upper_U = 0;         // 上アームUuをオフ
00050         pwm_lower_U = 0;         // 下アームUdをオフ
00051     }
00052     else if(uvw[i].mode == 3) { // モードが3のとき、Toffの状態をつくる
00053         // T3[μs]経過してからタイムアウトでこの関数自身をコール
00054         pwm[i].attach_us(this, &ThreePhasePWM::PwmUout, uvw[i].lower_us);
00055 
00056         pwm_upper_U = 0;         // 上アームUuをオフ
00057         pwm_lower_U = 1;         // 下アームUdをオン
00058     }
00059     else {                     // モードが4のとき、デッドタイムをつくる
00060         // Tdt[μs]経過してからタイムアウトでこの関数自身をコール
00061         pwm[i].attach_us(this, &ThreePhasePWM::PwmUout, DeadTime_);
00062 
00063         pwm_upper_U = 0;         // 上アームUuをオフ
00064         pwm_lower_U = 0;         // 下アームUdをオフ
00065 
00066         uvw[i].mode = 0;          // チョッピングのオンオフを決定するモードを0にする
00067     }
00068 }
00069 
00070 void ThreePhasePWM::PwmVout(void) {
00071     unsigned char i = 1;//i=1のときV相
00072     uvw[i].mode += 1;   //チョッピングのオンオフを決定するモードを1増やす
00073 
00074     if(uvw[i].mode == 1) { // モードが1のとき、Tonの状態をつくる
00075         pwm_upper_V = 1; //上アームVuをON
00076         pwm_lower_V = 0; //下アームVdをOFF
00077 
00078         // モード1の時間幅 T1 = Ton-Tdt を計算
00079         uvw[i].upper_us = uvw[i].duty * 1000000 / Frequency_ - DeadTime_;
00080         // 時間幅が小さいときはTMINにする
00081         if( uvw[i].upper_us < TMIN ) uvw[i].upper_us = TMIN;
00082 
00083         // T1[μs]経過してからタイムアウトでこの関数自身をコール
00084         pwm[i].attach_us(this, &ThreePhasePWM::PwmVout, uvw[i].upper_us);
00085 
00086         // モード3の時間幅 T3=Toff-Tdt=Tpwm-(T1+Tdt)-Tdtを計算
00087         uvw[i].lower_us = 1000000 / Frequency_ - uvw[i].upper_us - 2 * DeadTime_;
00088         // 時間幅が小さいときはTMINにする
00089         if( uvw[i].lower_us < TMIN ) uvw[i].lower_us = TMIN;
00090     }
00091     else if(uvw[i].mode == 2) { // モードが2のとき、デッドタイムをつくる
00092         // Tdt[μs]経過してからタイムアウトでこの関数自身をコール
00093         pwm[i].attach_us(this, &ThreePhasePWM::PwmVout, DeadTime_);
00094 
00095         pwm_upper_V = 0;         // 上アームVuをオフ
00096         pwm_lower_V = 0;         // 下アームVdをオフ
00097     }
00098     else if(uvw[i].mode == 3) { // モードが3のとき、Toffの状態をつくる
00099         // T3[μs]経過してからタイムアウトでこの関数自身をコール
00100         pwm[i].attach_us(this, &ThreePhasePWM::PwmVout, uvw[i].lower_us);
00101 
00102         pwm_upper_V = 0;         // 上アームVuをオフ
00103         pwm_lower_V = 1;         // 下アームVdをオン
00104     }
00105     else {                     // モードが4のとき、デッドタイムをつくる
00106         // Tdt[μs]経過してからタイムアウトでこの関数自身をコール
00107         pwm[i].attach_us(this, &ThreePhasePWM::PwmVout, DeadTime_);
00108 
00109         pwm_upper_V = 0;         // 上アームVuをオフ
00110         pwm_lower_V = 0;         // 下アームVdをオフ
00111 
00112         uvw[i].mode = 0;          // チョッピングのオンオフを決定するモードを0にする
00113     }
00114 }
00115 
00116 void ThreePhasePWM::PwmWout(void) {
00117     unsigned char i = 2;//i=2のときW相
00118     uvw[i].mode += 1;   //チョッピングのオンオフを決定するモードを1増やす
00119 
00120     if(uvw[i].mode == 1) { // モードが1のとき、Tonの状態をつくる
00121         pwm_upper_W = 1; //上アームWuをON
00122         pwm_lower_W = 0; //下アームWdをOFF
00123 
00124         // モード1の時間幅 T1 = Ton-Tdt を計算
00125         uvw[i].upper_us = uvw[i].duty * 1000000 / Frequency_ - DeadTime_;
00126         // 時間幅が小さいときはTMINにする
00127         if( uvw[i].upper_us < TMIN ) uvw[i].upper_us = TMIN;
00128 
00129         // T1[μs]経過してからタイムアウトでこの関数自身をコール
00130         pwm[i].attach_us(this, &ThreePhasePWM::PwmWout, uvw[i].upper_us);
00131 
00132         // モード3の時間幅 T3=Toff-Tdt=Tpwm-(T1+Tdt)-Tdtを計算
00133         uvw[i].lower_us = 1000000 / Frequency_ - uvw[i].upper_us - 2 * DeadTime_;
00134         // 時間幅が小さいときはTMINにする
00135         if( uvw[i].lower_us < TMIN ) uvw[i].lower_us = TMIN;
00136     }
00137     else if(uvw[i].mode == 2) { // モードが2のとき、デッドタイムをつくる
00138         // Tdt[μs]経過してからタイムアウトでこの関数自身をコール
00139         pwm[i].attach_us(this, &ThreePhasePWM::PwmWout, DeadTime_);
00140 
00141         pwm_upper_W = 0;         // 上アームWuをオフ
00142         pwm_lower_W = 0;         // 下アームWdをオフ
00143     }
00144     else if(uvw[i].mode == 3) { // モードが3のとき、Toffの状態をつくる
00145         // T3[μs]経過してからタイムアウトでこの関数自身をコール
00146         pwm[i].attach_us(this, &ThreePhasePWM::PwmWout, uvw[i].lower_us);
00147 
00148         pwm_upper_W = 0;         // 上アームWuをオフ
00149         pwm_lower_W = 1;         // 下アームWdをオン
00150     }
00151     else {                     // モードが4のとき、デッドタイムをつくる
00152         // Tdt[μs]経過してからタイムアウトでこの関数自身をコール
00153         pwm[i].attach_us(this, &ThreePhasePWM::PwmWout, DeadTime_);
00154 
00155         pwm_upper_W = 0;         // 上アームWuをオフ
00156         pwm_lower_W = 0;         // 下アームWdをオフ
00157 
00158         uvw[i].mode = 0;          // チョッピングのオンオフを決定するモードを0にする
00159     }
00160 }
00161 #endif
00162 
00163 
00164 #ifdef TRIANGLERWAVE
00165 void ThreePhasePWM::PwmUout(void) {
00166     unsigned char   i = 0;  // i=0のときU相
00167     uvw[i].mode += 1;   //チョッピングのオンオフを決定するモードを1増やす
00168 
00169     if( uvw[i].mode == 1 ){ // モードが1のとき、Toffの状態をつくる
00170         pwm_upper_U = 0;  // 上アームUuをオフ
00171         pwm_lower_U = 1;  // 下アームUdをオン
00172 
00173         // モード3の時間幅 T3 = Ton-Tdt を計算
00174         uvw[i].upper_us = uvw[i].duty * 1000000 / Frequency_ - DeadTime_;
00175         // 時間幅が小さいときはTMINにする
00176         if( uvw[i].upper_us < TMIN ) uvw[i].upper_us = TMIN;
00177 
00178         // モード1,5の時間幅 T1=(Toff-Tdt)/2=(Tpwm-T3-2Tdt)/2を計算
00179         uvw[i].lower_us = (1000000 / Frequency_ - uvw[i].upper_us - 2 * DeadTime_) / 2.0;
00180         // 時間幅が小さいときはTMINにする
00181         if( uvw[i].lower_us < TMIN ) uvw[i].lower_us = TMIN;
00182 
00183         // T1[μs]経過してからタイムアウトでこの関数自身をコール
00184         pwm[i].attach_us(this, &ThreePhasePWM::PwmUout, uvw[i].lower_us);
00185 
00186     }
00187     else if( uvw[i].mode == 2 ) { // モードが2のとき、デッドタイムをつくる
00188         // Tdt[μs]経過してからタイムアウトでこの関数自身をコール
00189         pwm[i].attach_us(this, &ThreePhasePWM::PwmUout, DeadTime_);
00190 
00191         pwm_upper_U = 0;         // 上アームUuをオフ
00192         pwm_lower_U = 0;         // 下アームUdをオフ
00193     }
00194     else if( uvw[i].mode == 3 ) { // モードが3のとき、Tonの状態をつくる
00195         // T3[μs]経過してからタイムアウトでこの関数自身をコール
00196         pwm[i].attach_us(this, &ThreePhasePWM::PwmUout, uvw[i].upper_us);
00197 
00198         pwm_upper_U = 1;         // 上アームUuをオン
00199         pwm_lower_U = 0;         // 下アームUdをオフ
00200     }
00201     else if( uvw[i].mode == 4 ) { // モードが4のとき、デッドタイムをつくる
00202         // Tdt[μs]経過してからタイムアウトでこの関数自身をコール
00203         pwm[i].attach_us(this, &ThreePhasePWM::PwmUout, DeadTime_);
00204 
00205         pwm_upper_U = 0;         // 上アームUuをオフ
00206         pwm_lower_U = 0;         // 下アームUdをオフ
00207     }
00208     else {                     // モードが5のとき、Toffの状態をつくる
00209         // T5(=T1)[μs]経過してからタイムアウトでこの関数自身をコール
00210         pwm[i].attach_us(this, &ThreePhasePWM::PwmUout, uvw[i].lower_us);
00211 
00212         pwm_upper_U = 0;         // 上アームUuをオフ
00213         pwm_lower_U = 1;         // 下アームUdをオン
00214 
00215         uvw[i].mode = 0;          // チョッピングのオンオフを決定するモードを0にする
00216     }                            
00217 }
00218 
00219 void ThreePhasePWM::PwmVout(void) {
00220     unsigned char   i = 1;  // i=1のときV相
00221     uvw[i].mode += 1;   //チョッピングのオンオフを決定するモードを1増やす
00222 
00223     if( uvw[i].mode == 1 ){ // モードが1のとき、Toffの状態をつくる
00224         pwm_upper_V = 0;  // 上アームVuをオフ
00225         pwm_lower_V = 1;  // 下アームVdをオン
00226 
00227         // モード3の時間幅 T3 = Ton-Tdt を計算
00228         uvw[i].upper_us = uvw[i].duty * 1000000 / Frequency_ - DeadTime_;
00229         // 時間幅が小さいときはTMINにする
00230         if( uvw[i].upper_us < TMIN ) uvw[i].upper_us = TMIN;
00231 
00232         // モード1,5の時間幅 T1=(Toff-Tdt)/2=(Tpwm-T3-2Tdt)/2を計算
00233         uvw[i].lower_us = (1000000 / Frequency_ - uvw[i].upper_us - 2 * DeadTime_) / 2.0;
00234         // 時間幅が小さいときはTMINにする
00235         if( uvw[i].lower_us < TMIN ) uvw[i].lower_us = TMIN;
00236 
00237         // T1[μs]経過してからタイムアウトでこの関数自身をコール
00238         pwm[i].attach_us(this, &ThreePhasePWM::PwmVout, uvw[i].lower_us);
00239 
00240     }
00241     else if( uvw[i].mode == 2 ) { // モードが2のとき、デッドタイムをつくる
00242         // Tdt[μs]経過してからタイムアウトでこの関数自身をコール
00243         pwm[i].attach_us(this, &ThreePhasePWM::PwmVout, DeadTime_);
00244 
00245         pwm_upper_V = 0;         // 上アームVuをオフ
00246         pwm_lower_V = 0;         // 下アームVdをオフ
00247     }
00248     else if( uvw[i].mode == 3 ) { // モードが3のとき、Tonの状態をつくる
00249         // T3[μs]経過してからタイムアウトでこの関数自身をコール
00250         pwm[i].attach_us(this, &ThreePhasePWM::PwmVout, uvw[i].upper_us);
00251 
00252         pwm_upper_V = 1;         // 上アームVuをオン
00253         pwm_lower_V = 0;         // 下アームVdをオフ
00254     }
00255     else if( uvw[i].mode == 4 ) { // モードが4のとき、デッドタイムをつくる
00256         // Tdt[μs]経過してからタイムアウトでこの関数自身をコール
00257         pwm[i].attach_us(this, &ThreePhasePWM::PwmVout, DeadTime_);
00258 
00259         pwm_upper_V = 0;         // 上アームVuをオフ
00260         pwm_lower_V = 0;         // 下アームVdをオフ
00261     }
00262     else {                     // モードが5のとき、Toffの状態をつくる
00263         // T5(=T1)[μs]経過してからタイムアウトでこの関数自身をコール
00264         pwm[i].attach_us(this, &ThreePhasePWM::PwmVout, uvw[i].lower_us);
00265 
00266         pwm_upper_V = 0;         // 上アームVuをオフ
00267         pwm_lower_V = 1;         // 下アームVdをオン
00268 
00269         uvw[i].mode = 0;          // チョッピングのオンオフを決定するモードを0にする
00270     }         
00271 }
00272 
00273 void ThreePhasePWM::PwmWout(void) {
00274     unsigned char   i = 2;  // i=2のときW相
00275     uvw[i].mode += 1;   //チョッピングのオンオフを決定するモードを1増やす
00276 
00277     if( uvw[i].mode == 1 ){ // モードが1のとき、Toffの状態をつくる
00278         pwm_upper_W = 0;  // 上アームWuをオフ
00279         pwm_lower_W = 1;  // 下アームWdをオン
00280 
00281         // モード3の時間幅 T3 = Ton-Tdt を計算
00282         uvw[i].upper_us = uvw[i].duty * 1000000 / Frequency_ - DeadTime_;
00283         // 時間幅が小さいときはTMINにする
00284         if( uvw[i].upper_us < TMIN ) uvw[i].upper_us = TMIN;
00285 
00286         // モード1,5の時間幅 T1=(Toff-Tdt)/2=(Tpwm-T3-2Tdt)/2を計算
00287         uvw[i].lower_us = (1000000 / Frequency_ - uvw[i].upper_us - 2 * DeadTime_) / 2.0;
00288         // 時間幅が小さいときはTMINにする
00289         if( uvw[i].lower_us < TMIN ) uvw[i].lower_us = TMIN;
00290 
00291         // T1[μs]経過してからタイムアウトでこの関数自身をコール
00292         pwm[i].attach_us(this, &ThreePhasePWM::PwmWout, uvw[i].lower_us);
00293 
00294     }
00295     else if( uvw[i].mode == 2 ) { // モードが2のとき、デッドタイムをつくる
00296         // Tdt[μs]経過してからタイムアウトでこの関数自身をコール
00297         pwm[i].attach_us(this, &ThreePhasePWM::PwmWout, DeadTime_);
00298 
00299         pwm_upper_W = 0;         // 上アームWuをオフ
00300         pwm_lower_W = 0;         // 下アームWdをオフ
00301     }
00302     else if( uvw[i].mode == 3 ) { // モードが3のとき、Tonの状態をつくる
00303         // T3[μs]経過してからタイムアウトでこの関数自身をコール
00304         pwm[i].attach_us(this, &ThreePhasePWM::PwmWout, uvw[i].upper_us);
00305 
00306         pwm_upper_W = 1;         // 上アームWuをオン
00307         pwm_lower_W = 0;         // 下アームWdをオフ
00308     }
00309     else if( uvw[i].mode == 4 ) { // モードが4のとき、デッドタイムをつくる
00310         // Tdt[μs]経過してからタイムアウトでこの関数自身をコール
00311         pwm[i].attach_us(this, &ThreePhasePWM::PwmWout, DeadTime_);
00312 
00313         pwm_upper_W = 0;         // 上アームWuをオフ
00314         pwm_lower_W = 0;         // 下アームWdをオフ
00315     }
00316     else {                     // モードが5のとき、Toffの状態をつくる
00317         // T5(=T1)[μs]経過してからタイムアウトでこの関数自身をコール
00318         pwm[i].attach_us(this, &ThreePhasePWM::PwmWout, uvw[i].lower_us);
00319 
00320         pwm_upper_W = 0;         // 上アームWuをオフ
00321         pwm_lower_W = 1;         // 下アームWdをオン
00322 
00323         uvw[i].mode = 0;          // チョッピングのオンオフを決定するモードを0にする
00324     }         
00325 }
00326 #endif
00327 
00328 
00329 
00330 void ThreePhasePWM::startPWM(void) {
00331 
00332     for (int i = 0; i < 3; i++) {
00333         uvw[i].duty  = 0.5; // 0.5のときにVu=0[V]
00334         uvw[i].mode = 0;    // チョッピングのオンオフを決定するモードを初期化
00335     }
00336 
00337     //PWM 出力開始
00338     PwmUout();
00339     PwmVout();
00340     PwmWout();
00341 }
00342 
00343 void ThreePhasePWM::stopPWM(void) {
00344     for(int i = 0; i < 3; i++) {
00345         uvw[i].mode = 0;
00346         pwm[i].detach(); //タイマー割り込みを停止
00347     }
00348     pwm_upper_U = 0;
00349     pwm_upper_V = 0;
00350     pwm_upper_W = 0;
00351     pwm_lower_U = 0;
00352     pwm_lower_V = 0;
00353     pwm_lower_W = 0;
00354 }
00355 
00356 
00357 
00358 void ThreePhasePWM::setU(float duty_u) {
00359     uvw[0].duty = duty_u;
00360 }
00361 
00362 void ThreePhasePWM::setV(float duty_v) {
00363     uvw[1].duty = duty_v;
00364 }
00365 
00366 void ThreePhasePWM::setW(float duty_w) {
00367     uvw[2].duty = duty_w;
00368 }
00369 
00370 void ThreePhasePWM::setUVW(float duty_u, float duty_v, float duty_w) {
00371     uvw[0].duty = duty_u;
00372     uvw[1].duty = duty_v;
00373     uvw[2].duty = duty_w;
00374 }
00375 
00376