こんにちは、ENGかぴです。
PIC16F1827は外部割込み機能(INT)を持っているため外部機器からのパルス信号に応答して処理を行うことができます。MPLAB X IDEのプラグインであるMCCでEXT_INTを実装して動作確認を行いました。
EXT_INTによるINT機能とIOC機能について説明しています。EXT_INTの動作確認にはGrove-Digital PIR Motion Sensor(Seeed Studio)を使用しています。
PIC16F1827で動作確認したことについてリンクをまとめています。
PICマイコン(PIC16F1827)で実現できる機能と解説リンクまとめ
EXT_INT(外部割込み)機能
外部割込み機能(INT機能)は多くのマイコンに実装されている機能です。INTピンはパルスの立ち上り/立ち下りエッジを検出して割り込みを発生させる機能です。
INTピンで立ち上りエッジで検出する場合はパルス波形がLOWからHIGHに変化した場合に割り込みを発生します。逆に立ち下がりエッジで検出する場合はパルス波形がHIGHからLOWに変化した場合に割り込みを発生します。
RTC(リアルタイムクロック)などの周期的なパルス波形の検出に使用したり、人感センサーが感知した場合のワンショット(周期的なパルス波形)の検出に使用したりと用途は様々です。
MCCで各種機能を実装する
PIC16F1827の各種設定はMCCを使っています。MCCの使い方については下記記事にまとめています。
MPLAB Code Configurator(MCC)の追加と使い方
今回はEXT_INT、IOC、TMR0の設定を行っています。
System Moduleの設定
最初に共通事項であるSystem Moduleの設定を行います。MPLAB X IDEを起動しMCCのアイコンをクリックしてMCCを有効にします。
内部クロックを使用するためINTOSCを選択しています。クロック周波数は任意でもよいですが4MHz_HFを選択しています。他にも設定項目はありますがクロックの設定のみとしています。
EXT_INTを設定する
EXT_INTはDevice Resources内のPeripherals欄のExt_InterruptからEXT_INTを選択して追加します。
Edge Detectで立ち上りエッジ(rising_edge)または立ち下がりエッジ(falling_edge)を指定します。
割り込み設定はEXT_INTを追加した時点で有効の設定になります。コールバック関数を指定することで割り込み発生時にユーザーの関数を呼び出すことができます。
void Int_CallBack(void); //INT割り込みのコールバック関数
//コールバック関数の指定例
INT_SetInterruptHandler(Int_CallBack); //コールバック関数を指定
INT_SetInterruptHandler()関数はコールバックするユーザーの関数を指定します。例では自作のInt_CallBack()関数を指定しています。
PR:スキマ時間を有効に!スマホで学べる人気のオンライン資格講座【スタディング】まずは気になる講座を無料で体験しよう!
IOC機能を設定する
IOC機能はPORTBに含まれている機能です。後述のピン設定で対象のポートをINPUTを選択した状態でIOC欄でnone、negative、any、positiveから指定します。立ち上がりエッジで検出する場合はpositiveを指定します。
MCCのSystem欄のInterrupt Moduleで割り込みを許可する必要があります。Interrupt Vector内のPinModuleのIOCIのEnabledをチェックして割り込みを許可します。
IOCの割り込みのコールバック関数を指定することで、割り込み発生時にユーザーの関数を呼び出すことができます。
void PB5Int_CallBack(void); //INT割り込みのコールバック関数
//コールバック関数の指定例
IOCBF5_SetInterruptHandler(PB5Int_CallBack); //コールバック関数を指定
IOCBF5_SetInterruptHandler()関数はコールバックするユーザーの関数を指定します。PORTBの番号によって関数は異なりますが、同一の指定方法でコールバック関数を指定することができます。例では自作のPB5Int_CallBack関数を指定しています。
TMR0を設定する
TMR0はDevice Resources内のPeripherals欄のTimerを選択しTMR0をクリックして追加します。
Timer Clock内でクロックに関する設定を行います。Clock Sourceは内部クロックを使用しているためFOSC(FOSC/4)を指定します。PrescalerはClock Sourceに対してTMR0のカウントアップする分周比を指定します。
Timer PeriodはTMR0がオーバーフローするタイミングを設定します。1ms毎にオーバーフロー割り込みが発生しますがCallback Function Rateを0x0A(10)を指定しているため10ms毎にコールバック関数が呼び出されます。
void mainTimer(void); //タイマー0割り込みのコールバック関数
//コールバック関数の指定例
TMR0_SetInterruptHandler(mainTimer); //コールバック関数を指定
TMR0_SetInterruptHandler()関数でコールバックするユーザーの関数を指定します。上記例ではmainTimer()が10ms毎にコールされます。
MCCが生成した関数の使用例
IO_RA3_SetLow(); //PORTAの3番(RA3)をLOW
IO_RA3_SetHigh(); //PORTAの3番(RA3)をHigh
IO_RB4_SetLow(); //PORTBの4番(RB4)をLOW
IO_RB4_SetHigh(); //PORTBの4番(RB4)をHigh
IO_RAX_SetLow()関数はRORTAのX番のポートをLOWにします。IO_RAX_SetHigh()関数はRORTAのX番のポートをHIGHにします。Xはポートの番号で0~7が入ります。
IO_RBX_SetLow()関数はRORTBのX番のポートをLOWにします。IO_RBX_SetHigh()関数はRORTBのX番のポートをHIGHにします。Xはポートの番号で0~7が入ります。
ピンの設定
MCCのピン設定は以下の通りです。
EXT_INTピンはEXT_INTを追加するとINTピン専用に設定されます。PB5ピンをINPUTにします。またPB5のIOC欄でpositiveを指定します。
PB0(INT)及びPB5はウィークプルアップ(WPU)設定を使用します。WPUを有効にするためにはRegistersのnWPUENをenabledにする必要があります。
Easy SetupでWPUにチェックするのみでは有効にならないので注意が必要です。Notificationsにワーニングで通知されます。
動作確認
Grove-Digital PIR Motion Sensorは人の移動など動的な変化があると赤外線で感知して通知するモジュールです。SIGピンは未検出の場合はLOWを出力し、感知するとHIGHを5秒程度出力します。
SIGピンLOWからHIGHになるとINTピンに立ち上がりエッジが入力されるため割り込みが発生しLED2を3秒間点灯します。
SWはポートの状態変化を検出するために使用します。PB5のIOCの設定をpositiveにしているため、SWを押してLOWにした状態からSWを離してHIGHするとIOC割り込みが発生しLED1を2秒間点灯します。
Grove-Digital PIR Motion Sensorに手をかざすとINTピンがエッジを検出しLED2が点灯することが確認できました。また、SW2を押した状態から離すとLED1が点灯することが確認できました。
ソースコード全体
以下のソースコードはコンパイルして動作確認をしております。コメントなど細かな部分で間違っていたりやライブラリの更新などにより動作しなくなったりする可能性があります。参考としてお使いいただければと思います。
#include "mcc_generated_files/mcc.h"
#define INT_MAX 300
#define INT_PB5_MAX 200
#define TIME_OFF -1
#define TIME_UP 0
int16_t timintpb5 = TIME_OFF;
int16_t timint = TIME_OFF;
void Int_CallBack(void);
void PB5Int_CallBack(void);
void mainTimer(void);
void mainApp(void);
/* Main application */
void main(void)
{
SYSTEM_Initialize();
INTERRUPT_GlobalInterruptEnable();
INTERRUPT_PeripheralInterruptEnable();
TMR0_SetInterruptHandler(mainTimer);
INT_SetInterruptHandler(Int_CallBack);
IOCBF5_SetInterruptHandler(PB5Int_CallBack);
while (1)
{
mainApp();
}
}
/* メイン処理 */
void mainApp(void){
if( timintpb5 == TIME_UP){
timintpb5 = INT_PB5_MAX;
IO_RA3_SetLow();
}
if( timint == TIME_UP ){
timint = TIME_OFF;
IO_RB4_SetLow();
}
}
/* EXT_INTの割り込みコールバック */
void Int_CallBack(void){
timint = INT_MAX;
IO_RB4_SetHigh();
}
/* IOCI(PB5)の割り込みコールバック */
void PB5Int_CallBack(void){
timintpb5 = INT_PB5_MAX;
IO_RA3_SetHigh();
}
/* タイマ管理 */
void mainTimer(void){
if( timintpb5 > TIME_UP ){
--timintpb5;
}
if( timint > TIME_UP ){
--timint;
}
}
/* End of File */
本ソースコードはMPLAB X IDEにMCCのプラグインをインストールしていることが前提となります。MCCをインストールする方法は下記記事を参考にしてください。
MPLAB Code Configurator(MCC)の追加と使い方
関連リンク
PICマイコンを使ってマイコンのレジスタの設定やMPLAB X IDEのプラグインであるMCCを使用して動作確認したことについてまとめています。
PICマイコン(PIC12F675)で実現できる機能と解説リンクまとめ
PICマイコン(PIC16F1827)で実現できる機能と解説リンクまとめ
最後まで、読んでいただきありがとうございました。