打印
[应用相关]

基于STM32CubeIDE搭建开发环境 --- 解决延时不准问题

[复制链接]
789|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本博客中示例代码下载路径: https://github.com/maziot-stm32/A1/releases/tag/v0.3




作者:mz8023yt
链接:https://www.jianshu.com/p/eb0d52ff0bb0
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

使用特权

评论回复
沙发
internally|  楼主 | 2020-5-10 09:06 | 只看该作者
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

/**
* [url=home.php?mod=space&uid=247401]@brief[/url]  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);
    }
}

使用特权

评论回复
板凳
internally|  楼主 | 2020-5-10 09:07 | 只看该作者
这里的逻辑很简单, 200ms切换一次 LED 的状态. 但是烧写到板子上后, 发现 LED 闪烁的并没有想象的那么快. 因此便用逻辑分析仪抓了下 PA8 引脚波形.

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

使用特权

评论回复
地板
internally|  楼主 | 2020-5-10 09:07 | 只看该作者
晶振时钟配置不对
追了下代码, 最后发现是晶振频率代码和板子没有对应上, 板子上贴的是 8M 晶振, 代码中的配置却是 16M, 修正后, 延时正常.

使用特权

评论回复
5
internally|  楼主 | 2020-5-10 09:10 | 只看该作者
修改 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};

使用特权

评论回复
6
internally|  楼主 | 2020-5-10 09:10 | 只看该作者
修正后重新用逻辑分析仪抓取波形确认延时就比较正常了, 201ms多一点.

使用特权

评论回复
7
internally|  楼主 | 2020-5-10 09:11 | 只看该作者
延时误差较大
讲道理, 硬件嘀嗒定时器延时, 应该比较精确, 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)
  {
  }
}

使用特权

评论回复
8
internally|  楼主 | 2020-5-10 09:12 | 只看该作者
最后发现, 居然是在 HAL_Delay 函数内部对延时时间进行了强制加1动作. 该强制加1动作是为了防止延迟时间为设置0时卡死在后面的 while ((HAL_GetTick() - tickstart) < wait) 循环中.

使用特权

评论回复
9
internally|  楼主 | 2020-5-10 09:13 | 只看该作者
因此做出如下修正:

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);
   }

使用特权

评论回复
10
internally|  楼主 | 2020-5-10 09:13 | 只看该作者
修正后, 时间就在 200ms 左右, 误差为 us 级别, 波形如下:

使用特权

评论回复
11
guanjiaer| | 2020-6-2 16:12 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
12
heimaojingzhang| | 2020-6-2 16:13 | 只看该作者
diff原来是多少来着

使用特权

评论回复
13
keaibukelian| | 2020-6-2 16:13 | 只看该作者
为什么需要这样修改呢

使用特权

评论回复
14
labasi| | 2020-6-2 16:14 | 只看该作者
这样修正的前提是时钟源是准确的 是吗

使用特权

评论回复
15
paotangsan| | 2020-6-2 16:15 | 只看该作者
改的很巧妙

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

15

主题

315

帖子

0

粉丝