DRV8301を使用してブラシレスモーター(BLDC)をパパッと回すために作りました。DRV8301の全機能は使用できていません。会社・学校などで無理やり実験の担当を押し付けられた際にどうぞ。
Dependencies: DRV8301CTRL mbed
Diff: main.cpp
- Revision:
- 0:a8f76586ab79
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Aug 31 17:03:46 2016 +0000 @@ -0,0 +1,227 @@ +#include "mbed.h" +#include "DRV8301CTRL.h" + +//ユーザーボタン +DigitalIn btn(USER_BUTTON); + +//シリアル通信 +Serial pc(USBTX, USBRX); + +//SPI通信 +SPI spi(D11, D12, D13); + +//DRV8301コントロールクラス +drv8301ctrl DRV(&pc, &spi, D10, D9); +//drv8301ctrl DRV(&spi, D10, D9); + +//PWM(3線式) +PwmOut m1a(D7); +PwmOut m1b(D8); +PwmOut m1c(D2); + +//アナログ読み取り +AnalogIn shunt1(A0); +AnalogIn shunt2(A1); +AnalogIn vbatt(A2); +AnalogIn rvar(A3); + +//PWM疑似正弦波テーブル +unsigned char step1A = 0; +unsigned char step1B = 64; +unsigned char step1C = 128; +const unsigned int sinwave[192] = { + 17, 15, 13, 12, 10, 8, 7, 6, 5, 4, 3, 2, 1, 1, 1, 0, + 0, 0, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 15, + 17, 19, 22, 24, 27, 29, 32, 35, 37, 40, 44, 47, 50, 53, 57, 60, + 64, 67, 71, 75, 79, 82, 86, 90, 94, 98,102,106,110,115,119,123, + 127,131,135,139,144,148,152,156,160,164,168,172,175,179,183,187, + 190,194,197,201,204,207,210,214,217,219,222,225,227,230,232,235, + 237,239,241,242,244,246,247,248,249,250,251,252,253,253,253,254, + 254,254,253,253,253,252,251,250,249,248,247,246,244,242,241,239, + 237,235,232,230,227,225,222,219,217,214,210,207,204,201,197,194, + 190,187,183,179,175,172,168,164,160,156,152,148,144,139,135,131, + 127,123,119,115,110,106,102, 98, 94, 90, 86, 82, 79, 75, 71, 67, + 64, 60, 57, 53, 50, 47, 44, 40, 37, 35, 32, 29, 27, 24, 22, 19 +}; + +//PWM周期(4us = 16KHz) +unsigned int period_us = 4; + +//PWM待ち基準(マイクロ秒)(待ち基準*rvar=PWM待ち時間) +int pwmWait_us = 600; +float pwmWait_cf = 1.0f; +float pwmWait_cf_cf = 0.000001f; + +//タイマー +Ticker pc_timer; + +//タイマー関数 +void out_pc1(){ + //pc.printf( + // "DutyA=%f,DutyB=%f,DutyC=%f,speed=%f,shunt1=%f,shunt2=%f,vbatt=%f\r\n", + // m1a.read(), m1b.read(), m1c.read(), rvar.read(), shunt1.read()*3.3f, shunt2.read()*3.3f, vbatt.read()*61.8f + //); +} +void out_pc2(){ + //pc.printf( + // "DutyA=%f,DutyB=%f,DutyC=%f,pwmWait_us=%05d,shunt1=%f,shunt2=%f,vbatt=%f\r\n", + // m1a.read(), m1b.read(), m1c.read(), pwmWait_us, shunt1.read()*3.3f, shunt2.read()*3.3f, vbatt.read()*61.8f + //); +} +void motor_run1(){ + step1A = (step1A+1) % 192; + step1B = (step1B+1) % 192; + step1C = (step1C+1) % 192; + m1a.write((float)(sinwave[step1A] / 255.0f)); + m1b.write((float)(sinwave[step1B] / 255.0f)); + m1c.write((float)(sinwave[step1C] / 255.0f)); +} +void motor_run2(){ + step1C = (step1C == 0) ? step1C = 191 : (step1C-1) % 192; + step1B = (step1B == 0) ? step1B = 191 : (step1B-1) % 192; + step1A = (step1A == 0) ? step1A = 191 : (step1A-1) % 192; + m1c.write((float)(sinwave[step1C] / 255.0f)); + m1b.write((float)(sinwave[step1B] / 255.0f)); + m1a.write((float)(sinwave[step1A] / 255.0f)); +} + +//メイン +int main(){ + + //シリアル出力 + pc.printf("mbed ready...\r\n"); + m1a.write(0.0); + m1b.write(0.0); + m1c.write(0.0); + + //ボタンが押されるまで待ち続ける + while(btn); + + //ドライバ初期化 + pc.printf("--------init drv8301...\r\n"); + DRV.init(); + + //ドライバの状態を読み取る + pc.printf("--------read status(before settings) drv8301...\r\n"); + DRV.readStatus1(); + DRV.readStatus2(); + DRV.readCtrl1(); + DRV.readCtrl2(); + + //シャントアンプのゲインを80V/Vに + pc.printf("--------set gain 80v/v...\r\n"); + DRV.readCtrl2(); //現在の値を内部変数に読み込み + DRV.setGAIN(3); //内部変数に値をセット(0x11) + DRV.writeCtrl2(); //書き込み(GAINはコントロールレジスタ2) + + //ドライバの状態を読み取る + pc.printf("--------read status(after settings) drv8301...\r\n"); + DRV.readStatus1(); + DRV.readStatus2(); + DRV.readCtrl1(); + DRV.readCtrl2(); + + //set PWM period + pc.printf("--------Set PWM period = %d[us](%f [Hz])...\r\n", period_us, (float)(1e6 / period_us)); + m1a.period_us(period_us); + m1b.period_us(period_us); + m1c.period_us(period_us); + + //ボタンが押されるまで待ち続ける + pc.printf("--------WAITING PUSH BUTTON...\r\n"); + while(btn); + wait(3.0); + + //PCへの送出開始 + pc.printf("--------Running motor!! until push user button...\r\n"); + pc_timer.attach(&out_pc1, 0.15f); + + //PWM送出(ボタンが押されるまで) + do{ + motor_run1(); + wait_us((int)(pwmWait_us * (1.0f - rvar.read()))); + }while(btn); + + //PCへの送出停止 + pc_timer.detach(); + //PWM送出停止 + pc.printf("--------STOP...\r\n"); + m1a.write(0.0); + m1b.write(0.0); + m1c.write(0.0); + wait(3.0); + + //ボタンが押されるまで待ち続ける + pc.printf("--------WAITING PUSH BUTTON...\r\n"); + while(btn); + wait(3.0); + + //PCへの送出開始 + pc.printf("--------Running motor!!(reverse) until push user button...\r\n"); + pc_timer.attach(&out_pc1, 0.15f); + + //PWM送出(ボタンが押されるまで) + do{ + motor_run2(); + wait_us((int)(pwmWait_us * (1.0f - rvar.read()))); + }while(btn); + + //PCへの送出停止 + pc_timer.detach(); + //PWM送出停止 + pc.printf("--------STOP...\r\n"); + m1a.write(0.0); + m1b.write(0.0); + m1c.write(0.0); + wait(3.0); + + + //ドライバの状態を読み取る + pc.printf("--------read status drv8301...\r\n"); + DRV.readStatus1(); + DRV.readStatus2(); + DRV.readCtrl1(); + DRV.readCtrl2(); + + //ボタンが押されるまで待ち続ける + pc.printf("----WAITING PUSH BUTTON !!(before automatic acc/dec sequence)!! ...\r\n"); + while(btn); + wait(3.0); + + //PWM送出(段々加速していく) + pc.printf("--------Running motor!!(automatic acceleration/deceleration)\r\n"); + //PCへの送出開始 + pc_timer.attach(&out_pc2, 0.15f); + do{ + motor_run1(); + wait_us((int)(pwmWait_us *= (pwmWait_cf -= pwmWait_cf_cf))); + }while(pwmWait_us > 2); + + pwmWait_us = (pwmWait_us < 2) ? 2 : pwmWait_us; + pwmWait_cf = (pwmWait_cf < 1.0f) ? 1.00f : pwmWait_cf; + pwmWait_cf_cf = 0.000005f; + + //PWM送出(段々減速していく) + do{ + motor_run1(); + wait_us((int)(pwmWait_us *= (pwmWait_cf += pwmWait_cf_cf))); + }while(pwmWait_us < 300); + + //PCへの送出停止 + pc_timer.detach(); + //減速終了 + pc.printf("--------Running motor!!(end of deceleration)\r\n"); + wait(2.5); + + //出力停止 + pc.printf("--------STOP...\r\n"); + m1a.write(0.0); + m1b.write(0.0); + m1c.write(0.0); + + //ゲートクローズ + DRV.gateDisable(); + + //PCへの送出停止 + pc_timer.detach(); +}