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.
Dependencies: QEI mbed-rtos mbed
Fork of BLDCmotor by
UVWpwm.cpp
00001 #include "mbed.h" 00002 #include "controller.h" 00003 #include "UVWpwm.h" // PWM発生用UVWpwm.cppの変数や定数の定義 00004 00005 #define DEADTIME_US (unsigned long)(DEADTIME*1000000) // [us], デッドタイム 00006 00007 Timeout pwm[3]; // タイムアウト関数の宣言(ある時間経過後に関数コールする) 00008 00009 // デジタル信号を出力するポートupperとlowerをU, V, W相について設定 00010 DigitalOut pwm_upper[] = {(U_UPPER_PORT), (V_UPPER_PORT),(W_UPPER_PORT)}; 00011 DigitalOut pwm_lower[] = {(U_LOWER_PORT), (V_LOWER_PORT),(W_LOWER_PORT)}; 00012 00013 pwm_parameters uvw[3]; // UVW相pwm用の定数、変数宣言 00014 00015 // U, V相シャント抵抗の両端の電圧のアナログ入力名の設定, *3.3[V] 00016 AnalogIn VshuntR_Uplus( R_SHUNT_UP_PORT); // *3.3[V], U相+側アナログ入力 00017 AnalogIn VshuntR_Uminus(R_SHUNT_UM_PORT); // *3.3[V], U相-側アナログ入力 00018 AnalogIn VshuntR_Vplus( R_SHUNT_VP_PORT); // *3.3[V], V相+側アナログ入力 00019 AnalogIn VshuntR_Vminus(R_SHUNT_VM_PORT); // *3.3[V], V相-側アナログ入力 00020 00021 // 関数配列: NG 00022 //void (*pwmUVWout[])(int) = {pwmout,pwmout,pwmout}; 00023 // pwmUVWout[i](i); 00024 void pwmVout(), pwmWout(); 00025 00026 #if PWM_WAVEFORM==0 // 0: saw tooth wave comparison 00027 void pwmUout() { // タイムアウト関数でU相PWMを発生する関数 00028 unsigned char i=0; // i=0のときU相 00029 uvw[i].mode += 1; // チョッピングのオンオフを決定するモードを1増やす 00030 if( uvw[i].mode==1 ){ // モードが1のとき、Tonの状態をつくる 00031 pwm_upper[i] = 1; // 上アームUuをオン 00032 pwm_lower[i] = 0; // 下アームUdをオフ 00033 // モード1の時間幅 T1 = Ton-Tdt を計算 00034 uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US; 00035 // 時間幅が小さいときはTMINにする 00036 if( uvw[i].upper_us < TMIN ){ uvw[i].upper_us=TMIN;} 00037 // T1[μs]経過してからタイムアウトでこの関数自身をコール 00038 pwm[i].attach_us(&pwmUout, uvw[i].upper_us); 00039 // モード3の時間幅 T3=Toff-Tdt=Tpwm-(T1+Tdt)-Tdtを計算 00040 uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; 00041 // 時間幅が小さいときはTMINにする 00042 if( uvw[i].lower_us < TMIN ){ uvw[i].lower_us=TMIN;} 00043 pwmVout(); pwmWout(); 00044 }else if( uvw[i].mode==2 ){ // モードが2のとき、デッドタイムをつくる 00045 // Tdt[μs]経過してからタイムアウトでこの関数自身をコール 00046 pwm[i].attach_us(&pwmUout, DEADTIME_US); 00047 #ifndef SIMULATION 00048 // シャント抵抗の両端の電圧を見てモータ電流を検出 00049 p.iuvw[0] = (VshuntR_Uplus - VshuntR_Uminus)*3.3 /R_SHUNT; // iu [A] 00050 #endif 00051 pwm_upper[i] = 0; // 上アームUuをオフ 00052 pwm_lower[i] = 0; // 下アームUdをオフ 00053 }else if( uvw[i].mode==3 ){ // モードが3のとき、Toffの状態をつくる 00054 // T3[μs]経過してからタイムアウトでこの関数自身をコール 00055 pwm[i].attach_us(&pwmUout, uvw[i].lower_us); 00056 pwm_upper[i] = 0; // 上アームUuをオフ 00057 pwm_lower[i] = 1; // 下アームUdをオン 00058 }else{ // モードが4のとき、デッドタイムをつくる 00059 // Tdt[μs]経過してからタイムアウトでこの関数自身をコール 00060 pwm[i].attach_us(&pwmUout, DEADTIME_US); 00061 pwm_upper[i] = 0; // 上アームUuをオフ 00062 pwm_lower[i] = 0; // 下アームUdをオフ 00063 uvw[i].mode = 0; // チョッピングのオンオフを決定するモードを 00064 } // 0にする 00065 } 00066 00067 void pwmVout() { // pwm out using timer 00068 unsigned char i=1; 00069 uvw[i].mode += 1; 00070 if( uvw[i].mode==1 ){ 00071 pwm_upper[i] = 1; 00072 pwm_lower[i] = 0; 00073 uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US; // ON time of Uupper 00074 if( uvw[i].upper_us < TMIN ){ uvw[i].upper_us=TMIN;} 00075 pwm[i].attach_us(&pwmVout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us] 00076 uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower 00077 if( uvw[i].lower_us < TMIN ){ uvw[i].lower_us=TMIN;} 00078 }else if( uvw[i].mode==2 ){ 00079 pwm[i].attach_us(&pwmVout, DEADTIME_US); // setup pwmU to call pwmUout after t [us] 00080 #ifndef SIMULATION 00081 // シャント抵抗の両端の電圧を見てモータ電流を検出 00082 p.iuvw[1] = (VshuntR_Vplus - VshuntR_Vminus)*3.3 /R_SHUNT; // iv [A] 00083 #endif 00084 pwm_upper[i] = 0; 00085 pwm_lower[i] = 0; 00086 }else if( uvw[i].mode==3 ){ 00087 pwm[i].attach_us(&pwmVout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us] 00088 pwm_upper[i] = 0; 00089 pwm_lower[i] = 1; 00090 }else{// if( u.mode==4 ){ 00091 // pwm[i].attach_us(&pwmVout, DEADTIME_US); // setup pwmU to call pwmUout after t [us] 00092 pwm_upper[i] = 0; 00093 pwm_lower[i] = 0; 00094 uvw[i].mode = 0; 00095 } 00096 } 00097 00098 void pwmWout() { // pwm out using timer 00099 unsigned char i=2; 00100 uvw[i].mode += 1; 00101 if( uvw[i].mode==1 ){ 00102 pwm_upper[i] = 1; 00103 pwm_lower[i] = 0; 00104 uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US; // ON time of Uupper 00105 if( uvw[i].upper_us < TMIN ){ uvw[i].upper_us=TMIN;} 00106 pwm[i].attach_us(&pwmWout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us] 00107 uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower 00108 if( uvw[i].lower_us < TMIN ){ uvw[i].lower_us=TMIN;} 00109 }else if( uvw[i].mode==2 ){ 00110 pwm[i].attach_us(&pwmWout, DEADTIME_US); // setup pwmU to call pwmUout after t [us] 00111 pwm_upper[i] = 0; 00112 pwm_lower[i] = 0; 00113 }else if( uvw[i].mode==3 ){ 00114 pwm[i].attach_us(&pwmWout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us] 00115 pwm_upper[i] = 0; 00116 pwm_lower[i] = 1; 00117 }else{// if( u.mode==4 ){ 00118 // pwm[i].attach_us(&pwmWout, DEADTIME_US); // setup pwmU to call pwmUout after t [us] 00119 pwm_upper[i] = 0; 00120 pwm_lower[i] = 0; 00121 uvw[i].mode = 0; 00122 } 00123 } 00124 #elif PWM_WAVEFORM==1 // 1: triangler wave comparison 00125 void pwmUout() { // タイムアウト関数でU相PWMを発生する関数 00126 unsigned char i=0; // i=0のときU相 00127 uvw[i].mode += 1; // チョッピングのオンオフを決定するモードを1増やす 00128 if( uvw[i].mode==1 ){ // モードが1のとき、Toffの状態をつくる 00129 pwm_upper[i] = 0; // 上アームUuをオフ 00130 pwm_lower[i] = 1; // 下アームUdをオン 00131 // モード3の時間幅 T3 = Ton-Tdt を計算 00132 uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US; 00133 // モード1,5の時間幅 T1=(Toff-Tdt)/2=(Tpwm-T3-2Tdt)/2を計算 00134 uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; 00135 uvw[i].lower_us /= 2; 00136 // 時間幅が小さいときはTMINにする 00137 if( uvw[i].lower_us < TMIN ){ uvw[i].lower_us=TMIN;} 00138 // T1[μs]経過してからタイムアウトでこの関数自身をコール 00139 pwm[i].attach_us(&pwmUout, uvw[i].lower_us); 00140 // 時間幅が小さいときはTMINにする 00141 if( uvw[i].upper_us < TMIN ){ uvw[i].upper_us=TMIN;} 00142 }else if( uvw[i].mode==2 ){ // モードが2のとき、デッドタイムをつくる 00143 // Tdt[μs]経過してからタイムアウトでこの関数自身をコール 00144 pwm[i].attach_us(&pwmUout, DEADTIME_US); 00145 pwm_upper[i] = 0; // 上アームUuをオフ 00146 pwm_lower[i] = 0; // 下アームUdをオフ 00147 }else if( uvw[i].mode==3 ){ // モードが3のとき、Tonの状態をつくる 00148 // T3[μs]経過してからタイムアウトでこの関数自身をコール 00149 pwm[i].attach_us(&pwmUout, uvw[i].upper_us); 00150 pwm_upper[i] = 1; // 上アームUuをオン 00151 pwm_lower[i] = 0; // 下アームUdをオフ 00152 }else if( uvw[i].mode==4 ){ // モードが4のとき、デッドタイムをつくる 00153 // Tdt[μs]経過してからタイムアウトでこの関数自身をコール 00154 pwm[i].attach_us(&pwmUout, DEADTIME_US); 00155 #ifndef SIMULATION 00156 // シャント抵抗の両端の電圧を見てモータ電流を検出 00157 p.iuvw[0] = (VshuntR_Uplus - VshuntR_Uminus)*3.3 /R_SHUNT; // iu [A] 00158 #endif 00159 pwm_upper[i] = 0; // 上アームUuをオフ 00160 pwm_lower[i] = 0; // 下アームUdをオフ 00161 }else{ // モードが5のとき、Toffの状態をつくる 00162 // T5(=T1)[μs]経過してからタイムアウトでこの関数自身をコール 00163 pwm[i].attach_us(&pwmUout, uvw[i].lower_us); 00164 pwm_upper[i] = 0; // 上アームUuをオフ 00165 pwm_lower[i] = 1; // 下アームUdをオン 00166 uvw[i].mode = 0; // チョッピングのオンオフを決定するモードを 00167 } // 0にする 00168 } 00169 void pwmVout() { // pwm out using timer 00170 unsigned char i=1; 00171 uvw[i].mode += 1; 00172 if( uvw[i].mode==1 ){ 00173 uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US; // ON time of Uupper 00174 uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower 00175 pwm_upper[i] = 0; 00176 pwm_lower[i] = 1; 00177 uvw[i].lower_us /= 2; 00178 if( uvw[i].lower_us < TMIN ){ uvw[i].lower_us=TMIN;} 00179 pwm[i].attach_us(&pwmVout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us] 00180 if( uvw[i].upper_us < TMIN ){ uvw[i].upper_us=TMIN;} 00181 }else if( uvw[i].mode==2 ){ 00182 pwm[i].attach_us(&pwmVout, DEADTIME_US); // setup pwmU to call pwmUout after t [us] 00183 pwm_upper[i] = 0; 00184 pwm_lower[i] = 0; 00185 }else if( uvw[i].mode==3 ){ 00186 pwm[i].attach_us(&pwmVout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us] 00187 pwm_upper[i] = 1; 00188 pwm_lower[i] = 0; 00189 }else if( uvw[i].mode==4 ){ 00190 pwm[i].attach_us(&pwmVout, DEADTIME_US); // setup pwmU to call pwmUout after t [us] 00191 #ifndef SIMULATION 00192 // シャント抵抗の両端の電圧を見てモータ電流を検出 00193 p.iuvw[1] = (VshuntR_Vplus - VshuntR_Vminus)*3.3 /R_SHUNT; // iv [A] 00194 #endif 00195 pwm_upper[i] = 0; 00196 pwm_lower[i] = 0; 00197 }else{// if( uvw[i].mode==5 ){ 00198 pwm[i].attach_us(&pwmVout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us] 00199 pwm_upper[i] = 0; 00200 pwm_lower[i] = 1; 00201 uvw[i].mode = 0; 00202 } 00203 } 00204 00205 void pwmWout() { // pwm out using timer 00206 unsigned char i=2; 00207 uvw[i].mode += 1; 00208 if( uvw[i].mode==1 ){ 00209 uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US; // ON time of Uupper 00210 uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower 00211 pwm_upper[i] = 0; 00212 pwm_lower[i] = 1; 00213 uvw[i].lower_us /= 2; 00214 if( uvw[i].lower_us < TMIN ){ uvw[i].lower_us=TMIN;} 00215 pwm[i].attach_us(&pwmWout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us] 00216 if( uvw[i].upper_us < TMIN ){ uvw[i].upper_us=TMIN;} 00217 }else if( uvw[i].mode==2 ){ 00218 pwm[i].attach_us(&pwmWout, DEADTIME_US); // setup pwmU to call pwmUout after t [us] 00219 pwm_upper[i] = 0; 00220 pwm_lower[i] = 0; 00221 }else if( uvw[i].mode==3 ){ 00222 pwm[i].attach_us(&pwmWout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us] 00223 pwm_upper[i] = 1; 00224 pwm_lower[i] = 0; 00225 }else if( uvw[i].mode==4 ){ 00226 pwm[i].attach_us(&pwmWout, DEADTIME_US); // setup pwmU to call pwmUout after t [us] 00227 pwm_upper[i] = 0; 00228 pwm_lower[i] = 0; 00229 }else{// if( uvw[i].mode==5 ){ 00230 pwm[i].attach_us(&pwmWout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us] 00231 pwm_upper[i] = 0; 00232 pwm_lower[i] = 1; 00233 uvw[i].mode = 0; 00234 } 00235 } 00236 #endif 00237 00238 00239 void start_pwm(){ 00240 unsigned char i; 00241 for( i=0;i<3;i++ ){ 00242 uvw[i].duty = 0.5; // 0.5のときにVu=0[V] 00243 pwm_upper[i] = pwm_lower[i] = 0; 00244 uvw[i].mode = 0; 00245 } 00246 pwmUout(); 00247 #if PWM_WAVEFORM == 1 00248 pwmVout(); 00249 pwmWout(); 00250 #endif 00251 } 00252 00253 void stop_pwm(){ 00254 unsigned char i; 00255 for( i=0;i<3;i++ ){ 00256 pwm_upper[i] = pwm_lower[i] = 0; 00257 uvw[i].mode = 0; 00258 pwm[i].detach(); 00259 } 00260 }
Generated on Tue Jul 12 2022 20:05:59 by
1.7.2
