MSP432 Timer


 MSP432には4つの16ビットタイマーと2の32ビットタイマーがあり、CCRが5つ。

CCR(Caputure/Compare register)の略のはず。

Exampleを一つ開いてみる。1秒おきにオンボードのLEDが点滅するという例題。ある意味正確な時間のLチカ。


timer_a_upmode_gpio_toggleを選択しIMPORTする。本家のExampleなのでエラーもでないから、ビルトして書き込みをしてみる。


P1.0に接続されたLEDが点滅

ソースコードを解釈していく

/* Application Defines  */

#define TIMER_PERIOD    0x2DC6

10進数では11718。

const Timer_A_UpModeConfig upConfig =

{

        TIMER_A_CLOCKSOURCE_SMCLK,              // SMCLK Clock Source

        TIMER_A_CLOCKSOURCE_DIVIDER_64,          // SMCLK/1 = 3MHz

        TIMER_PERIOD,                           // 5000 tick period

        TIMER_A_TAIE_INTERRUPT_DISABLE,         // Disable Timer interrupt

        TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE ,    // Enable CCR0 interrupt

        TIMER_A_DO_CLEAR                        // Clear value

};

タイマーの設定。

クロックをSMCLK(デフォルトでは3MHz)

TIMER_A_CLOCKSOURCE_DIVIDER_64:分周率を1/64?

TIMER_PERIOD:この値がCCRに書き込みまれて、カウントしていってこの値を超えるかをみる。16ビット整数は2^16(65536)までの数字。

TIMER_A_TAIE_INTERRUPT_DISABLE:読んで字のごとく、タイマーによるインターラプトをEnableにするか?無効にするか?よくわからない・・・

TIMER_A_DO_CLEAR:リセットしたりした場合にタイマーをクリアーするか?

ほとんどの用途ではクリアしていくはず。しない場合は、TIMER_A_SKIP_CLEAR。


    /* Configuring Timer_A1 for Up Mode */

    MAP_Timer_A_configureUpMode(TIMER_A1_BASE, &upConfig);

タイマーのモードの設定をする。UPModeはカウントが増えていき、目的のカウントになったならゼロに戻ってまたカウントを増やしていく数え方。

ContinuesModeってのもあってこちらもゼロから増えていって目的になったらゼロに戻ってを繰り返す。UPモードとほぼ同じだが、UPMODEは、ゼロ(TAIFG)と目的の値(CCIFG Flag)のところでフラグが立つが、ContinuesModeは目的値のところでCCIFGのフラグだけが立つ。

UpDownModeというのもあって、アップしていき、目的カウントになったらダウンしてゼロまで行くカウント方法。周期が倍になる。

4つあるどのタイマーを使うかはここで、TIMER_A1_BASEの部分で指定する。

    /* Enabling interrupts and starting the timer */

    MAP_Interrupt_enableSleepOnIsrExit();

    MAP_Interrupt_enableInterrupt(INT_TA1_0);

    MAP_Timer_A_startCounter(TIMER_A1_BASE, TIMER_A_UP_MODE);

最初の2行は、タイマーというより、インターラプトの設定。インターラプト中MPUを低消費電力化のためにスリープさせる命令で、2行目は、タイマー1のインターラプトを許容して、カウントが完了したらIRQへ飛ぶようにしている。

MAP_Timer_A_startCounterの部分で、実際にタイマー動作をスタートさせている。

Configの中のTIMER_A_TAIE_INTERRUPT_DISABLEってどんな意味かは現時点では不明TAIEの意味がわかっていない。

void TA1_0_IRQHandler(void)

{

    MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);

    MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A1_BASE,

            TIMER_A_CAPTURECOMPARE_REGISTER_0);

}

TA1のIRQハンドル。タイマーが目的値になったらここに飛んできて、LEDをトグル(ONならOFF、OFFならON)して、CCR0をクリアー(カウントをはじめから)する。

一連の流れはこんなもの。


このサンプルコードで多くの事はできるが、タイマーなので時間に関しては今一度見たい。

TIMER_A_CLOCKSOURCE_SMCLKはデフォルトでは3MHz

DIVIDER_64は意味は1/64にすることと思われる。

3000kHz/64=64.875kHz=64875Hz、64875カウントすると1秒になるはず。

TIMER_PERIODを64875にしてみる。がしかし!1秒よりやや長い。20回点滅するまでの時間を計測したら27秒かかっている・・・

TIMER_A_CLOCKSOURCE_ACLK

に変更してみる。TIMER_A_CLOCKSOURCE_SMCLKの部分を置き換える。ACLKは32.768KHz。DIVIDER_16に設定すると、32768/16=2048Hzになる。2048カウントすると1秒だからここでは、TIMER_PERIOD を1024にしてみる。これだと0.5秒点灯して、0.5秒消灯、点灯が1秒おきに繰り返されることになる。

→この結果はほぼ1秒。20回点滅の時間が20秒に当然なる。

TIMER_A_CLOCKSOURCE_SMCLKでは早い間隔usecとかを測定するならともかく、秒単位でタイマーをやはり動かしたい時は、クロックを適切に選ぶべしということか。

個人的な実験結果です。









コメント

このブログの人気の投稿

Attiny85とAQM0802A(LCD)のI2C接続

ILI9341 240X320 Arduino

Attiny85 FuseRest