[综合信息] 华大HC32L130/HC32L136驱动RTC时钟芯片BL5372

[复制链接]
2445|21
 楼主| 和下土 发表于 2023-8-27 18:12 | 显示全部楼层 |阅读模式
先放一张BL5372使用文档里的原理图
7542464eb2177f30ba.png
 楼主| 和下土 发表于 2023-8-27 18:12 | 显示全部楼层
这里与RTC模块通信用的是模拟IIC 由手册知道IIC写地址为0x64 读为0x65
以下部分代码 为模拟IIC的一些函数 与设置/调取时间的一些函数
 楼主| 和下土 发表于 2023-8-27 18:12 | 显示全部楼层
  1. #include "RTC_BL5372.h"
  2. #include "rx.h"
  3. #include "DataStore.h"
  4. #include "ddl.h"


  5. h_alarm_set alarm_value;
  6. h_rtc_init_time current_time;
  7. h_rtc_read_time current_read_time;



  8. void RTC_SDA_IN(void)
  9. {
  10.     stc_gpio_cfg_t stcGpioCfg;

  11.     Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); //打开GPIO外设时钟

  12.     stcGpioCfg.enDir = GpioDirIn;   //端口方向配置->输入
  13.     stcGpioCfg.enDrv = GpioDrvL;    //驱动能力配置->高驱动能力
  14.     stcGpioCfg.enPu = GpioPuEnable; //端口上下拉配置->无
  15.     stcGpioCfg.enPd = GpioPdDisable;
  16.     stcGpioCfg.enOD = GpioOdDisable; //开漏输出配置->开漏输出关闭
  17.     stcGpioCfg.enCtrlMode = GpioAHB; //总线控制模式配置->AHB

  18.     Gpio_Init(RTC_IIC_PORT, RTC_IIC_SDA, &stcGpioCfg);
  19. }

  20. void RTC_SDA_OUT(void)
  21. {
  22.     stc_gpio_cfg_t stcGpioCfg;

  23.     Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); //打开GPIO外设时钟

  24.     stcGpioCfg.enDir = GpioDirOut;  //端口方向配置->输入
  25.     stcGpioCfg.enDrv = GpioDrvL;    //驱动能力配置->高驱动能力
  26.     stcGpioCfg.enPu = GpioPuEnable; //端口上下拉配置->无
  27.     stcGpioCfg.enPd = GpioPdDisable;
  28.     stcGpioCfg.enOD = GpioOdDisable; //开漏输出配置->开漏输出关闭
  29.     stcGpioCfg.enCtrlMode = GpioAHB; //总线控制模式配置->AHB

  30.     Gpio_Init(RTC_IIC_PORT, RTC_IIC_SDA, &stcGpioCfg);
  31. }

  32. //初始化IIC
  33. void RTC_IIC_Init(void)
  34. {
  35.     stc_gpio_cfg_t stcGpioCfg;

  36.     Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); //打开GPIO外设时钟

  37.     stcGpioCfg.enDir = GpioDirOut;   //端口方向配置->输入
  38.     stcGpioCfg.enDrv = GpioDrvL;     //驱动能力配置->高驱动能力
  39.     stcGpioCfg.enPu = GpioPuDisable; //端口上下拉配置->无
  40.     stcGpioCfg.enPd = GpioPdDisable;
  41.     stcGpioCfg.enOD = GpioOdDisable; //开漏输出配置->开漏输出关闭
  42.     stcGpioCfg.enCtrlMode = GpioAHB; //总线控制模式配置->AHB

  43.     Gpio_Init(RTC_IIC_PORT, RTC_IIC_SCL, &stcGpioCfg);
  44.     Gpio_Init(RTC_IIC_PORT, RTC_IIC_SDA, &stcGpioCfg);

  45.     Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
  46.     Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SDA);
  47. }
  48. //产生IIC起始信号
  49. void RTC_IIC_Start(void)
  50. {
  51.     RTC_SDA_OUT(); // sda线输出
  52.     Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SDA);
  53.     Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
  54.     Ddl_Delay1us(4);
  55.     Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SDA); // START:when CLK is high,DATA change form high to low
  56.     Ddl_Delay1us(4);
  57.     Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL); //钳住I2C总线,准备发送或接收数据
  58. }
  59. //产生IIC停止信号
  60. void RTC_IIC_Stop(void)
  61. {
  62.     RTC_SDA_OUT(); // sda线输出
  63.     Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL);
  64.     Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SDA); // STOP:when CLK is high DATA change form low to high
  65.     Ddl_Delay1us(4);
  66.     Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
  67.     Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SDA); //发送I2C总线结束信号
  68.     Ddl_Delay1us(4);
  69. }
  70. //等待应答信号到来
  71. //返回值:1,接收应答失败
  72. //        0,接收应答成功
  73. u8 RTC_IIC_Wait_Ack(void)
  74. {
  75.     u8 ucErrTime = 0;
  76.     RTC_SDA_IN(); // SDA设置为输入
  77.     Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SDA);
  78.     Ddl_Delay1us(2);
  79.     Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
  80.     Ddl_Delay1us(2);
  81.     while (RTC_READ_SDA == TRUE)
  82.     {
  83.         ucErrTime++;
  84.         if (ucErrTime > 250)
  85.         {
  86.             RTC_IIC_Stop();
  87.             return 1;
  88.         }
  89.     }
  90.     Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL); //时钟输出0
  91.     return 0;
  92. }
  93. //产生ACK应答
  94. void RTC_IIC_Ack(void)
  95. {
  96.     Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL);
  97.     RTC_SDA_OUT();
  98.     Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SDA);
  99.     Ddl_Delay1us(2);
  100.     Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
  101.     Ddl_Delay1us(2);
  102.     Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL);
  103. }
  104. //不产生ACK应答
  105. void RTC_IIC_NAck(void)
  106. {
  107.     Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL);
  108.     RTC_SDA_OUT();
  109.     Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SDA);
  110.     Ddl_Delay1us(2);
  111.     Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
  112.     Ddl_Delay1us(2);
  113.     Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL);
  114. }
  115. // IIC发送一个字节
  116. //返回从机有无应答
  117. // 1,有应答
  118. // 0,无应答
  119. void RTC_IIC_Send_Byte(u8 txd)
  120. {
  121.     u8 t;
  122.     RTC_SDA_OUT();
  123.     Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL); //拉低时钟开始数据传输
  124.     for (t = 0; t < 8; t++)
  125.     {
  126.         // RTC_IIC_SDA=(txd&0x80)>>7;
  127.         if ((txd & 0x80) >> 7)
  128.             Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SDA);
  129.         else
  130.             Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SDA);
  131.         txd <<= 1;
  132.         // Ddl_Delay1us(2); //对TEA5767这三个延时都是必须的
  133.         Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
  134.         // Ddl_Delay1us(2);
  135.         Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL);
  136.         // Ddl_Delay1us(2);
  137.     }
  138. }
  139. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
  140. u8 RTC_IIC_Read_Byte(unsigned char ack)
  141. {
  142.     unsigned char i, receive = 0;
  143.     RTC_SDA_IN(); // SDA设置为输入
  144.     for (i = 0; i < 8; i++)
  145.     {
  146.         Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL);
  147.         delay10us(1);
  148.         Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
  149.         receive <<= 1;
  150.         if (RTC_READ_SDA == TRUE)
  151.             receive++;
  152.         Ddl_Delay1us(1);
  153.     }
  154.     if (!ack)
  155.         RTC_IIC_NAck(); //发送nACK
  156.     else
  157.         RTC_IIC_Ack(); //发送ACK
  158.     return receive;
  159. }

  160. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
  161. u8 RTC_IIC_Read_Byte_Fast_Ack(unsigned char ack)
  162. {
  163.     unsigned char i, receive = 0;
  164.     RTC_SDA_IN(); // SDA设置为输入
  165.     for (i = 0; i < 8; i++)
  166.     {
  167.         Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL);
  168.         Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
  169.         receive <<= 1;
  170.         if (RTC_READ_SDA == TRUE)
  171.             receive++;
  172.     }
  173.     if (!ack)
  174.         RTC_IIC_NAck(); //发送nACK
  175.     else
  176.         RTC_IIC_Ack(); //发送ACK
  177.     return receive;
  178. }

  179. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
  180. u8 RTC_IIC_Read_Byte_Fast_No_Ack()
  181. {
  182.     unsigned char i, receive = 0;
  183.     RTC_SDA_IN(); // SDA设置为输入
  184.     for (i = 0; i < 8; i++)
  185.     {
  186.         Gpio_ClrIO(RTC_IIC_PORT, RTC_IIC_SCL);
  187.         Gpio_SetIO(RTC_IIC_PORT, RTC_IIC_SCL);
  188.         receive <<= 1;
  189.         if (RTC_READ_SDA == TRUE)
  190.             receive++;
  191.     }

  192.     return receive;
  193. }

  194. //初始化IIC接口
  195. void RTC_Init(void)
  196. {
  197.     RTC_IIC_Init();
  198. }
  199. //在AT24CXX指定地址读出一个数据
  200. // ReadAddr:开始读数的地址
  201. //返回值  :读到的数据
  202. u8 RTC_ReadOneByte(u16 ReadAddr)
  203. {
  204.     u8 temp = 0;
  205.     RTC_IIC_Start();
  206.     RTC_IIC_Send_Byte(IIC_WRITE_ARR); //发送写命令
  207.     RTC_IIC_Wait_Ack();
  208.     RTC_IIC_Send_Byte(((ReadAddr<<4)|0)); //发送高地址
  209.     RTC_IIC_Wait_Ack();
  210.     RTC_IIC_Start();
  211.     RTC_IIC_Send_Byte(IIC_READ_ARR); //进入接收模式
  212.     RTC_IIC_Wait_Ack();
  213.     temp = RTC_IIC_Read_Byte(0);
  214.     // IIC_NAck();
  215.     RTC_IIC_Stop(); //产生一个停止条件

  216.     delay1ms(1);
  217.     Wdt_Feed();
  218.     return temp;
  219. }
  220. //在AT24CXX指定地址写入一个数据
  221. // WriteAddr  :写入数据的目的地址
  222. // DataToWrite:要写入的数据
  223. void RTC_WriteOneByte(u16 WriteAddr, u8 DataToWrite)
  224. {
  225. RTC_IIC_Start();
  226. RTC_IIC_Send_Byte(IIC_WRITE_ARR); //发送写命令
  227. RTC_IIC_Wait_Ack();
  228. RTC_IIC_Send_Byte(((WriteAddr<<4)|0)); //发送高地址
  229. RTC_IIC_Wait_Ack();
  230. RTC_IIC_Send_Byte(DataToWrite); //发送字节
  231. RTC_IIC_Wait_Ack();
  232. RTC_IIC_Stop(); //产生一个停止条件

  233.     delay1ms(10);
  234. }

  235. //在AT24CXX里面的指定地址开始写入长度为Len的数据
  236. //该函数用于写入16bit或者32bit的数据.
  237. // WriteAddr  :开始写入的地址
  238. // DataToWrite:数据数组首地址
  239. // Len        :要写入数据的长度2,4
  240. void RTC_WriteLenByte(u16 WriteAddr, unsigned char *pBuffer, u8 Len)
  241. {       
  242.         while(Len--)
  243.         {
  244.                 RTC_WriteOneByte(WriteAddr,*pBuffer);
  245.                 WriteAddr++;
  246.                 pBuffer++;
  247.         }
  248. }

  249. //在AT24CXX里面的指定地址开始读出长度为Len的数据
  250. //该函数用于读出16bit或者32bit的数据.
  251. // ReadAddr   :开始读出的地址
  252. //返回值     :数据
  253. // Len        :要读出数据的长度2,4

  254. void RTC_ReadLenByte(unsigned char ReadAddr,unsigned char *pBuffer,unsigned char NumToRead)
  255. {
  256.         while(NumToRead)
  257.         {
  258.                 *pBuffer++=RTC_ReadOneByte(ReadAddr++);       
  259.                 NumToRead--;
  260.         }
  261. }
  262. //检查AT24CXX是否正常
  263. //这里用了24XX的最后一个地址(255)65535来存储标志字.
  264. //如果用其他24C系列,这个地址要修改
  265. //返回1:检测失败
  266. //返回0:检测成功
  267. u8 RTC_Check(void)
  268. {
  269.     u8 temp;
  270.     temp = RTC_ReadOneByte(65535); //避免每次开机都写AT24CXX
  271.     if (temp == 0x55)
  272.         return 0;
  273.     else //排除第一次初始化的情况
  274.     {
  275.         RTC_WriteOneByte(65535, 0x55);
  276.         temp = RTC_ReadOneByte(65535);
  277.         if (temp == 0x55)
  278.             return 0;
  279.     }
  280.     return 1;
  281. }

  282. //在AT24CXX里面的指定地址开始读出指定个数的数据
  283. // ReadAddr :开始读出的地址 对24c02为0~255
  284. // pBuffer  :数据数组首地址
  285. // NumToRead:要读出数据的个数
  286. void RTC_Read(u16 ReadAddr, u8 *pBuffer, u16 NumToRead)
  287. {
  288.     while (NumToRead)
  289.     {
  290.         *pBuffer++ = RTC_ReadOneByte(ReadAddr++);
  291.         // printf("%c\n",*pBuffer);//显示读到的字符串
  292.         NumToRead--;
  293.                        
  294.                                 Wdt_Feed();
  295.     }
  296. }
  297. //在AT24CXX里面的指定地址开始写入指定个数的数据
  298. // WriteAddr :开始写入的地址 对24c02为0~255
  299. // pBuffer   :数据数组首地址
  300. // NumToWrite:要写入数据的个数
  301. void RTC_Write(u16 WriteAddr, u8 *pBuffer, u16 NumToWrite)
  302. {
  303.     while (NumToWrite--)
  304.     {
  305.         RTC_WriteOneByte(WriteAddr, *pBuffer);
  306.         WriteAddr++;
  307.         pBuffer++;
  308.                        
  309.                                 Wdt_Feed();
  310.     }
  311. }


  312. //用来设置当前的时间
  313. void BL5372_init(h_rtc_init_time time)
  314. {
  315.                 unsigned char  BL5372buf[16];
  316.             unsigned char temp;
  317.                     unsigned char index=0;

  318.                ///RTC_IIC_Init

  319.                            BL5372buf[index++]=time.Set_Second;second
  320.                            BL5372buf[index++]=time.Set_Minute;minute
  321.                            BL5372buf[index++]=time.Set_Hour;hour
  322.                            BL5372buf[index++]=time.Set_Week;week
  323.                            BL5372buf[index++]=time.Set_Day;day
  324.                            BL5372buf[index++]=time.Set_Month;month
  325.                            BL5372buf[index++]=time.Set_Year;///year
  326.                            BL5372buf[index++]=0x00;
  327.                            BL5372buf[index++]=0x00;
  328.                            BL5372buf[index++]=0x00;
  329.                            BL5372buf[index++]=0x00;
  330.                            BL5372buf[index++]=0x00;
  331.                            BL5372buf[index++]=0x00;
  332.                            BL5372buf[index++]=0x00;
  333.                BL5372buf[index++]=RTC_CRL_G1_USUAL;
  334.                            BL5372buf[index++]=RTC_CRL_G2_USUAL;                                 
  335.               do{
  336.                    RTC_WriteLenByte(0x00,BL5372buf,16);
  337.                    temp=RTC_ReadOneByte(RTC_CRL_G2_ARR);
  338.                                    }while((temp&0x10)==0x10);
  339.        
  340. }       


  341. //读当前时间
  342. void Read_Nowtime(h_rtc_read_time *read_time)
  343. {  
  344.     read_time->Second=RTC_ReadOneByte(RTC_SECOND_ARR);
  345.           read_time->Minute=RTC_ReadOneByte(RTC_MINUTE_ARR);
  346.     read_time->Hour=RTC_ReadOneByte(RTC_HOUR_ARR);
  347.     read_time->Week=RTC_ReadOneByte(RTC_WEEK_ARR);
  348.     read_time->Day=RTC_ReadOneByte(RTC_DAY_ARR);
  349.     read_time->Month=RTC_ReadOneByte(RTC_MONTH_ARR);
  350.           read_time->Year=RTC_ReadOneByte(RTC_YEAR_ARR);
  351.           read_time->Control_1=RTC_ReadOneByte(RTC_CRL_G1_ARR);
  352.           read_time->Control_2=RTC_ReadOneByte(RTC_CRL_G2_ARR);
  353. }

  354. //自定义时间闹钟
  355. void RTC_SetAlarm(h_alarm_set value)
  356. {
  357.                 RTC_WriteOneByte(ALARM_CLOCK_MINUTE_ARR,value.Minute);
  358.                 RTC_WriteOneByte(ALARM_CLOCK_HOUR_ARR,value.Hour);
  359.                 RTC_WriteOneByte(ALARM_CLOCK_WEEK_ARR,value.Week);
  360.                 RTC_WriteOneByte(RTC_CRL_G1_ARR,RTC_CRL_G1_ALARM);
  361.                 RTC_WriteOneByte(RTC_CRL_G2_ARR,RTC_CRL_G2_ALARM);
  362. }       

  363. //定时间隔输出
  364. void RTC_Fixed_interval_timer(interval_timer Mode)
  365. {
  366.                 RTC_WriteOneByte(RTC_CRL_G1_ARR,Mode);
  367.                 RTC_WriteOneByte(RTC_CRL_G2_ARR,RTC_CRL_G2_USUAL);
  368. }       
 楼主| 和下土 发表于 2023-8-27 18:12 | 显示全部楼层
