Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
Generated on Sun Jul 17 2022 16:02:58 by
1.7.2