代码之家  ›  专栏  ›  技术社区  ›  taquionbcn

stm32l4 RTC HAL不工作

  •  5
  • taquionbcn  · 技术社区  · 7 年前

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

    另外,如果我在stm32l4xx\u hal\u rtc上放置断点时进行调试。c第583行:

    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 */
      }
    }
    

    读取和打印时钟的任务所有这些任务和功能都位于同一菜单中。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;
        }
    
    }
    

    这里是有问题的部分,正如你所看到的,我已经尝试了等待同步,但也没有工作。我对syncro和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);
    }
    

    有可能我读不到RTC快到100ms吗? 有人可以向我解释为什么需要同步?数据表解释说,如果时钟快7倍就可以了,我使用的是80Mhz APB1时钟

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

    时间无关紧要,我试过5秒的延迟,也不管用

    谢谢

    4 回复  |  直到 7 年前
        1
  •  18
  •   John Wick    5 年前

    可能有点晚了,但我遇到了同样的问题,结果是 HAL_GetTime(..) 函数有一个怪癖。 HAL_RTC_GetDate() 必须在其后面调用才能解锁值。

    你必须打电话 之后 HAL_RTC_GetTime() 解锁值 *在高阶日历阴影寄存器中,以确保时间和日期值之间的一致性。 *读取RTC当前时间将锁定日历阴影寄存器中的值,直到读取当前日期。

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

    就我个人而言,我认为ST的人应该 HAL_RTC_GetTimeAndDate() 不要让我们落入这个陷阱。

        2
  •  0
  •   0___________    7 年前
    struct 
    {
        unsigned TR;
    }*rcc = (void *)0x56456546;
    
    typedef struct
    {
        unsigned    su  :4;
        unsigned    st  :2;
        unsigned        :1;
        unsigned    mu  :4;
        unsigned    mt  :2;
        unsigned        :1;
        unsigned    hu  :4;
        unsigned    ht  :2;
        unsigned    pm  :1;
        unsigned        :9
    }RCC_TR_T;
    
    
    typedef struct
    {
        uint8_t seconds, minutes, hours, pm;
    }TIME_T;
    
    
    TIME_T *GetTime(TIME_T *time)
    {
        RCC_TR_T *tr = (RCC_TR_T *)&rcc -> TR;
    
        time -> hours = tr -> hu + tr -> ht * 10;
        time -> minutes = tr -> mu + tr -> mt * 10;
        time -> seconds = tr -> su + tr -> st * 10;
        time -> pm = tr -> pm;
        return time;
    }
    
        3
  •  0
  •   taquionbcn    7 年前

    这个答案并没有回答为什么ST“hal”不工作,但它解决了我需要的问题,即使用RTC。

    void CheckClock(){
    
        uint32_t tmpreg = (uint32_t) hrtc.Instance->TR;
    
        /* Fill the structure fields with the read parameters */
        timeVar.Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16);
        timeVar.Minutes = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >>8);
        timeVar.Seconds = (uint8_t)(tmpreg & (RTC_TR_ST | RTC_TR_SU));
    
        if(timeVar.Seconds != timeVarAnt.Seconds){
            HAL_GPIO_TogglePin(LEDR_GPIO_Port, LEDR_Pin);
            timeVarAnt.Minutes = timeVar.Minutes;
            timeVarAnt.Hours = timeVar.Hours;
            timeVarAnt.Seconds = timeVar.Seconds;
            updateNeeded.Clock = 1;
        }
    }
    

    谢谢

    void CheckClock(){
    
        uint32_t tmpreg = (uint32_t) hrtc.Instance->TR;
        timeVar.Hours = Bcd2ToByte((uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16));
        timeVar.Minutes =Bcd2ToByte( (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >>8));
        timeVar.Seconds =Bcd2ToByte( (uint8_t)(tmpreg & (RTC_TR_ST | RTC_TR_SU)));
    
        if(timeVar.Seconds != timeVarAnt.Seconds){
            timeVarAnt.Minutes = timeVar.Minutes;
            timeVarAnt.Hours = timeVar.Hours;
            timeVarAnt.Seconds = timeVar.Seconds;
            IBS.updates.Clock = 1;
        }
        //  }
    }
    
        4
  •  0
  •   Dursun Ali ÇİLİNGİROĞLU    4 年前
             //HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN); 
             char xsa[6];
             char your_time[9];
             sprintf(xsa,"%06x",(uint32_t)hrtc.Instance->TR);
             sprintf((char*)your_time,"%c%c:%c%c:%c%c%c",xsa[0],xsa[1],xsa[2],xsa[3],xsa[4],xsa[5],'\0');