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秒之后,我是在单片机进入掉电模式前重新初始化。