3相インバータで3相PWMを生成するためのライブラリです。ブラシレスDCモータの制御に利用できます。

Committer:
porizou
Date:
Fri Jan 26 01:13:45 2018 +0000
Revision:
0:e82b1532eec5
Child:
1:209637768493
3PhasePWM

Who changed what in which revision?

UserRevisionLine numberNew 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 0:e82b1532eec5 170 pwm_upper[i] = 0; // 上アームUuをオフ
porizou 0:e82b1532eec5 171 pwm_lower[i] = 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 0:e82b1532eec5 191 pwm_upper[i] = 0; // 上アームUuをオフ
porizou 0:e82b1532eec5 192 pwm_lower[i] = 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 0:e82b1532eec5 198 pwm_upper[i] = 1; // 上アームUuをオン
porizou 0:e82b1532eec5 199 pwm_lower[i] = 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 0:e82b1532eec5 205 pwm_upper[i] = 0; // 上アームUuをオフ
porizou 0:e82b1532eec5 206 pwm_lower[i] = 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 0:e82b1532eec5 212 pwm_upper[i] = 0; // 上アームUuをオフ
porizou 0:e82b1532eec5 213 pwm_lower[i] = 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 0:e82b1532eec5 224 pwm_upper[i] = 0; // 上アームVuをオフ
porizou 0:e82b1532eec5 225 pwm_lower[i] = 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 0:e82b1532eec5 245 pwm_upper[i] = 0; // 上アームVuをオフ
porizou 0:e82b1532eec5 246 pwm_lower[i] = 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 0:e82b1532eec5 252 pwm_upper[i] = 1; // 上アームVuをオン
porizou 0:e82b1532eec5 253 pwm_lower[i] = 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 0:e82b1532eec5 259 pwm_upper[i] = 0; // 上アームVuをオフ
porizou 0:e82b1532eec5 260 pwm_lower[i] = 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 0:e82b1532eec5 266 pwm_upper[i] = 0; // 上アームVuをオフ
porizou 0:e82b1532eec5 267 pwm_lower[i] = 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 0:e82b1532eec5 278 pwm_upper[i] = 0; // 上アームWuをオフ
porizou 0:e82b1532eec5 279 pwm_lower[i] = 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 0:e82b1532eec5 299 pwm_upper[i] = 0; // 上アームWuをオフ
porizou 0:e82b1532eec5 300 pwm_lower[i] = 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 0:e82b1532eec5 306 pwm_upper[i] = 1; // 上アームWuをオン
porizou 0:e82b1532eec5 307 pwm_lower[i] = 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 0:e82b1532eec5 313 pwm_upper[i] = 0; // 上アームWuをオフ
porizou 0:e82b1532eec5 314 pwm_lower[i] = 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 0:e82b1532eec5 320 pwm_upper[i] = 0; // 上アームWuをオフ
porizou 0:e82b1532eec5 321 pwm_lower[i] = 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