3相インバータで3相PWMを生成するためのライブラリです。ブラシレスDCモータの制御に利用できます。
3PhasePWM.cpp@1:209637768493, 2018-01-26 (annotated)
- Committer:
- porizou
- Date:
- Fri Jan 26 01:50:53 2018 +0000
- Revision:
- 1:209637768493
- Parent:
- 0:e82b1532eec5
??????
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
porizou | 0:e82b1532eec5 | 1 | #include "3PhasePWM.h" |
porizou | 0:e82b1532eec5 | 2 | |
porizou | 0:e82b1532eec5 | 3 | #include "mbed.h" |
porizou | 0:e82b1532eec5 | 4 | |
porizou | 0:e82b1532eec5 | 5 | ThreePhasePWM::ThreePhasePWM(PinName upper_U, PinName upper_V, PinName upper_W, |
porizou | 0:e82b1532eec5 | 6 | PinName lower_U, PinName lower_V, PinName lower_W, |
porizou | 0:e82b1532eec5 | 7 | float Frequency, float DeadTime): |
porizou | 0:e82b1532eec5 | 8 | pwm_upper_U(upper_U), pwm_upper_V(upper_V), pwm_upper_W(upper_W), |
porizou | 0:e82b1532eec5 | 9 | pwm_lower_U(lower_U), pwm_lower_V(lower_V), pwm_lower_W(lower_W) |
porizou | 0:e82b1532eec5 | 10 | { |
porizou | 0:e82b1532eec5 | 11 | pwm_upper_U = 0; |
porizou | 0:e82b1532eec5 | 12 | pwm_upper_V = 0; |
porizou | 0:e82b1532eec5 | 13 | pwm_upper_W = 0; |
porizou | 0:e82b1532eec5 | 14 | pwm_lower_U = 0; |
porizou | 0:e82b1532eec5 | 15 | pwm_lower_V = 0; |
porizou | 0:e82b1532eec5 | 16 | pwm_lower_W = 0; |
porizou | 0:e82b1532eec5 | 17 | |
porizou | 0:e82b1532eec5 | 18 | Frequency_ = Frequency; |
porizou | 0:e82b1532eec5 | 19 | DeadTime_ = DeadTime; |
porizou | 0:e82b1532eec5 | 20 | } |
porizou | 0:e82b1532eec5 | 21 | |
porizou | 0:e82b1532eec5 | 22 | |
porizou | 0:e82b1532eec5 | 23 | #ifdef TOOTHWAVE |
porizou | 0:e82b1532eec5 | 24 | void ThreePhasePWM::PwmUout(void) { |
porizou | 0:e82b1532eec5 | 25 | unsigned char i = 0;//i=0のときU相 |
porizou | 0:e82b1532eec5 | 26 | uvw[i].mode += 1; //チョッピングのオンオフを決定するモードを1増やす |
porizou | 0:e82b1532eec5 | 27 | |
porizou | 0:e82b1532eec5 | 28 | if(uvw[i].mode == 1) { // モードが1のとき、Tonの状態をつくる |
porizou | 0:e82b1532eec5 | 29 | pwm_upper_U = 1; //上アームUuをON |
porizou | 0:e82b1532eec5 | 30 | pwm_lower_U = 0; //下アームUdをOFF |
porizou | 0:e82b1532eec5 | 31 | |
porizou | 0:e82b1532eec5 | 32 | // モード1の時間幅 T1 = Ton-Tdt を計算 |
porizou | 0:e82b1532eec5 | 33 | uvw[i].upper_us = uvw[i].duty * 1000000 / Frequency_ - DeadTime_; |
porizou | 0:e82b1532eec5 | 34 | // 時間幅が小さいときはTMINにする |
porizou | 0:e82b1532eec5 | 35 | if( uvw[i].upper_us < TMIN ) uvw[i].upper_us = TMIN; |
porizou | 0:e82b1532eec5 | 36 | |
porizou | 0:e82b1532eec5 | 37 | // T1[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 38 | pwm[i].attach_us(this, &ThreePhasePWM::PwmUout, uvw[i].upper_us); |
porizou | 0:e82b1532eec5 | 39 | |
porizou | 0:e82b1532eec5 | 40 | // モード3の時間幅 T3=Toff-Tdt=Tpwm-(T1+Tdt)-Tdtを計算 |
porizou | 0:e82b1532eec5 | 41 | uvw[i].lower_us = 1000000 / Frequency_ - uvw[i].upper_us - 2 * DeadTime_; |
porizou | 0:e82b1532eec5 | 42 | // 時間幅が小さいときはTMINにする |
porizou | 0:e82b1532eec5 | 43 | if( uvw[i].lower_us < TMIN ) uvw[i].lower_us = TMIN; |
porizou | 0:e82b1532eec5 | 44 | } |
porizou | 0:e82b1532eec5 | 45 | else if(uvw[i].mode == 2) { // モードが2のとき、デッドタイムをつくる |
porizou | 0:e82b1532eec5 | 46 | // Tdt[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 47 | pwm[i].attach_us(this, &ThreePhasePWM::PwmUout, DeadTime_); |
porizou | 0:e82b1532eec5 | 48 | |
porizou | 0:e82b1532eec5 | 49 | pwm_upper_U = 0; // 上アームUuをオフ |
porizou | 0:e82b1532eec5 | 50 | pwm_lower_U = 0; // 下アームUdをオフ |
porizou | 0:e82b1532eec5 | 51 | } |
porizou | 0:e82b1532eec5 | 52 | else if(uvw[i].mode == 3) { // モードが3のとき、Toffの状態をつくる |
porizou | 0:e82b1532eec5 | 53 | // T3[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 54 | pwm[i].attach_us(this, &ThreePhasePWM::PwmUout, uvw[i].lower_us); |
porizou | 0:e82b1532eec5 | 55 | |
porizou | 0:e82b1532eec5 | 56 | pwm_upper_U = 0; // 上アームUuをオフ |
porizou | 0:e82b1532eec5 | 57 | pwm_lower_U = 1; // 下アームUdをオン |
porizou | 0:e82b1532eec5 | 58 | } |
porizou | 0:e82b1532eec5 | 59 | else { // モードが4のとき、デッドタイムをつくる |
porizou | 0:e82b1532eec5 | 60 | // Tdt[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 61 | pwm[i].attach_us(this, &ThreePhasePWM::PwmUout, DeadTime_); |
porizou | 0:e82b1532eec5 | 62 | |
porizou | 0:e82b1532eec5 | 63 | pwm_upper_U = 0; // 上アームUuをオフ |
porizou | 0:e82b1532eec5 | 64 | pwm_lower_U = 0; // 下アームUdをオフ |
porizou | 0:e82b1532eec5 | 65 | |
porizou | 0:e82b1532eec5 | 66 | uvw[i].mode = 0; // チョッピングのオンオフを決定するモードを0にする |
porizou | 0:e82b1532eec5 | 67 | } |
porizou | 0:e82b1532eec5 | 68 | } |
porizou | 0:e82b1532eec5 | 69 | |
porizou | 0:e82b1532eec5 | 70 | void ThreePhasePWM::PwmVout(void) { |
porizou | 0:e82b1532eec5 | 71 | unsigned char i = 1;//i=1のときV相 |
porizou | 0:e82b1532eec5 | 72 | uvw[i].mode += 1; //チョッピングのオンオフを決定するモードを1増やす |
porizou | 0:e82b1532eec5 | 73 | |
porizou | 0:e82b1532eec5 | 74 | if(uvw[i].mode == 1) { // モードが1のとき、Tonの状態をつくる |
porizou | 0:e82b1532eec5 | 75 | pwm_upper_V = 1; //上アームVuをON |
porizou | 0:e82b1532eec5 | 76 | pwm_lower_V = 0; //下アームVdをOFF |
porizou | 0:e82b1532eec5 | 77 | |
porizou | 0:e82b1532eec5 | 78 | // モード1の時間幅 T1 = Ton-Tdt を計算 |
porizou | 0:e82b1532eec5 | 79 | uvw[i].upper_us = uvw[i].duty * 1000000 / Frequency_ - DeadTime_; |
porizou | 0:e82b1532eec5 | 80 | // 時間幅が小さいときはTMINにする |
porizou | 0:e82b1532eec5 | 81 | if( uvw[i].upper_us < TMIN ) uvw[i].upper_us = TMIN; |
porizou | 0:e82b1532eec5 | 82 | |
porizou | 0:e82b1532eec5 | 83 | // T1[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 84 | pwm[i].attach_us(this, &ThreePhasePWM::PwmVout, uvw[i].upper_us); |
porizou | 0:e82b1532eec5 | 85 | |
porizou | 0:e82b1532eec5 | 86 | // モード3の時間幅 T3=Toff-Tdt=Tpwm-(T1+Tdt)-Tdtを計算 |
porizou | 0:e82b1532eec5 | 87 | uvw[i].lower_us = 1000000 / Frequency_ - uvw[i].upper_us - 2 * DeadTime_; |
porizou | 0:e82b1532eec5 | 88 | // 時間幅が小さいときはTMINにする |
porizou | 0:e82b1532eec5 | 89 | if( uvw[i].lower_us < TMIN ) uvw[i].lower_us = TMIN; |
porizou | 0:e82b1532eec5 | 90 | } |
porizou | 0:e82b1532eec5 | 91 | else if(uvw[i].mode == 2) { // モードが2のとき、デッドタイムをつくる |
porizou | 0:e82b1532eec5 | 92 | // Tdt[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 93 | pwm[i].attach_us(this, &ThreePhasePWM::PwmVout, DeadTime_); |
porizou | 0:e82b1532eec5 | 94 | |
porizou | 0:e82b1532eec5 | 95 | pwm_upper_V = 0; // 上アームVuをオフ |
porizou | 0:e82b1532eec5 | 96 | pwm_lower_V = 0; // 下アームVdをオフ |
porizou | 0:e82b1532eec5 | 97 | } |
porizou | 0:e82b1532eec5 | 98 | else if(uvw[i].mode == 3) { // モードが3のとき、Toffの状態をつくる |
porizou | 0:e82b1532eec5 | 99 | // T3[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 100 | pwm[i].attach_us(this, &ThreePhasePWM::PwmVout, uvw[i].lower_us); |
porizou | 0:e82b1532eec5 | 101 | |
porizou | 0:e82b1532eec5 | 102 | pwm_upper_V = 0; // 上アームVuをオフ |
porizou | 0:e82b1532eec5 | 103 | pwm_lower_V = 1; // 下アームVdをオン |
porizou | 0:e82b1532eec5 | 104 | } |
porizou | 0:e82b1532eec5 | 105 | else { // モードが4のとき、デッドタイムをつくる |
porizou | 0:e82b1532eec5 | 106 | // Tdt[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 107 | pwm[i].attach_us(this, &ThreePhasePWM::PwmVout, DeadTime_); |
porizou | 0:e82b1532eec5 | 108 | |
porizou | 0:e82b1532eec5 | 109 | pwm_upper_V = 0; // 上アームVuをオフ |
porizou | 0:e82b1532eec5 | 110 | pwm_lower_V = 0; // 下アームVdをオフ |
porizou | 0:e82b1532eec5 | 111 | |
porizou | 0:e82b1532eec5 | 112 | uvw[i].mode = 0; // チョッピングのオンオフを決定するモードを0にする |
porizou | 0:e82b1532eec5 | 113 | } |
porizou | 0:e82b1532eec5 | 114 | } |
porizou | 0:e82b1532eec5 | 115 | |
porizou | 0:e82b1532eec5 | 116 | void ThreePhasePWM::PwmWout(void) { |
porizou | 0:e82b1532eec5 | 117 | unsigned char i = 2;//i=2のときW相 |
porizou | 0:e82b1532eec5 | 118 | uvw[i].mode += 1; //チョッピングのオンオフを決定するモードを1増やす |
porizou | 0:e82b1532eec5 | 119 | |
porizou | 0:e82b1532eec5 | 120 | if(uvw[i].mode == 1) { // モードが1のとき、Tonの状態をつくる |
porizou | 0:e82b1532eec5 | 121 | pwm_upper_W = 1; //上アームWuをON |
porizou | 0:e82b1532eec5 | 122 | pwm_lower_W = 0; //下アームWdをOFF |
porizou | 0:e82b1532eec5 | 123 | |
porizou | 0:e82b1532eec5 | 124 | // モード1の時間幅 T1 = Ton-Tdt を計算 |
porizou | 0:e82b1532eec5 | 125 | uvw[i].upper_us = uvw[i].duty * 1000000 / Frequency_ - DeadTime_; |
porizou | 0:e82b1532eec5 | 126 | // 時間幅が小さいときはTMINにする |
porizou | 0:e82b1532eec5 | 127 | if( uvw[i].upper_us < TMIN ) uvw[i].upper_us = TMIN; |
porizou | 0:e82b1532eec5 | 128 | |
porizou | 0:e82b1532eec5 | 129 | // T1[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 130 | pwm[i].attach_us(this, &ThreePhasePWM::PwmWout, uvw[i].upper_us); |
porizou | 0:e82b1532eec5 | 131 | |
porizou | 0:e82b1532eec5 | 132 | // モード3の時間幅 T3=Toff-Tdt=Tpwm-(T1+Tdt)-Tdtを計算 |
porizou | 0:e82b1532eec5 | 133 | uvw[i].lower_us = 1000000 / Frequency_ - uvw[i].upper_us - 2 * DeadTime_; |
porizou | 0:e82b1532eec5 | 134 | // 時間幅が小さいときはTMINにする |
porizou | 0:e82b1532eec5 | 135 | if( uvw[i].lower_us < TMIN ) uvw[i].lower_us = TMIN; |
porizou | 0:e82b1532eec5 | 136 | } |
porizou | 0:e82b1532eec5 | 137 | else if(uvw[i].mode == 2) { // モードが2のとき、デッドタイムをつくる |
porizou | 0:e82b1532eec5 | 138 | // Tdt[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 139 | pwm[i].attach_us(this, &ThreePhasePWM::PwmWout, DeadTime_); |
porizou | 0:e82b1532eec5 | 140 | |
porizou | 0:e82b1532eec5 | 141 | pwm_upper_W = 0; // 上アームWuをオフ |
porizou | 0:e82b1532eec5 | 142 | pwm_lower_W = 0; // 下アームWdをオフ |
porizou | 0:e82b1532eec5 | 143 | } |
porizou | 0:e82b1532eec5 | 144 | else if(uvw[i].mode == 3) { // モードが3のとき、Toffの状態をつくる |
porizou | 0:e82b1532eec5 | 145 | // T3[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 146 | pwm[i].attach_us(this, &ThreePhasePWM::PwmWout, uvw[i].lower_us); |
porizou | 0:e82b1532eec5 | 147 | |
porizou | 0:e82b1532eec5 | 148 | pwm_upper_W = 0; // 上アームWuをオフ |
porizou | 0:e82b1532eec5 | 149 | pwm_lower_W = 1; // 下アームWdをオン |
porizou | 0:e82b1532eec5 | 150 | } |
porizou | 0:e82b1532eec5 | 151 | else { // モードが4のとき、デッドタイムをつくる |
porizou | 0:e82b1532eec5 | 152 | // Tdt[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 153 | pwm[i].attach_us(this, &ThreePhasePWM::PwmWout, DeadTime_); |
porizou | 0:e82b1532eec5 | 154 | |
porizou | 0:e82b1532eec5 | 155 | pwm_upper_W = 0; // 上アームWuをオフ |
porizou | 0:e82b1532eec5 | 156 | pwm_lower_W = 0; // 下アームWdをオフ |
porizou | 0:e82b1532eec5 | 157 | |
porizou | 0:e82b1532eec5 | 158 | uvw[i].mode = 0; // チョッピングのオンオフを決定するモードを0にする |
porizou | 0:e82b1532eec5 | 159 | } |
porizou | 0:e82b1532eec5 | 160 | } |
porizou | 0:e82b1532eec5 | 161 | #endif |
porizou | 0:e82b1532eec5 | 162 | |
porizou | 0:e82b1532eec5 | 163 | |
porizou | 0:e82b1532eec5 | 164 | #ifdef TRIANGLERWAVE |
porizou | 0:e82b1532eec5 | 165 | void ThreePhasePWM::PwmUout(void) { |
porizou | 0:e82b1532eec5 | 166 | unsigned char i = 0; // i=0のときU相 |
porizou | 0:e82b1532eec5 | 167 | uvw[i].mode += 1; //チョッピングのオンオフを決定するモードを1増やす |
porizou | 0:e82b1532eec5 | 168 | |
porizou | 0:e82b1532eec5 | 169 | if( uvw[i].mode == 1 ){ // モードが1のとき、Toffの状態をつくる |
porizou | 1:209637768493 | 170 | pwm_upper_U = 0; // 上アームUuをオフ |
porizou | 1:209637768493 | 171 | pwm_lower_U = 1; // 下アームUdをオン |
porizou | 0:e82b1532eec5 | 172 | |
porizou | 0:e82b1532eec5 | 173 | // モード3の時間幅 T3 = Ton-Tdt を計算 |
porizou | 0:e82b1532eec5 | 174 | uvw[i].upper_us = uvw[i].duty * 1000000 / Frequency_ - DeadTime_; |
porizou | 0:e82b1532eec5 | 175 | // 時間幅が小さいときはTMINにする |
porizou | 0:e82b1532eec5 | 176 | if( uvw[i].upper_us < TMIN ) uvw[i].upper_us = TMIN; |
porizou | 0:e82b1532eec5 | 177 | |
porizou | 0:e82b1532eec5 | 178 | // モード1,5の時間幅 T1=(Toff-Tdt)/2=(Tpwm-T3-2Tdt)/2を計算 |
porizou | 0:e82b1532eec5 | 179 | uvw[i].lower_us = (1000000 / Frequency_ - uvw[i].upper_us - 2 * DeadTime_) / 2.0; |
porizou | 0:e82b1532eec5 | 180 | // 時間幅が小さいときはTMINにする |
porizou | 0:e82b1532eec5 | 181 | if( uvw[i].lower_us < TMIN ) uvw[i].lower_us = TMIN; |
porizou | 0:e82b1532eec5 | 182 | |
porizou | 0:e82b1532eec5 | 183 | // T1[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 184 | pwm[i].attach_us(this, &ThreePhasePWM::PwmUout, uvw[i].lower_us); |
porizou | 0:e82b1532eec5 | 185 | |
porizou | 0:e82b1532eec5 | 186 | } |
porizou | 0:e82b1532eec5 | 187 | else if( uvw[i].mode == 2 ) { // モードが2のとき、デッドタイムをつくる |
porizou | 0:e82b1532eec5 | 188 | // Tdt[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 189 | pwm[i].attach_us(this, &ThreePhasePWM::PwmUout, DeadTime_); |
porizou | 0:e82b1532eec5 | 190 | |
porizou | 1:209637768493 | 191 | pwm_upper_U = 0; // 上アームUuをオフ |
porizou | 1:209637768493 | 192 | pwm_lower_U = 0; // 下アームUdをオフ |
porizou | 0:e82b1532eec5 | 193 | } |
porizou | 0:e82b1532eec5 | 194 | else if( uvw[i].mode == 3 ) { // モードが3のとき、Tonの状態をつくる |
porizou | 0:e82b1532eec5 | 195 | // T3[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 196 | pwm[i].attach_us(this, &ThreePhasePWM::PwmUout, uvw[i].upper_us); |
porizou | 0:e82b1532eec5 | 197 | |
porizou | 1:209637768493 | 198 | pwm_upper_U = 1; // 上アームUuをオン |
porizou | 1:209637768493 | 199 | pwm_lower_U = 0; // 下アームUdをオフ |
porizou | 0:e82b1532eec5 | 200 | } |
porizou | 0:e82b1532eec5 | 201 | else if( uvw[i].mode == 4 ) { // モードが4のとき、デッドタイムをつくる |
porizou | 0:e82b1532eec5 | 202 | // Tdt[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 203 | pwm[i].attach_us(this, &ThreePhasePWM::PwmUout, DeadTime_); |
porizou | 0:e82b1532eec5 | 204 | |
porizou | 1:209637768493 | 205 | pwm_upper_U = 0; // 上アームUuをオフ |
porizou | 1:209637768493 | 206 | pwm_lower_U = 0; // 下アームUdをオフ |
porizou | 0:e82b1532eec5 | 207 | } |
porizou | 0:e82b1532eec5 | 208 | else { // モードが5のとき、Toffの状態をつくる |
porizou | 0:e82b1532eec5 | 209 | // T5(=T1)[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 210 | pwm[i].attach_us(this, &ThreePhasePWM::PwmUout, uvw[i].lower_us); |
porizou | 0:e82b1532eec5 | 211 | |
porizou | 1:209637768493 | 212 | pwm_upper_U = 0; // 上アームUuをオフ |
porizou | 1:209637768493 | 213 | pwm_lower_U = 1; // 下アームUdをオン |
porizou | 0:e82b1532eec5 | 214 | |
porizou | 0:e82b1532eec5 | 215 | uvw[i].mode = 0; // チョッピングのオンオフを決定するモードを0にする |
porizou | 0:e82b1532eec5 | 216 | } |
porizou | 0:e82b1532eec5 | 217 | } |
porizou | 0:e82b1532eec5 | 218 | |
porizou | 0:e82b1532eec5 | 219 | void ThreePhasePWM::PwmVout(void) { |
porizou | 0:e82b1532eec5 | 220 | unsigned char i = 1; // i=1のときV相 |
porizou | 0:e82b1532eec5 | 221 | uvw[i].mode += 1; //チョッピングのオンオフを決定するモードを1増やす |
porizou | 0:e82b1532eec5 | 222 | |
porizou | 0:e82b1532eec5 | 223 | if( uvw[i].mode == 1 ){ // モードが1のとき、Toffの状態をつくる |
porizou | 1:209637768493 | 224 | pwm_upper_V = 0; // 上アームVuをオフ |
porizou | 1:209637768493 | 225 | pwm_lower_V = 1; // 下アームVdをオン |
porizou | 0:e82b1532eec5 | 226 | |
porizou | 0:e82b1532eec5 | 227 | // モード3の時間幅 T3 = Ton-Tdt を計算 |
porizou | 0:e82b1532eec5 | 228 | uvw[i].upper_us = uvw[i].duty * 1000000 / Frequency_ - DeadTime_; |
porizou | 0:e82b1532eec5 | 229 | // 時間幅が小さいときはTMINにする |
porizou | 0:e82b1532eec5 | 230 | if( uvw[i].upper_us < TMIN ) uvw[i].upper_us = TMIN; |
porizou | 0:e82b1532eec5 | 231 | |
porizou | 0:e82b1532eec5 | 232 | // モード1,5の時間幅 T1=(Toff-Tdt)/2=(Tpwm-T3-2Tdt)/2を計算 |
porizou | 0:e82b1532eec5 | 233 | uvw[i].lower_us = (1000000 / Frequency_ - uvw[i].upper_us - 2 * DeadTime_) / 2.0; |
porizou | 0:e82b1532eec5 | 234 | // 時間幅が小さいときはTMINにする |
porizou | 0:e82b1532eec5 | 235 | if( uvw[i].lower_us < TMIN ) uvw[i].lower_us = TMIN; |
porizou | 0:e82b1532eec5 | 236 | |
porizou | 0:e82b1532eec5 | 237 | // T1[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 238 | pwm[i].attach_us(this, &ThreePhasePWM::PwmVout, uvw[i].lower_us); |
porizou | 0:e82b1532eec5 | 239 | |
porizou | 0:e82b1532eec5 | 240 | } |
porizou | 0:e82b1532eec5 | 241 | else if( uvw[i].mode == 2 ) { // モードが2のとき、デッドタイムをつくる |
porizou | 0:e82b1532eec5 | 242 | // Tdt[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 243 | pwm[i].attach_us(this, &ThreePhasePWM::PwmVout, DeadTime_); |
porizou | 0:e82b1532eec5 | 244 | |
porizou | 1:209637768493 | 245 | pwm_upper_V = 0; // 上アームVuをオフ |
porizou | 1:209637768493 | 246 | pwm_lower_V = 0; // 下アームVdをオフ |
porizou | 0:e82b1532eec5 | 247 | } |
porizou | 0:e82b1532eec5 | 248 | else if( uvw[i].mode == 3 ) { // モードが3のとき、Tonの状態をつくる |
porizou | 0:e82b1532eec5 | 249 | // T3[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 250 | pwm[i].attach_us(this, &ThreePhasePWM::PwmVout, uvw[i].upper_us); |
porizou | 0:e82b1532eec5 | 251 | |
porizou | 1:209637768493 | 252 | pwm_upper_V = 1; // 上アームVuをオン |
porizou | 1:209637768493 | 253 | pwm_lower_V = 0; // 下アームVdをオフ |
porizou | 0:e82b1532eec5 | 254 | } |
porizou | 0:e82b1532eec5 | 255 | else if( uvw[i].mode == 4 ) { // モードが4のとき、デッドタイムをつくる |
porizou | 0:e82b1532eec5 | 256 | // Tdt[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 257 | pwm[i].attach_us(this, &ThreePhasePWM::PwmVout, DeadTime_); |
porizou | 0:e82b1532eec5 | 258 | |
porizou | 1:209637768493 | 259 | pwm_upper_V = 0; // 上アームVuをオフ |
porizou | 1:209637768493 | 260 | pwm_lower_V = 0; // 下アームVdをオフ |
porizou | 0:e82b1532eec5 | 261 | } |
porizou | 0:e82b1532eec5 | 262 | else { // モードが5のとき、Toffの状態をつくる |
porizou | 0:e82b1532eec5 | 263 | // T5(=T1)[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 264 | pwm[i].attach_us(this, &ThreePhasePWM::PwmVout, uvw[i].lower_us); |
porizou | 0:e82b1532eec5 | 265 | |
porizou | 1:209637768493 | 266 | pwm_upper_V = 0; // 上アームVuをオフ |
porizou | 1:209637768493 | 267 | pwm_lower_V = 1; // 下アームVdをオン |
porizou | 0:e82b1532eec5 | 268 | |
porizou | 0:e82b1532eec5 | 269 | uvw[i].mode = 0; // チョッピングのオンオフを決定するモードを0にする |
porizou | 0:e82b1532eec5 | 270 | } |
porizou | 0:e82b1532eec5 | 271 | } |
porizou | 0:e82b1532eec5 | 272 | |
porizou | 0:e82b1532eec5 | 273 | void ThreePhasePWM::PwmWout(void) { |
porizou | 0:e82b1532eec5 | 274 | unsigned char i = 2; // i=2のときW相 |
porizou | 0:e82b1532eec5 | 275 | uvw[i].mode += 1; //チョッピングのオンオフを決定するモードを1増やす |
porizou | 0:e82b1532eec5 | 276 | |
porizou | 0:e82b1532eec5 | 277 | if( uvw[i].mode == 1 ){ // モードが1のとき、Toffの状態をつくる |
porizou | 1:209637768493 | 278 | pwm_upper_W = 0; // 上アームWuをオフ |
porizou | 1:209637768493 | 279 | pwm_lower_W = 1; // 下アームWdをオン |
porizou | 0:e82b1532eec5 | 280 | |
porizou | 0:e82b1532eec5 | 281 | // モード3の時間幅 T3 = Ton-Tdt を計算 |
porizou | 0:e82b1532eec5 | 282 | uvw[i].upper_us = uvw[i].duty * 1000000 / Frequency_ - DeadTime_; |
porizou | 0:e82b1532eec5 | 283 | // 時間幅が小さいときはTMINにする |
porizou | 0:e82b1532eec5 | 284 | if( uvw[i].upper_us < TMIN ) uvw[i].upper_us = TMIN; |
porizou | 0:e82b1532eec5 | 285 | |
porizou | 0:e82b1532eec5 | 286 | // モード1,5の時間幅 T1=(Toff-Tdt)/2=(Tpwm-T3-2Tdt)/2を計算 |
porizou | 0:e82b1532eec5 | 287 | uvw[i].lower_us = (1000000 / Frequency_ - uvw[i].upper_us - 2 * DeadTime_) / 2.0; |
porizou | 0:e82b1532eec5 | 288 | // 時間幅が小さいときはTMINにする |
porizou | 0:e82b1532eec5 | 289 | if( uvw[i].lower_us < TMIN ) uvw[i].lower_us = TMIN; |
porizou | 0:e82b1532eec5 | 290 | |
porizou | 0:e82b1532eec5 | 291 | // T1[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 292 | pwm[i].attach_us(this, &ThreePhasePWM::PwmWout, uvw[i].lower_us); |
porizou | 0:e82b1532eec5 | 293 | |
porizou | 0:e82b1532eec5 | 294 | } |
porizou | 0:e82b1532eec5 | 295 | else if( uvw[i].mode == 2 ) { // モードが2のとき、デッドタイムをつくる |
porizou | 0:e82b1532eec5 | 296 | // Tdt[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 297 | pwm[i].attach_us(this, &ThreePhasePWM::PwmWout, DeadTime_); |
porizou | 0:e82b1532eec5 | 298 | |
porizou | 1:209637768493 | 299 | pwm_upper_W = 0; // 上アームWuをオフ |
porizou | 1:209637768493 | 300 | pwm_lower_W = 0; // 下アームWdをオフ |
porizou | 0:e82b1532eec5 | 301 | } |
porizou | 0:e82b1532eec5 | 302 | else if( uvw[i].mode == 3 ) { // モードが3のとき、Tonの状態をつくる |
porizou | 0:e82b1532eec5 | 303 | // T3[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 304 | pwm[i].attach_us(this, &ThreePhasePWM::PwmWout, uvw[i].upper_us); |
porizou | 0:e82b1532eec5 | 305 | |
porizou | 1:209637768493 | 306 | pwm_upper_W = 1; // 上アームWuをオン |
porizou | 1:209637768493 | 307 | pwm_lower_W = 0; // 下アームWdをオフ |
porizou | 0:e82b1532eec5 | 308 | } |
porizou | 0:e82b1532eec5 | 309 | else if( uvw[i].mode == 4 ) { // モードが4のとき、デッドタイムをつくる |
porizou | 0:e82b1532eec5 | 310 | // Tdt[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 311 | pwm[i].attach_us(this, &ThreePhasePWM::PwmWout, DeadTime_); |
porizou | 0:e82b1532eec5 | 312 | |
porizou | 1:209637768493 | 313 | pwm_upper_W = 0; // 上アームWuをオフ |
porizou | 1:209637768493 | 314 | pwm_lower_W = 0; // 下アームWdをオフ |
porizou | 0:e82b1532eec5 | 315 | } |
porizou | 0:e82b1532eec5 | 316 | else { // モードが5のとき、Toffの状態をつくる |
porizou | 0:e82b1532eec5 | 317 | // T5(=T1)[μs]経過してからタイムアウトでこの関数自身をコール |
porizou | 0:e82b1532eec5 | 318 | pwm[i].attach_us(this, &ThreePhasePWM::PwmWout, uvw[i].lower_us); |
porizou | 0:e82b1532eec5 | 319 | |
porizou | 1:209637768493 | 320 | pwm_upper_W = 0; // 上アームWuをオフ |
porizou | 1:209637768493 | 321 | pwm_lower_W = 1; // 下アームWdをオン |
porizou | 0:e82b1532eec5 | 322 | |
porizou | 0:e82b1532eec5 | 323 | uvw[i].mode = 0; // チョッピングのオンオフを決定するモードを0にする |
porizou | 0:e82b1532eec5 | 324 | } |
porizou | 0:e82b1532eec5 | 325 | } |
porizou | 0:e82b1532eec5 | 326 | #endif |
porizou | 0:e82b1532eec5 | 327 | |
porizou | 0:e82b1532eec5 | 328 | |
porizou | 0:e82b1532eec5 | 329 | |
porizou | 0:e82b1532eec5 | 330 | void ThreePhasePWM::startPWM(void) { |
porizou | 0:e82b1532eec5 | 331 | |
porizou | 0:e82b1532eec5 | 332 | for (int i = 0; i < 3; i++) { |
porizou | 0:e82b1532eec5 | 333 | uvw[i].duty = 0.5; // 0.5のときにVu=0[V] |
porizou | 0:e82b1532eec5 | 334 | uvw[i].mode = 0; // チョッピングのオンオフを決定するモードを初期化 |
porizou | 0:e82b1532eec5 | 335 | } |
porizou | 0:e82b1532eec5 | 336 | |
porizou | 0:e82b1532eec5 | 337 | //PWM 出力開始 |
porizou | 0:e82b1532eec5 | 338 | PwmUout(); |
porizou | 0:e82b1532eec5 | 339 | PwmVout(); |
porizou | 0:e82b1532eec5 | 340 | PwmWout(); |
porizou | 0:e82b1532eec5 | 341 | } |
porizou | 0:e82b1532eec5 | 342 | |
porizou | 0:e82b1532eec5 | 343 | void ThreePhasePWM::stopPWM(void) { |
porizou | 0:e82b1532eec5 | 344 | for(int i = 0; i < 3; i++) { |
porizou | 0:e82b1532eec5 | 345 | uvw[i].mode = 0; |
porizou | 0:e82b1532eec5 | 346 | pwm[i].detach(); //タイマー割り込みを停止 |
porizou | 0:e82b1532eec5 | 347 | } |
porizou | 0:e82b1532eec5 | 348 | pwm_upper_U = 0; |
porizou | 0:e82b1532eec5 | 349 | pwm_upper_V = 0; |
porizou | 0:e82b1532eec5 | 350 | pwm_upper_W = 0; |
porizou | 0:e82b1532eec5 | 351 | pwm_lower_U = 0; |
porizou | 0:e82b1532eec5 | 352 | pwm_lower_V = 0; |
porizou | 0:e82b1532eec5 | 353 | pwm_lower_W = 0; |
porizou | 0:e82b1532eec5 | 354 | } |
porizou | 0:e82b1532eec5 | 355 | |
porizou | 0:e82b1532eec5 | 356 | |
porizou | 0:e82b1532eec5 | 357 | |
porizou | 0:e82b1532eec5 | 358 | void ThreePhasePWM::setU(float duty_u) { |
porizou | 0:e82b1532eec5 | 359 | uvw[0].duty = duty_u; |
porizou | 0:e82b1532eec5 | 360 | } |
porizou | 0:e82b1532eec5 | 361 | |
porizou | 0:e82b1532eec5 | 362 | void ThreePhasePWM::setV(float duty_v) { |
porizou | 0:e82b1532eec5 | 363 | uvw[1].duty = duty_v; |
porizou | 0:e82b1532eec5 | 364 | } |
porizou | 0:e82b1532eec5 | 365 | |
porizou | 0:e82b1532eec5 | 366 | void ThreePhasePWM::setW(float duty_w) { |
porizou | 0:e82b1532eec5 | 367 | uvw[2].duty = duty_w; |
porizou | 0:e82b1532eec5 | 368 | } |
porizou | 0:e82b1532eec5 | 369 | |
porizou | 0:e82b1532eec5 | 370 | void ThreePhasePWM::setUVW(float duty_u, float duty_v, float duty_w) { |
porizou | 0:e82b1532eec5 | 371 | uvw[0].duty = duty_u; |
porizou | 0:e82b1532eec5 | 372 | uvw[1].duty = duty_v; |
porizou | 0:e82b1532eec5 | 373 | uvw[2].duty = duty_w; |
porizou | 0:e82b1532eec5 | 374 | } |
porizou | 0:e82b1532eec5 | 375 | |
porizou | 0:e82b1532eec5 | 376 |