HOME > 技術談話 > PIC® microcontroller > タイマを使ったLED制御1
はじめに テーマ 回路図 部品の配置 フローチャート プログラム説明
前回はソフトウェアタイマ(__delay_ms)を使用したLED制御でしたが、今回はPICマイコンに内蔵されるタイマを利用してLEDを制御します。 ソフトウェアタイマは前後の処理時間、割り込み処理が発生すると遅延が生じますが、内蔵タイマを利用することでタイマカウント中に別の作業を行えるだけでなく、遅延を回避することができます。 |
▲ |
(1)基本仕様 PICマイコンにLEDを3個接続し、500ミリ秒単位で順番に点灯します(LED0 > LED1 > LED2 > LED0 > LED1 > …) (2)ハードウェア PIC12F683(8pin)を3Vで動作させます。源発振は内蔵クロックを利用します(4MHz)。 (3)ファームウェア 500ミリ秒の基準は内蔵タイマの状況をポーリングして算出します。LEDの点灯はスタティック制御です。 なお、厳密に言うと500ミリ秒の近似値499.712msで制御します。 |
▲ |
前回の回路図が利用されます(クリックすると新しいウィンドウが開きます)。 |
▲ |
前回の配置が利用されます(クリックすると新しいウィンドウが開きます)。 |
▲ |
関数mainは自動生成されるスタートアップルーチンから呼び出されます。 基本的な流れは前回と同様ですが、タイマの初期設定とタイムアウト検出を繰り返す箇所が異なります。 タイマの初期設定では8bitタイマであるタイマ0を内蔵クロック16分周で設定します。このタイマ0は停止することができず、タイマ0レジスタの更新を行った結果、オーバーフローすると割り込み要求をセットします。 タイマ0は割り込み要求源として使用できますが、必ずしも割り込みにて処理を行う必要はありません。割り込み要求源であるフラグレジスタはタイマ0のオーバーフローに連動してセットされますがプログラムから参照可能であり、また、プログラムで解除することができます。 タイマ0の動作は、源発振4Mhz、内蔵クロック16分周なのでタイマ0レジスタの更新は16us周期、そして8bitのレジスタがオーバーフローするまでに16*256=4096us要します。 今回のサンプルプログラムではタイマ0のタイムアウト状況をポーリングで認識するだけなのでタイムアウト未検出時の処理はありません。一般的なプログラムではタイムアウト検出するまでに様々な処理を行っています。 |
待機監視は前回とは全く異なります。 最初にタイマ0の割り込み要求を示すフラグレジスタを確認します。このフラグレジスタは4096us周期でセットされます。フラグレジスタをセットした後もタイマ0の更新は停止せず、再び4096us後にフラグレジスタのセットが行われます。 割り込み要求を示すフラグの解除はプログラムで行います。ですので少なくともフラグがセットされてから4096us以内にフラグの解除を行わないと1回分の割り込み要求を見失います。 この待機監視では500msを検出します。タイマ割り込み要求が4096us周期で発生するので、122回分のタイマ割り込み要求を検出すると500ms経過と判断します。なお厳密には499.712msです。 PIC12F683にはタイマ0の他にタイマ1、タイマ2があります。タイマ2を利用すれば500msちょうどのタイミングを作りだすことができます。やり方はタイマ0の場合と同様ですが、基準のタイマ割り込み発生周期を4000usという具合に綺麗な数字を導き出すことができます。 今回はPIC12F683だけでなく他のPICマイコンでも共通して存在するタイマ0をあえて使用しています。 |
この処理は前回と同様です。 |
▲ |
(1)プログラム本体
サンプルプログラムを公開します … Test102_LED001.zip HI-TECH C v9.70 で作成されたプログラムを v9.81 以降のコンパイラで再コンパイルする際の注意点 → 開発環境による修正 2011/03/09 プログラムには特別な記述はありません。コメントを見るだけでも大まかに理解できると思いますが、気になりそうな箇所だけをピックアップして補足説明します。 |
(2)タイマの初期設定
タイマ0の初期設定方法はデータシートに記載されているので、これに準じたコーディングを行っています。ですが、ウォッチドッグタイマを稼働していない、もしくはウォッチドッグタイマからタイマ0にプリスケーラを切り替える事がないのであればウォッチドッグタイマのリフレッシュ命令は不要です(記述しても問題無し)。 既に設定済みのOPTIONレジスタを再設定することでタイマ0の初期設定を行います。初期設定からの変更内容は、 ・タイマ0のカウントに内部クロックを利用する … 源発振の4分周(Fosc/4)でカウントされる ・プリスケーラはタイマ0で利用する ・プリスケーラは16分周を利用する … 割り込み要求回数を1バイトの変数で管理する為 になっています。 |
タイマ0は停止することができないタイマです。タイマの初期設定を行う以前から動作していて、割り込み要求フラグのセットを繰り返しているはずです。今回の場合は幸か不幸かタイマ0のクロック源に外部クロックが指定(初期値)されていたのでタイマ0レジスタの更新は行われていませんが、作法としてタイマ0の基本動作設定を行った後は割り込み要求を解除(T0IF=0)しています。 |
(3)タイマの動作
タイマ0レジスタは8bitです。0から始まり255までインクリメントします。そして255の次のインクリメントでオーバーフローが発生して割り込み要求T0IFをセットします。タイマ0レジスタ自体はオーバーフローにより0に戻ります。このT0IFをセットする周期は一定で、今回のサンプルプログラムでは4096usになります。 今回のサンプルプログラムでは割り込み要求T0IFをポーリングし、セットされていたらクリアします。このクリアするタイミングは一定ではありませんが平均すれば4096usになるはずです。 |
上図では割り込み要求T0IFのセットに追従してクリアできていますが、何らかの要因で割り込み要求をポーリングするタイミングが遅延し、割り込み要求T0IFがセットされたまま次のタイマ0レジスタのオーバーフローが発生した場合は時間計測を誤ることになります。 |
(4)タイムアウトの検出
割り込みを使用しないのでメイン処理で空いた時間を利用して(今回のサンプルプログラムでは全速力ですが)割り込み要求T0IFをチェックします。割り込み要求がセットされていたら4096us経過したと判断し、割り込み要求をクリアすると共に割り込み要求回数を更新します。割り込み要求回数が122以上になったところで500ms(厳密には499.712ms)経過でタイムアウトとしています。 前回のソフトウェタイマ方式では遅延の累積が発生する可能性がありますが、PICマイコン内蔵タイマを利用し、その割り込み要求を漏れなく確実に読み取れるならば遅延の累積は発生しません。 |
▲ |