STM32F407读写IIC串行接口高精度实时时钟SD2405ALPI以及时间报警中断详细使用

tech2024-07-20  60

        因项目需要使用IIC串行接口高精度实时时钟SD2405ALPI芯片按照时间要求自动启动单片机,因此研究了一下SD2405ALPI芯片,并且在STM32F407单片机上实现了根据小时和分钟的要求,时间到时(时钟芯片的小时等于预定的小数,时钟芯片的分钟等于预定的分钟)后自动启动单片机。

一、寄存器

        SD2405ALPI实时时钟芯片共有20个控制寄存器(00H---13H),另外还有12个RAM寄存器(14H---1FH)用于存储参数。

 

 二、实时实钟寄存器

        SD2405ALPI实时时钟芯片共有7个寄存器(00H---06H),用于读取芯片的时间(年、月、日、时、分、秒、星期)或都往芯片写时间(年、月、日、时、分、秒、星期)。

         1、00H=秒      寄存器    

         2、01H=分钟   寄存器

         3、02H=小时   寄存器

         4、03H=星期   寄存器

         5、04H=日       寄存器

         6、05H=月       寄存器

         7、06H=年       寄存器

       

        (一)、小时格式

                  SD2405ALPI实时时钟芯片支持12小时和24小时二种。如果小时寄存器的最高位为1,代表24小时;如果小时寄存器的最高位为0,代表12小时。

                       例如:读取的小时为0x03,代表实时时钟被设置为12小时制,当前时间为3点。

                       例如:读取的小时为0x83,代表实时时钟被设置为24小时制,当前时间为3点。

                       例如:读取的小时为0x93,代表实时时钟被设置为24小时制,当前时间为13点。

        (二)、星期

                   SD2405ALPI实时时钟芯片的星期为七进制数。

                   0---星期天    1---星期一    2---星期二   3---星期三    4---星期四   5---星期五   6---星期六

        (三)、读时钟芯片时间

                    1、如果读取的时间为:年=0x19,月=0x09,日=0x28,星期=0x02,小时=0x83,分钟=0x59,秒=0x58

                    代表 2019年9月28日星期二  3点(24小时制)59分58秒

                    2、如果读取的时间为:年=0x08,月=0x09,日=0x28,星期=0x03,小时=0xA3,分钟=0x59,秒=0x58

                    代表 2008年9月28日星期三  23点(24小时制)59分58秒

                    3、如果读取的时间为:年=0x08,月=0x09,日=0x28,星期=0x03,小时=0x03,分钟=0x59,秒=0x58

                    代表 2008年9月28日星期三  03点(12小时制)59分58秒

                   总结:读时钟芯片时间(年、月、日、星期、时、分、秒),必须将读取到的数值由BCD码转换十六进制。

        (四)、写时间到时钟芯片

                   1、要将芯片设置为2018年12月6日星期五 15点12分16秒 ,必须给时钟芯片送如下数值

                        年=0x18,月=0x12,日=0x06,星期=0x05,小时=0x95,分钟=0x12,秒=0x16

                   总结:给芯片写的时间(年、月、日、星期、时、分、秒)之前,必须先将要写的数值由十六进制转换成BCD码,然后送给芯片。

