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

Dependencies:   mbed

main.cpp

Committer:
maxonK
Date:
2016-03-22
Revision:
1:efe01e5b6f28
Parent:
0:9fa317215b7b

File content as of revision 1:efe01e5b6f28:

#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_MAT3_PWM_registerSet(unsigned int );

//グローバル変数宣言
//dp24pwmDuty
unsigned int dp4pwmDuty = 0;
//dp24pwmFrequency
unsigned int dp4pwmFrequency = 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_MAT3に対応したマッチレジスタアドレス
    volatile unsigned int *TMR32B0MR3 = (unsigned int *)(0x40014024);
    //ゼロの時はレジスタへセットする値に+1してカウンタよりマッチレジスタが大きくなるようにする
    if(dp4pwmDuty == 0) {
        *TMR32B0MR3 = (((48000000 / dp4pwmFrequency) / 1024)*(1024 - dp4pwmDuty + 1));
    } else {
        //デューティセット
        *TMR32B0MR3 = (((48000000 / dp4pwmFrequency) / 1024)*(1024 - dp4pwmDuty));
    }
    /*******************************************************************************************/

    //タイマリセット解除
    //タイマ制御レジスタセット
    *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周波数
    dp4pwmFrequency = 60;
    //dp4pwm初期化
    CT32B0_MAT3_PWM_registerSet(dp4pwmFrequency);

    int val = 0;
    int sval = 0;
    /*********************************************************************************/
    while (true) {
        //LED1点灯
        *GPIO0DATA |= mask_pin8;
        val = (Speed.read_u16()>>6);
        //グローバルdp4pwmDutyセット
        dp4pwmDuty = val;
        if(val != sval) {
            sval = val;
            //pwm周波数設定用マッチレジスタの動作をタイマークリアから割り込み発生へ変更
            //マッチ制御レジスタアドレス
            volatile unsigned int *TMR32B0MCR = (unsigned int *)(0x40014014);
            //マッチ制御レジスタマスク
            //マッチレジスタMR0とのマッチで割り込みが発生するように機能切り替え//マッチでのクリアは停止される
            unsigned int mask_TMR32B0MCR = 1;
            //マッチ制御レジスタセット
            *TMR32B0MCR = mask_TMR32B0MCR;


        }


    }
    /**************************************************************************************/
}

/***********************************************************************************************************/
/////////////////////////////////////////////////////////////////////////////////////////////////////////////

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;
}