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