LPC1769 タイマー割り込みでPWM | 遥かなるひよこ道
LPCにはPWMユニットが一個あるけどタイマーを使ってPWMによるLED明るさ制御をした。

■PWMの考え方
パルス幅変調のことで、1周期の中でHレベルの幅とLレベルの幅の割合を調整することで電力を制御するというもの。1周期でHレベルの幅が長いほど電力は大きいし、Lレベルの幅が長いほど電力は小さい。

■タイマーの基礎
マイコンのタイマーはシステムのクロックと同期している。
たとえば1kHzのマイコンがあるとする。このマイコンで1000カウントするのにかかる時間は1秒。
プログラムでは1KHzという周波数と1000カウントの二つの数値を指定することで任意のタイミングをつくる。

■プリスケール
マイコンのクロックは非常に高速。LPC1769は120MHzとマイコン屈指の高速駆動であるので速すぎて使いづらい。(1秒で120万数える速さ)そこでプリスケールをする。
プリスケールは分周のことで120MHzを使いやすい周波数まで落とすこと。120MHzであれば1/120して1MHzとするのが多いのではなかろうか。

■マッチレジスタ
タイマーはシステムのクロックに同期してカウントをする。そのカウントがいくつになったらどうするというときの「いくつ」という数字を入れるレジスタがこれ。
そして、カウントがマッチレジスタと同じになった時の動作も設定する。LPCでは以下の3つ
・割り込みを発生させる
・カウントをクリアする
・タイマーを停止する
なので同じになったら割り込みを発生させてカウントをクリアするのが一般的な使い方

■今回のソース
LEDが 明→暗 を繰り返すプログラム

uint32_t TimerInterval, now, mode;
void init_timer ();
void TIMER0_IRQHandler(void);


int main(void) {
TimerInterval = 1024;
init_timer();
LPC_GPIO0->FIODIR |= 1 << 22;
int i;
while(1) {
LPC_TIM0->MR0 = now = (now + 20) & 1023;;//Hレベル幅を変更
for(i = 0; i < 100000; i++);//ちょっと待ち
}
return 0 ;
}

void init_timer ()
{
LPC_TIM0->PR = 300; //プリスケール 120MHz / 200 = 600kHz
LPC_TIM0->MR0 = now; //Hレベル幅
LPC_TIM0->MR1 = TimerInterval;//周期
LPC_TIM0->MCR = 1 + 8 + 16; /* MR0で割り込み  MR1で割り込み+カウント初期化 */
NVIC_EnableIRQ(TIMER0_IRQn);//割り込み登録
LPC_TIM0->TCR = 1;//タイマースタート
}
void TIMER0_IRQHandler(void){
  LPC_TIM0->IR = 0xff;//割り込みフラグ初期化
//■LED切り替え処理
  if(mode == 0) LPC_GPIO0->FIOCLR = 1 << 22;
  else LPC_GPIO0->FIOSET = 1 << 22;
    mode = ~mode;
}