Keiju Nakano
/
mbed1114_shakehands_host_DirectRegisterPWM
うごく
Diff: main.cpp
- 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; +}