analogInでとった値をpwmにセットしてpwmoutputする。 pwmDutyを変化させたいときは割り込みONにして割り込みハンドラ内でdutyセットするとガンガン更新しても更新時に停波しない

Dependencies:   mbed

Revision:
0:9fa317215b7b
Child:
1:efe01e5b6f28
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri May 08 02:33:57 2015 +0000
@@ -0,0 +1,205 @@
+#include "mbed.h"
+
+// Reuse initialization code from the mbed library
+DigitalOut PIO0_8(dp1); // P1_18
+AnalogIn Speed(dp13);
+Serial uP(dp16, dp15);
+
+//dp24pwm初期化関数プロトタイプ宣言
+void CT32B0_MAT2_PWM_registerSet(unsigned int );
+//dp24pwmdutyセット関数プロトタイプ宣言
+void CT32B0_MAT2_PWM_dutySet(unsigned int , unsigned int);
+
+//グローバル変数宣言
+    //dp24pwmDuty
+    unsigned int dp24pwmDuty = 0;
+    //dp24pwmFrequency
+    unsigned int dp24pwmFrequency = 0;
+
+//割り込みハンドラ(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_MAT2に対応したマッチレジスタアドレス
+    volatile unsigned int *TMR32B0MR2 = (unsigned int *)(0x40014020);
+    //ゼロの時はレジスタへセットする値に+1してカウンタよりマッチレジスタが大きくなるようにする
+    if(dp24pwmDuty == 0) {
+        *TMR32B0MR2 = (((48000000 / dp24pwmFrequency) / 1024)*(1024 - dp24pwmDuty + 1));
+    }else{
+        //デューティセット
+        *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()
+{
+    //割り込み設定
+    //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);
+    //LEDチカチカ
+    //後ろから8bit目まで1を送る(たぶんそこがp0_8のビット位置)
+    unsigned int mask_pin8 = 1 << 8;
+    //レジスタ位置。メモリ上にあるのでポインタでアクセスできるぽい
+    volatile unsigned int *GPIO0DATA = (unsigned int *)(0x50000000 + 0x3FFC );
+    uP.baud(9600);
+
+    //PWM周波数
+    dp24pwmFrequency = 60;
+    //dp24pwm初期化
+    CT32B0_MAT2_PWM_registerSet(dp24pwmFrequency);
+
+    int val = 0;
+    int sval = 0;
+/*********************************************************************************/
+    while (true) {
+        //LED1点灯
+        *GPIO0DATA |= mask_pin8;
+        val = (Speed.read_u16()>>6);
+        //グローバルdp24pwmDutyセット
+        dp24pwmDuty = val;
+        if(val != sval) {
+            sval = val;
+            //pwm周波数設定用マッチレジスタの動作をタイマークリアから割り込み発生へ変更
+            //マッチ制御レジスタアドレス
+            volatile unsigned int *TMR32B0MCR = (unsigned int *)(0x40014014);
+            //マッチ制御レジスタマスク
+            //マッチレジスタMR3とのマッチで割り込みが発生するように機能切り替え//マッチでのクリアは停止
+            unsigned int mask_TMR32B0MCR = 1 << 9;
+            //マッチ制御レジスタセット
+            *TMR32B0MCR = mask_TMR32B0MCR;
+
+
+        }
+        uP.printf("val = %04d\n",val);
+        //dp24pwm出力をセット
+        //CT32B0_MAT2_PWM_dutySet(dp24pwmFrequency,val);
+
+
+    }
+/**************************************************************************************/
+}
+
+/***********************************************************************************************************/
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+void CT32B0_MAT2_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_1 = 1 << 1;
+    //タイマ制御レジスタマスク
+    //0ビット目を1にしてタイマ、プリスケールカウンタをイネーブルへ
+    unsigned int mask_TMR32B0TCR = 1;
+    //プリスケールレジスタマスク
+    unsigned int val_TMR32B0PR = 0;
+    //マッチ制御レジスタマスク
+    //0~3番のマッチレジスタの、PWM出力ピンにしたい番号以外のどれか1つをタイマ・カウンタ(TC)リセット用に設定する
+    //残りのマッチレジスタはディスエーブルにする
+    //mbedのピン配列ではタイマ0は3番をTCリセットに使うといいかも
+    unsigned int mask_TMR32B0MCR = 1 << 10;
+    //PWM制御レジスタマスク
+    //1つのタイマブロックで同時に、異なるデューティで動作できるPWMは3つまで
+    //CT32Bn_MATxピンの、TCリセットに使っていない番号のどれをPWMピンにするか選択して、ビットを1にする
+    //mbedではMAT2がpwmOutになってる
+    unsigned int mask_TMR32B0PWMC = 1 << 2;
+    //マッチレジスタ値
+    //・マッチ制御レジスタでTCリセット用に設定したマッチレジスタに、周期を設定する
+    // ((48*10^6)/nHz)で任意の周波数になる、はずである
+    //・マッチ制御レジスタでTCリセット用に設定しなかったマッチレジスタで、PWM出力ピンにする番号のマッチレジスタにパルス長を設定する
+    // ここでいうパルス長は、LOWレベルの長さになる。 0で常にHIGH,TCリセット値より大きいと常にLOW,TCリセット値と等しい場合は完全にはLOWにならない
+    unsigned int val_TMR32B0MR3 = /*10;*/((48000000) / (pwmFrequency));
+    unsigned int val_TMR32B0MR2 = /*8;*/((48000000) / (pwmFrequency)) + 1;
+
+    //システムAHBクロック制御レジスタアドレス
+    volatile unsigned int *SYSAHBCLKCTRLLocal = (unsigned int *)0x40048080;
+    //IO設定レジスタアドレス
+    //volatile unsigned int *IOCON_PIO0_1Local = (unsigned int *)0x40044010;
+    //プリスケールレジスタアドレス
+    volatile unsigned int *TMR32B0PRLocal = (unsigned int *)0x4001400C;
+    //タイマ制御レジスタアドレス
+    volatile unsigned int *TMR32B0TCR = (unsigned int *)(0x40014004);
+    //マッチ制御レジスタアドレス
+    volatile unsigned int *TMR32B0MCR = (unsigned int *)(0x40014014);
+    //マッチレジスタ2アドレス
+    volatile unsigned int *TMR32B0MR2 = (unsigned int *)(0x40014020);
+    //マッチレジスタ3アドレス
+    volatile unsigned int *TMR32B0MR3 = (unsigned int *)(0x40014024);
+    //PWM制御レジスタアドレス
+    volatile unsigned int *TMR32B0PWMC = (unsigned int *)(0x40014074);
+
+    //PWM機能制御レジスタセット
+    //システムAHBクロック制御レジスタセット
+    *SYSAHBCLKCTRLLocal |= mask_SYSAHBCLKCTRL;
+    //IO設定レジスタセット
+    //*IOCON_PIO0_1Local |= mask_IOCON_PIO0_1;
+    //プリスケーラレジスタセット
+    *TMR32B0PRLocal = val_TMR32B0PR;
+    //PWM制御レジスタセット
+    *TMR32B0PWMC |= mask_TMR32B0PWMC;
+    //マッチレジスタセット
+    //デフォルト値設定操作
+    //MR3_周波数
+    *TMR32B0MR3 = val_TMR32B0MR3;
+    //MR2_LOWパルス長
+    *TMR32B0MR2 = val_TMR32B0MR2;
+    //マッチ制御レジスタセット
+    *TMR32B0MCR |= mask_TMR32B0MCR;
+    //タイマ制御レジスタセット
+    *TMR32B0TCR |= mask_TMR32B0TCR;
+}
+
+void CT32B0_MAT2_PWM_dutySet(unsigned int pwmFrequency , unsigned int duty)
+{
+    //0~1023もらって0%~100%のpwm出力する
+    //CT32B0_MAT2に対応したマッチレジスタアドレス
+    volatile unsigned int *TMR32B0MR2 = (unsigned int *)(0x40014020);
+    //ゼロの時はレジスタへセットする値に+1してカウンタよりマッチレジスタが大きくなるようにする
+    if(duty == 0) {
+        *TMR32B0MR2 = (((48000000 / pwmFrequency) / 1024)*(1024 - duty + 1));
+        return;
+    }
+    //デューティセット
+    *TMR32B0MR2 = (((48000000 / pwmFrequency) / 1024)*(1024 - duty));
+
+
+}
\ No newline at end of file