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

【经验分享】STM32G030F6使用CubeMx配置RTC及闹钟实验

[复制链接]
STMCU小助手 发布时间:2021-11-10 18:02
1. 使用 CubeMx 创建 RTC 工程
打开 CubeMx 软件,选中我们此次使用的单片机型号 STM32G030F6P6 ,点击 StartProject.

先配置一下串口,用来打印相关信息

20210128091458888.png


再来配置 RTC

20210128170709886.png


20210128170837705.png


配置时钟

20210128171003870.png


ps:本实验使用内部低速时钟测试,未使用外部晶振.

配置工程相关选项

20210128171144837.png


配置完成后点击右上角 GENERATE CODE完成工程的创建

2. 编程
2.1 熟悉一下 Hal 库中 RTC 使用到的相关 API 接口
  1. /*设置系统时间*/
  2. HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
  3. /*读取系统时间*/
  4. HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
  5. /*设置系统日期*/
  6. HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
  7. /*读取系统日期*/
  8. HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
  9. /*启动报警功能*/
  10. HAL_StatusTypeDef HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
  11. /*设置报警中断*/
  12. HAL_StatusTypeDef HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
  13. /*报警时间回调函数*/
  14. __weak void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
  15. /*写入后备储存器*/
  16. void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister, uint32_t Data)
  17. /*读取后备储存器*/
  18. uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister
复制代码

2.2 串口相关的代码
因打印相关信息需要使用 printf ,需要包含 stdio.h 的头文件,且需要重新设 fputc 的函数
  1. /* Includes ------------------------------------------------------------------*/
  2. #include "main.h"

  3. /* Private includes ----------------------------------------------------------*/
  4. /* USER CODE BEGIN Includes */
  5. #include "stdio.h"
  6. /* USER CODE END Includes */

  7. /* Private typedef -----------------------------------------------------------*/
  8. /* USER CODE BEGIN PTD */

  9. /* USER CODE END PTD */

  10. /* Private define ------------------------------------------------------------*/
  11. /* USER CODE BEGIN PD */
  12. /* USER CODE END PD */

  13. /* Private macro -------------------------------------------------------------*/
  14. /* USER CODE BEGIN PM */

  15. /* USER CODE END PM */

  16. /* Private variables ---------------------------------------------------------*/
  17. RTC_HandleTypeDef hrtc;

  18. UART_HandleTypeDef huart1;

  19. /* USER CODE BEGIN PV */
  20. RTC_DateTypeDef date;        //读取日期
  21. RTC_TimeTypeDef time;        //读取时间
  22. uint8_t RTCStatus = 0;        //指示RTC状态

  23. /* USER CODE END PV */

  24. /* Private function prototypes -----------------------------------------------*/
  25. void SystemClock_Config(void);
  26. static void MX_GPIO_Init(void);
  27. static void MX_RTC_Init(void);
  28. static void MX_USART1_UART_Init(void);
  29. /* USER CODE BEGIN PFP */
  30. // fputc 函数重映射
  31. #ifdef __GNUC_
  32. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
  33. #else
  34. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
  35. #endif
  36. PUTCHAR_PROTOTYPE
  37. {
  38.     HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 0xFFFF);

  39.     return ch;
  40. }
  41. /* USER CODE END PFP */
复制代码


RTC 初始化
  1. static void MX_RTC_Init(void)
  2. {

  3.   /* USER CODE BEGIN RTC_Init 0 */

  4.   /* USER CODE END RTC_Init 0 */

  5.   RTC_TimeTypeDef sTime = {0};
  6.   RTC_DateTypeDef sDate = {0};
  7.   RTC_AlarmTypeDef sAlarm = {0};

  8.   /* USER CODE BEGIN RTC_Init 1 */

  9.   /* USER CODE END RTC_Init 1 */
  10.   /** Initialize RTC Only
  11.   */
  12.   hrtc.Instance = RTC;
  13.   hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  14.   hrtc.Init.AsynchPrediv = 127;
  15.   hrtc.Init.SynchPrediv = 255;
  16.   hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  17.   hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
  18.   hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  19.   hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  20.   hrtc.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE;
  21.   if (HAL_RTC_Init(&hrtc) != HAL_OK)
  22.   {
  23.     Error_Handler();
  24.   }

  25.   /* USER CODE BEGIN Check_RTC_BKUP */
  26. //    //重启后判断该寄存器是否有值,判定是不是第丿次初始化,是否要装载初始倿
  27. //    if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1) == 0xAA)
  28. //    {
  29. //        //已经初始化过了,直接跳出初始化函
  30. //        return;
  31. //    }
  32. //    //第一次初始化,将任意后备寄存器写任意值,做个标记,标记已经初始化过了,下次系统复位时不用初始匿
  33. //    HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, 0xAA);
  34.   /* USER CODE END Check_RTC_BKUP */

  35.   /** Initialize RTC and set the Time and Date
  36.   */
  37.   sTime.Hours = 14;
  38.   sTime.Minutes = 50;
  39.   sTime.Seconds = 0;
  40.   sTime.SubSeconds = 0;
  41.   sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  42.   sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  43.   if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
  44.   {
  45.     Error_Handler();
  46.   }
  47.   sDate.WeekDay = RTC_WEEKDAY_THURSDAY;
  48.   sDate.Month = RTC_MONTH_JANUARY;
  49.   sDate.Date = 28;
  50.   sDate.Year = 21;

  51.   if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
  52.   {
  53.     Error_Handler();
  54.   }
  55.   /** Enable the Alarm A
  56.   */
  57.   sAlarm.AlarmTime.Hours = 14;
  58.   sAlarm.AlarmTime.Minutes = 50;
  59.   sAlarm.AlarmTime.Seconds = 10;        //设置 10s 后产生闹钟中断
  60.   sAlarm.AlarmTime.SubSeconds = 0;
  61.   sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  62.   sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
  63.   sAlarm.AlarmMask = RTC_ALARMMASK_NONE;
  64.   sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_NONE;
  65.   sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
  66.   sAlarm.AlarmDateWeekDay = 28;
  67.   sAlarm.Alarm = RTC_ALARM_A;
  68.   if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
  69.   {
  70.     Error_Handler();
  71.   }
  72.   /* USER CODE BEGIN RTC_Init 2 */

  73.   /* USER CODE END RTC_Init 2 */

  74. }