下面为.h文件
  1. #ifndef __RTC_BL5372_H
  2. #define __RTC_BL5372_H

  3. #include "main.h"
  4. #include "rx.h"
  5. #include "device_menu.h"

  6. //IO操作函数
  7. #define RTC_IIC_PORT GpioPortB
  8. #define RTC_IIC_SCL GpioPin8                           //SCL
  9. #define RTC_IIC_SDA GpioPin9                           //SDA
  10. #define RTC_READ_SDA Gpio_GetInputIO(RTC_IIC_PORT, RTC_IIC_SDA) //输入SDA
  11. #define IIC_WRITE_ARR 0x64
  12. #define IIC_READ_ARR 0x65

  13. #define RTC_CRL_G1_USUAL 0x00      //控制寄存器1通常值
  14. #define RTC_CRL_G2_USUAL 0x20      //控制寄存器2通常值(清除中断的值)
  15. #define RTC_CRL_G1_ALARM 0x80      //控制寄存器1闹钟值
  16. #define RTC_CRL_G2_ALARM 0x20      //控制寄存器2闹钟值
  17. #define ALARM_CLOCK_MINUTE_ARR 0x08  //定时闹钟分钟地址
  18. #define ALARM_CLOCK_HOUR_ARR 0x09  //定时闹钟小时地址
  19. #define ALARM_CLOCK_WEEK_ARR 0x0A  //定时闹钟每周哪几天响地址

  20. #define RTC_SECOND_ARR   0x00  //读取秒时地址
  21. #define RTC_MINUTE_ARR   0x01  //读取分时地址
  22. #define RTC_HOUR_ARR   0x02  //读取时时地址
  23. #define RTC_WEEK_ARR   0x03  //读取周时地址
  24. #define RTC_DAY_ARR   0x04  //读取天时地址
  25. #define RTC_MONTH_ARR   0x05  //读取月时地址
  26. #define RTC_YEAR_ARR   0x06  //读取年时地址
  27. #define RTC_CRL_G1_ARR 0x0E  //控制寄存器1地址
  28. #define RTC_CRL_G2_ARR 0x0F  //控制寄存器2地址

  29. #define RTC_ALARM_CLEAR_IRQ 0x22  //闹钟进中断控制寄存器2的值
  30. #define RTC_TIMER_CLEAR_IRQ 0x24  //定时进中断控制寄存器2的值



  31. extern uint8_t  RRTCiic_buf[16];  //读出来的时间放在这里
  32. typedef struct rtc_init_time
  33. {
  34.         unsigned char Set_Year;
  35.         unsigned char Set_Month;
  36.         unsigned char Set_Day;
  37.         unsigned char Set_Week;
  38.         unsigned char Set_Hour;
  39.         unsigned char Set_Minute;
  40.         unsigned char Set_Second;
  41. }h_rtc_init_time;

  42. extern h_rtc_init_time current_time;

  43. typedef struct rtc_read_time
  44. {
  45.         unsigned char Year;
  46.         unsigned char Month;
  47.         unsigned char Day;
  48.         unsigned char Week;
  49.         unsigned char Hour;
  50.         unsigned char Minute;
  51.         unsigned char Second;
  52.         unsigned char Control_1;
  53.         unsigned char Control_2;
  54.        
  55. }h_rtc_read_time;

  56. extern h_rtc_read_time current_read_time;



  57. //可设置每周哪几天的几点几分
  58. //Week表示:二进制1111111分别代表周日周一到周六 全一代表每天都设置了闹钟 0000001代表只有周六设置了闹钟
  59. //Hour,Minute为闹钟几点几分
  60. /*
  61. 如果用这个函数main里可以这样检测  
  62. 闹钟到了会触发寄存器0x0F里的位
  63. if(((RTC_ReadOneByte(0x0F))==0x24||(RTC_ReadOneByte(0x0F))==0x22)||(RTC_ReadOneByte(0x0F))==0x26)
  64. {
  65.         delay1ms(5000);
  66.   RTC_WriteOneByte(0x0F,0x20); //清除闹钟标志位
  67. }
  68. */
  69. typedef struct alarm_set
  70. {
  71.         unsigned char Week;
  72.         unsigned char Hour;
  73.         unsigned char Minute;
  74. }h_alarm_set;

  75. extern h_alarm_set alarm_value;





  76. /*
  77. 1.SECOND_MODE:每秒标志位置一
  78. 2.MINUTE_MODE:每分标志位置一(每分 00 秒)
  79. 3.HOUR_MODE:每时标志位置一(每时 00 分:00 秒)
  80. 4.MONTH_MODE:每月标志位置一(每月第 1 天 00 时:00 分:00 秒)
  81. 标志位需清除 例:
  82. if(((RTC_ReadOneByte(0x0F))==0x24||(RTC_ReadOneByte(0x0F))==0x22)||(RTC_ReadOneByte(0x0F))==0x26)
  83. {
  84.         delay1ms(500);
  85.   RTC_WriteOneByte(0x0F,0x20); //清除标志位
  86. }
  87. */
  88. typedef enum
  89. {
  90.           SECOND_MODE = 0x84,
  91.     MINUTE_MODE,
  92.     HOUR_MODE,
  93.     MONTH_MODE
  94.        
  95. }interval_timer;


  96. //IIC所有操作函数
  97. void RTC_IIC_Init(void);                 //初始化IIC的IO口
  98. void RTC_IIC_Start(void);                //发送IIC开始信号
  99. void RTC_IIC_Stop(void);                 //发送IIC停止信号
  100. void RTC_IIC_Send_Byte(u8 txd);          //IIC发送一个字节
  101. u8 RTC_IIC_Read_Byte(unsigned char ack); //IIC读取一个字节
  102. u8 RTC_IIC_Wait_Ack(void);               //IIC等待ACK信号
  103. void RTC_IIC_Ack(void);                  //IIC发送ACK信号
  104. void RTC_IIC_NAck(void);                 //IIC不发送ACK信号

  105. void RTC_IIC_Write_One_Byte(u8 daddr, u8 addr, u8 data);
  106. u8 RTC_IIC_Read_One_Byte(u8 daddr, u8 addr);

  107. u8 RTC_ReadOneByte(u16 ReadAddr);                              //指定地址读取一个字节
  108. void RTC_WriteOneByte(u16 WriteAddr, u8 DataToWrite);          //指定地址写入一个字节
  109. void RTC_WriteLenByte(u16 WriteAddr, unsigned char *pBuffer, u8 Len); //指定地址开始写入指定长度的数据
  110. void RTC_ReadLenByte(unsigned char ReadAddr,unsigned char *pBuffer,unsigned char NumToRead);                     //指定地址开始读取指定长度数据
  111. void RTC_Write(u16 WriteAddr, u8 *pBuffer, u16 NumToWrite);    //从指定地址开始写入指定长度的数据
  112. void RTC_Read(u16 ReadAddr, u8 *pBuffer, u16 NumToRead);       //从指定地址开始读出指定长度的数据
  113. void BL5372_init(h_rtc_init_time time);
  114. void Read_Nowtime(h_rtc_read_time *read_time);
  115. void RTC_SetAlarm(h_alarm_set value);
  116. void RTC_Fixed_interval_timer(interval_timer Mode);



  117. #endif
 楼主| 和下土 发表于 2023-8-27 18:13 | 显示全部楼层
