AVRのI2Cモジュール / リアルタイムクロックDS3231 / アラームを使う / 割り込み用の信号をピン変化割り込み(PCINTx)で検知する

今度はピン変化割り込み(PCINTx)で割り込む。前回の外部割り込み(INTx)とほとんど同じである。前回と同じく割り込みサービスルーチンは割り込み発生を受けてフラグを立てるだけにする。
f:id:ti-nspire:20200207132733p:plain:w400
f:id:ti-nspire:20200207132822p:plain:w400

#include <avr/io.h>
#include <util/delay.h>
#include "USART.h"
#include "myI2Cv2.h"
#include "DS3231.h"

volatile uint8_t alarmActivated = 0;
ISR(PCINT2_vect){                // ポートDにピン変化割り込みが発生して、
    if(bit_is_clear(PIND, PD2)){ // かつDS3231の!INT端子からLが出力されていたなら(PD2にLが入力されていたなら)、
        alarmActivated = 1;      // アラーム発動を示すフラグを立てる。
    }
}
void initPCINT18(){
    PCICR |= (1 << PCIE2); // ポートDのピン変化割り込みを有効化する。
    PCMSK2 = (1 << PD2);   // PD2 (PCINT18) から割り込むことにする。
    sei();                 // グローバル割り込みを有効化する。
}

int main(){
    initUSART();
    
    // DDRD &= ~(1 << PD2); // PD2のIOをINにする(0にする)(INが初期値なので省略できる)。内部プルアップはしない。

    DS3231 rtc;         // リアルタイムクロックDS3231 (I2Cスレーブ)を実体化する。
    myI2Cv2.enable(80); // システムクロックの80分周をI2CクロックとしてAVRのI2Cモジュールを有効化する。
   
    //rtc.setDateTimeMan(); // USART経由で手動で時刻合わせをして、
    
    printString("***** Set the alarm 1 *****\n"); // USART経由で手動でアラーム1の発動タイミングを設定して、
    rtc.setAlarmMan(1);
    printString("***** Set the alarm 2 *****\n"); // USART経由で手動でアラーム2の発動タイミングを設定して、
    rtc.setAlarmMan(2);

    rtc.enableAlarm(3); // アラーム1、アラーム2を両方有効化して、
    initPCINT18();      // AVRのPD2のピン変化割り込みを有効化して、
    
    while(1){

        if(alarmActivated){                                 // アラームが発動したら、
            uint8_t whichAlarm = rtc.whichAlarmActivated(); // どちらのアラームが発動したのかを調べて、(1または2、両方発動時は3)
            rtc.getDateTimeBCD();                           // それに応じて何かをして、
            rtc.printDateTime();
            printString(" Alarm "); printNibble(whichAlarm); printString(" has been activated.\n");
            rtc.clearAlarmFlag(whichAlarm);                 // そのアラーム発動フラグを解除する。
            alarmActivated = 0; 
        }

        _delay_ms(100);
    }

    // unreachable:
    rtc.disableAlarm(3); // アラーム1、アラーム2を両方無効化する。
    myI2Cv2.disable();
    return 0;
}