NUCLEOのキットを使った秒針
Diff: main.cpp
- Revision:
- 0:a1180efb20e0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Mar 22 22:52:08 2016 +0000 @@ -0,0 +1,160 @@ +/************************************************* +"Nucleo_motor_control" +Nucleo Pack + マイコンボード NUCLEO-F302R8 + 拡張ボード X-NUCLEO-IHM07M1 + モーター BR2804-1700KV-1 +を使ったモーター制御の実験 + +アナログPWM版 秒針仕様 + Copyright(C) 2016 Columbus-seiki + + 2016-02-22 Rev0 + +***************************************************/ +#include "mbed.h" +#include "main.h" + +#define POLE_PAIR 7//モーターの磁極対数 +#define PERIOD_TIMER 0.005 //タイマー周期(S) +#define SINTBL_LENGTH 512 //sinTbl[]要素数 +#define PERIOD_PWM 0.0002 //PWM周期(S) これ以下では ヒゲ がでる +#define HALF_PWM (PERIOD_PWM / 2) //PWM周期の真ん中 PERIOD_PWM÷2 +#define DEG360 1024 //360°相当 +#define DEG120 341 //120° +#define DEG240 682 //240° + +//入出力ピンを定義 +DigitalIn mybutton(USER_BUTTON); +//Serial pc(PA_2, PA_3); //USB/COM パソコンの仮想シリアルポートへ。ここでは使いません +DigitalOut ld2(PB_13); //LD2 グリーンLED +DigitalOut d11(PB_2); //D11 パワボード赤LED + +//pwm出力の定義 +PwmOut pwmU(PA_8), pwmV(PA_9), pwmW(PA_10);//それぞれUH_PWM, VH_PWM, WH_PWM + +//IOの定義 +DigitalOut enableU(PC_10), enableV(PC_11), enableW(PC_12);//それぞれEnable_CH1-L6230, _CH2-, _CH3- + +//アナログ入力の定義 +AnalogIn ain(PB_1);//R42 POTENTIOPOTENTIOMETER + +//タイマーの定義 +Ticker myTimer;//繰返しタイマー + +//変数 +int preMybutton; //記憶 +int enablePWM=0;//PWM開始と停止フラグ +//int scope[100];//モニター用バッファ +int count, loopCount=0; //カウンター +double outDuty=0 ,outU, outV, outW; //PWM出力デューティー +float theta, omega; //角度と角速度 +int timePerRound=60; //1回転時間(S) + +/********************************** + sin関数 + 引数:最大1024=360° + 出力:最大512=1.0 +***********************************/ +int mySin(int angleNum) +{ + + angleNum &= 0x3ff; //0x3ff=1023 でマスク + if(angleNum >= 512) //180~360° + return -sinTbl[angleNum - 512]; + else //0~180° + return sinTbl[angleNum]; +} + + +/********************************** + タイマー割込み関数 5mS +***********************************/ +void myTimerCallBack() //全相をONにする +{ + outDuty = 0.2; //最大1.0 出力電圧を調整します + + theta += omega; //増加分 + if(theta >= 1024) //360°オーバーフローを防止 + theta -= 1024; + else if(theta <= -1024) + theta += 1024; + + pwmU.pulsewidth(HALF_PWM + outDuty * mySin((int)theta & 0x3ff) / 512.0 * HALF_PWM); + pwmV.pulsewidth(HALF_PWM + outDuty * mySin(((int)theta - DEG120) & 0x3ff) / 512.0 * HALF_PWM); + pwmW.pulsewidth(HALF_PWM + outDuty * mySin(((int)theta - DEG240) & 0x3ff) / 512.0 * HALF_PWM); + + //サイクルカウンター処理(同期) + count++; + if( count == 100) { + count = 0; + loopCount = 1; //loopの同期用 5mS X 100 = 0.5S + } + +} +/*********************************** + +************************************/ +int main() +{ + + //pwmデューティー 初期値 + outU = 0; + outV = 0; + outW = 0; + + //PWM設定 + pwmU.period(PERIOD_PWM);//0.2mS 5KHz + pwmV.period(PERIOD_PWM); + pwmW.period(PERIOD_PWM); + + //タイマー設定 + myTimer.attach(&myTimerCallBack, PERIOD_TIMER);//5mS毎にmyTimerCallBack()がコールされます + + + while(1) { + //------ およそ一定周期の処理 ------- + if(loopCount != 0) {//5x100=0.5S + loopCount = 0; + + ld2 = !ld2; //点滅 + d11 = !d11; //パワボード + } + + //-------- 時間に関係しない処理 -------- + //PWM開始と停止 + if((int)mybutton != preMybutton) {//ボタンが押された。チャタリングを考慮していません + preMybutton = (int)mybutton;//次に押されたときのために記憶 + + if(mybutton == 0)//押されたときだけ。 + enablePWM = ~enablePWM;//オルタネート + + //PWM開始 + if(enablePWM) { + enableU = 1;//PWM出力ON. L6230PのENable端子です + enableV = 1; + enableW = 1; + } else { + enableU = 0;//PWM出力OFF. L6230PのENable端子です. PWM出力は止まりません + enableV = 0; + enableW = 0; + } + } //ボタンが押された の終わり + + //速度指定 ポテンショメータをディップスイッチのように処理 + if(ain < 0.3L) //ain=0~1.0 + timePerRound = 60 * 5; //5分時計 ボリューム左一杯 + else if( ain < 0.6L) + timePerRound = 60 * 3; //3分時計 ボリューム中央 + else + timePerRound = 60; //1分時計 ボリューム右一杯 + + //指定の周期を角速度に変換 + omega = PERIOD_TIMER * DEG360 * POLE_PAIR / timePerRound; + + + }//END while(1) + + +} +