前回はアラームフラグをI2C経由でポーリングしたが、今度はINT/SQW端子から出る信号そのものをAVRのPD2端子でポーリングする。INT/SQW端子はどちらのアラームも共通なので、どちらのアラームが発動したのかを知るためには結局アラームフラグも見なければならない。
#include <avr/io.h> #include <util/delay.h> #include "USART.h" #include "myI2Cv2.h" #include "DS3231.h" int main(){ // DDRD &= ~(1 << PD2); // PD2のIOをINにする(0にする)(INが初期値なので省略できる)。L、Hを入力するので内部プルアップはしない。 initUSART(); 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(1); // アラーム1を有効化して、 rtc.enableAlarm(2); // アラーム2を有効化して、 uint8_t whichAlarm; while(1){ loop_until_bit_is_clear(PIND, PD2); // 割り込み用の信号(L)がPD2に検知されたら、 whichAlarm = rtc.whichAlarmActivated(); // どちらのアラームが発動したのかを調べて、 rtc.getDateTimeBCD(); // それに応じて何かをして、 rtc.printDateTime(); printString(" Alarm "); printNibble(whichAlarm); printString(" has been activated.\n"); rtc.clearAlarmFlag(whichAlarm); // そのアラーム発動フラグを解除して、 /* if(bit_is_clear(PIND, PD2) && rtc.alarmActivated(1)){ // 割り込み用の信号(L)がPD2に検知されて、かつそれがアラーム1であったなら、 // 何かをして、 rtc.getDateTimeBCD(); rtc.printDateTime(); printString(" Alarm 1 has been activated.\n"); rtc.clearAlarmFlag(1); // アラーム1発動フラグを解除して、 } if(bit_is_clear(PIND, PD2) && rtc.alarmActivated(2)){ // 割り込み用の信号(L)がPD2に検知されて、かつそれがアラーム2であったなら、 // 何かをして、 rtc.getDateTimeBCD(); rtc.printDateTime(); printString(" Alarm 2 has been activated.\n"); rtc.clearAlarmFlag(2); // アラーム2発動フラグを解除して、 } */ _delay_ms(200); // またアラームの発動を待つ。を繰り返す。 } // unreachable: rtc.disableAlarm(1); rtc.disableAlarm(2); myI2Cv2.disable(); return 0; }
uint8_t whichAlarmActivated(); // どちらのアラームが出たのか
uint8_t DS3231::whichAlarmActivated(){ myI2Cv2.start(); // スタートコンディションを生成して、 myI2Cv2.writeByte(ADDRESS_W); // スレーブに呼びかけて、writeであることを示して、 myI2Cv2.writeByte(CONTROL_STATUS); // スレーブ側のレジスタポインタをセットして、 myI2Cv2.start(); // スタートコンディションを生成して、 myI2Cv2.writeByte(ADDRESS_R); // スレーブに呼びかけて、readであることを示して、 uint8_t cs = myI2Cv2.readByteNACK(); // 目的のCONTROL_STATUSレジスタの内容を読み出して、 myI2Cv2.stop(); // ストップコンディションを生成して、 return (cs & 0x03); // どちらのアラームが出たのか(下2ビット)を返す。 }