[STM32F1] 【HAL库每天一例】第036例: RTC-实时时钟

[复制链接]
 楼主| 亼亽 发表于 2016-6-10 08:39 | 显示全部楼层 |阅读模式
【HAL库每天一例】系列例程从今天开始持续更新。。。。。
我们将**每天至少发布一个基于YS-F1Pro开发板的HAL库例程,
该系列例程将带领大家从零开始使用HAL库,后面会持续添加模块应用例程。
同样的,我们还程序发布基于HAL库的指导文档和视频教程,欢迎持续关注,并提出改进意见。
例程下载:
资料包括程序、相关说明资料以及软件使用截图
等级不够,不给发连接(去掉下面链接空格)
百度云:pan. baidu. com/s/1jIvrqlC
(硬石YS-F1Pro开发板HAL库例程持续更新\1. 软件设计之基本裸机例程(HAL库版本)\YSF1_HAL-036. RTC-实时时钟



/**
  ******************************************************************************
  *                           硬石YS-F1Pro开发板例程功能说明
  *
  *  例程名称: YSF1_HAL-036. RTC-实时时钟
  *   
  ******************************************************************************
  * 说明:
  * 本例程配套硬石stm32开发板YS-F1Pro使用。
  *
  * 淘宝:
  * 论坛:ing10bbs
  * 版权归硬石嵌入式开发团队所有,请勿商用。
  ******************************************************************************
  */

【1】例程简介
RTC实时时钟用于时间记录,一般需要外接32.768KHz晶振,YS-F1Pro开发板已接入,可以
得到精确的时间。
  
【2】跳线帽情况
******* 为保证例程正常运行,必须插入以下跳线帽 **********
丝印编号     IO端口      目标功能引脚        出厂默认设置
  JP1        PA10        TXD(CH340G)          已接入
  JP2        PA9         RXD(CH340G)          已接入
  
【3】操作及现象
    使用开发板配套的MINI USB线连接到开发板标示“调试串口”字样的MIMI USB接口(需要安
装驱动),在电脑端打开串口调试助手工具,设置参数为115200 8-N-1。下载程序之后,在
串口调试助手打印提示信息,根据要求输入设置当前时间。之后每过一秒时间打印一次时间。

/******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/

CubeMX_1.jpg
CubeMX_2.jpg
CubeMX_3.jpg
CubeMX_4.jpg
CubeMX_5.jpg
CubeMX_6.jpg


bsp_rtc.c文件内容:
  1. /**
  2.   ******************************************************************************
  3.   * 文件名程: bsp_rtc.c
  4.   * 作    者: 硬石嵌入式开发团队
  5.   * 版    本: V1.0
  6.   * 编写日期: 2015-10-04
  7.   * 功    能: 板载调试串口底层驱动程序:默认使用USART1
  8.   ******************************************************************************
  9.   * 说明:
  10.   * 本例程配套硬石stm32开发板YS-F1Pro使用。
  11.   *
  12.   * 淘宝:
  13.   * 论坛:ing10bbs
  14.   * 版权归硬石嵌入式开发团队所有,请勿商用。
  15.   ******************************************************************************
  16.   */

  17. /* 包含头文件 ----------------------------------------------------------------*/
  18. #include "rtc/bsp_rtc.h"
  19. #include "usart/bsp_debug_usart.h"

  20. /* 私有类型定义 --------------------------------------------------------------*/
  21. /* 私有宏定义 ----------------------------------------------------------------*/
  22. /* 私有变量 ------------------------------------------------------------------*/
  23. RTC_HandleTypeDef hrtc;

  24. /* 扩展变量 ------------------------------------------------------------------*/
  25. /* 私有函数原形 --------------------------------------------------------------*/
  26. /* 函数体 --------------------------------------------------------------------*/
  27. /**
  28.   * 函数功能: 从串口调试助手获取数字值(把ASCII码转换为数字)
  29.   * 输入参数: value 用户在超级终端中输入的数值
  30.   * 返 回 值: 输入字符的ASCII码对应的数值
  31.   * 说    明:本函数专用于RTC获取时间,若进行其它输入应用,要修改一下
  32.   */
  33. uint8_t USART_Scanf(uint32_t value)
  34. {
  35.   uint32_t index = 0;
  36.   uint32_t tmp[2] = {0, 0};
  37.   while (index < 2)
  38.   {
  39.     /* 等待直到串口接收到数据 */
  40.     tmp[index++] =getchar();
  41.     if ((tmp[index - 1] < 0x30) || (tmp[index - 1] > 0x39))   /*数字0到9的ASCII码为0x30至0x39*/
  42.     {                   
  43.       printf("请输入 0 到 9 之间的数字 -->:\n");
  44.       index--;                  
  45.     }
  46.   }  
  47.   /* 计算输入字符的ASCII码转换为数字*/
  48.   index = (tmp[1] - 0x30) + ((tmp[0] - 0x30) * 10);
  49.   
  50.   /* 检查数据有效性 */
  51.   if (index > value)
  52.   {
  53.     printf("请输入 0 到 %d 之间的数字\n", value);
  54.     return 0xFF;
  55.   }
  56.   return index;
  57. }

  58. /**
  59.   * 函数功能: 配置当前时间和日期
  60.   * 输入参数: 无
  61.   * 返 回 值: 无
  62.   * 说    明: 无
  63.   */
  64. static void RTC_CalendarConfig(void)
  65. {
  66.   RTC_TimeTypeDef sTime;
  67.   RTC_DateTypeDef DateToUpdate;
  68. #if 1
  69.   /* 配置日期 */
  70.   /* 设置日期:2015年10月4日 星期日 */
  71.   DateToUpdate.WeekDay = RTC_WEEKDAY_SUNDAY;
  72.   DateToUpdate.Month = RTC_MONTH_OCTOBER;
  73.   DateToUpdate.Date = 0x4;
  74.   DateToUpdate.Year = 0x15;  
  75.   HAL_RTC_SetDate(&hrtc,&DateToUpdate,RTC_FORMAT_BCD);
  76.   
  77.   /* 配置时间 */
  78.   /* 时钟时间:10:15:46 */
  79.   sTime.Hours = 0x10;
  80.   sTime.Minutes = 0x15;
  81.   sTime.Seconds = 0x46;
  82.   HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD);
  83. #else
  84.   __IO uint32_t Tmp_YY = 0xFF, Tmp_MM = 0xFF, Tmp_DD = 0xFF, Tmp_HH = 0xFF, Tmp_MI = 0xFF, Tmp_SS = 0xFF;

  85.   printf("=========================时间设置==================\n");
  86.   printf("请输入年份: 20\n");
  87.   while (Tmp_YY == 0xFF)
  88.   {
  89.     Tmp_YY = USART_Scanf(99);
  90.   }
  91.   printf("年份被设置为:  20%0.2d\n", Tmp_YY);

  92.   DateToUpdate.Year = Tmp_YY;
  93.   
  94.   printf("请输入月份:  \n");
  95.   while (Tmp_MM == 0xFF)
  96.   {
  97.     Tmp_MM = USART_Scanf(12);
  98.   }
  99.   printf("月份被设置为:  %d\n", Tmp_MM);

  100.   DateToUpdate.Month= Tmp_MM;

  101.   printf("请输入日期:  \n");
  102.   while (Tmp_DD == 0xFF)
  103.   {
  104.     Tmp_DD = USART_Scanf(31);
  105.   }
  106.   printf("日期被设置为:  %d\n", Tmp_DD);
  107.   DateToUpdate.Date= Tmp_DD;
  108.   HAL_RTC_SetDate(&hrtc,&DateToUpdate,RTC_FORMAT_BIN);
  109.   
  110.   printf("请输入时钟:  \n");
  111.   while (Tmp_HH == 0xFF)
  112.   {
  113.     Tmp_HH = USART_Scanf(23);
  114.   }
  115.   printf("时钟被设置为:  %d\n", Tmp_HH );
  116.   sTime.Hours= Tmp_HH;


  117.   printf("请输入分钟:  \n");
  118.   while (Tmp_MI == 0xFF)
  119.   {
  120.     Tmp_MI = USART_Scanf(59);
  121.   }
  122.   printf("分钟被设置为:  %d\n", Tmp_MI);
  123.   sTime.Minutes= Tmp_MI;

  124.   printf("请输入秒钟:  \n");
  125.   while (Tmp_SS == 0xFF)
  126.   {
  127.     Tmp_SS = USART_Scanf(59);
  128.   }
  129.   printf("秒钟被设置为:  %d\n", Tmp_SS);
  130.   sTime.Seconds= Tmp_SS;
  131.   HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
  132. #endif

  133.   /* 写入一个数值:0x32F1到RTC备份数据寄存器1 */
  134.   HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, 0x32F1);
  135. }

  136. /**
  137.   * 函数功能: RTC实时时钟初始化
  138.   * 输入参数: 无
  139.   * 返 回 值: 无
  140.   * 说    明: 无
  141.   */
  142. void MX_RTC_Init(void)
  143. {
  144.   /* 初始化RTC实时时钟并设置时间和日期 */
  145.   hrtc.Instance = RTC;
  146.   hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
  147.   hrtc.Init.OutPut = RTC_OUTPUTSOURCE_NONE;
  148.   HAL_RTC_Init(&hrtc);

  149. #if 1
  150.   /* 配置RTC万年历:时间和日期 */
  151.   RTC_CalendarConfig();
  152. #else
  153.   /* 检测数据是否保存在RTC备份寄存器1:如果已经保存就不需要运行日期和时间设置 */
  154.   /* 读取备份寄存器1数据 */
  155.   if (HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1) != 0x32F1)
  156.   {
  157.     /* 配置RTC万年历:时间和日期 */
  158.     RTC_CalendarConfig();
  159.   }
  160.   else
  161.   {
  162.     /* 检查上电复位标志位是否为:SET */
  163.     if (__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) != RESET)
  164.     {
  165.       printf("发生上电复位!!!\n");
  166.     }
  167.     /* 检测引脚复位标志位是否为:SET */
  168.     if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST) != RESET)
  169.     {
  170.       printf("发生外部引脚复位!!!\n");
  171.     }
  172.     /* 清楚复位源标志位 */
  173.     __HAL_RCC_CLEAR_RESET_FLAGS();
  174.   }
  175. #endif
  176. }

  177. /**
  178.   * 函数功能: RTC实时时钟初始化
  179.   * 输入参数: hrtc:RTC外设句柄指针
  180.   * 返 回 值: 无
  181.   * 说    明: 该函数供HAL库内部函数调用
  182.   */
  183. void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
  184. {
  185.   RCC_OscInitTypeDef        RCC_OscInitStruct;
  186.   RCC_PeriphCLKInitTypeDef  PeriphClkInitStruct;

  187.   if(hrtc->Instance==RTC)
  188.   {
  189.     /* To change the source clock of the RTC feature (LSE, LSI), You have to:
  190.        - Enable the power clock using __HAL_RCC_PWR_CLK_ENABLE()
  191.        - Enable write access using HAL_PWR_EnableBkUpAccess() function before to
  192.          configure the RTC clock source (to be done once after reset).
  193.        - Reset the Back up Domain using __HAL_RCC_BACKUPRESET_FORCE() and
  194.          __HAL_RCC_BACKUPRESET_RELEASE().
  195.        - Configure the needed RTc clock source */
  196.     /* 使能PWR(电源管理外设)时钟和使能获取备份域 */
  197.     __HAL_RCC_PWR_CLK_ENABLE();
  198.     HAL_PWR_EnableBkUpAccess();
  199.    
  200.     /* 使能备份时钟:备份寄存器 */
  201.     __HAL_RCC_BKP_CLK_ENABLE();
  202.    
  203.     /* 配置外部低速时钟为RTC时钟源 */
  204.     RCC_OscInitStruct.OscillatorType =  RCC_OSCILLATORTYPE_LSE;
  205.     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  206.     RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  207.     HAL_RCC_OscConfig(&RCC_OscInitStruct);
  208.    
  209.     PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
  210.     PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  211.     HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
  212.    
  213.     /* 使能RTC外设时钟 */
  214.     __HAL_RCC_RTC_ENABLE();
  215.   }
  216.   
  217. }

  218. /**
  219.   * 函数功能: RTC实时时钟反初始化
  220.   * 输入参数: hrtc:RTC外设句柄指针
  221.   * 返 回 值: 无
  222.   * 说    明: 该函数供HAL库内部函数调用
  223.   */
  224. void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc)
  225. {

  226.   if(hrtc->Instance==RTC)
  227.   {
  228.     /* 禁用RTC时钟 */
  229.     __HAL_RCC_RTC_DISABLE();

  230.     /* 禁用PWR时钟和读取备份域 */
  231.     HAL_PWR_DisableBkUpAccess();
  232.     __HAL_RCC_PWR_CLK_DISABLE();
  233.    
  234.     /* 禁用备份时钟:备份寄存器 */
  235.     __HAL_RCC_BKP_CLK_DISABLE();
  236.   }
  237. }


  238. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/

