DRV8301を使用してブラシレスモーター(BLDC)をパパッと回すために作りました。DRV8301の全機能は使用できていません。会社・学校などで無理やり実験の担当を押し付けられた際にどうぞ。
Dependencies: DRV8301CTRL mbed
main.cpp
- Committer:
- Yajirushi
- Date:
- 2016-08-31
- Revision:
- 1:27f8a06ce16d
- Parent:
- 0:a8f76586ab79
File content as of revision 1:27f8a06ce16d:
#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(); }