三、时间报警寄存器

        07H---0EH为时间报警寄存器。

        07H为【秒】报警寄存器(前提是你必须在0EH寄存器中允许秒报警)

        08H为【分钟】报警寄存器(前提是你必须在0EH寄存器中允许分钟报警)

        09H为【小时】报警寄存器(前提是你必须在0EH寄存器中允许小时报警)

        0AH为【星期】报警寄存器(前提是你必须在0EH寄存器中允许星期报警)

        0BH为【日】报警寄存器(前提是你必须在0EH寄存器中允许日报警)

        0CH为【月】报警寄存器(前提是你必须在0EH寄存器中允许月报警)

        0DH为【年】报警寄存器(前提是你必须在0EH寄存器中允许年报警)

        0EH为【报警允许】寄存器。

                    bit0=1,代表允许秒报警,bit0=0,代表禁止秒报警。

                    bit1=1,代表允许分钟报警,bit1=0,代表禁止分钟报警。

                    bit2=1,代表允许小时报警,bit2=0,代表禁止小时报警。

                    bit3=1,代表允许星期报警,bit3=0,代表禁止星期报警。

                    bit4=1,代表允许日报警,bit4=0,代表禁止日报警。

                    bit5=1,代表允许月报警,bit5=0,代表禁止月报警。

                    bit6=1,代表允许年报警,bit6=0,代表禁止年报警。

          例子:

                    假如你想2021年12月31日报警,那么需要在0EH允许年报警、月报警、允许日报警

                    假如你想2021年12月31日8点报警,那么需要在0EH允许年报警、月报警、允许日报警、允许小时报警。

                    假如你想2021年12月31日8点30分报警,那么需要在0EH允许年报警、月报警、允许日报警、允许小时报警、允许分钟报警。

                    假如你想2021年12月31日8点30分20秒报警,那么需要在0EH允许年报警、月报警、允许日报警、允许小时报警、允许分钟报警、允许秒报警。

                    假如你想星期一报警,那么需要在0EH允许星期报警

   四、控制寄存器

        0FH---13H为控制寄存器。其中0FH为CTR1控制寄存器,10H为CTR2控制寄存器,11H为CTR3控制寄存器。

1、写允许和写禁止。

        当CTR2控制寄存器(10H)的WRTC1位=1,CTR1控制寄存器(0FH)的WRTC3位=1,WRTC2位=1,则允许00H---1FH这些寄存器进行写操作(允许写)。

        当CTR2控制寄存器(10H)的WRTC1位=0,CTR1控制寄存器(0FH)的WRTC3位=0,WRTC2位=0,则禁止00H---1FH这些寄存器进行写操作(禁止写或者写后无效)。

        警告:写允许时,往WRTC1位、WRTC2位、WRTC3位写1时要有先后顺序。

              必须先给WRTC1位写1,然后才能给WRTC2位和WRTC3位写1。

        警告:写禁止时,往WRTC1位、WRTC2位、WRTC3位写0时要有先后顺序。

              必须先给WRTC2位和WRTC3位写0,然后才能给WRTC1位写0。

         警告:写禁止时,00H---0EH寄存器禁止写,11H-1FH寄存器禁止写。

                    写禁止时,0FH寄存器只有WRTC3位和WRTC2位允许写,0FH寄存器其余位均禁止写。

                    写禁止时,10H寄存器只有WRTC1位允许写,10H寄存器其余位均禁止写。

        总结:写允许时,00H---1FH所有的寄存器都允许写;写禁止时,只有0FH寄存器的WRTC3位和WRTC2位以及10H寄存器的WRTC1位允许写(只有3个位允许写),其余均不允许写。

2、配置中断允许和中断类型

     10H寄存器的INTS1位和INTS0位用于选择中断类型。

      当配置10H寄存器的INTS1=0,INTS0=1表示启用报警中断输出。

      当配置10H寄存器的INTS1=1,INTS0=1表示启用倒计时中断输出。

 10H寄存器的INTAE位用于设置时间报警中断禁止/允许。 INTAE=0,禁止时间报警中断,INTAE=1,允许时间报警中断

 10H寄存器的INTDE位用于设置倒计时中断禁止/允许。 INTDE=0,禁止倒计时中断,INTDE=1,允许倒计时中断

 

 10H寄存器的INTFE位用于设置频率中断禁止/允许。 INTFE=0,禁止频率中断,INTFE=1,允许频率中断

  

              总结:

                          假如你想启用时间报警中断,10H寄存器设置如下:WRTC1=1,INTS1=0,INTS0=1,INTAE=1

                          假如你想启用频率中断,10H寄存器设置如下:WRTC1=1,INTS1=1,INTS0=0,INTFE=1

                          假如你想启用倒计时中断,10H寄存器设置如下:WRTC1=1,INTS1=1,INTS0=1,INTDE=1

