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

        因项目需要使用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
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,您可以参考以下步骤进行操作: 1. 在 CubeMX 中配置 PB6 和 PB7 为 I2C 接口的 SCL 和 SDA 引脚,并使能 I2C 接口。 2. 在 main 函数中初始化 I2C 接口,可以使用 HAL_I2C_Init 函数进行初始化。示例代码如下: ```c /* I2C 初始化结构体 */ I2C_HandleTypeDef hi2c1; /* 初始化 I2C 接口 */ void MX_I2C1_Init(void) { hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 100000; hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { Error_Handler(); } } ``` 3. 连接 HYM8563 时间芯片到 I2C 接口上,并写入数据。可以使用 HAL_I2C_Master_Transmit 函数进行数据写入。示例代码如下: ```c #define HYM8563_ADDR 0xD0 uint8_t data[3] = {0x00, 0x01, 0x02}; /* 写入数据到 HYM8563 */ void HYM8563_WriteData(void) { if (HAL_I2C_Master_Transmit(&hi2c1, HYM8563_ADDR, data, 3, HAL_MAX_DELAY) != HAL_OK) { Error_Handler(); } } ``` 4. 从 HYM8563 时间芯片中读取数据。可以使用 HAL_I2C_Master_Receive 函数进行数据读取。示例代码如下: ```c #define HYM8563_ADDR 0xD0 uint8_t data[3]; /* 从 HYM8563 中读取数据 */ void HYM8563_ReadData(void) { if (HAL_I2C_Master_Receive(&hi2c1, HYM8563_ADDR, data, 3, HAL_MAX_DELAY) != HAL_OK) { Error_Handler(); } } ``` 注意,HYM8563 的地址为 0xD0,其中高 7 位为地址码,最低位为读写控制位,读取时为 1,写入时为 0。在传输数据时,需要传入正确的地址码。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值