202|3

23

帖子

2

TA的资源

一粒金砂(中级)

STM32H7S78-DK测评(四)——RTC测试 [复制链接]

本帖最后由 FuShenxiao 于 2024-10-24 16:58 编辑

STM32的RTC指的是实时时钟(Real-Time Clock),它是一种用于计时和日期记录的硬件模块。在STM32微控制器中,RTC模块是由一个32位的计数器和一组用于保存日期和时间的寄存器组成的。由于RTC具有较高的精度和稳定性,从而能保持准确的日期和时间信息,因此它常用于需要精确定时和实时数据处理的应用场景。

本来以为RTC实现挺简单的,没想到这里还有那么多坑,主要是CubeMX代码生成存在一些问题。

在CubeMX中配置

选择STM32H7S78-DK模板

配置RTC

image.png

 

image.png   

为了能输出时间和日期,还需要配置UART4

image.png  

代码编写

生成RTC初始化代码如下

void MX_RTC_Init(void)
{

  /* USER CODE BEGIN RTC_Init 0 */

  /* USER CODE END RTC_Init 0 */

  RTC_PrivilegeStateTypeDef privilegeState = {0};
  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef sDate = {0};

  /* USER CODE BEGIN RTC_Init 1 */

  /* USER CODE END RTC_Init 1 */

  /** Initialize RTC Only
  */
  hrtc.Instance = RTC;
  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  hrtc.Init.AsynchPrediv = 127;
  hrtc.Init.SynchPrediv = 255;
  hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  hrtc.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE;
  hrtc.Init.BinMode = RTC_BINARY_NONE;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }
  privilegeState.rtcPrivilegeFull = RTC_PRIVILEGE_FULL_NO;
  privilegeState.backupRegisterPrivZone = RTC_PRIVILEGE_BKUP_ZONE_NONE;
  privilegeState.backupRegisterStartZone2 = RTC_BKP_DR0;
  privilegeState.backupRegisterStartZone3 = RTC_BKP_DR0;
  if (HAL_RTCEx_PrivilegeModeSet(&hrtc, &privilegeState) != HAL_OK)
  {
    Error_Handler();
  }

  /* USER CODE BEGIN Check_RTC_BKUP */

  /* USER CODE END Check_RTC_BKUP */

  /** Initialize RTC and set the Time and Date
  */
  sTime.Hours = 0x15;
  sTime.Minutes = 0x0;
  sTime.Seconds = 0x0;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  sDate.WeekDay = RTC_WEEKDAY_THURSDAY;
  sDate.Month = RTC_MONTH_OCTOBER;
  sDate.Date = 0x24;
  sDate.Year = 0x24;

  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN RTC_Init 2 */

  /* USER CODE END RTC_Init 2 */

}

编写printf重定向

int fputc(int ch,FILE *p)
{
    char c=ch;
    HAL_UART_Transmit(&huart4,(unsigned char *)&c,1,50);
    return ch;
}

void UART4_SendByte(char c)
{
    HAL_UART_Transmit(&huart4,(unsigned char *)&c,1,50);
}

void UART4_SendData(char *p,int len)
{
    HAL_UART_Transmit(&huart4,(unsigned char *)p,len,50);
}

编写输出RTC日历的代码

static void RTC_CalendarShow(uint8_t *showtime, uint8_t *showdate)
{
  RTC_DateTypeDef sdatestructureget;
  RTC_TimeTypeDef stimestructureget;

  /* Get the RTC current Time */
  HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);
  /* Get the RTC current Date */
  HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);
  /* Display time Format : hh:mm:ss */
  sprintf((char *)showtime, "%2d:%2d:%2d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);
  /* Display date Format : mm-dd-yyyy */
  sprintf((char *)showdate, "%2d-%2d-%2d", sdatestructureget.Month, sdatestructureget.Date, 2000 + sdatestructureget.Year);
  printf("%s\r\n", showtime);
  printf("%s\r\n", showdate);
}

初始化时间/日期字符串

uint8_t aShowTime[16] = "hh:ms:ss";
uint8_t aShowDate[16] = "mm-dd-yyyy";

在主函数循环中加入如下代码

RTC_CalendarShow(aShowTime, aShowDate);
HAL_Delay(1000);

但是,这样还是有问题的。

问题出在 HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef *hrtc)

其代码如下

HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef *hrtc)
{
  uint32_t tickstart;
  HAL_StatusTypeDef status = HAL_OK;

  /* Check if the Initialization mode is set */
  if (READ_BIT(RTC->ICSR, RTC_ICSR_INITF) == 0U)
  {
    /* Set the Initialization mode */
    SET_BIT(RTC->ICSR, RTC_ICSR_INIT);

    tickstart = HAL_GetTick();
    /* Wait till RTC is in INIT state and if Time out is reached exit */
    while ((READ_BIT(RTC->ICSR, RTC_ICSR_INITF) == 0U) && (status != HAL_TIMEOUT))
    {
      if ((HAL_GetTick()  - tickstart) > RTC_TIMEOUT_VALUE)
      {
        /* New check to avoid false timeout detection in case of preemption */
        if (READ_BIT(RTC->ICSR, RTC_ICSR_INITF) == 0U)
        {
          status = HAL_TIMEOUT;

          /* Change RTC state */
          hrtc->State = HAL_RTC_STATE_TIMEOUT;
        }
        else
        {
          break;
        }
      }
    }
  }

  return status;
}

问题出现在执行 SET_BIT(RTC->ICSR, RTC_ICSR_INIT); 之后,寄存器的初始化位并没有置1。

阅读手册可知需要对DBP置1才能使能写RTC寄存器。

image.png  

en.DM00686107.pdf (72.38 MB, 下载次数: 0)
此帖出自stm32/stm8论坛

最新回复

感觉MCU硬件也要过剩了,和PC当年一样,软件跟不上。   详情 回复 发表于 2024-10-25 10:38

回复
举报

7419

帖子

18

TA的资源

五彩晶圆(高级)

S又是个主打哪个方向的型号?

此帖出自stm32/stm8论坛

点评

我觉得主要是它的高性能图像显示能力吧,主要吸引人的是它DMA2D,也就是GPU功能,这块开发板的屏幕有480*800,已经挺大的了。  详情 回复 发表于 2024-10-24 20:06
个人签名

默认摸鱼,再摸鱼。2022、9、28


回复

23

帖子

2

TA的资源

一粒金砂(中级)

freebsder 发表于 2024-10-24 19:19 S又是个主打哪个方向的型号?

我觉得主要是它的高性能图像显示能力吧,主要吸引人的是它DMA2D,也就是GPU功能,这块开发板的屏幕有480*800,已经挺大的了。

此帖出自stm32/stm8论坛

点评

感觉MCU硬件也要过剩了,和PC当年一样,软件跟不上。  详情 回复 发表于 2024-10-25 10:38

回复

7419

帖子

18

TA的资源

五彩晶圆(高级)

FuShenxiao 发表于 2024-10-24 20:06 我觉得主要是它的高性能图像显示能力吧,主要吸引人的是它DMA2D,也就是GPU功能,这块开发板的屏幕有480* ...

感觉MCU硬件也要过剩了,和PC当年一样,软件跟不上。

此帖出自stm32/stm8论坛
个人签名

默认摸鱼,再摸鱼。2022、9、28


回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表