[其他ST产品] 使用STM32 HAL库的硬件I2C驱动RX8025T实时时钟芯片

[复制链接]
2193|17
 楼主| gaonaiweng 发表于 2022-8-25 23:12 | 显示全部楼层 |阅读模式
基础配置
  • 使用单片机APM32F103RBT6
  • 使用外设I2C1 - PB7 SDA
  • 使用外设I2C1 - PB6 SCK
  • STM32CUBEMX 版本5.6
配置如下
2821563079162e0254.png

210466307916ad30df.png



 楼主| gaonaiweng 发表于 2022-8-25 23:14 | 显示全部楼层
i2c.c文件
  1. /**
  2.   ******************************************************************************
  3.   * File Name          : I2C.c
  4.   * Description        : This file provides code for the configuration
  5.   *                      of the I2C instances.
  6.   ******************************************************************************
  7.   * @attention
  8.   *
  9.   * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
  10.   * All rights reserved.</center></h2>
  11.   *
  12.   * This software component is licensed by ST under Ultimate Liberty license
  13.   * SLA0044, the "License"; You may not use this file except in compliance with
  14.   * the License. You may obtain a copy of the License at:
  15.   *                             www.st.com/SLA0044
  16.   *
  17.   ******************************************************************************
  18.   */

  19. /* Includes ------------------------------------------------------------------*/
  20. #include "i2c.h"

  21. /* USER CODE BEGIN 0 */

  22. /* USER CODE END 0 */

  23. I2C_HandleTypeDef hi2c1;

  24. /* I2C1 init function */
  25. void MX_I2C1_Init(void)
  26. {

  27.   hi2c1.Instance = I2C1;
  28.   hi2c1.Init.ClockSpeed = 100000;
  29.   hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  30.   hi2c1.Init.OwnAddress1 = 0;
  31.   hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  32.   hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  33.   hi2c1.Init.OwnAddress2 = 0;
  34.   hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  35.   hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  36.   if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  37.   {
  38.     Error_Handler();
  39.   }

  40. }

  41. void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
  42. {

  43.   GPIO_InitTypeDef GPIO_InitStruct = {0};
  44.   if(i2cHandle->Instance==I2C1)
  45.   {
  46.   /* USER CODE BEGIN I2C1_MspInit 0 */

  47.   /* USER CODE END I2C1_MspInit 0 */
  48.   
  49.     __HAL_RCC_GPIOB_CLK_ENABLE();
  50.     /**I2C1 GPIO Configuration   
  51.     PB6     ------> I2C1_SCL
  52.     PB7     ------> I2C1_SDA
  53.     */
  54.     GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
  55.     GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
  56.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  57.     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  58.     /* I2C1 clock enable */
  59.     __HAL_RCC_I2C1_CLK_ENABLE();
  60.   /* USER CODE BEGIN I2C1_MspInit 1 */

  61.   /* USER CODE END I2C1_MspInit 1 */
  62.   }
  63. }

  64. void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle)
  65. {

  66.   if(i2cHandle->Instance==I2C1)
  67.   {
  68.   /* USER CODE BEGIN I2C1_MspDeInit 0 */

  69.   /* USER CODE END I2C1_MspDeInit 0 */
  70.     /* Peripheral clock disable */
  71.     __HAL_RCC_I2C1_CLK_DISABLE();
  72.   
  73.     /**I2C1 GPIO Configuration   
  74.     PB6     ------> I2C1_SCL
  75.     PB7     ------> I2C1_SDA
  76.     */
  77.     HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);

  78.   /* USER CODE BEGIN I2C1_MspDeInit 1 */

  79.   /* USER CODE END I2C1_MspDeInit 1 */
  80.   }
  81. }

  82. /* USER CODE BEGIN 1 */

  83. /*******************************************************************************
  84. * 函数名: WriteI2CTData
  85. * 描述  : 写入I2C数据
  86. * 参数  : addr设备地址,reg 寄存器地址 *buf写入的数据,len写入的长度
  87. * 返回值:
  88. *******************************************************************************/
  89. HAL_StatusTypeDef WriteI2cData(uint8_t addr, uint8_t reg, uint8_t *pBuffer, uint8_t len)
  90. {
  91.         HAL_StatusTypeDef status = HAL_OK;
  92.   
  93.   status = HAL_I2C_Mem_Write(&hi2c1, addr, (uint16_t)reg, I2C_MEMADD_SIZE_8BIT, pBuffer, len, 1000);
  94.       
  95.   return status;
  96. }

  97. /*******************************************************************************
  98. * 函数名: ReadI2cData
  99. * 描述  : 读RX8025T寄存器
  100. * 参数  : addr寄存器地址,*buf存储位置,len读取的长度
  101. * 返回值: 1=操作失败,0=操作成功
  102. *******************************************************************************/
  103. uint8_t ReadI2cData(uint8_t addr, uint8_t reg, uint8_t *buf,uint8_t len)
  104. {
  105.         HAL_StatusTypeDef status = HAL_OK;
  106.        
  107.         status = HAL_I2C_Mem_Read(&hi2c1, addr, (uint16_t)reg, I2C_MEMADD_SIZE_8BIT, buf, len, 1000);
  108.        
  109.         return status;
  110. }

  111. /*******************************************************************************
  112. * 函数名: I2cIsDeviceReady
  113. * 描述  : 检测I2C设备是否处于准备好可以通信状态
  114. * 参数  : DevAddress 设备地址,Trials 尝试测试次数
  115. * 返回值:
  116. *******************************************************************************/
  117. HAL_StatusTypeDef I2cIsDeviceReady(uint16_t DevAddress, uint32_t Trials)
  118. {
  119.   return (HAL_I2C_IsDeviceReady(&hi2c1, DevAddress, Trials, 1000));
  120. }

  121. /* USER CODE END 1 */

  122. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

 楼主| gaonaiweng 发表于 2022-8-25 23:15 | 显示全部楼层
