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