c - stm32l4 RTC HAL 不工作

标签 c stm32 freertos hal real-time-clock

我在带有 FreeRTOS 的 stm32L476 上的 RTC 有一个奇怪的行为。

它只在 RUN 模式下第一次读取,RTC 正在工作,因为从运行到运行它保存内部寄存器的值并且在上升。

此外,如果我在第 583 行的 stm32l4xx_hal_rtc.c 中放置断点时执行 DEBUG:

tmpreg = (uint32_t)(hrtc->Instance->TR & RTC_TR_RESERVED_MASK);    
*breakpoint* sTime->Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16);

我可以看到 tmpreg 和 TR 注册它们是如何更新的,然后当我点击跳转到下一个断点时,我看到显示更新了。

那么为什么正常运行时它不工作?

初始化代码(生成的立方体MX):

void MX_RTC_Init(void)
{
  RTC_TimeTypeDef sTime;
  RTC_DateTypeDef sDate;

    /**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;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Initialize RTC and set the Time and Date 
    */
  if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != 0x32F2){
  sTime.Hours = 0;
  sTime.Minutes = 0;
  sTime.Seconds = 0;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sDate.WeekDay = RTC_WEEKDAY_MONDAY;
  sDate.Month = RTC_MONTH_JANUARY;
  sDate.Date = 1;
  sDate.Year = 0;

  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0,0x32F2);
  }

}

void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle)
{

  if(rtcHandle->Instance==RTC)
  {
  /* USER CODE BEGIN RTC_MspInit 0 */

  /* USER CODE END RTC_MspInit 0 */
    /* RTC clock enable */
    __HAL_RCC_RTC_ENABLE();
  /* USER CODE BEGIN RTC_MspInit 1 */

  /* USER CODE END RTC_MspInit 1 */
  }
}

读取和打印时钟的任务所有这些任务和功能都在同一个 menu.c 中:

void MenuTask(void const *argument){
    for(;;){

        /*
         * Menus
         */
        DrawMenu();

        osDelay(100);
    }
}

void DrawMenu(){
    switch(menuTaskStatus){

/* Not important code */

    case MENU_INFO:
        menuInfoBar();

        break;

    }
}

我在 LCD 上打印了一个中间有时钟的条形

void menuInfoBar(){

    //Clock
    CheckClock();
    if(updateNeeded.Clock){
        DrawClock();
        updateNeeded.Clock = 0;
    }

}

这是有问题的部分,如您所见,我已经尝试等待同步,但也没有成功。我对这种同步和 RTC 读取是如何工作的有些疑问。

void CheckClock(){
    RTC_TimeTypeDef timeVar;
    //  HAL_GPIO_TogglePin(LEDR_GPIO_Port, LEDR_Pin);
//  if(HAL_RTC_WaitForSynchro(&hrtc) == HAL_OK){
        while(HAL_RTC_GetTime(&hrtc,&timeVar,RTC_FORMAT_BIN)!= HAL_OK);
        if(timeVar.Seconds != timeVarAnt.Seconds){
            timeVarAnt.Minutes = timeVar.Minutes;
            timeVarAnt.Hours = timeVar.Hours;
            timeVarAnt.Seconds = timeVar.Seconds;
            updateNeeded.Clock = 1;
        }
//  }
}

这里我只在显示器上画时钟

void DrawClock(){
    DISP_locate(49,0);
    sprintf((char *)stringBuffer,"%02d:%02d:%02d",(int)timeVarAnt.Hours,(int)timeVarAnt.Minutes,(int)timeVarAnt.Seconds);
    DISP_puts((char *)stringBuffer);
}

我可能无法以 100 毫秒的速度读取 RTC? 有人可以向我解释为什么需要同步?数据表解释说如果时钟快 7 倍就可以了,我使用的是 80Mhz APB1 时钟

我发现一些教程和示例与我所做的完全相同,但它们在主循环中读取了具有许多值的 osDelay()。使用 freeRTOS 和从任务读取有问题吗?

时间无关我试过延迟 5 秒也不起作用

谢谢

最佳答案

可能有点晚了,但我遇到了同样的问题,事实证明 HAL_GetTime(..) 函数有一个怪癖。 HAL_RTC_GetDate() 必须在它之后调用以解锁值。

You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the values * in the higher-order calendar shadow registers to ensure consistency between the time and date values. * Reading RTC current time locks the values in calendar shadow registers until current date is read.

这是在他们的文档以及 RTC HAL 驱动程序的源代码中作为注释编写的。

就我个人而言,我认为 ST 的人应该制作一个 HAL_RTC_GetTimeAndDate(),以免我们落入这个陷阱。

关于c - stm32l4 RTC HAL 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47040039/

相关文章:

objective-c - 使用 NSArray 进行 C 类型的 int 比较

stm32 - 如何写入STM32 Flash

重置后的ARM PC值

task - 如何在 CCS (Code Composer Studio) 上跟踪和分析 FreeRTOS 任务 9

c - STM32 - 从多个任务中读取 I/O

c - gSOAP - XML 数据到 C 结构(也由 gSOAP 生成)

c - 使用递归函数反向打印链表

c - 使用protobuf和STM32F7设计协议(protocol)

freertos - 为什么 Cortex-M FreeRTOS 中的 WFI 之后需要 ISB?

c - 了解有关 C 'bomb' 的 x86 语法