i2c.h文件
  1. /**
  2.   ******************************************************************************
  3.   * File Name          : I2C.h
  4.   * Description        : This file provides code for the configuration
  5.   *                      of the I2C instances.
  6.   ******************************************************************************
  7.   * @attention
  8.   *
  9.   * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
  10.   * All rights reserved.</center></h2>
  11.   *
  12.   * This software component is licensed by ST under Ultimate Liberty license
  13.   * SLA0044, the "License"; You may not use this file except in compliance with
  14.   * the License. You may obtain a copy of the License at:
  15.   *                             www.st.com/SLA0044
  16.   *
  17.   ******************************************************************************
  18.   */
  19. /* Define to prevent recursive inclusion -------------------------------------*/
  20. #ifndef __i2c_H
  21. #define __i2c_H
  22. #ifdef __cplusplus
  23. extern "C" {
  24. #endif

  25. /* Includes ------------------------------------------------------------------*/
  26. #include "main.h"

  27. /* USER CODE BEGIN Includes */

  28. /* USER CODE END Includes */

  29. extern I2C_HandleTypeDef hi2c1;

  30. /* USER CODE BEGIN Private defines */

  31. /* USER CODE END Private defines */

  32. void MX_I2C1_Init(void);

  33. /* USER CODE BEGIN Prototypes */
  34. HAL_StatusTypeDef WriteI2cData(uint8_t addr, uint8_t reg, uint8_t *pBuffer, uint8_t len);
  35. uint8_t ReadI2cData(uint8_t addr, uint8_t reg, uint8_t *buf,uint8_t len);
  36. HAL_StatusTypeDef I2cIsDeviceReady(uint16_t DevAddress, uint32_t Trials);
  37. /* USER CODE END Prototypes */

  38. #ifdef __cplusplus
  39. }
  40. #endif
  41. #endif /*__ i2c_H */

  42. /**
  43.   * @}
  44.   */

  45. /**
  46.   * @}
  47.   */

  48. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

 楼主| gaonaiweng 发表于 2022-8-25 23:16 | 显示全部楼层