五、INT脚输出

        10H寄存器的IM位用于设置实时时钟INT引脚的输出模式。

        1、当IM位=0,当触发报警时为单事件报警,INT引脚持续输出低电平,只有当你将0FH寄存器的INTAF位清零后,INT引脚才会输出高电平。

        2、当IM位=1,当触发报警时为周期性报警,INT引脚持续输出宽度为250的周期性脉冲,只有当你将0FH寄存器的INTAF位清零后,INT引脚才会输出高电平。

        总结:当时钟芯片触发任意一种中断(时间报警中断、频率中断或倒计时中断) ,时钟芯片都会将INT引脚置为低电平。如果配置IM=0,则触发任意一种中断后,INT引脚持续输出低电平,直到你将0FH寄存器的INTAF位清零后,INT引脚才会输出高电平。如果配置IM=1,则触发任意一种中断后,INT引脚持续输出宽度为250ms的周期性脉冲,直到你将0FH寄存器的INTAF位清零后,INT引脚才会输出高电平。

 

六、SD2405ALP器件IIC读写地址

        SD2405ALP器件IIC写地址为0x64

        SD2405ALP器件IIC读地址为0x65

 

七、源程序

// //写SD2405允许程序 // void WriteTimeOn(void) { I2CStart(); I2CSendByte(0x64); I2CWaitAck(); I2CSendByte(0x10); //设置写地址10H I2CWaitAck(); I2CSendByte(0x80); //置WRTC1=1 I2CWaitAck(); I2CStop(); I2CStart(); I2CSendByte(0x64); I2CWaitAck(); I2CSendByte(0x0F); //设置写地址0FH I2CWaitAck(); I2CSendByte(0x84); //置WRTC2,WRTC3=1 I2CWaitAck(); I2CStop(); } // //写SD2405禁止程序 // void WriteTimeOff(void) { I2CStart(); I2CSendByte(0x64); I2CWaitAck(); I2CSendByte(0x0F); //设置写地址0FH I2CWaitAck(); I2CSendByte(0x0) ; //置WRTC2,WRTC3=0 I2CWaitAck(); I2CStart(); I2CSendByte(0x64); I2CWaitAck(); I2CSendByte(0x10); //设置写地址10H I2CWaitAck(); I2CSendByte(0x0) ; //置WRTC1=0(10H地址) I2CWaitAck(); I2CStop(); } //设置SD2405中断程序(设置报警时间:小时+分钟) void WriteALARM(uint8_t hour , uint8_t minute) { WriteTimeOn(); //写SD2405允许 I2CStart(); I2CSendByte(0x64); //发送SD2400写寄存器命令 I2CWaitAck(); I2CSendByte(0x08); //发送起始地址(0x08=分钟报警寄存器) I2CWaitAck(); I2CSendByte(HEXtoBCD(minute)); //分钟 I2CWaitAck(); I2CStop(); I2CStart(); I2CSendByte(0x64); //发送SD2400写寄存器命令 I2CWaitAck(); I2CSendByte(0x09); //发送起始地址(0x09=小时报警寄存器) I2CWaitAck(); I2CSendByte(HEXtoBCD(hour)); //小时 I2CWaitAck(); I2CStop(); I2CStart(); I2CSendByte(0x64); //发送SD2400写寄存器命令 I2CWaitAck(); I2CSendByte(0x0E); //发送起始地址(0x0E=报警允许寄存器) I2CWaitAck(); I2CSendByte(0x06); //设置报警允许(使能小时、分钟报警) I2CWaitAck(); I2CStop(); I2CStart(); I2CSendByte(0x64); //发送SD2400写寄存器命令 I2CWaitAck(); I2CSendByte(0x10); //发送起始地址(0x10=CTR2控制寄存器) I2CWaitAck(); I2CSendByte(0x92); //设置INT中断选通(INTS1,INTS0),及报警中断总允许位(INTAE) I2CWaitAck(); I2CStop(); WriteTimeOff(); //写SD2405禁止 } //关闭报警中断 void ClrALARM(void) { WriteTimeOn(); //写SD2405允许 I2CStart(); I2CSendByte(0x64); //发送SD2400写寄存器命令 I2CWaitAck(); I2CSendByte(0x10); //发送起始地址 I2CWaitAck(); I2CSendByte(0x90); //清报警中断总允许位(INTAE) I2CWaitAck(); I2CStop(); WriteTimeOff(); //写SD2405禁止 }

 

最新回复(0)