以下为主函数设置与读取时间代码
  1. int main(void)
  2. {
  3.         Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); // GPIO外设时钟打开
  4.         Sysctrl_SetPeripheralGate(SysctrlPeripheralRtc, TRUE);        // RTC模块时钟打开
  5.         Sysctrl_ClkSourceEnable(SysctrlClkRCL, TRUE);
  6.         RTC_Init(); // iic初始化
  7.        
  8.   //设置时间
  9.         current_time.Set_Year=0x23;
  10.         current_time.Set_Month=0x07;
  11.         current_time.Set_Day =0x11;
  12.         current_time.Set_Week=0x02;       
  13.         current_time.Set_Hour=0x09;
  14.         current_time.Set_Minute=0x43;
  15.         current_time.Set_Second=0x00;
  16.         BL5372_init(current_time);

  17.         while (1)
  18.         {
  19.                     //读取时间到结构体
  20.                         Read_Nowtime(&current_read_time);
  21.   }

  22. }
 楼主| 和下土 发表于 2023-8-27 18:13 | 显示全部楼层
以上为设置/读取时间的一些函数

该RTC芯片还有两个额外功能

1.可设置闹钟输出电平

2.可设置每时/分/秒输出电平

以上两种功能主要是需要设置两个控制寄存器的值

先说控制寄存器1 这里有几个重要的位 我贴出来
 楼主| 和下土 发表于 2023-8-28 07:16 | 显示全部楼层
 楼主| 和下土 发表于 2023-8-28 07:17 | 显示全部楼层
 楼主| 和下土 发表于 2023-8-28 07:17 | 显示全部楼层
 楼主| 和下土 发表于 2023-8-28 07:17 | 显示全部楼层