bsp_rtc.c文件(名字可以自己随意定义)
  1. #include "bsp.h"
  2. #include "app_task.h"


  3. #define  RX8025T_DEVICE_ADDRESS  0x64


  4. /***********************************************************************************

  5.                 RX8025T实时时钟驱动程序(硬件IIC)
  6.                
  7.                 BL8025T 的从地址为 7bit 固定的数据(0110 010)在通信时,从地址是附加上 R/W 以 8bit 数据发送的。
  8.                 0110 0100为写模式,0110 0101为读模式,对应十进制为:100、101;对应16进制为:0x64、0x65。
  9.                
  10.                 BL8025T 有地址自动增加功能。指定的从地址一旦开始,之后只有数据字节被发送。每个字节后,BL8025T 的地址自动增加。
  11.                
  12. ***********************************************************************************/


  13. /*
  14. *********************************************************************************************************
  15. *        函 数 名: bsp_InitRtc
  16. *        功能说明: 初始RTC. 该函数被 bsp_Init() 调用。
  17. *        形    参: 无
  18. *        返 回 值: 无
  19. *********************************************************************************************************
  20. */
  21. void bsp_InitRtc(void)
  22. {

  23.         uint8_t status;
  24.                 //固定周期时钟源为分钟更新
  25.         uint8_t val[3]={0x03,0x00,0x40};  //0x0D、0x0E、0x0F、三个寄存器的值,设置时间更新为“秒”更新,关闭所有闹钟,温补时间为2秒,打开时间更新中断,关闭其他中断。
  26.                   
  27.        
  28.         status = WriteI2cData(RX8025T_DEVICE_ADDRESS, RX8025T_EXT_REG,val,3);

  29.   printf("RX8025T set OK! %d\r\n", status);       
  30. }



  31. /*******************************************************************************
  32. * 函数名: bsp_SetRTCAlarm
  33. * 描述  : 设置RX8025T的闹钟
  34. * 参数  : 存储时间的结构体
  35. * 返回值: 0成功,其它失败。
  36. *******************************************************************************/
  37. uint8_t bsp_SetRTCAlarm(uint16_t alarm)
  38. {
  39.                  uint8_t  status;
  40.                 uint8_t  value = 0;
  41.                 uint8_t  reg_cy1[2];//报警固定周期寄存器
  42.                 uint8_t  reg[3];
  43. //        uint8_t  buf[5];
  44. /*
  45.                 固定周期定时器配置

  46.                 先将TIE置“0”,以避免在配置固定周期中断的同时发生意外的硬件中断。
  47.                 (1) 设定TSEL1,0两位选择倒计时周期。
  48.                 (2) 设定B,C寄存器,从而设置减法计数器的初值,然后初始化TF标志为“0”。
  49.                 (3) 设置TIE,TE位为“1”

  50. */       
  51.                         value = 0x40;
  52.                         status = WriteI2cData(RX8025T_DEVICE_ADDRESS, RX8025T_CONT_REG, &value, 1);
  53.        
  54.                         value = 0x00;
  55.                         status = WriteI2cData(RX8025T_DEVICE_ADDRESS, RX8025T_EXT_REG, &value, 1);                       
  56.                        
  57.                         reg_cy1[0] = alarm & 0xFF;
  58.                         reg_cy1[1] = (alarm >> 8) & 0xFF;                       
  59.                         status = WriteI2cData(RX8025T_DEVICE_ADDRESS, RX8025T_CYl_REG, reg_cy1, 2);               
  60.                        
  61.                         reg[0] = 0x13;                //分钟更新
  62.                         reg[1] = 0x10;
  63.                         reg[2] = 0x50;       
  64.                         status = WriteI2cData(RX8025T_DEVICE_ADDRESS, RX8025T_EXT_REG, reg, 3);               
  65.        
  66.                         return status;
  67.   
  68. }

  69. /*******************************************************************************
  70. * 函数名: bsp_GetRtcTime
  71. * 描述  : 从RX8025T获取时间
  72. * 参数  : 存储时间的结构体
  73. * 返回值: 0成功,1失败。
  74. *******************************************************************************/
  75. uint8_t bsp_GetRtcTime(TIME_T *t)
  76. {
  77.         uint8_t rtc_str[7];
  78.   
  79.         if(ReadI2cData(RX8025T_DEVICE_ADDRESS, RX8025T_SEC_REG, rtc_str,7) != 0)  //获取日期与时间
  80.                 return 1;  //读取出错

  81.         t->second = ((rtc_str[0]>>4)*10) + (rtc_str[0] & 0x0f);
  82.         t->minute = ((rtc_str[1]>>4)*10) + (rtc_str[1] & 0x0f);
  83.         t->hour   = ((rtc_str[2]>>4)*10) + (rtc_str[2] & 0x0f);
  84.         t->week                = rtc_str[3];       
  85.         t->day    = ((rtc_str[4]>>4)*10) + (rtc_str[4] & 0x0f);
  86.         t->month  = ((rtc_str[5]>>4)*10) + (rtc_str[5] & 0x0f);
  87.   t->year   = ((rtc_str[6]>>4)*10) + (rtc_str[6] & 0x0f);
  88.        
  89.         return 0;
  90. }

  91. /*******************************************************************************
  92. * 函数名: bsp_SetRtcTime
  93. * 描述  : 设置RX8025T时间
  94. * 参数  : 存储时间的结构体
  95. * 返回值: 0成功,1失败。
  96. *******************************************************************************/
  97. uint8_t bsp_SetRtcTime(TIME_T *t)
  98. {
  99.                 uint8_t  status;
  100.                 uint8_t rtc_str[7];
  101.        
  102.                 rtc_str[0] = ((t->second/10)<<4) | (t->second%10);
  103.                 rtc_str[1] = ((t->minute/10)<<4) | (t->minute%10);
  104.                 rtc_str[2] = ((t->hour/10)<<4) | (t->hour%10);
  105.                 rtc_str[3] = t->week;
  106.                 rtc_str[4] = ((t->day/10)<<4) | (t->day%10);
  107.                 rtc_str[5] = ((t->month/10)<<4) | (t->month%10);
  108.                 rtc_str[6] = ((t->year/10)<<4) | (t->year%10);

  109.                
  110.                 status = WriteI2cData(RX8025T_DEVICE_ADDRESS, RX8025T_SEC_REG, rtc_str, 7);               
  111.                 return status;
  112. }



 楼主| gaonaiweng 发表于 2022-8-25 23:17 | 显示全部楼层
