前回は外部端子からの割り込み使うべしということでEXT-INTを使用。PIC素人には複雑そうなInterrupt-ON-Change(IOC)よりもEXT-INTの方がフツーに見えたからです。しかし、今回IOCを使ってみて、こっちゃの方がフツーでないの、という認識にいたりました。即使えるようになっているんだこれが。
※『PIC三昧』PIC関係の記事総目次はこちら
今回もターゲット・マイコンは、PIC16F18855 です。例によってMPLAB X IDEを起動しマイコン機種を選択した後、MCC Classicを使ってプロジェクトをコンフィギュレーションしております。
Interrupt-ON-Change(IOC)
一部のピンを除き、ほとんどのIO端子をこのIOC割り込みに使用することができるようです。単独の端子を割り込みに使うことは勿論、複数の端子を組み合わせて合わせ技で判断することもできそうです。
このIOCを使うために、まずDevice Resourcesの中を探したのですが、IOCのようなお名前を持つリソースは存在しません。前回「シンプルな外部端子割り込み」EXT-INTを使ったときは、Device Resourcesの中にリソースがあったのに。
そう思って調べたら、IOCのためのリソースは最初からプロジェクトに含まれておりました。最初から含まれているのは以下の3つのモジュールです。そのうち、GPIOの入出力なども司るPin Moduleの中にIOCの制御も入っておるのです。
なんだ、IOC使う気満々(逆にいえばEXT-INTなど使わんでも済む?)
今回はLED出力に2ピン(PA0とPA1)、そしてIOC割り込みに1ピン(PC3)をアサインしました。いつものPin Manager画面が以下に。
上記のようにPin ManagerのGrid Viewで設定すると、Pin ModuleのSetup画面には、上記の3端子が以下のように現れてます。そこで、RC3のIOCという項目のところ、プルダウンメニューから割り込む条件を選択すれば設定OKデス。今回は以下のようにネガティブエッジで割り込みかけるように設定してみました。
なお、忘れずにInterrupt Moduleから、IOCIをEnableにしておかないとなりません。
MCCが自動生成したソースに追加
上記設定後、Generateボタンを押せばMCCがソースコードを自動生成してくれます。といって何をやりたいのかまでは流石に用意してはくれないので自分で書きます。今回は、
-
- RC3端子へ外部のプッシュボタンで割り込み(立下りエッジ)かける。割り込んだら、RA1端子に接続したLEDを点灯する。
- mainのループ内では、RA0端子に接続したLEDをゆっくり(2秒周期)で点滅させる。なお、2秒周期のループの末尾で常にRA1端子を消灯する。
という塩梅。
まずは、main.c内のmain()関数が以下に。忘れずに割り込みイネーブルしておきます。
void main(void) { SYSTEM_Initialize(); INTERRUPT_GlobalInterruptEnable(); INTERRUPT_PeripheralInterruptEnable(); while (1) { RA0 = 1; __delay_ms(1000); RA0 = 0; __delay_ms(1000); RA1 = 0; } }
続いて、RC3端子からの割り込みを受けるサービスルーチンへの追加です。pin_manager.c 内の関数。一行 RA1=1(RA1端子の先のLED点灯)のみ追加。
void IOCCF3_ISR(void) { RA1 = 1; if(IOCCF3_InterruptHandler) { IOCCF3_InterruptHandler(); } IOCCFbits.IOCCF3 = 0; }
動作確認
以下のような回路で、上記ソースからビルドしたオブジェクトを走らせます。
何もしないとD1のLEDがゆっくり点滅しております。SW1を押すと、D2のLEDが点灯しますが、D1のLEDが点灯する瞬間に入れ違いに消灯いたします。一応、意図通りの動作しているみたい。