PIC16F1827の割り込みの一つのIOC(Interrupt-On-Chane)ピン状態変化割り込みのテストをします。
IOCを可能にするには、INTCONレジスタのbit3 IOCIEを1にセットします。
ICO割り込みが使えるのは、PORTBで、割り込みのタイミングをraising(立ち上がり)とfalling(立ち下り)に設定することができます。
立ち上がりでの割り込みを設定するのは、IOCBPレジスタで、RB0~RB7それぞれに設定できます。同様に立下りでの割り込みを設定するのは、IOCNPレジスタです。
割り込みがかかるとIOCBFレジスタの各ピンに対応したIOCBFxが1になります。
今回は、RB0の状態が変化したときにRB4のLEDが点灯、消灯を繰り返すようにプログラムします。
回路図です。RB0はウィークプルアップし、プルアップ抵抗は省略します。
プログラムです。
内部クロック8MHzで、PLL=ONで32MHzクロックで動作させています。
電源は、乾電池2本(3V)です。
RB0は、pull-upしておきます。
SWが押されたときプルアップされていた電圧が0になりますので、立下りで割り込みがかかるように設定しました。
---------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include <xc.h>
// CONFIG1
#pragma config FOSC = INTOSC
#pragma config WDTE = OFF
#pragma config PWRTE = ON
#pragma config MCLRE = OFF
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config CLKOUTEN = OFF
#pragma config IESO = OFF
#pragma config FCMEN = OFF
#pragma config FOSC = INTOSC
#pragma config WDTE = OFF
#pragma config PWRTE = ON
#pragma config MCLRE = OFF
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config CLKOUTEN = OFF
#pragma config IESO = OFF
#pragma config FCMEN = OFF
// CONFIG2
#pragma config WRT = OFF
#pragma config PLLEN = ON
#pragma config STVREN = ON
#pragma config BORV = HI
#pragma config LVP = OFF
#pragma config WRT = OFF
#pragma config PLLEN = ON
#pragma config STVREN = ON
#pragma config BORV = HI
#pragma config LVP = OFF
#define _XTAL_FREQ 32000000 //クロック32MHz
#define LED RB4
volatile unsigned char val = 0;//val= 1: LED点灯 val=0:LED消灯
#define LED RB4
volatile unsigned char val = 0;//val= 1: LED点灯 val=0:LED消灯
/* RB0 SW fallingでIOC(Interrupt-on-change)が発生する
* RB4 LED SWが押される度に点灯、消灯を繰り返す
*/
* RB4 LED SWが押される度に点灯、消灯を繰り返す
*/
void interrupt Blink(){
IOCBFbits.IOCBF0 = 0; //IOCBF0クリア
val = 1 - val; // Valの値を反転させる
LED = val;
}
IOCBFbits.IOCBF0 = 0; //IOCBF0クリア
val = 1 - val; // Valの値を反転させる
LED = val;
}
void main() {
OSCCON = 0b01110000 ; // 内部クロック8MHz PLL ONで8×4=32MHz
ANSELA = 0b00000000 ; // AN0-AN4は使用しない
ANSELB = 0b00000000 ; // AN5-AN11は使用しない
TRISA = 0b00000000 ; // PORTAは全て出力(RA5は入力)
TRISB = 0b00000001 ; // RB0 入力 他は出力
PORTA = 0b00000000 ; // PORTA初期化
PORTB = 0b00000000 ; // PORTB初期化
OPTION_REGbits.nWPUEN = 0;// week pull-up enable
WPUB = 0b00000001; // RB0 pull-up
/*割り込み設定*/
IOCBNbits.IOCBN0 = 1; // RB0 を立下り割り込みに設定
INTCONbits.IOCIE = 1; // IOC割り込み許可
GIE = 1; // 全割り込み許可
while(1){
}
}
OSCCON = 0b01110000 ; // 内部クロック8MHz PLL ONで8×4=32MHz
ANSELA = 0b00000000 ; // AN0-AN4は使用しない
ANSELB = 0b00000000 ; // AN5-AN11は使用しない
TRISA = 0b00000000 ; // PORTAは全て出力(RA5は入力)
TRISB = 0b00000001 ; // RB0 入力 他は出力
PORTA = 0b00000000 ; // PORTA初期化
PORTB = 0b00000000 ; // PORTB初期化
OPTION_REGbits.nWPUEN = 0;// week pull-up enable
WPUB = 0b00000001; // RB0 pull-up
/*割り込み設定*/
IOCBNbits.IOCBN0 = 1; // RB0 を立下り割り込みに設定
INTCONbits.IOCIE = 1; // IOC割り込み許可
GIE = 1; // 全割り込み許可
while(1){
}
}
-------------------------------------------------
タクトスイッチを押すたびにLEDが点灯、消灯します。
タクトスイッチは、押したときは問題なのですが、離したときにチャタリングがあり、時々誤動作します。
これを回避する方法もあるのですが、今回は、IOC割り込みの確認ですので対策をしませんでした。