今度はピン変化割り込み(PCINTx)で割り込む。前回の外部割り込み(INTx)とほとんど同じである。前回と同じく割り込みサービスルーチンは割り込み発生を受けてフラグを立てるだけにする。
#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; }