美文网首页
3. 基于STM32CubeIDE搭建开发环境 --- 解决延时

3. 基于STM32CubeIDE搭建开发环境 --- 解决延时

作者: mz8023yt | 来源:发表于2019-12-27 22:14 被阅读0次

    本博客中示例代码下载路径: https://github.com/maziot-stm32/A1/releases/tag/v0.3

    HAL_Delay 延时时间不准确

    在上一篇文章中有编写一个点灯的 demo 程序用于验证工程. 其中主函数测试代码如下:

    #define LED0_Pin        GPIO_PIN_8
    #define LED0_GPIO_Port  GPIOA
    #define LED1_Pin        GPIO_PIN_2
    #define LED1_GPIO_Port  GPIOD
    
    /**
     * @brief  The application entry point.
     * @retval int
     */
    int main(void)
    {
        HAL_Init();
        SystemClock_Config();
        MX_GPIO_Init();
        led_init();
    
        while (1)
        {
            HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, LED_ON);
            HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, LED_ON);
            HAL_Delay(200);
            HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, LED_OFF);
            HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, LED_OFF);
            HAL_Delay(200);
        }
    }
    

    这里的逻辑很简单, 200ms切换一次 LED 的状态. 但是烧写到板子上后, 发现 LED 闪烁的并没有想象的那么快. 因此便用逻辑分析仪抓了下 PA8 引脚波形.

    PA8波形

    通过波形确认到 HAL_Delay(200) 实际延时了 400ms, 果然不对.

    晶振时钟配置不对

    追了下代码, 最后发现是晶振频率代码和板子没有对应上, 板子上贴的是 8M 晶振, 代码中的配置却是 16M, 修正后, 延时正常.

    修改 diff 如下:

    Paul@DESKTOP-PUB20JQ MINGW64 /f/Workspaces/stm32/A1 (master)
    $ git diff
    diff --git a/MAZ_Applications/system_stm32f1xx.c b/MAZ_Applications/system_stm32f1xx.c
    index 7cacb32..40f4488 100644
    --- a/MAZ_Applications/system_stm32f1xx.c
    +++ b/MAZ_Applications/system_stm32f1xx.c
    @@ -120,7 +120,7 @@
                    is no need to call the 2 first functions listed above, since SystemCoreClock
                    variable is updated automatically.
       */
    -uint32_t SystemCoreClock = 16000000;
    +uint32_t SystemCoreClock = 8000000;
     const uint8_t AHBPrescTable[16U] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
     const uint8_t APBPrescTable[8U] =  {0, 0, 0, 0, 1, 2, 3, 4};
    

    修正后重新用逻辑分析仪抓取波形确认延时就比较正常了, 201ms多一点.

    修改晶振频率后PA8波形

    延时误差较大

    讲道理, 硬件嘀嗒定时器延时, 应该比较精确, us级别可以理解, 不应该出现ms级别的误差. 找找原因.

    __weak void HAL_Delay(uint32_t Delay)
    {
      uint32_t tickstart = HAL_GetTick();
      uint32_t wait = Delay;
    
      /* Add a freq to guarantee minimum wait */
      if (wait < HAL_MAX_DELAY) 
      {
        wait += (uint32_t)(uwTickFreq);               // 强制加1
      }
    
      while ((HAL_GetTick() - tickstart) < wait)
      {
      }
    }
    

    最后发现, 居然是在 HAL_Delay 函数内部对延时时间进行了强制加1动作. 该强制加1动作是为了防止延迟时间为设置0时卡死在后面的 while ((HAL_GetTick() - tickstart) < wait) 循环中.
    因此做出如下修正:

    Paul@DESKTOP-PUB20JQ MINGW64 /f/Workspaces/stm32/A1 (master)
    $ git diff
    diff --git a/MAZ_Vendors/ST/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h b/MAZ_Vendors/ST/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h
    index c287eb3..c8630f8 100644
    --- a/MAZ_Vendors/ST/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h
    +++ b/MAZ_Vendors/ST/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h
    @@ -57,6 +57,7 @@ typedef enum
    
     /* Exported macro ------------------------------------------------------------*/
     #define HAL_MAX_DELAY      0xFFFFFFFFU
    +#define HAL_NO_DELAY       0x0
    
     #define HAL_IS_BIT_SET(REG, BIT)         (((REG) & (BIT)) != 0U)
     #define HAL_IS_BIT_CLR(REG, BIT)         (((REG) & (BIT)) == 0U)
    diff --git a/MAZ_Vendors/ST/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c b/MAZ_Vendors/ST/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c
    index 252f973..aa3f5c5 100644
    --- a/MAZ_Vendors/ST/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c
    +++ b/MAZ_Vendors/ST/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal.c
    @@ -363,7 +363,8 @@ __weak void HAL_Delay(uint32_t Delay)
       uint32_t wait = Delay;
    
       /* Add a freq to guarantee minimum wait */
    -  if (wait < HAL_MAX_DELAY)
    +//  if (wait < HAL_MAX_DELAY)
    +  if (wait == HAL_NO_DELAY)
       {
         wait += (uint32_t)(uwTickFreq);
       }
    

    修正后, 时间就在 200ms 左右, 误差为 us 级别, 波形如下:

    修改延时函数后PA8波形

    相关文章

      网友评论

          本文标题:3. 基于STM32CubeIDE搭建开发环境 --- 解决延时

          本文链接:https://www.haomeiwen.com/subject/vsljoctx.html