main.c文件内容:
  1. /**
  2.   ******************************************************************************
  3.   * 文件名程: main.c
  4.   * 作    者: 硬石嵌入式开发团队
  5.   * 版    本: V1.0
  6.   * 编写日期: 2015-10-04
  7.   * 功    能: RTC实时时钟实现
  8.   ******************************************************************************
  9.   * 说明:
  10.   * 本例程配套硬石stm32开发板YS-F1Pro使用。
  11.   *
  12.   * 淘宝:
  13.   * 论坛:ing10bbs
  14.   * 版权归硬石嵌入式开发团队所有,请勿商用。
  15.   ******************************************************************************
  16.   */
  17. /* 包含头文件 ----------------------------------------------------------------*/
  18. #include "stm32f1xx_hal.h"
  19. #include "usart/bsp_debug_usart.h"
  20. #include "rtc/bsp_rtc.h"

  21. /* 私有类型定义 --------------------------------------------------------------*/
  22. /* 私有宏定义 ----------------------------------------------------------------*/
  23. /* 私有变量 ------------------------------------------------------------------*/
  24. /* 扩展变量 ------------------------------------------------------------------*/
  25. /* 私有函数原形 --------------------------------------------------------------*/
  26. static void RTC_CalendarShow(void);
  27. /* 函数体 --------------------------------------------------------------------*/
  28. /**
  29.   * 函数功能: 系统时钟配置
  30.   * 输入参数: 无
  31.   * 返 回 值: 无
  32.   * 说    明: 无
  33.   */
  34. void SystemClock_Config(void)
  35. {
  36.   RCC_OscInitTypeDef RCC_OscInitStruct;
  37.   RCC_ClkInitTypeDef RCC_ClkInitStruct;

  38.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;  // 外部晶振,8MHz
  39.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  40.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  41.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  42.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  43.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;  // 9倍频,得到72MHz主时钟
  44.   HAL_RCC_OscConfig(&RCC_OscInitStruct);

  45.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  46.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  47.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;       // 系统时钟:72MHz
  48.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;              // AHB时钟:72MHz
  49.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;               // APB1时钟:36MHz
  50.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;               // APB2时钟:72MHz
  51.   HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);

  52.         // HAL_RCC_GetHCLKFreq()/1000    1ms中断一次
  53.         // HAL_RCC_GetHCLKFreq()/100000         10us中断一次
  54.         // HAL_RCC_GetHCLKFreq()/1000000 1us中断一次
  55.   HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);  // 配置并启动系统滴答定时器
  56.   /* 系统滴答定时器时钟源 */
  57.   HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
  58.   /* 系统滴答定时器中断优先级配置 */
  59.   HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
  60. }

  61. /**
  62.   * 函数功能: 主函数.
  63.   * 输入参数: 无
  64.   * 返 回 值: 无
  65.   * 说    明: 无
  66.   */
  67. int main(void)
  68. {  
  69.   /* 复位所有外设,初始化Flash接口和系统滴答定时器 */
  70.   HAL_Init();
  71.   /* 配置系统时钟 */
  72.   SystemClock_Config();

  73.   /* 初始化串口并配置串口中断优先级 */
  74.   MX_DEBUG_USART_Init();
  75.   
  76.   /* 初始化RTC实时时钟 */
  77.   MX_RTC_Init();
  78.   
  79.   /* 无限循环 */
  80.   while (1)
  81.   {
  82.     /* 显示更新时间和日期 */
  83.     RTC_CalendarShow();
  84.     HAL_Delay(1000);
  85.   }
  86. }

  87. /**
  88.   * 函数功能: 显示当前时间和日期
  89.   * 输入参数: 无
  90.   * 返 回 值: 无
  91.   * 说    明: 无
  92.   */
  93. static void RTC_CalendarShow(void)
  94. {
  95.   uint8_t str[30]; // 字符串暂存  
  96.   static uint8_t FirstDisplay = 1;
  97.   
  98.   RTC_DateTypeDef sdatestructureget;
  99.   RTC_TimeTypeDef stimestructureget;
  100.   /* 获取当前时间 */
  101.   HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);
  102.   /* 获取当前日期 */
  103.   HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);
  104.   
  105.   if(FirstDisplay)
  106.   {
  107.     GetChinaCalendarStr(sdatestructureget.Year+2000,sdatestructureget.Month, sdatestructureget.Date,str);
  108.       printf("今天农历:%s\n", str);

  109.    if(GetJieQiStr(sdatestructureget.Year+2000,sdatestructureget.Month, sdatestructureget.Date, str))
  110.       printf("今天农历:%s\n", str);

  111.     FirstDisplay = 0;
  112.   }
  113.   /* 显示日期*/
  114.   printf("当前时间为: %02d年(%s年)%02d月%02d日(星期%s)  ", 2000+sdatestructureget.Year,zodiac_sign[(2000+sdatestructureget.Year-3)%12],
  115.   sdatestructureget.Month, sdatestructureget.Date,WEEK_STR[sdatestructureget.WeekDay]);
  116.   /* 显示时间 */
  117.   printf("%02d:%02d:%02d\n", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);
  118.   
  119. }
  120. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/




串口调试助手截图.jpg


victor1934 发表于 2016-6-10 18:43 | 显示全部楼层
支持一下,趁这几天好好看看
您需要登录后才可以回帖 登录 | 注册

本版积分规则

122

主题

216

帖子

48

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