DS3231高精度時鐘模塊倒是又便宜又好用,SDA/SCL兩個IO口就能搞定基本功能,不過在使用鬧鈴中斷輸出的時候遇到了問題,那就是鬧鈴中斷只會輸出一次,之後始終保持低電平。
這個問題數據手冊上沒有明說,在網上搜索了很久,一點信息都沒有找到,只好自己折騰。
經過反覆嘗試,最終確認DS3231的鬧鈴中斷輸出正確使用方式如下:
首先是初始化,設定鬧鈴時間和允許中斷輸出
void DS3231_Init_Alarm2() {
I2C_Start();
I2C_PutByte(DS3231_Write);
I2C_PutByte(DS3231_CONTROL);
I2C_PutByte(0x0); // INTCN=1,A2IE=1,enable interrupts, alarm 2 output
I2C_PutByte(0x0);
I2C_Stop();
I2C_Start();
I2C_PutByte(DS3231_Write);
I2C_PutByte(DS3231_ALARM2MINUTE);
I2C_PutByte(0x0); // 分,A2M2=0
I2C_PutByte(0x80); // 時,A2M3=1
I2C_PutByte(0x80); // A2M4=1,DY=0
I2C_Stop();
I2C_Start();
I2C_PutByte(DS3231_Write);
I2C_PutByte(DS3231_CONTROL);
I2C_PutByte(0x06); // INTCN=1,A2IE=1,enable interrupts, alarm 2 output
I2C_PutByte(0x0);
I2C_Stop();
}
我這裏使用的是鬧鈴2,每小時整點時輸出中斷
在觸發中斷後,要關閉相應的鬧鈴中斷輸出(A2IE=0)
void Perhour_ExtInt1() interrupt 2 using 1 {
EX1 = 0;
DS3231_Disable_Alarm2();
……
}
void DS3231_Disable_Alarm2()
{
I2C_Start();
I2C_PutByte(DS3231_Write);
I2C_PutByte(DS3231_CONTROL);
I2C_PutByte(0x4); // INTCN=1,A2IE=0,
I2C_PutByte(0x0);
I2C_Stop();
}
在合適的時候,重新初始化鬧鈴
這裏合適的時候很重要,如果立即重新初始化,中斷條件仍滿足,繼續觸發中斷,將導致下一次鬧鈴失效。也就是說至少要在1秒之後,我是在單片機進入掉電模式前重新初始化。