LPC1343 32bit TimerでPWM

出来た事

1.32bit Timerを使ったPWM出力をLEDで確認
2.16bit Timerを使ったPWM出力をLEDで確認

開発Listへ戻る

今日はタイマーを使ってみたいと思います。
タイマーの結果はPWMとして出力しLEDのon-offで動作確認をします。

下の図はユーザーマニュアルからLPC1343のタイマーの構成部分を抜き出したものです。
32bitタイマーが2個,16bitタイマーが2個 計4個のタイマーがあります。

またタイマーだけではなく、
外部信号の立上がり立下りのカウンターとしても使えるようです。
タイマー or カウンターの出力は MAT[3:0]の4本
設定数に達するとHigh,Low,反転やPWM出力などが選べるようです。
外部信号をカウントする場合はCAP0から入力するようです。



今回はCT32B1とCT16B1のタイマーを使い
それぞれのMAT[0]をPWM出力として
LEDをon-offさせます。

構成図からもわかるようにタイマーおよびMAT,CAPは
メインの演算部とは独立した機能ですから設定してしまえば
自動的ににPWMが出ます。


接続図は以下のようになります。

LEDの点灯コントロールは以下のようにします。



タイマーの構成のイメージは以下のようです。

PCLKがタイマーユニットに供給されるクロックです。

LPC_SYSCON->SYSAHBCLKDIV で設定されるクロック周波数です。
通常はこのレジスタは1で、
その場合はLPC1343のSystem clock周波数=72MHzです。

 PCLK= 72MHz / SYSAHBCLKDIV [MHz]です。

これを変更すると他にも影響するので私は72MHzで使います。

PCがプリスケールカウンタです。
PCがPCLKによって設定値までカウントアップしたときにTCが+1され,PCがリセットされます。
(PRレジスタで設定)

たとえばPCLK=72MHzのときにPR=71とすると1MHz周期でTCがカウントアップすることになります。
(PCは0からスタートなので-1する必要がある)

TCがタイマーカウンターです。
TCに関してはリセットするカウント数,割り込みを発生させるカウント数
あわせて4つ設定できます。

MR0〜MR3 がTCのタイミングを設定するレジスタです。

MCRレジスタでMR0-3のどれをリセットにするか、割り込みにするかを設定できます。

今回はPWM出力にします。
MAT0端子を出力にする場合以下のようになります。

MAT0を使う場合はHighに変化するポイントをMR0で指定することが決まっているので
必然的にTCをリセットするカウント数はMR0以外を指定する必要があります。

コードです。

ifdef __USE_CMSIS
#include "LPC13xx.h"
#endif

#include
#include


__CRP const unsigned int CRP_WORD = CRP_NO_CRP ;


int main(void) {
volatile static int i = 0 ; // dummy counter


// 32bit Timer
LPC_SYSCON->SYSAHBCLKCTRL |=0x400; // Timer32B1 Turn ON
LPC_IOCON->JTAG_TDO_PIO1_1 =0x83; // PIO1_1 as 32B1_MAT0
LPC_TMR32B1->PR =72000-1; // 1kHz(Max 32bit dec:4294967295)
LPC_TMR32B1->PWMC |=0x01; // MAT0 as PWM
LPC_TMR32B1->MCR =0x400; // MR3 as Period of 32B1
LPC_TMR32B1->MR0 =1000; // PWM High duration=MR3-MR0
LPC_TMR32B1->MR3 =3000; // PWM Period (Max 32bit dec:4294967295)
LPC_TMR32B1->TCR =2; // TCR Reset
LPC_TMR32B1->TCR =1; // TCR start

// 16bit Timer
LPC_SYSCON->SYSAHBCLKCTRL |=0x100; // Timer16B1 Turn ON
LPC_IOCON->PIO1_9 = 0x001; // PIO1_9 as CT16B1_MAT0
LPC_TMR16B1->PR = 7200-1; // 10kHz (Max 16bit dec:65535)
LPC_TMR16B1->PWMC = 1; // MAT0 as PWM
LPC_TMR16B1->MCR = 0x80; // MR2 as Period of 16B1
LPC_TMR16B1->MR0 = 10000; // PWM High duration=MR2-MR0
LPC_TMR16B1->MR2 = 15000; // PWM Period (Max 16bit dec:65535)
LPC_TMR16B1->TCR = 2; // TCR Reset
LPC_TMR16B1->TCR = 1; // TCR Start


// Enter an infinite loop
while(1) { // Infinite loop
i++; // dummy count.
}
return 0 ;
}

コード中のコメントでほぼ問題ないと思います。

32bit Timerの場合ですが
MAT0を使うためにTCのリセットはMR0意外にしなければならないので

LPC_TMR32B1->MCR =0x400; MR3をリセットにしました。

LPC_TMR32B1->PWMC |=0x01; はMAT0をPWMにするという事です。


ちなみに、16bit timerの場合はTCだけではなくPC(プリスケールカウンタ)まで16bitです
したがって、72MHzのPCLKの場合はPCで1kHzを作ることは出来ません。
(1kHzを作るには 72000-1にする必要がありますが16bitだと65535がMaxのため)

こいつに気づかずに少々ハマったので念のため・・・・