你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32 RTC程序示例

[复制链接]
STMCU小助手 发布时间:2022-6-14 14:04
01. RTC时钟简介
STM32F4 的实时时钟(RTC)相对于 STM32F1 来说,改进了不少,带了日历功能了,STM32F4 的 RTC,是一个独立的 BCD 定时器/计数器。RTC 提供一个日历时钟(包含年月日时分秒信息)、两个可编程闹钟(ALARM A 和 ALARM B)中断,以及一个具有中断功能的周
期性可编程唤醒标志。RTC 还包含用于管理低功耗模 式的自动唤醒单元。

两个 32 位寄存器(TR 和 DR)包含二进码十进数格式 (BCD) 的秒、分钟、小时(12 或24 小时制)、星期、日期、月份和年份。此外,还可提供二进制格式的亚秒值。

STM32F4 的 RTC 可以自动将月份的天数补偿为 28、29(闰年)、30 和 31 天。并且还可以进行夏令时 补偿。

RTC 模块和时钟配置是在后备区域,即在系统复位或从待机模式唤醒后 RTC 的设置和时间维持不变,只要后备区域供电正常,那么 RTC 将可以一直运行。但是在系统复位后,会自动禁止访问后备寄存器和 RTC,以防止对后备区域(BKP)的意外写操作。所以在要设置时间之前,先要取消备份区域(BKP)写保护。

02. 硬件设计
用到的硬件资源有:
1) 指示灯 DS0
2) 串口
3) TFTLCD 模块
4) RTC

03. RTC日历配置步骤
①使能PWR时钟:RCC_APB1PeriphClockCmd();

② 使能后备寄存器访问: PWR_BackupAccessCmd()

③ 配置RTC时钟源,使能RTC时钟:

RCC_RTCCLKConfig();

RCC_RTCCLKCmd();

如果使用LSE,要打开LSE:RCC_LSEConfig(RCC_LSE_ON);

④ 初始化RTC(同步/异步分频系数和时钟格式):RTC_Init ();

⑤ 设置时间:RTC_SetTime ();

⑥设置日期:RTC_SetDate();

04. 设置和获取日期示例
rtc.h
  1. #ifndef __RTC_H__
  2. #define __RTC_H__

  3. #include "sys.h"

  4. //RTC初始化
  5. u8 MY_RTC_Init(void);

  6. //RTC时间设置
  7. ErrorStatus RTC_Set_Time(u8 hour, u8 min, u8 sec, u8 ampm);

  8. //RTC日期设置
  9. ErrorStatus RTC_Set_Date(u8 year, u8 mon, u8 day, u8 week);

  10. #endif /*__RTC_H__*/
复制代码

rtc.c

  1. #include "rtc.h"
  2. #include "delay.h"


  3. //RTC时间设置
  4. ErrorStatus RTC_Set_Time(u8 hour, u8 min, u8 sec, u8 ampm)
  5. {
  6.         RTC_TimeTypeDef RTC_TimeStruct;
  7.         RTC_TimeStruct.RTC_H12 = ampm;
  8.         RTC_TimeStruct.RTC_Hours = hour;
  9.         RTC_TimeStruct.RTC_Minutes = min;
  10.         RTC_TimeStruct.RTC_Seconds = sec;

  11.         return RTC_SetTime(RTC_Format_BIN,&RTC_TimeStruct);
  12. }

  13. //RTC日期设置
  14. ErrorStatus RTC_Set_Date(u8 year, u8 mon, u8 day, u8 week)
  15. {
  16.         RTC_DateTypeDef RTC_DateStruct;
  17.         
  18.         RTC_DateStruct.RTC_Year = year;
  19.         RTC_DateStruct.RTC_Month = mon;
  20.         RTC_DateStruct.RTC_Date = day;
  21.         RTC_DateStruct.RTC_WeekDay = week;

  22.         return RTC_SetDate(RTC_Format_BIN, &RTC_DateStruct);
  23. }

  24. //RTC初始化
  25. u8 MY_RTC_Init(void)
  26. {
  27.         u16 retry = 0x1fff;
  28.         
  29.         RTC_InitTypeDef RTC_InitStruct;

  30.         //使能PWR时钟
  31.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  32.         
  33.         //使能后备寄存器访问
  34.         PWR_BackupAccessCmd(ENABLE);
  35.         
  36.         //判断是否第一次初始化
  37.         if (RTC_ReadBackupRegister(RTC_BKP_DR0) != 0x8080)
  38.         {
  39.         
  40.                 //开启LSE
  41.                 RCC_LSEConfig(RCC_LSE_ON);
  42.                 //等待LSE准备就绪
  43.                 while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)
  44.                 {
  45.                         retry++;
  46.                         delay_ms(10);
  47.                 }
  48.                
  49.                 //开始LSE失败
  50.                 if (0 ==  retry)
  51.                 {
  52.                         return 1;
  53.                 }
  54.                
  55.                 //设置RTC时钟为LSE
  56.                 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
  57.                
  58.                 //使能RTC时钟
  59.                 RCC_RTCCLKCmd(ENABLE);
  60.                
  61.                 //初始化RTC
  62.                 RTC_InitStruct.RTC_HourFormat = RTC_HourFormat_24;
  63.                 RTC_InitStruct.RTC_AsynchPrediv = 0x7F;
  64.                 RTC_InitStruct.RTC_SynchPrediv = 0xFF;
  65.                
  66.                 RTC_Init(&RTC_InitStruct);
  67.                
  68.                 //设置时间
  69.                 RTC_Set_Time(16, 06, 50, RTC_H12_AM);
  70.                
  71.                 //设置日期
  72.                 RTC_Set_Date(20, 9, 9, RTC_Weekday_Wednesday);
  73.                
  74.                 //标记已经初始化
  75.                 RTC_WriteBackupRegister(RTC_BKP_DR0, 0x8080);
  76.                
  77.         }

  78.         return 0;
  79. }
