PIC16F1459の基本動作から応用プログラムまでを学びます。

ホーム
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
    
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
入力ピン外部割込み

16F1459は、外部からの信号で割込み(インタラプト)を発生させることができます。RC0 ピンの信号で割り込みを発生する「INTピン」割込みと、すべてのPORTA PORTB で利用できる「IOC」割込みの2種類があります。

<INTピン割込み>
INIT ピンでは、エッジ トリガ型割り込みを発生します。OPTION レジスタのINTEDG ビットによって、割り込みを発生させるエッジが決定されます。INTEDG ビットがセットされていると、立ち上がりエッジで割り込みが発生し、クリアされていると立ち下がりで割り込みが発生します。INIT ピンに有効なエッジが現れると、INTCON レジスタの INTF ビットがセットされ、このとき、GIE および INTE ビットもセットされていると、割り込み処理が実施されます。

<IOC割込み>
IOC(INTERRUPT-ON-CHANGE)割込みも、エッジ トリガ型割り込みを発生します。IOCAPまたはIOCBP レジスタのビットがセットされていると、PortAまたはPortBの該当ビット入力信号の立ち上がりエッジで、IOCANまたはIOCBN レジスタのビットがセットされていると立ち下がりで割り込みが発生します。IOCxP とIOCxNの両方がセットされていれば、 立ち上がりと立ち下がりのどちらのエッジでも割り込みが発生します。該当 ピンに有効なエッジが現れると、IOCAFまたはIOCBF レジスタの該当 ビットがセットされ、このとき、GIE および IOCIE ビットもセットされていると、割り込み処理が実施されます。 INTCONレジスタの IOCIF ビットはRead only で直接クリアすることはできませんが、セット原因となったIOCAFまたはIOCBF レジスタを全てクリアすることでIOCIF ビットもクリアします。

割り込みに関連するレジスター一覧を下表に示します。

レジスタ bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
INTCON GIE PEIE TMR0IE INTE IOCIE TMR0IF INTF IOCIF*1
OPTION_REG nWPUEN INTEDG TMR0CS TMR0SE PSA  PS<2-0>
IOCAF - - IOCAF5 IOCAF4 IOCAF3 - IOCAF1 IOCAF0
IOCAN - - IOCAN5 IOCAN4 IOCAN3 - IOCAN1 IOCAN0
IOCAP - - IOCAP5 IOCAP4 IOCAP3 - IOCAP1 IOCAP0
IOCBF IOCBF7 IOCBF6 IOCBF5 IOCBF4 - - - -
IOCBN IOCBN7 IOCBN6 IOCBN5 IOCBN4 - - - -
IOCBP IOCBP7 IOCBP6 IOCBP5 IOCBP4 - - - -

割り込みのプログラム例

ササンプルで作成したプログラムは、SW1,SW2でLEDの点滅方向を変化させます。

<プログラム>

/*  File name: IOCA
 *   Description: interrupt-on-change example
 *   SW1(RA3),SW2(RA5)が押されると割込みが発生し、
 *   カウントの加算、減算を変更する。
 *   カウント値により、LEDを点灯させる。
 *   Notes: 4MHz内部クロック
 *     LED:      RC2
 *     Language: MPLABX XC8
 *     Target:   PIC16F1459
 */

#include <xc.h>
#define _XTAL_FREQ 4000000

#pragma config FOSC  = INTOSC, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP  = OFF
#pragma config BOREN = ON, CLKOUTEN = OFF, IESO  = OFF, FCMEN = OFF
#pragma config WRT = OFF, CPUDIV = NOCLKDIV, USBLSCLK = 48MHz, PLLMULT = 3x
#pragma config PLLEN = DISABLED, STVREN = ON, BORV = LO, LPBOR = OFF, LVP = OFF

char dir = 1;                  // カウント方向

void main(void){
    char num = 0;
    OSCCON = 0b00110111;      // 内部クロック4Mhz
    LATC   = 0;
    TRISC  = 0b11110000;      // 入出力設定
    IOCAN  = 0b00101000;      // RA3,RA5入力立下りで割込み
    IOCAF = 0;
    IOCIE = 1;                // IOCを許可
    GIE = 1;                  // 割込み許可

    while(1){                 //
        num += dir;           // カウントを更新
        switch(num & 3){
            case 0:LATC = 0b0001;break;
            case 1:LATC = 0b0010;break;
            case 2:LATC = 0b0100;break;
            case 3:LATC = 0b1000;break;
        }
        __delay_ms(400);      // LEDスピード
    }
}

//----------------------割込み処理------------------------
void interrupt isr(void){
   if(IOCAF){                 // Port A からの割込みを確認
       if(IOCAF5) dir =  1;   // RA5 割込み
       if(IOCAF3) dir = -1;   // RA3 割込み
       IOCAF = 0;             // 割込みフラッグをクリア
   }
}