エビデイエビナイ電子工作

やったことの記録

LPCマイコンでARM開発 #3 ~割り込み編~

LPC1114FN28は、ARMのCortex-M0というコアを搭載しています。ARM Cortex-Mシリーズのマイコンには、NVIC(Nested Vectored Interrupt Controller) と呼ばれる割り込み専用のコントローラが内蔵されています。

NVICは、割り込みの種類に応じた割り込みハンドラの呼び出し, 複数の割り込みが発生したときの割り込み処理順序の決定, 割り込み処理間の効率化など、割り込みに関する処理を行います。


SysTickタイマを利用したタイマ割り込み

ARMマイコンは、SysTickタイマと呼ばれるペリフェラルを持っています。SysTickタイマは、値をセットしておくとカウントダウンしていくタイマで、タイマの値が0になったとき割り込みを発生させることができます。

この機能を利用して、Lチカプログラムを書いてみます。

#ifdef __USE_CMSIS
#include "LPC11xx.h"
#endif

#include <cr_section_macros.h>

#define LED_DELAY 500

int main(void) {

    /*ポートの初期化*/
    LPC_IOCON->PIO0_7 = 0xd0;

    /*ポートの方向を設定*/
    LPC_GPIO0->DIR |=  (1<<7);

    /*ポートの出力設定*/
    LPC_GPIO0->DATA |= (1<<7);

    /*SysTickタイマの設定*/
    SysTick_Config(SystemCoreClock / 1000);

    while(1);

    return 0 ;
}

/*SysTickタイマ割り込みハンドラ*/
void SysTick_Handler(void){
    static uint16_t cnt = 0;
    cnt++;
    if(cnt >= LED_DELAY){
        LPC_GPIO0->DATA ^= (1<<7);
        cnt = 0;
    }
}

SysTick_Config() は、SysTickタイマに設定する値を指定する関数です。引数として SystemCoreClock(マイコンの動作クロック周波数。デフォルトで48M) を渡すと、48Mの値を48MHzでカウントすることになり、結果として一秒ごとに割り込みが発生します。 今回は SystemCoreClockの値を1000で除算することで、1msごとの割り込みを実現しています。

ディレクトリの cr_startup_lpc11xx.cを見ると、SysTickタイマの割り込みハンドラがSysTick_Handler という名前で定義されています。 これにはWEAKシンボルがついているので、メインのソースファイルで新たに定義して利用することができます。

このプログラムでは、割り込みハンドラ内で値をカウントし、カウントした値がLED_DELAY以上になったとき、つまり500msごとにLEDの出力を反転させています。


動作確認

28番ピン(GPIO0_7ポート) にLEDと抵抗を接続し、動作を確認してみます。

www.youtube.com

きちんと500msごとにLEDが点滅しています。


おわりに

どうやらLPCマイコンではデフォルトでDelay関数が用意されていない(実はあるかもしれない) ようなのでSysTickタイマを使ってLチカしてみました。割り込み編と言っておきながらタイマ割り込みしか試しませんでしたが、他の割り込みについても必要になったら試してみようと思います。


twitter.com