复制代码

main.c

  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "beep.h"
  6. #include "key.h"
  7. #include "usmart.h"
  8. #include "lcd.h"
  9. #include "rtc.h"

  10. //LED状态设置函数
  11. void led_set(u8 sta)
  12. {
  13.         LED1 = sta;
  14. }

  15. //函数参数调用测试函数
  16. void test_fun(void(*ledset)(u8), u8 sta)
  17. {
  18.         ledset(sta);
  19. }

  20. int main(void)
  21. {
  22.         u8 buf[40];
  23.         u8 t = 0;
  24.         
  25.         RTC_TimeTypeDef RTC_TimeStruct;
  26.         RTC_DateTypeDef RTC_DateStruct;
  27.         
  28.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
  29.         
  30.         delay_init(168);
  31.         
  32.         uart_init(115200);
  33.         
  34.         usmart_dev.init(84);
  35.         
  36.         LED_Init();
  37.         LCD_Init();
  38.         
  39.         //RTC初始化
  40.         MY_RTC_Init();
  41.         
  42.         
  43.         POINT_COLOR = RED;
  44.         
  45.         LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");        
  46.         LCD_ShowString(30,70,200,16,16,"USMART TEST");        
  47.         LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
  48.         LCD_ShowString(30,110,200,16,16,"2020/09/09");         
  49.         
  50.         while(1)
  51.         {
  52.                 t++;
  53.                
  54.                 //每隔100ms更新显示
  55.                 if (0 == t % 10)
  56.                 {
  57.                         RTC_GetTime(RTC_Format_BIN, &RTC_TimeStruct);
  58.                         sprintf((char*)buf, "Time: %02d:%02d:%02d", RTC_TimeStruct.RTC_Hours, RTC_TimeStruct.RTC_Minutes, RTC_TimeStruct.RTC_Seconds);
  59.                         LCD_ShowString(30, 140, 210, 16, 16, buf);
  60.                         
  61.                         
  62.                         RTC_GetDate(RTC_Format_BIN, &RTC_DateStruct);
  63.                         sprintf((char*)buf, "Date: 20%02d-%02d-%02d", RTC_DateStruct.RTC_Year, RTC_DateStruct.RTC_Month, RTC_DateStruct.RTC_Date);
  64.                         LCD_ShowString(30, 160, 210, 16, 16, buf);
  65.                         
  66.                         sprintf((char*)buf, "Week: %d", RTC_DateStruct.RTC_WeekDay);
  67.                         LCD_ShowString(30, 180, 210, 16, 16, buf);               
  68.                         
  69.                 }
  70.                
  71.                
  72.                 if (0 == t % 20)
  73.                 {
  74.                         LED1 = !LED1;
  75.                 }
  76.                
  77.                 //睡眠10毫秒
  78.                 delay_ms(10);
  79.         }
  80. }
复制代码