接下来看控制寄存器2
 楼主| 和下土 发表于 2023-8-28 07:17 | 显示全部楼层
 楼主| 和下土 发表于 2023-8-28 07:17 | 显示全部楼层
 楼主| 和下土 发表于 2023-8-28 07:17 | 显示全部楼层
 楼主| 和下土 发表于 2023-8-28 07:18 | 显示全部楼层
以下为我自己总结的两种功能分别要发送什么
 楼主| 和下土 发表于 2023-8-28 07:18 | 显示全部楼层
 楼主| 和下土 发表于 2023-8-28 07:18 | 显示全部楼层
对于这些寄存器的配置 我已经写好函数 直接将结构体赋值 引用函数即可

例:设置闹钟 (INTRA引脚输出低电平)
 楼主| 和下土 发表于 2023-8-28 07:18 | 显示全部楼层
  1. int main(void)
  2. {
  3.         Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); // GPIO外设时钟打开
  4.         Sysctrl_SetPeripheralGate(SysctrlPeripheralRtc, TRUE);        // RTC模块时钟打开
  5.         Sysctrl_ClkSourceEnable(SysctrlClkRCL, TRUE);
  6.         RTC_Init(); // iic初始化
  7.   //设置时间
  8.         current_time.Set_Year=0x23;
  9.         current_time.Set_Month=0x07;
  10.         current_time.Set_Day =0x11;
  11.         current_time.Set_Week=0x02;       
  12.         current_time.Set_Hour=0x09;
  13.         current_time.Set_Minute=0x43;
  14.         current_time.Set_Second=0x00;
  15.         BL5372_init(current_time);
  16.   
  17.         //每天9点45分INTRA引脚输出低电平
  18.         alarm_value.Hour=0x09;      
  19.         alarm_value.Minute=0x45;
  20.         alarm_value.Week=0x7F;   //代表1111111 一周里每天的意思
  21.   RTC_SetAlarm(alarm_value);
  22.         while (1)
  23.         {
  24.                
  25.                         Read_Nowtime(&current_read_time);

  26.   }

  27. }
 楼主| 和下土 发表于 2023-8-28 07:18 | 显示全部楼层
