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();
}