bsp_rtc.h文件(名字可以自己随意定义)
  1. #ifndef _BSP_RTC_H_
  2. #define _BSP_RTC_H_


  3. #define RX8025T_SEC_REG                0x00        //秒
  4. #define RX8025T_MIN_REG         0x01        //分
  5. #define RX8025T_HOU_REG                0x02        //时
  6. #define RX8025T_WEE_REG          0x03        //星期,bit0~bit7对应日、一、二、三、四、五、六,对应值为0x01,0x02,0x04,0x08,0x10,0x20,0x40,不可出现2位为1的情况。
  7. #define RX8025T_DAY_REG                0x04        //日期
  8. #define RX8025T_MON_REG         0x05        //月份
  9. #define RX8025T_YEA_REG                0x06        //年
  10. #define RX8025T_RAM_REG                0x07        //RAM

  11. #define RX8025T_ALm_REG         0x08        //闹钟分,不用是可做为ram使用。
  12. #define RX8025T_ALh_REG                0x09        //闹钟时,不用是可做为ram使用。

  13. #define RX8025T_ALw_REG         0x0a        //闹钟星期,不用是可做为ram使用。
  14. #define RX8025T_CYl_REG          0x0b        //周期定时器的低8位
  15. #define RX8025T_CYm_REG          0x0c        //周期定时器的高4位,周期定时器共计12位。

  16. #define RX8025T_EXT_REG          0x0d        //扩展寄存器,bit7-TEST=工厂测试,总应该写0;bit6-WADA=星期或日历报警选择位;bit5-USEL=选择秒或分钟更新触发更新中断,0=秒更新,1=分钟更新;
  17.                                                                                                                                                         //bit4-TE=周期定时使能;bit3\2-FSEL1\0=芯片FOUT引脚输出频率选择位;bit1\0-TSEL1\0=用来设定固定周期的内部时钟源。

  18. #define RX8025T_FLAG_REG        0x0e        //标志寄存器,bit5-UF,bit4-TF,bit3-AF,分别是时间更新中断,固定周期定时中断,闹钟中断的中断标志位;bit1-VLF电压低,bit0-VDET由于电压低温补停止工作标志位。

  19. #define RX8025T_CONT_REG         0x0f        //控制寄存器,bit6~7(CSEL0、1)=温补间隔设置;bit5(UIE)=时间更新中断使能位(可由D寄存器的USEL位配置为1秒更新或1分钟更新);
  20.    

  21. #define TESL1_0_CLOCK_4069                        0
  22. #define TESL1_0_CLOCK_64                                1
  23. #define TESL1_0_CLOCK_S                                        2
  24. #define TESL1_0_CLOCK_M                                        3


  25. //TE 位  此位是用来控制固定周期定时功能使能。
  26. //置“1”是选择开启固定周期定时功能。
  27. //置“0”是选择关闭固定周期定时功能。
  28. #define TE_1                                                                                        1<<4       
  29. #define TE_0                                                                                        (~(1<<4))
  30.        

  31. #define TF_1                                                                                        1<<4       
  32. #define TF_0                                                                                        (~(1<<4))


  33. #define TF_FLAG                                                                                0x10


  34. //定时中断使能位
  35. #define TIE_1                                                                                        1<<4       
  36. #define TIE_0                                                                                        (~(1<<4))


  37. typedef struct  // _TIME  
  38. {
  39.         uint8_t second;
  40.         uint8_t minute;
  41.         uint8_t hour;
  42.         uint8_t week;
  43.         uint8_t day;
  44.         uint8_t month;
  45.         uint8_t year;
  46.         uint8_t reserve;
  47. }TIME_T;




  48. void bsp_InitRtc(void);
  49. uint8_t bsp_SetRTCAlarm(uint16_t alarm);
  50. uint8_t bsp_SetRtcTime(TIME_T *t);
  51. uint8_t bsp_GetRtcTime(TIME_T *t);












  52. #endif





