うごく

Dependencies:   mbed

Revision:
0:9a0a89ffaa43
Child:
1:f50a49407c60
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri May 08 15:44:13 2015 +0000
@@ -0,0 +1,392 @@
+
+#include <mbed.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+//文字列受信関数プロトタイプ宣言
+int stringReceive();
+//float cramp関数プロトタイプ宣言
+int cramp(int,int,int);
+//serialハードウェアバッファクリア関数プロトタイプ宣言
+void bufferClear ();
+
+//dp4pwm初期化関数プロトタイプ宣言
+void CT32B0_MAT3_PWM_registerSet(unsigned int );
+//グローバル変数宣言
+//dp4pwmDuty
+unsigned int dp4pwmDuty = 0;
+//dp4pwmFrequency
+unsigned int dp4pwmFrequency = 0;
+
+
+DigitalOut myled(LED1);
+
+//シリアル初期化
+Serial sensSerial (dp16, dp15);
+/*
+//I2C初期化
+I2C i2c(dp5 , dp27 ); //sda scl
+const int addr = 0x20 << 1; // I2C address
+*/
+
+//割り込みハンドラ(PICでいうISRのこと)
+void TIMER32_0_IRQHandler(void)
+{
+    //タイマー操作
+    //タイマリセット→保持
+    //タイマ制御レジスタアドレス
+    volatile unsigned int *TMR32B0TCRLocal = (unsigned int *)0x40014004;
+    //1ビット目を1にしてタイマリセット
+    unsigned int mask_TMR32B0TCR = 1 << 1;
+    //タイマ制御レジスタセット
+    *TMR32B0TCRLocal |= mask_TMR32B0TCR;
+    /***********************************************************************************/
+    //マッチレジスタセット
+    //新しくセットする値はグローバルで宣言しとく(割り込みハンドラは、引数、戻り値ともに意味を成さない)
+    //0~1023もらって0%~100%のpwm出力する
+    //CT32B0_MAT3に対応したマッチレジスタアドレス
+    volatile unsigned int *TMR32B0MR3 = (unsigned int *)(0x40014024);
+    //デューティセット
+    *TMR32B0MR3 = ((((48000000 / dp4pwmFrequency)/20)*18)+((((48000000 / dp4pwmFrequency)/20)/1024) * (1024 - dp4pwmDuty)));//停波(18ms)+((1ms/1024)*(1024-Duty))
+    //*TMR32B0MR2 = (((48000000 / dp24pwmFrequency) / 1024)*(1024 - dp24pwmDuty));
+    /*******************************************************************************************/
+
+    //タイマリセット解除
+    //タイマ制御レジスタセット
+    *TMR32B0TCRLocal &= ~mask_TMR32B0TCR;
+    /*******************************************************************************************/
+
+    //マッチチャネル0 用の割り込みフラグリセット
+    //割り込みレジスタアドレス
+    volatile unsigned int *TMR32B0IRLocal = (unsigned int *)0x40014000;
+    //0ビット目を1にしてMR0の割り込みフラグをリセット
+    unsigned int mask_TMR32B0IR = 1;
+    //割り込みレジスタセット
+    *TMR32B0IRLocal |= mask_TMR32B0IR;
+
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/*****************************************************************************************************************/
+
+int main()
+{
+    //setup
+    sensSerial.baud(9600);//シリアル通信開く
+    //(switchmbed基板でUSB通信するときは低速に抑えること)
+    myled = 0;
+
+    //割り込み設定
+    //Interrupt Service Routineが書いてある、割り込み時ジャンプ先アドレス設定?
+    NVIC_SetVector(TIMER_32_0_IRQn, (uint32_t)&TIMER32_0_IRQHandler);
+    //割り込みハンドライネーブル
+    NVIC_EnableIRQ(TIMER_32_0_IRQn);
+    //割り込み優先順位設定
+    NVIC_SetPriority(TIMER_32_0_IRQn, 1);
+    //PWM周波数
+    dp4pwmFrequency = 50;
+    //dp4pwm初期化
+    CT32B0_MAT3_PWM_registerSet(dp4pwmFrequency);
+
+    //ESCのセンター感知のため中立サーボ信号を5秒間出力
+    //pwm関係
+    //グローバルdp4pwmDutyセット
+    dp4pwmDuty = (1024 / 2);
+        //pwm周波数設定用マッチレジスタの動作をタイマークリアから割り込み発生へ変更
+        //マッチ制御レジスタアドレス
+        volatile unsigned int *TMR32B0MCR = (unsigned int *)(0x40014014);
+        //マッチ制御レジスタマスク
+        //マッチレジスタMR0とのマッチで割り込みが発生するように機能切り替え//マッチでのクリアは停止される
+        unsigned int mask_TMR32B0MCR = 1;
+        //マッチ制御レジスタセット
+        *TMR32B0MCR = mask_TMR32B0MCR;
+        //待ち
+        wait(5);
+
+    /***************************************************************************/
+    //mainloop
+    while(1) {
+        int receiveVal = 0;
+        static int sReceiveVal = 0;
+        int gain = 10;
+        receiveVal = stringReceive();
+
+
+        if(receiveVal >= 0) {
+            myled = !myled;
+
+            //pwm関係
+            //グローバルdp4pwmDutyセット
+            dp4pwmDuty = cramp((( receiveVal*gain ) - (((1023*gain)/2)-(1023/2)) ),0,1023);
+            //dp24pwmDuty = cramp((( receiveVal*gain ) - (((1023*gain)/2)-(1023/2)) - (512 - 76) ),51,102);
+            //dp24pwmDuty = receiveVal;
+
+            if(receiveVal != sReceiveVal) {
+                sReceiveVal = receiveVal;
+                //pwm周波数設定用マッチレジスタの動作をタイマークリアから割り込み発生へ変更
+                //マッチ制御レジスタアドレス
+                volatile unsigned int *TMR32B0MCR = (unsigned int *)(0x40014014);
+                //マッチ制御レジスタマスク
+                //マッチレジスタMR0とのマッチで割り込みが発生するように機能切り替え//マッチでのクリアは停止される
+                unsigned int mask_TMR32B0MCR = 1;
+                //マッチ制御レジスタセット
+                *TMR32B0MCR = mask_TMR32B0MCR;
+            }
+            /*
+            //I2C送信
+            char cmd[10] = {'\0'};//I2C送信バッファ
+            //int to asic2(sprintf関数)
+            sprintf(cmd ,"%4d",dp4pwmDuty);//格納する配列アドレス , 書式文字列
+            //null終端
+            cmd[sizeof(cmd) - 1] = '\0'; // NULL 終端する
+            //書き出し
+            i2c.write(addr, cmd, 7);
+            */
+        }
+
+    }
+    /****************************************************************************/
+
+}
+
+/*****************************************************************************************************************/
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+//受信関数
+//受信完了時0~4095
+int stringReceive()
+{
+    //各種定数
+    //正常なデータ長,書き込み位置大きくなりすぎていないかチェック用
+    const int dataLength = 7;//7個(6個のデータ+null終端)(添字は0~ 宣言時の大きさは1~)(添字の位置確認時は-1する)
+    //startbitに使用する文字
+    char startbitChar = '*';
+    //stopbitに使用する文字
+    char stopbitChar = '#';
+    //各種変数
+    //現在書き込むべきバッファの位置変数
+    static int stringPosition = 0;
+    //受信値一時格納変数
+    char receiveChar = '\0';
+    //受信データ格納バッファ文字列
+    static char receiveDataString [dataLength] = {'\0'};//7個
+
+
+    //データ送信要求
+    sensSerial.putc('C');
+    //ハードウェアバッファに到着した情報があるか
+    //空ならリターン、あるなら受信値格納用変数にうつす
+    if(!sensSerial.readable()) {
+        //空のとき
+        return -1;
+    } else { //あるとき
+        receiveChar = sensSerial.getc();
+    }
+    //バッファ書き込み位置変数が大きくなりすぎている
+    //(ストップビットがくるはずがきてない)ときリターン
+    if(stringPosition > (dataLength - 2)) {
+        stringPosition = 0;
+        //ハードウェアバッファクリア
+        bufferClear();
+        return -2;
+    }
+
+    //到着していたデータがスタートビットだった場合
+    if(receiveChar == startbitChar) {
+
+        //バッファクリア
+        for (int i = 0; i < dataLength; i++) { //配列の要素は0~ 大きさは1~
+            receiveDataString[i] = '\0';
+        }
+        //書き込み位置変数クリア
+        stringPosition = 0;
+        //バッファへ書き込み
+        receiveDataString[stringPosition] = receiveChar ;
+
+
+        //書き込み位置進め
+        stringPosition ++;
+        //-1リターン
+        return -3;
+    }
+
+    //到着していたデータが数字だった場合
+    if(receiveChar=='0'||receiveChar=='1'||receiveChar=='2'||receiveChar=='3'||receiveChar=='4'||receiveChar=='5'||receiveChar=='6'||receiveChar=='7'||receiveChar=='8'||receiveChar=='9') {
+        //バッファへ書き込み
+        receiveDataString[stringPosition] = receiveChar ;
+
+        //書き込み位置進め
+        stringPosition++;
+        //-1リターン
+        return -4;
+    }
+
+    //到着していたデータがストップビットだった場合
+    if(receiveChar == stopbitChar) {
+        //使う変数宣言
+        //バッファ内容をコピーするための文字列
+        char copyString [dataLength] = {'\0'};
+        //スタート、ストップビットをトリムしたデータだけの文字列
+        char trimString [dataLength] = {'\0'};
+        //文字列→数値変換後の値を格納する変数
+        int intVal = 0;
+
+        //バッファへ書き込み
+        receiveDataString[stringPosition] = receiveChar ;
+        //null終端
+        copyString[sizeof(copyString) - 1] = '\0'; /* NULL 終端する */
+        receiveDataString[sizeof(receiveDataString) - 1] = '\0';//null終端
+
+
+        //バッファの内容をうつす
+        strlcpy(copyString,receiveDataString,sizeof(copyString));
+        //バッファクリア
+        for (int i = 0; i < dataLength; i++) { //配列の要素は0~ 大きさは1~
+            receiveDataString[i] = '\0';
+        }
+        //ハードウェアバッファクリア
+        bufferClear();
+        //書き込み位置クリア
+        stringPosition = 0;
+
+        //以下チェックとAtoI
+        //先頭がスタートビットになってるか
+        if(!(copyString[0] == startbitChar)) {
+            return -5;
+        }
+        //末尾がストップビットになっているか(配列の最後はnull)
+        if(!(copyString[(dataLength - 2)] == stopbitChar)) {
+            return -6;
+        }
+        //データだけをトリミング
+        //1個目から、後ろから2個目まで*xxxx#(\n)
+        for(int Idx = 1; Idx < (dataLength - 2) ; Idx++) {
+            trimString[(Idx - 1) ] = copyString[Idx];
+        }
+        //null終端
+        trimString[sizeof(trimString) - 1] = '\0'; /* NULL 終端する */
+        //文字列→数値
+        intVal = atoi(trimString);
+        //数値リターン
+        return intVal;
+
+    }
+
+
+    //以上にひっかからなかった異常時
+    //バッファクリア
+    for (int i = 0; i <dataLength; i++) { //配列の要素は0~ 大きさは1~
+        receiveDataString[i] = '\0';
+    }
+    //ハードウェアバッファクリア
+    bufferClear();
+    //書き込み位置クリア
+    stringPosition = 0;
+    //-3リターン
+    return -7;
+}
+
+
+//cramp関数
+int cramp(int val , int min , int max)
+{
+    if(val < min) {
+        return min;
+    }
+    if(val > max) {
+        return max;
+    }
+
+    return val;
+}
+
+//serialハードウェアバッファクリア関数
+void bufferClear()
+{
+    char temp = 0;
+    while(sensSerial.readable()) {
+        temp = sensSerial.getc();
+    }
+    return;
+}
+
+
+
+
+
+
+void CT32B0_MAT3_PWM_registerSet(unsigned int pwmFrequency)
+{
+    //PWM機能設定用
+    //pwmピンのピン機能選択をmbedで行う
+    //PwmOut MAT2(dp24);//CT32B0_MAT2
+    //PWM周波数
+    //unsigned int pwmFrequency = 4;
+    //各種レジスタ設定用ビットマスク
+    //システムAHBクロック制御レジスタマスク
+    unsigned int mask_SYSAHBCLKCTRL = 0x3 << 9;
+    //IO設定レジスタレジスタマスク
+    unsigned int mask_IOCON_PIO0_11 = 0x3;
+    //タイマ制御レジスタマスク
+    //0ビット目を1にしてタイマ、プリスケールカウンタをイネーブルへ
+    unsigned int mask_TMR32B0TCR = 1;
+    //プリスケールレジスタマスク
+    unsigned int val_TMR32B0PR = 0;
+    //マッチ制御レジスタマスク
+    //0~3番のマッチレジスタの、PWM出力ピンにしたい番号以外のどれか1つをタイマ・カウンタ(TC)リセット用に設定する
+    //残りのマッチレジスタはディスエーブルにする
+    //mbedのピン配列ではタイマ0は0番をTCリセットに使うといいかも
+    unsigned int mask_TMR32B0MCR = 1 << 1;
+    //PWM制御レジスタマスク
+    //1つのタイマブロックで同時に、異なるデューティで動作できるPWMは3つまで
+    //CT32Bn_MATxピンの、TCリセットに使っていない番号のどれをPWMピンにするか選択して、ビットを1にする
+    //mbedではMAT2がpwmOutになってるがISPモードに使用しているので、dp4-MAT3を試す
+    unsigned int mask_TMR32B0PWMC = 1 << 3;
+    //マッチレジスタ値
+    //・マッチ制御レジスタでTCリセット用に設定したマッチレジスタに、周期を設定する
+    // ((48*10^6)/nHz)で任意の周波数になる、はずである
+    //・マッチ制御レジスタでTCリセット用に設定しなかったマッチレジスタで、PWM出力ピンにする番号のマッチレジスタにパルス長を設定する
+    // ここでいうパルス長は、LOWレベルの長さになる。 0で常にHIGH,TCリセット値より大きいと常にLOW,TCリセット値と等しい場合は完全にはLOWにならない
+    unsigned int val_TMR32B0MR0 = /*10;*/((48000000) / (pwmFrequency));
+    unsigned int val_TMR32B0MR3 = /*8;*/((48000000) / (pwmFrequency)) + 1;
+
+    //システムAHBクロック制御レジスタアドレス
+    volatile unsigned int *SYSAHBCLKCTRLLocal = (unsigned int *)0x40048080;
+    //IO設定レジスタアドレス
+    volatile unsigned int *IOCON_PIO0_11Local = (unsigned int *)0x40044074;
+    //プリスケールレジスタアドレス
+    volatile unsigned int *TMR32B0PRLocal = (unsigned int *)0x4001400C;
+    //タイマ制御レジスタアドレス
+    volatile unsigned int *TMR32B0TCR = (unsigned int *)(0x40014004);
+    //マッチ制御レジスタアドレス
+    volatile unsigned int *TMR32B0MCR = (unsigned int *)(0x40014014);
+    //マッチレジスタ0アドレス
+    volatile unsigned int *TMR32B0MR0 = (unsigned int *)(0x40014018);
+    //マッチレジスタ3アドレス
+    volatile unsigned int *TMR32B0MR3 = (unsigned int *)(0x40014024);
+    //PWM制御レジスタアドレス
+    volatile unsigned int *TMR32B0PWMC = (unsigned int *)(0x40014074);
+
+    //PWM機能制御レジスタセット
+    //システムAHBクロック制御レジスタセット
+    *SYSAHBCLKCTRLLocal |= mask_SYSAHBCLKCTRL;
+    //IO設定レジスタセット
+    *IOCON_PIO0_11Local |= mask_IOCON_PIO0_11;
+    //プリスケーラレジスタセット
+    *TMR32B0PRLocal = val_TMR32B0PR;
+    //PWM制御レジスタセット
+    *TMR32B0PWMC |= mask_TMR32B0PWMC;
+    //マッチレジスタセット
+    //デフォルト値設定操作
+    //MR0_周波数
+    *TMR32B0MR0 = val_TMR32B0MR0;
+    //MR3_LOWパルス長
+    *TMR32B0MR3 = val_TMR32B0MR3;
+    //マッチ制御レジスタセット
+    *TMR32B0MCR |= mask_TMR32B0MCR;
+    //タイマ制御レジスタセット
+    *TMR32B0TCR |= mask_TMR32B0TCR;
+}