UVW 3 phases Brushless DC motor control
Dependencies: QEI mbed-rtos mbed
Fork of BLDCmotor by
UVWpwm.cpp@17:1ac855d69c78, 2013-09-07 (annotated)
- Committer:
- kosakaLab
- Date:
- Sat Sep 07 02:47:09 2013 +0000
- Revision:
- 17:1ac855d69c78
- Parent:
- 15:427f5ae8e957
for TBLM-01 18T and OME-360-2MCA
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kosaka | 12:a4b17bb682eb | 1 | #include "mbed.h" |
kosaka | 12:a4b17bb682eb | 2 | #include "controller.h" |
kosaka | 13:791e20f1af43 | 3 | #include "UVWpwm.h" // PWM発生用UVWpwm.cppの変数や定数の定義 |
kosaka | 13:791e20f1af43 | 4 | |
kosaka | 13:791e20f1af43 | 5 | #define DEADTIME_US (unsigned long)(DEADTIME*1000000) // [us], デッドタイム |
kosaka | 12:a4b17bb682eb | 6 | |
kosaka | 13:791e20f1af43 | 7 | Timeout pwm[3]; // タイムアウト関数の宣言(ある時間経過後に関数コールする) |
kosaka | 12:a4b17bb682eb | 8 | |
kosaka | 13:791e20f1af43 | 9 | // デジタル信号を出力するポートupperとlowerをU, V, W相について設定 |
kosaka | 12:a4b17bb682eb | 10 | DigitalOut pwm_upper[] = {(U_UPPER_PORT), (V_UPPER_PORT),(W_UPPER_PORT)}; |
kosaka | 12:a4b17bb682eb | 11 | DigitalOut pwm_lower[] = {(U_LOWER_PORT), (V_LOWER_PORT),(W_LOWER_PORT)}; |
kosaka | 12:a4b17bb682eb | 12 | |
kosaka | 13:791e20f1af43 | 13 | pwm_parameters uvw[3]; // UVW相pwm用の定数、変数宣言 |
kosaka | 13:791e20f1af43 | 14 | |
kosaka | 13:791e20f1af43 | 15 | // U, V相シャント抵抗の両端の電圧のアナログ入力名の設定, *3.3[V] |
kosaka | 13:791e20f1af43 | 16 | AnalogIn VshuntR_Uplus( R_SHUNT_UP_PORT); // *3.3[V], U相+側アナログ入力 |
kosaka | 13:791e20f1af43 | 17 | AnalogIn VshuntR_Uminus(R_SHUNT_UM_PORT); // *3.3[V], U相-側アナログ入力 |
kosaka | 13:791e20f1af43 | 18 | AnalogIn VshuntR_Vplus( R_SHUNT_VP_PORT); // *3.3[V], V相+側アナログ入力 |
kosaka | 13:791e20f1af43 | 19 | AnalogIn VshuntR_Vminus(R_SHUNT_VM_PORT); // *3.3[V], V相-側アナログ入力 |
kosaka | 12:a4b17bb682eb | 20 | |
kosaka | 12:a4b17bb682eb | 21 | // 関数配列: NG |
kosaka | 12:a4b17bb682eb | 22 | //void (*pwmUVWout[])(int) = {pwmout,pwmout,pwmout}; |
kosaka | 12:a4b17bb682eb | 23 | // pwmUVWout[i](i); |
kosakaLab | 15:427f5ae8e957 | 24 | void pwmVout(), pwmWout(); |
kosaka | 12:a4b17bb682eb | 25 | |
kosaka | 12:a4b17bb682eb | 26 | #if PWM_WAVEFORM==0 // 0: saw tooth wave comparison |
kosaka | 13:791e20f1af43 | 27 | void pwmUout() { // タイムアウト関数でU相PWMを発生する関数 |
kosaka | 13:791e20f1af43 | 28 | unsigned char i=0; // i=0のときU相 |
kosaka | 13:791e20f1af43 | 29 | uvw[i].mode += 1; // チョッピングのオンオフを決定するモードを1増やす |
kosaka | 13:791e20f1af43 | 30 | if( uvw[i].mode==1 ){ // モードが1のとき、Tonの状態をつくる |
kosaka | 13:791e20f1af43 | 31 | pwm_upper[i] = 1; // 上アームUuをオン |
kosaka | 13:791e20f1af43 | 32 | pwm_lower[i] = 0; // 下アームUdをオフ |
kosaka | 13:791e20f1af43 | 33 | // モード1の時間幅 T1 = Ton-Tdt を計算 |
kosaka | 13:791e20f1af43 | 34 | uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US; |
kosaka | 13:791e20f1af43 | 35 | // 時間幅が小さいときはTMINにする |
kosaka | 13:791e20f1af43 | 36 | if( uvw[i].upper_us < TMIN ){ uvw[i].upper_us=TMIN;} |
kosaka | 13:791e20f1af43 | 37 | // T1[μs]経過してからタイムアウトでこの関数自身をコール |
kosaka | 13:791e20f1af43 | 38 | pwm[i].attach_us(&pwmUout, uvw[i].upper_us); |
kosaka | 13:791e20f1af43 | 39 | // モード3の時間幅 T3=Toff-Tdt=Tpwm-(T1+Tdt)-Tdtを計算 |
kosaka | 13:791e20f1af43 | 40 | uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; |
kosaka | 13:791e20f1af43 | 41 | // 時間幅が小さいときはTMINにする |
kosaka | 13:791e20f1af43 | 42 | if( uvw[i].lower_us < TMIN ){ uvw[i].lower_us=TMIN;} |
kosakaLab | 15:427f5ae8e957 | 43 | pwmVout(); pwmWout(); |
kosaka | 13:791e20f1af43 | 44 | }else if( uvw[i].mode==2 ){ // モードが2のとき、デッドタイムをつくる |
kosaka | 13:791e20f1af43 | 45 | // Tdt[μs]経過してからタイムアウトでこの関数自身をコール |
kosaka | 13:791e20f1af43 | 46 | pwm[i].attach_us(&pwmUout, DEADTIME_US); |
kosaka | 13:791e20f1af43 | 47 | #ifndef SIMULATION |
kosaka | 13:791e20f1af43 | 48 | // シャント抵抗の両端の電圧を見てモータ電流を検出 |
kosaka | 13:791e20f1af43 | 49 | p.iuvw[0] = (VshuntR_Uplus - VshuntR_Uminus)*3.3 /R_SHUNT; // iu [A] |
kosaka | 13:791e20f1af43 | 50 | #endif |
kosaka | 13:791e20f1af43 | 51 | pwm_upper[i] = 0; // 上アームUuをオフ |
kosaka | 13:791e20f1af43 | 52 | pwm_lower[i] = 0; // 下アームUdをオフ |
kosaka | 13:791e20f1af43 | 53 | }else if( uvw[i].mode==3 ){ // モードが3のとき、Toffの状態をつくる |
kosaka | 13:791e20f1af43 | 54 | // T3[μs]経過してからタイムアウトでこの関数自身をコール |
kosaka | 13:791e20f1af43 | 55 | pwm[i].attach_us(&pwmUout, uvw[i].lower_us); |
kosaka | 13:791e20f1af43 | 56 | pwm_upper[i] = 0; // 上アームUuをオフ |
kosaka | 13:791e20f1af43 | 57 | pwm_lower[i] = 1; // 下アームUdをオン |
kosaka | 13:791e20f1af43 | 58 | }else{ // モードが4のとき、デッドタイムをつくる |
kosaka | 13:791e20f1af43 | 59 | // Tdt[μs]経過してからタイムアウトでこの関数自身をコール |
kosaka | 13:791e20f1af43 | 60 | pwm[i].attach_us(&pwmUout, DEADTIME_US); |
kosaka | 13:791e20f1af43 | 61 | pwm_upper[i] = 0; // 上アームUuをオフ |
kosaka | 13:791e20f1af43 | 62 | pwm_lower[i] = 0; // 下アームUdをオフ |
kosaka | 13:791e20f1af43 | 63 | uvw[i].mode = 0; // チョッピングのオンオフを決定するモードを |
kosaka | 13:791e20f1af43 | 64 | } // 0にする |
kosaka | 12:a4b17bb682eb | 65 | } |
kosaka | 12:a4b17bb682eb | 66 | |
kosaka | 12:a4b17bb682eb | 67 | void pwmVout() { // pwm out using timer |
kosaka | 12:a4b17bb682eb | 68 | unsigned char i=1; |
kosaka | 12:a4b17bb682eb | 69 | uvw[i].mode += 1; |
kosaka | 12:a4b17bb682eb | 70 | if( uvw[i].mode==1 ){ |
kosaka | 12:a4b17bb682eb | 71 | pwm_upper[i] = 1; |
kosaka | 12:a4b17bb682eb | 72 | pwm_lower[i] = 0; |
kosaka | 12:a4b17bb682eb | 73 | uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US; // ON time of Uupper |
kosaka | 13:791e20f1af43 | 74 | if( uvw[i].upper_us < TMIN ){ uvw[i].upper_us=TMIN;} |
kosaka | 12:a4b17bb682eb | 75 | pwm[i].attach_us(&pwmVout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us] |
kosaka | 12:a4b17bb682eb | 76 | uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower |
kosaka | 13:791e20f1af43 | 77 | if( uvw[i].lower_us < TMIN ){ uvw[i].lower_us=TMIN;} |
kosaka | 12:a4b17bb682eb | 78 | }else if( uvw[i].mode==2 ){ |
kosaka | 12:a4b17bb682eb | 79 | pwm[i].attach_us(&pwmVout, DEADTIME_US); // setup pwmU to call pwmUout after t [us] |
kosaka | 13:791e20f1af43 | 80 | #ifndef SIMULATION |
kosaka | 13:791e20f1af43 | 81 | // シャント抵抗の両端の電圧を見てモータ電流を検出 |
kosaka | 13:791e20f1af43 | 82 | p.iuvw[1] = (VshuntR_Vplus - VshuntR_Vminus)*3.3 /R_SHUNT; // iv [A] |
kosaka | 13:791e20f1af43 | 83 | #endif |
kosaka | 12:a4b17bb682eb | 84 | pwm_upper[i] = 0; |
kosaka | 12:a4b17bb682eb | 85 | pwm_lower[i] = 0; |
kosaka | 12:a4b17bb682eb | 86 | }else if( uvw[i].mode==3 ){ |
kosaka | 12:a4b17bb682eb | 87 | pwm[i].attach_us(&pwmVout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us] |
kosaka | 12:a4b17bb682eb | 88 | pwm_upper[i] = 0; |
kosaka | 12:a4b17bb682eb | 89 | pwm_lower[i] = 1; |
kosaka | 12:a4b17bb682eb | 90 | }else{// if( u.mode==4 ){ |
kosakaLab | 15:427f5ae8e957 | 91 | // pwm[i].attach_us(&pwmVout, DEADTIME_US); // setup pwmU to call pwmUout after t [us] |
kosaka | 12:a4b17bb682eb | 92 | pwm_upper[i] = 0; |
kosaka | 12:a4b17bb682eb | 93 | pwm_lower[i] = 0; |
kosaka | 12:a4b17bb682eb | 94 | uvw[i].mode = 0; |
kosaka | 12:a4b17bb682eb | 95 | } |
kosaka | 12:a4b17bb682eb | 96 | } |
kosaka | 12:a4b17bb682eb | 97 | |
kosaka | 12:a4b17bb682eb | 98 | void pwmWout() { // pwm out using timer |
kosaka | 12:a4b17bb682eb | 99 | unsigned char i=2; |
kosaka | 12:a4b17bb682eb | 100 | uvw[i].mode += 1; |
kosaka | 12:a4b17bb682eb | 101 | if( uvw[i].mode==1 ){ |
kosaka | 12:a4b17bb682eb | 102 | pwm_upper[i] = 1; |
kosaka | 12:a4b17bb682eb | 103 | pwm_lower[i] = 0; |
kosaka | 12:a4b17bb682eb | 104 | uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US; // ON time of Uupper |
kosaka | 13:791e20f1af43 | 105 | if( uvw[i].upper_us < TMIN ){ uvw[i].upper_us=TMIN;} |
kosaka | 12:a4b17bb682eb | 106 | pwm[i].attach_us(&pwmWout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us] |
kosaka | 12:a4b17bb682eb | 107 | uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower |
kosaka | 13:791e20f1af43 | 108 | if( uvw[i].lower_us < TMIN ){ uvw[i].lower_us=TMIN;} |
kosaka | 12:a4b17bb682eb | 109 | }else if( uvw[i].mode==2 ){ |
kosaka | 12:a4b17bb682eb | 110 | pwm[i].attach_us(&pwmWout, DEADTIME_US); // setup pwmU to call pwmUout after t [us] |
kosaka | 12:a4b17bb682eb | 111 | pwm_upper[i] = 0; |
kosaka | 12:a4b17bb682eb | 112 | pwm_lower[i] = 0; |
kosaka | 12:a4b17bb682eb | 113 | }else if( uvw[i].mode==3 ){ |
kosaka | 12:a4b17bb682eb | 114 | pwm[i].attach_us(&pwmWout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us] |
kosaka | 12:a4b17bb682eb | 115 | pwm_upper[i] = 0; |
kosaka | 12:a4b17bb682eb | 116 | pwm_lower[i] = 1; |
kosaka | 12:a4b17bb682eb | 117 | }else{// if( u.mode==4 ){ |
kosakaLab | 15:427f5ae8e957 | 118 | // pwm[i].attach_us(&pwmWout, DEADTIME_US); // setup pwmU to call pwmUout after t [us] |
kosaka | 12:a4b17bb682eb | 119 | pwm_upper[i] = 0; |
kosaka | 12:a4b17bb682eb | 120 | pwm_lower[i] = 0; |
kosaka | 12:a4b17bb682eb | 121 | uvw[i].mode = 0; |
kosaka | 12:a4b17bb682eb | 122 | } |
kosaka | 12:a4b17bb682eb | 123 | } |
kosaka | 12:a4b17bb682eb | 124 | #elif PWM_WAVEFORM==1 // 1: triangler wave comparison |
kosaka | 13:791e20f1af43 | 125 | void pwmUout() { // タイムアウト関数でU相PWMを発生する関数 |
kosaka | 13:791e20f1af43 | 126 | unsigned char i=0; // i=0のときU相 |
kosaka | 13:791e20f1af43 | 127 | uvw[i].mode += 1; // チョッピングのオンオフを決定するモードを1増やす |
kosaka | 13:791e20f1af43 | 128 | if( uvw[i].mode==1 ){ // モードが1のとき、Toffの状態をつくる |
kosaka | 13:791e20f1af43 | 129 | pwm_upper[i] = 0; // 上アームUuをオフ |
kosaka | 13:791e20f1af43 | 130 | pwm_lower[i] = 1; // 下アームUdをオン |
kosaka | 13:791e20f1af43 | 131 | // モード3の時間幅 T3 = Ton-Tdt を計算 |
kosaka | 13:791e20f1af43 | 132 | uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US; |
kosaka | 13:791e20f1af43 | 133 | // モード1,5の時間幅 T1=(Toff-Tdt)/2=(Tpwm-T3-2Tdt)/2を計算 |
kosaka | 13:791e20f1af43 | 134 | uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; |
kosaka | 12:a4b17bb682eb | 135 | uvw[i].lower_us /= 2; |
kosaka | 13:791e20f1af43 | 136 | // 時間幅が小さいときはTMINにする |
kosaka | 13:791e20f1af43 | 137 | if( uvw[i].lower_us < TMIN ){ uvw[i].lower_us=TMIN;} |
kosaka | 13:791e20f1af43 | 138 | // T1[μs]経過してからタイムアウトでこの関数自身をコール |
kosaka | 13:791e20f1af43 | 139 | pwm[i].attach_us(&pwmUout, uvw[i].lower_us); |
kosaka | 13:791e20f1af43 | 140 | // 時間幅が小さいときはTMINにする |
kosaka | 13:791e20f1af43 | 141 | if( uvw[i].upper_us < TMIN ){ uvw[i].upper_us=TMIN;} |
kosaka | 13:791e20f1af43 | 142 | }else if( uvw[i].mode==2 ){ // モードが2のとき、デッドタイムをつくる |
kosaka | 13:791e20f1af43 | 143 | // Tdt[μs]経過してからタイムアウトでこの関数自身をコール |
kosaka | 13:791e20f1af43 | 144 | pwm[i].attach_us(&pwmUout, DEADTIME_US); |
kosaka | 13:791e20f1af43 | 145 | pwm_upper[i] = 0; // 上アームUuをオフ |
kosaka | 13:791e20f1af43 | 146 | pwm_lower[i] = 0; // 下アームUdをオフ |
kosaka | 13:791e20f1af43 | 147 | }else if( uvw[i].mode==3 ){ // モードが3のとき、Tonの状態をつくる |
kosaka | 13:791e20f1af43 | 148 | // T3[μs]経過してからタイムアウトでこの関数自身をコール |
kosaka | 13:791e20f1af43 | 149 | pwm[i].attach_us(&pwmUout, uvw[i].upper_us); |
kosaka | 13:791e20f1af43 | 150 | pwm_upper[i] = 1; // 上アームUuをオン |
kosaka | 13:791e20f1af43 | 151 | pwm_lower[i] = 0; // 下アームUdをオフ |
kosaka | 13:791e20f1af43 | 152 | }else if( uvw[i].mode==4 ){ // モードが4のとき、デッドタイムをつくる |
kosaka | 13:791e20f1af43 | 153 | // Tdt[μs]経過してからタイムアウトでこの関数自身をコール |
kosaka | 13:791e20f1af43 | 154 | pwm[i].attach_us(&pwmUout, DEADTIME_US); |
kosaka | 13:791e20f1af43 | 155 | #ifndef SIMULATION |
kosaka | 13:791e20f1af43 | 156 | // シャント抵抗の両端の電圧を見てモータ電流を検出 |
kosaka | 13:791e20f1af43 | 157 | p.iuvw[0] = (VshuntR_Uplus - VshuntR_Uminus)*3.3 /R_SHUNT; // iu [A] |
kosaka | 13:791e20f1af43 | 158 | #endif |
kosaka | 13:791e20f1af43 | 159 | pwm_upper[i] = 0; // 上アームUuをオフ |
kosaka | 13:791e20f1af43 | 160 | pwm_lower[i] = 0; // 下アームUdをオフ |
kosaka | 13:791e20f1af43 | 161 | }else{ // モードが5のとき、Toffの状態をつくる |
kosaka | 13:791e20f1af43 | 162 | // T5(=T1)[μs]経過してからタイムアウトでこの関数自身をコール |
kosaka | 13:791e20f1af43 | 163 | pwm[i].attach_us(&pwmUout, uvw[i].lower_us); |
kosaka | 13:791e20f1af43 | 164 | pwm_upper[i] = 0; // 上アームUuをオフ |
kosaka | 13:791e20f1af43 | 165 | pwm_lower[i] = 1; // 下アームUdをオン |
kosaka | 13:791e20f1af43 | 166 | uvw[i].mode = 0; // チョッピングのオンオフを決定するモードを |
kosaka | 13:791e20f1af43 | 167 | } // 0にする |
kosaka | 12:a4b17bb682eb | 168 | } |
kosaka | 12:a4b17bb682eb | 169 | void pwmVout() { // pwm out using timer |
kosaka | 12:a4b17bb682eb | 170 | unsigned char i=1; |
kosaka | 12:a4b17bb682eb | 171 | uvw[i].mode += 1; |
kosaka | 12:a4b17bb682eb | 172 | if( uvw[i].mode==1 ){ |
kosaka | 12:a4b17bb682eb | 173 | uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US; // ON time of Uupper |
kosaka | 12:a4b17bb682eb | 174 | uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower |
kosaka | 12:a4b17bb682eb | 175 | pwm_upper[i] = 0; |
kosaka | 12:a4b17bb682eb | 176 | pwm_lower[i] = 1; |
kosaka | 12:a4b17bb682eb | 177 | uvw[i].lower_us /= 2; |
kosaka | 13:791e20f1af43 | 178 | if( uvw[i].lower_us < TMIN ){ uvw[i].lower_us=TMIN;} |
kosaka | 12:a4b17bb682eb | 179 | pwm[i].attach_us(&pwmVout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us] |
kosaka | 13:791e20f1af43 | 180 | if( uvw[i].upper_us < TMIN ){ uvw[i].upper_us=TMIN;} |
kosaka | 12:a4b17bb682eb | 181 | }else if( uvw[i].mode==2 ){ |
kosaka | 12:a4b17bb682eb | 182 | pwm[i].attach_us(&pwmVout, DEADTIME_US); // setup pwmU to call pwmUout after t [us] |
kosaka | 12:a4b17bb682eb | 183 | pwm_upper[i] = 0; |
kosaka | 12:a4b17bb682eb | 184 | pwm_lower[i] = 0; |
kosaka | 12:a4b17bb682eb | 185 | }else if( uvw[i].mode==3 ){ |
kosaka | 12:a4b17bb682eb | 186 | pwm[i].attach_us(&pwmVout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us] |
kosaka | 12:a4b17bb682eb | 187 | pwm_upper[i] = 1; |
kosaka | 12:a4b17bb682eb | 188 | pwm_lower[i] = 0; |
kosaka | 12:a4b17bb682eb | 189 | }else if( uvw[i].mode==4 ){ |
kosaka | 12:a4b17bb682eb | 190 | pwm[i].attach_us(&pwmVout, DEADTIME_US); // setup pwmU to call pwmUout after t [us] |
kosaka | 13:791e20f1af43 | 191 | #ifndef SIMULATION |
kosaka | 13:791e20f1af43 | 192 | // シャント抵抗の両端の電圧を見てモータ電流を検出 |
kosaka | 13:791e20f1af43 | 193 | p.iuvw[1] = (VshuntR_Vplus - VshuntR_Vminus)*3.3 /R_SHUNT; // iv [A] |
kosaka | 13:791e20f1af43 | 194 | #endif |
kosaka | 12:a4b17bb682eb | 195 | pwm_upper[i] = 0; |
kosaka | 12:a4b17bb682eb | 196 | pwm_lower[i] = 0; |
kosaka | 12:a4b17bb682eb | 197 | }else{// if( uvw[i].mode==5 ){ |
kosaka | 12:a4b17bb682eb | 198 | pwm[i].attach_us(&pwmVout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us] |
kosaka | 12:a4b17bb682eb | 199 | pwm_upper[i] = 0; |
kosaka | 12:a4b17bb682eb | 200 | pwm_lower[i] = 1; |
kosaka | 12:a4b17bb682eb | 201 | uvw[i].mode = 0; |
kosaka | 12:a4b17bb682eb | 202 | } |
kosaka | 12:a4b17bb682eb | 203 | } |
kosaka | 12:a4b17bb682eb | 204 | |
kosaka | 12:a4b17bb682eb | 205 | void pwmWout() { // pwm out using timer |
kosaka | 12:a4b17bb682eb | 206 | unsigned char i=2; |
kosaka | 12:a4b17bb682eb | 207 | uvw[i].mode += 1; |
kosaka | 12:a4b17bb682eb | 208 | if( uvw[i].mode==1 ){ |
kosaka | 12:a4b17bb682eb | 209 | uvw[i].upper_us = uvw[i].duty*1000000/PWM_FREQ - DEADTIME_US; // ON time of Uupper |
kosaka | 12:a4b17bb682eb | 210 | uvw[i].lower_us = 1000000/PWM_FREQ -uvw[i].upper_us - 2*DEADTIME_US; // ON time of Ulower |
kosaka | 12:a4b17bb682eb | 211 | pwm_upper[i] = 0; |
kosaka | 12:a4b17bb682eb | 212 | pwm_lower[i] = 1; |
kosaka | 12:a4b17bb682eb | 213 | uvw[i].lower_us /= 2; |
kosaka | 13:791e20f1af43 | 214 | if( uvw[i].lower_us < TMIN ){ uvw[i].lower_us=TMIN;} |
kosaka | 12:a4b17bb682eb | 215 | pwm[i].attach_us(&pwmWout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us] |
kosaka | 13:791e20f1af43 | 216 | if( uvw[i].upper_us < TMIN ){ uvw[i].upper_us=TMIN;} |
kosaka | 12:a4b17bb682eb | 217 | }else if( uvw[i].mode==2 ){ |
kosaka | 12:a4b17bb682eb | 218 | pwm[i].attach_us(&pwmWout, DEADTIME_US); // setup pwmU to call pwmUout after t [us] |
kosaka | 12:a4b17bb682eb | 219 | pwm_upper[i] = 0; |
kosaka | 12:a4b17bb682eb | 220 | pwm_lower[i] = 0; |
kosaka | 12:a4b17bb682eb | 221 | }else if( uvw[i].mode==3 ){ |
kosaka | 12:a4b17bb682eb | 222 | pwm[i].attach_us(&pwmWout, uvw[i].upper_us); // setup pwmU to call pwmUout after t [us] |
kosaka | 12:a4b17bb682eb | 223 | pwm_upper[i] = 1; |
kosaka | 12:a4b17bb682eb | 224 | pwm_lower[i] = 0; |
kosaka | 12:a4b17bb682eb | 225 | }else if( uvw[i].mode==4 ){ |
kosaka | 12:a4b17bb682eb | 226 | pwm[i].attach_us(&pwmWout, DEADTIME_US); // setup pwmU to call pwmUout after t [us] |
kosaka | 12:a4b17bb682eb | 227 | pwm_upper[i] = 0; |
kosaka | 12:a4b17bb682eb | 228 | pwm_lower[i] = 0; |
kosaka | 12:a4b17bb682eb | 229 | }else{// if( uvw[i].mode==5 ){ |
kosaka | 12:a4b17bb682eb | 230 | pwm[i].attach_us(&pwmWout, uvw[i].lower_us); // setup pwmU to call pwmUout after t [us] |
kosaka | 12:a4b17bb682eb | 231 | pwm_upper[i] = 0; |
kosaka | 12:a4b17bb682eb | 232 | pwm_lower[i] = 1; |
kosaka | 12:a4b17bb682eb | 233 | uvw[i].mode = 0; |
kosaka | 12:a4b17bb682eb | 234 | } |
kosaka | 12:a4b17bb682eb | 235 | } |
kosaka | 12:a4b17bb682eb | 236 | #endif |
kosaka | 12:a4b17bb682eb | 237 | |
kosaka | 12:a4b17bb682eb | 238 | |
kosaka | 12:a4b17bb682eb | 239 | void start_pwm(){ |
kosaka | 12:a4b17bb682eb | 240 | unsigned char i; |
kosaka | 12:a4b17bb682eb | 241 | for( i=0;i<3;i++ ){ |
kosaka | 13:791e20f1af43 | 242 | uvw[i].duty = 0.5; // 0.5のときにVu=0[V] |
kosaka | 12:a4b17bb682eb | 243 | pwm_upper[i] = pwm_lower[i] = 0; |
kosaka | 12:a4b17bb682eb | 244 | uvw[i].mode = 0; |
kosaka | 12:a4b17bb682eb | 245 | } |
kosaka | 12:a4b17bb682eb | 246 | pwmUout(); |
kosakaLab | 15:427f5ae8e957 | 247 | #if PWM_WAVEFORM == 1 |
kosaka | 12:a4b17bb682eb | 248 | pwmVout(); |
kosaka | 12:a4b17bb682eb | 249 | pwmWout(); |
kosakaLab | 15:427f5ae8e957 | 250 | #endif |
kosaka | 12:a4b17bb682eb | 251 | } |
kosaka | 12:a4b17bb682eb | 252 | |
kosaka | 12:a4b17bb682eb | 253 | void stop_pwm(){ |
kosaka | 12:a4b17bb682eb | 254 | unsigned char i; |
kosaka | 12:a4b17bb682eb | 255 | for( i=0;i<3;i++ ){ |
kosaka | 12:a4b17bb682eb | 256 | pwm_upper[i] = pwm_lower[i] = 0; |
kosaka | 12:a4b17bb682eb | 257 | uvw[i].mode = 0; |
kosaka | 12:a4b17bb682eb | 258 | pwm[i].detach(); |
kosaka | 12:a4b17bb682eb | 259 | } |
kosaka | 12:a4b17bb682eb | 260 | } |