PIC 12F615


初めての PIC 割り込みに挑戦 (3)

やっと解決

ヒントはリアルタイムクロックRTC8564を使用した時刻表示(インターバル割り込み(INT1)、ICSP端子を入力として使用)のページにありました。
こちらによるとIOC系の状態変化割り込みは、どのポートで割り込みが発生したのかハード的に判別できないのでソフトで判断する必要があるとのことです。
プログラムの実装として、割り込みをトリガーするGPIOポートを読み出した後に目的のポートに出力するようにする必要があるということのようです。
そして実際のソースは次のようになりました。

/*
 * CNC Power unit
 * 
 * File:   main.c
 * Author: masato
 *
 * Created on 2017/02/05, 8:02
 */

// PIC12F615 Configuration Bit Settings
// 'C' source line config statements
// CONFIG
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSCIO oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config IOSCFS = 8MHZ    // Internal Oscillator Frequency Select (4 MHz)
#pragma config BOREN = ON       // Brown-out Reset Selection bits (BOR enabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>

static int odd = 0;
static int gp3_old = 0;
void interrupt ISR(void) {
    if (INTCONbits.GPIF) {
        if (gp3_old != GP3) {
            odd ^= 1;
            gp3_old = GP3;
            if (odd) {
                GP4 = !GP4;
            }
        }
        INTCONbits.GPIF = 0;    // 割り込みフラグクリア
    }
}

void main(void) {

    // レジスタセット
    TRISIO = 0b00001000;
    ANSEL =  0b00000000;
    CMCON0 = 0b00000000;
    IOCbits.IOC3 = 1;

    INTCONbits.GPIE = 1;        // GPIO変更割り込み許可
    INTCONbits.GIE =  1;        // グローバル割り込み許可

    GP0 = 0;
    GP1 = 0;
    GP2 = 0;
    GP4 = 0;
    GP5 = 0;

    while(1);

    return;
}