LPC810メモ:MRT(Lチカ)

Multi-Rate Timer (MRT)を試す。指定した時間経過で割り込みを発生させる機能らしい。

前提とする環境はこちら→LPC810メモ 共通の準備

サンプルコード

#include "LPC8xx.h"

// msミリ秒待つ、という関数をMRTを使って定義してみる
volatile bool waiting = false;
void wait_ms(uint32_t ms) {
    // 待ち中。
    waiting = true;

    // 割り込み発生させる周期を設定
    // 最後に最上位bitを立ててるのは、強制的にこの値をreloadするため。
    // UM10601 11.6.1 Time interval register
    LPC_MRT->Channel[0].INTVAL = (12000000 / 1000) * ms; // 12MHzなのでこれでmsミリ秒分
    LPC_MRT->Channel[0].INTVAL |= 0x1UL<<31;
    // なお現在のカウンタ値はLPC_MRT->Channel[0].TIMER(の31bit目まで)で読める模様

    // 下で定義しているMRTの割り込みによりwaitingがクリアされるのを待つ
    while(waiting) {};
}

extern "C" {
    // MRT割り込み用のハンドラを定義
    // 関数名はcr_startup_lpc8xx.cの中で定義されているもの
    void MRT_IRQHandler(void) {

        // status registerをチェック。
        // 1bit目が立ってれば、その番号のMRTで割り込みがあった
        // UM10601 11.6.4 Status register
        if ( LPC_MRT->Channel[0].STAT & 0x1) {

            // 同じbitに1を書き込むことで割り込みを処理したことを伝える
            LPC_MRT->Channel[0].STAT = 0x1;

            // waitingフラグをクリア
            waiting = false;
        }
        return;
    }
}

int main(void) {
    // GPIOに対してclockを有効化
    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);

    // PIO0_0(すなわち8番のpin)をoutputに設定
    LPC_GPIO_PORT->DIR0 |= (1<<0);

    // MRTに対してclockを有効化、
    // UM10601 11.3 Basic configuration
    // In the SYSAHBCLKCTRL register, set bit 10 (Table 30) to
    // enable the clock to the register interface.
    LPC_SYSCON->SYSAHBCLKCTRL |= (0x1<<10);

    // UM10601 11.3 Basic configuration
    // Clear the MRT reset using the PRESETCTRL register (Table 19).
    LPC_SYSCON->PRESETCTRL &= ~(0x1<<7);
    LPC_SYSCON->PRESETCTRL |= (0x1<<7);

    // The global MRT interrupt is connected to interrupt #10 in the NVIC.
    // 以下にしたがって設定
    // UM10601 3.4.1 Interrupt Set Enable Register 0 register
    NVIC->ISER[0] = (0x1 << 10);

    // One-shot interrupt modeにする
    // UM10601 11.6.3 Control register
    // [0]なのは、MRTは0-3の4本使えるから。
    LPC_MRT->Channel[0].CTRL = (0x01 << 1) | (0x1);
    // Repeat interrupt modeにしたければ、単純に0x1のはず

    // LED点滅
    while(1) {
        // PIO0_0の出力をtoggle
        LPC_GPIO_PORT->NOT0 |= (1<<0);

        // 上でMRTを使って用意した関数を使って待つ
        wait_ms(250);
    }
    return 0 ;
}

接続

これと同じなので略。

補足/雑感

  • 今度はタイマなので、10回点滅でちょど5秒。
  • 割込のハンドラ作る時に、extern "C" を忘れてハマった。

みっかぼの無料Androidアプリはこちら。