前回に続きTIMER0を試用。今回はワンショットで出力パルス幅を制御するのに使ってみたいと思います。外部でボタンが押されたことをトリガにして、ボタンが押された直後から所定の幅のパルスを一発出力するもの。制御ではアリガチ?今回は16ビット利用なので最小4μsから最大約260msまでのパルスを自由自在だと。
※『PIC三昧』PIC関係の記事総目次はこちら
※作業はMicroChip社の統合開発環境 MPLAB X IDEと、その上で走るコンフィギュレーションツールMCC Classic を使用して行っています。ターゲット・マイコンはPIC16F18855です。
今回は割り込み源は2つだ
今回は以下のようなシナリオとなり、割り込み源は2つです。
-
- ユーザーキーが押されたら外部端子割り込みをかける
- 外部端子割り込みハンドラ内で、出力パルス(ロウアクティブ)をロウに設定するとともにタイマ0を起動する
- タイマ0の割り込みが発生したらタイマ割り込みハンドラ内でタイマ0を止め、出力パルスをハイに戻す
- 上記とは無関係にソフトウエアで吉例Lチカを続ける
今回のターゲットボードの場合、ユーザーキーはPA5端子に接続(ボタンを押すとロウ)されています。出力パルスはPB0端子に出力とします。またPA0端子にLEDが接続されているので、毎度の吉例LチカはPA0です。
MCC Classicでコンフィギュレーション
今回使用するリソース2つ、EXT_INTとTMR0をプロジェクトリソースに追加しておきます。
FOSCはデフォルトのまま1MHzなので、TIMER0は250kHzでカウントすることになります。今回は16ビットモードなので、結構広い時間間隔を設定することができます。上記では25.6msとしてあります。
一方、外部端子割り込みの設定は以下です。立下りエッジでお願いっと。
実をいうと最初ピン設定を取り違えていて、「動かん」とハマリました。調べてみればピン設定間違え、足元よく見ろよ、自分。
今回実験用のコード
MCCが自動生成してくれた main.c ファイル内に書き加えたコードは以下のとおりです。割り込みハンドラが2つとmain()関数。
void myEXTINT_InterruptHandler(void){ RB0 = 0; TMR0_Reload(); TMR0_StartTimer(); } void myTMR0_InterruptHandler(void){ RB0 = 1; TMR0_StopTimer(); } void main(void) { SYSTEM_Initialize(); INT_SetInterruptHandler(myEXTINT_InterruptHandler); TMR0_SetInterruptHandler(myTMR0_InterruptHandler); INTERRUPT_GlobalInterruptEnable(); INTERRUPT_PeripheralInterruptEnable(); RB0 = 1; while (1) { RA0 = 1; __delay_ms(100); RA0 = 0; __delay_ms(100); } }
実機で確認
黄色C1がPA5のユーザーキーの入力波形です。手動ボタンなのでかなり長い期間ロウになってます。青色C2がタイマ使って制御しているワンショットパルスです。ユーザーキーがアクティブになるのとほぼほぼ同時にロウが出力され、設定した約25.6msほどロウ期間が続いてからインアクティブに戻っています。
これでワンショットもできたな、ホントか?