05. 设置闹钟中断示例
  1. //设置闹钟时间(按星期闹铃,24小时制)
  2. //week:星期几(1~7) @ref  RTC_Alarm_Definitions
  3. //hour,min,sec:小时,分钟,秒钟
  4. void RTC_Set_AlarmA(u8 week,u8 hour,u8 min,u8 sec)
  5. {
  6.         RTC_TimeTypeDef RTC_TimeStruct;
  7.         
  8.         RTC_AlarmTypeDef RTC_AlarmStruct;
  9.         
  10.         EXTI_InitTypeDef EXTI_InitStruct;
  11.         
  12.         NVIC_InitTypeDef NVIC_InitStruct;
  13.         
  14.         
  15.         //关闭闹钟A
  16.         RTC_AlarmCmd(RTC_Alarm_A, DISABLE);
  17.         
  18.         //设置闹钟参数
  19.         RTC_TimeStruct.RTC_H12 = RTC_H12_AM;
  20.         RTC_TimeStruct.RTC_Hours = hour;
  21.         RTC_TimeStruct.RTC_Minutes = min;
  22.         RTC_TimeStruct.RTC_Seconds = sec;
  23.         
  24.         
  25.         RTC_AlarmStruct.RTC_AlarmTime = RTC_TimeStruct;
  26.         RTC_AlarmStruct.RTC_AlarmMask = RTC_AlarmMask_None;
  27.         RTC_AlarmStruct.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_WeekDay;
  28.         RTC_AlarmStruct.RTC_AlarmDateWeekDay = week;
  29.         
  30.         RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStruct);

  31.         //清除闹钟A的中断标志
  32.         RTC_ClearITPendingBit(RTC_IT_ALRA);
  33.         //清除中断线17上的中断标志
  34.         EXTI_ClearITPendingBit(EXTI_Line17);
  35.         
  36.         //开启闹钟A中断
  37.         RTC_ITConfig(RTC_IT_ALRA, ENABLE);
  38.         
  39.         //开启闹钟
  40.         RTC_AlarmCmd(RTC_Alarm_A, ENABLE);
  41.         
  42.         //初始化中断
  43.         EXTI_InitStruct.EXTI_Line = EXTI_Line17;
  44.         EXTI_InitStruct.EXTI_LineCmd = ENABLE;
  45.         EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
  46.         EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
  47.         EXTI_Init(&EXTI_InitStruct);
  48.         
  49.         //初始化中断优先级
  50.         NVIC_InitStruct.NVIC_IRQChannel = RTC_Alarm_IRQn;
  51.         NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  52.         NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority =  0x2;
  53.         NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x2;
  54.         NVIC_Init(&NVIC_InitStruct);
  55. }

  56. //闹钟中断处理函数
  57. void RTC_Alarm_IRQHandler(void)
  58. {
  59.         if (RTC_GetFlagStatus(RTC_FLAG_ALRAF) == SET)
  60.         {
  61.                 RTC_ClearFlag(RTC_FLAG_ALRAF);
  62.                 printf("ALARM A!\r\n");
  63.         }
  64.         
  65.         //清中断
  66.         EXTI_ClearITPendingBit(EXTI_Line17);        
  67. }
复制代码

06. 设置唤醒中断示例

  1. //周期性唤醒定时器设置  
  2. /*wksel:  @ref RTC_Wakeup_Timer_Definitions
  3. #define RTC_WakeUpClock_RTCCLK_Div16        ((uint32_t)0x00000000)
  4. #define RTC_WakeUpClock_RTCCLK_Div8         ((uint32_t)0x00000001)
  5. #define RTC_WakeUpClok_RTCCLK_Div4         ((uint32_t)0x00000002)
  6. #define RTC_WakeUpClock_RTCCLK_Div2         ((uint32_t)0x00000003)
  7. #define RTC_WakeUpClock_CK_SPRE_16bits      ((uint32_t)0x00000004)
  8. #define RTC_WakeUpClock_CK_SPRE_17bits      ((uint32_t)0x00000006)
  9. */
  10. //cnt:自动重装载值.减到0,产生中断.
  11. void RTC_Set_WakeUp(u32 wksel,u16 cnt)
  12. {
  13.                
  14.         EXTI_InitTypeDef EXTI_InitStruct;
  15.         
  16.         NVIC_InitTypeDef NVIC_InitStruct;
  17.         
  18.         //关闭WakeUP
  19.         RTC_WakeUpCmd(DISABLE);
  20.         
  21.         //配置WakeUP时钟分频系数或者来源
  22.         RTC_WakeUpClockConfig(wksel);
  23.         
  24.         //设置WakeUP自动装载值
  25.         RTC_SetWakeUpCounter(cnt);
  26.         
  27.         //清除中断标志
  28.         RTC_ClearITPendingBit(RTC_IT_WUT);
  29.         //清除中断线17上的中断标志
  30.         EXTI_ClearITPendingBit(EXTI_Line22);
  31.         
  32.         //开启WakeUP中断
  33.         RTC_ITConfig(RTC_IT_WUT, ENABLE);
  34.         
  35.         //使能WakeUp
  36.         RTC_WakeUpCmd(ENABLE);
  37.         
  38.                 //初始化中断
  39.         EXTI_InitStruct.EXTI_Line = EXTI_Line22;
  40.         EXTI_InitStruct.EXTI_LineCmd = ENABLE;
  41.         EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
  42.         EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
  43.         EXTI_Init(&EXTI_InitStruct);
  44.         
  45.         //初始化中断优先级
  46.         NVIC_InitStruct.NVIC_IRQChannel = RTC_WKUP_IRQn;
  47.         NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  48.         NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority =  0x2;
  49.         NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x2;
  50.         NVIC_Init(&NVIC_InitStruct);


  51. }


  52. //唤醒中断处理函数
  53. void RTC_WKUP_IRQHandler(void)
  54. {
  55.         if (RTC_GetFlagStatus(RTC_FLAG_WUTF) == SET)
  56.         {
  57.                 RTC_ClearFlag(RTC_FLAG_WUTF);
  58.                 LED2 = !LED2;
  59.         }
  60.         
  61.         //清中断
  62.         EXTI_ClearITPendingBit(EXTI_Line22);        

  63. }
复制代码



收藏 评论0 发布时间:2022-6-14 14:04

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版