×
单片机 > 单片机程序设计 > 详情

使用STM32 HAL库读取RTC时间芯片SD3088

发布时间:2020-08-27 发布时间:
|

信的RTC芯片看起来不错,但是贵。

威帆的SD3088这个不错,而且还可以给电池充电,便宜很多,淘宝上价格6元一片。我这项目对时间要求严格,就不使用1元多的芯片了。


网传STM32F1的I2C有Bug,模拟通信最为保险。

威帆网站上的例子是模拟的,看起来也蛮简单。官方说0.5秒内读值就行,要求不高。


我这里是使用HAL库,先前使用I2C读过PCF8563,看起来也正常。


环境:

IAR7.40

STM32CUBEMX 4.10.0

STM32F1 V1.20


1、STM32CUBEMX配置I2C

按默认值。

不启用中断。

不使用DMA。

  • /* 

  • *文件 sd3088.h 

  • */  

  • #ifndef SD3088_H  

  • #define SD3088_H  

  • #include "i2c.h"  

  • #define DEBUG  

  •   

  • #ifdef DEBUG  

  • #include "stdio.h"  

  • #endif  

  •   

  • #define RTC_Addr 0x64  //RTC器件地址  

  • #define IDcode 0x72  //8字节ID号起始地址  

  • #define Bat_High_Addr 0x1A  //电量最高位寄存器地址  

  • #define Bat_Low_Addr 0x1B  //电量低八位寄存器地址  

  •   

  • #define BCD2DEC(x) (((x) >> 4) * 10 + ((x) & 0x0f))  

  •   

  • typedef struct  

  • {  

  •   uint8_t second;  

  •   uint8_t minute;  

  •   uint8_t hour;  

  •   uint8_t week;  

  •   uint8_t day;  

  •   uint8_t month;  

  •   uint8_t year;  

  •   uint8_t quantity;  // 电量  

  • }Time;  

  •   

  • extern Time Time_sd3088;    //初始化时间结构体变量(设置时间:2014年11月12日 14:59:55  星期一)  

  •   

  • void read_rtc(void);  

  •   

  • #endif  




  • 4、sd3088.c


    1. /* 

    2. *SD3088时钟芯片 读写 

    3. *文件 sd3088.h 

    4. *作者 于 

    5. *麦知 www.mazclub.com 

    6. *版本 v1.0 

    7. */  

    8. #include "sd3088.h"  

    9.   

    10. extern I2C_HandleTypeDef hi2c1;  

    11.   

    12. Time Time_sd3088 = {0x55, 0x59, 0x14, 0x01, 0x12, 0x11, 0x14};  //初始化时间结构体变量(设置时间:2014年11月12日 14:59:55  星期一)  

    13.   

    14. uint8_t  rtc_data[8];       //通用数据缓存器  

    15. uint8_t sram[8];        //通用数据缓存器  

    16. uint8_t pdata;  

    17.   

    18. void read_rtc(void)  

    19. {    

    20.   // 读取时间  

    21.   pdata = 0;  

    22.   if(HAL_I2C_Master_Transmit(&hi2c1, 0x64, &pdata, 1, 1) == HAL_OK)  

    23.     if(HAL_I2C_Master_Receive(&hi2c1, 0x65, &rtc_data[0], 7, 1) == HAL_OK) {  

    24.         

    25.       Time_sd3088.second = BCD2DEC(rtc_data[0] & 0x7f);  

    26.       Time_sd3088.minute = BCD2DEC(rtc_data[1] & 0x7f);  

    27.       Time_sd3088.hour = BCD2DEC(rtc_data[2] & 0x1f);  

    28.       Time_sd3088.week = BCD2DEC(rtc_data[3] & 0x07);  

    29.       Time_sd3088.day = BCD2DEC(rtc_data[4] & 0x3f);  

    30.       Time_sd3088.month = BCD2DEC(rtc_data[5] & 0x1f);  

    31.       Time_sd3088.year = BCD2DEC(rtc_data[6]);   

    32.   

    33.     }  

    34.       

    35.   // 电量  

    36.   pdata = 0x1b;  

    37.   if(HAL_I2C_Master_Transmit(&hi2c1, 0x64, &pdata, 1, 1) == HAL_OK)  

    38.     if(HAL_I2C_Master_Receive(&hi2c1, 0x65, &rtc_data[7], 1, 1) == HAL_OK) {  

    39.       

    40.     Time_sd3088.quantity = BCD2DEC(rtc_data[7]);  

    41.   }  

    42.     

    43.           

    44.   #ifdef DEBUG  

    45.   printf("%d-%d-%d,week %d, %d:%d:%d, qualit:%d\r\n",Time_sd3088.year,Time_sd3088.month,Time_sd3088.day, \  

    46.        Time_sd3088.week,Time_sd3088.hour,Time_sd3088.minute,Time_sd3088.second, Time_sd3088.quantity);           

    47.   #endif  

    48.     

    49. }  





    存在的错误,读取 星期和电量不对。

  • /* USER CODE BEGIN 0 */  

  • FILE __stdout;  

  • /* USER CODE END 0 */  




  • 2)添加 函数


    在需要打印的位置使用printf函数即可, 头文件要保含 stdio.h。

    IAR的工程配置为默认。


    1. /* USER CODE BEGIN 1 */  

    2. int fputc(int ch, FILE *f)   

    3. {  

    4.     /* Send your custom byte */  

    5.     /* Send byte to USART */  

    6.   uint8_t ch_t[1] = {ch};  

    7.     HAL_UART_Transmit(&huart1, ch_t, 1, 1);   

    8.       

    9.     /* If everything is OK, you have to return character written */  

    10.     return ch;  

    11.     /* If character is not correct, you can return EOF (-1) to stop writing */  

    12.     //return -1;  

    13. }  

    14. /* USER CODE END 1 */  




    PC端使用Tera Term, 波特率是38400bps 。


    关键字:STM32  HAL库  读取RTC时间  SD3088 

    『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

    热门文章 更多
    浅谈AVR中定时器几种工作模式