复制代码

此初始化函数中 设置了当前的时间和日期,并使能了闹钟中断在 10s 后产生.

配置 RTC 闹钟中断的回调函数及设置下次产生闹钟中断的时间函数
  1. /* 设置闹钟下次产生的时间 */
  2. void setalarm(int hours, int minutes, int seconds)
  3. {
  4.     RTC_AlarmTypeDef sAlarm = {0};
  5.     RTC_DateTypeDef sdate = {0};   
  6.     RTC_TimeTypeDef stime = {0};

  7.     //读取当前时间
  8.     HAL_RTC_GetTime(&hrtc, &stime, RTC_FORMAT_BIN);
  9.     HAL_RTC_GetDate(&hrtc, &sdate, RTC_FORMAT_BIN);
  10.     //获取设置中断时的时间
  11.     sAlarm.Alarm = RTC_ALARM_A;
  12.     sAlarm.AlarmTime.Hours   = hours   + stime.Hours;
  13.     sAlarm.AlarmTime.Minutes = minutes + stime.Minutes;
  14.     sAlarm.AlarmTime.Seconds = seconds + stime.Seconds;
  15.     if(sAlarm.AlarmTime.Seconds >= 60)
  16.     {
  17.         sAlarm.AlarmTime.Seconds = sAlarm.AlarmTime.Seconds % 60;
  18.         sAlarm.AlarmTime.Minutes += 1;
  19.         if(sAlarm.AlarmTime.Minutes >= 60)
  20.         {
  21.             sAlarm.AlarmTime.Minutes = sAlarm.AlarmTime.Minutes % 60;
  22.             sAlarm.AlarmTime.Hours += 1;
  23.             if(sAlarm.AlarmTime.Hours >= 24)
  24.             {
  25.                 sAlarm.AlarmTime.Hours = sAlarm.AlarmTime.Hours % 24;
  26.                 sdate.Date += 1;
  27.             }
  28.         }
  29.     }
  30.     sAlarm.AlarmTime.SubSeconds = 0;
  31.     sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  32.     sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
  33.     sAlarm.AlarmMask = RTC_ALARMMASK_NONE;
  34.     sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_NONE;
  35.     sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
  36.     sAlarm.AlarmDateWeekDay = sdate.Date;   //跨天数定时,需要注意


  37.     if(HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK)
  38.     {
  39.         Error_Handler();
  40.     }
  41. }

  42. /**
  43.   * @brief  Alarm callback 闹钟中断回调函数
  44.   * @param  hrtc : RTC handle
  45.   * @retval None
  46.   */
  47. void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
  48. {
  49.     static uint16_t sEnterCnt = 0;

  50.     setalarm(0,0,5);        //设置 5s 后再次产生闹钟中断
  51.     printf("Alarm A Interrupt Cnt:%d \r\n",sEnterCnt++);
  52. }
复制代码

main 函数
  1. /**
  2.   * @brief  The application entry point.
  3.   * @retval int
  4.   */
  5. int main(void)
  6. {
  7.   /* USER CODE BEGIN 1 */

  8.   /* USER CODE END 1 */

  9.   /* MCU Configuration--------------------------------------------------------*/

  10.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  11.   HAL_Init();

  12.   /* USER CODE BEGIN Init */

  13.   /* USER CODE END Init */

  14.   /* Configure the system clock */
  15.   SystemClock_Config();

  16.   /* USER CODE BEGIN SysInit */

  17.   /* USER CODE END SysInit */

  18.   /* Initialize all configured peripherals */
  19.   MX_GPIO_Init();
  20.   MX_RTC_Init();
  21.   MX_USART1_UART_Init();
  22.   /* USER CODE BEGIN 2 */
  23.   printf("stm32g030f6 rtc & alarm demo start......\n");
  24.   RTCStatus = 0x01;
  25.   /* USER CODE END 2 */

  26.   /* Infinite loop */
  27.   /* USER CODE BEGIN WHILE */
  28.     while(1)
  29.     {
  30.         HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN);
  31.         HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN);
  32.         printf("20%d-%02d-%02d %02d:%02d:%02d \r\n", date.Year, date.Month, date.Date, time.Hours, time.Minutes, time.Seconds);
  33.         HAL_Delay(1000);
  34.     /* USER CODE END WHILE */

  35.     /* USER CODE BEGIN 3 */
  36.     }
  37.   /* USER CODE END 3 */
  38. }
复制代码

主函数中每隔 1s 读取一次实时日期和时间,并打印出来.

3. 编译并下载测试
将程序下载到开发板中,连接串口助手并打开;
实验现象: 打印实时时间,10s 后,第一次进入中断,并打印进入中断的次数,而后每隔 5s 打印一次进入中断的次数.

20210128175241625.png


收藏 1 评论0 发布时间:2021-11-10 18:02

举报

0个回答

所属标签

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