cashrwood 发表于 2022-11-17 14:53 | 显示全部楼层
有模拟iic驱动代码吗?向移植到其他的单片机上。
yeates333 发表于 2022-11-17 15:09 | 显示全部楼层
不是内部集成了RTC时钟了吗?              
jimmhu 发表于 2022-11-17 15:30 | 显示全部楼层
为什么要用RX8025T时钟芯片替代外置32.768KHZ晶振?
bestwell 发表于 2022-11-17 19:33 | 显示全部楼层
硬件iic会不会造成死机?              
zerorobert 发表于 2022-11-17 20:01 | 显示全部楼层
3231和8025t 哪个精度更高  
sdlls 发表于 2022-11-17 20:29 | 显示全部楼层
RX8025T组成的RTC电路图中的元器件问题,求一个原理图
jtracy3 发表于 2022-11-17 20:56 | 显示全部楼层
RX8025T实时时钟芯片能够提供中断吗?
youtome 发表于 2022-11-20 13:54 | 显示全部楼层
这个还是使用ds1302啊              
alvpeg 发表于 2022-11-20 17:04 | 显示全部楼层
RX8025T的精度大约是多少?
Clyde011 发表于 2024-11-12 07:16 | 显示全部楼层

在其他的交流电流环路都布置好后再放置
公羊子丹 发表于 2024-11-12 08:09 | 显示全部楼层

I2C1的时钟可以自行选择HSI或者SYSCLK
万图 发表于 2024-11-12 09:12 | 显示全部楼层

任何与多条功率线相连的功率器件要尽可能紧挨在一起,以减短连线长度
Uriah 发表于 2024-11-12 10:15 | 显示全部楼层

工作时的电压降低了
帛灿灿 发表于 2024-11-12 12:11 | 显示全部楼层

发射出过量的电磁干扰(EMI)
Bblythe 发表于 2024-11-12 13:14 | 显示全部楼层

典型的转换时间大约是50ns
您需要登录后才可以回帖 登录 | 注册

本版积分规则

80

主题

875

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部