Keiju Nakano
/
mbed1114_shakehands_host_DirectRegisterPWM
うごく
main.cpp
- Committer:
- maxonK
- Date:
- 2015-05-08
- Revision:
- 0:9a0a89ffaa43
- Child:
- 1:f50a49407c60
File content as of revision 0:9a0a89ffaa43:
#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; }