例:设置每分钟进中断(INTRA引脚输出低电平)
 楼主| 和下土 发表于 2023-8-28 07:18 | 显示全部楼层
  1. int main(void)
  2. {
  3.         Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); // GPIO外设时钟打开
  4.         Sysctrl_SetPeripheralGate(SysctrlPeripheralRtc, TRUE);        // RTC模块时钟打开
  5.         Sysctrl_ClkSourceEnable(SysctrlClkRCL, TRUE);
  6.         RTC_Init(); // iic初始化

  7.   //设置时间
  8.         current_time.Set_Year=0x23;
  9.         current_time.Set_Month=0x07;
  10.         current_time.Set_Day =0x11;
  11.         current_time.Set_Week=0x02;       
  12.         current_time.Set_Hour=0x09;
  13.         current_time.Set_Minute=0x43;
  14.         current_time.Set_Second=0x00;
  15.         BL5372_init(current_time);
  16.         //设置每分钟进中断
  17.   RTC_Fixed_interval_timer(MINUTE_MODE);

  18.         while (1)
  19.         {
  20.                
  21.                         Read_Nowtime(&current_read_time);

  22.   }


  23. }
 楼主| 和下土 发表于 2023-8-28 07:18 | 显示全部楼层
注意:这里清除中断为在while(1)里加入

           另外延时时间可以根据需要修改
您需要登录后才可以回帖 登录 | 注册

本版积分规则

114

主题

1405

帖子

0

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