STM32 使用HAL库,HAL_Delay()会卡死, 程序一直卡在 HAL_GetTick( ) 函数中(已解决)

今天遇到个很奇怪的问题, 不知道为什么, 单片机运行一会之后, 系统就没反应了, 经过调试发现, 系统卡在HAL_Delay()中了.

之前也遇到过这个问题后来把HAL_Delay 去掉了. 然后发现不行, 还是得有它.不然发串口数据发的太快会乱掉. 得慢点发.

然后调试到HAL_Delay()方法的内部发现 HAL_GetTick( )函数一直返回

c 复制代码
__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);
  }
	
  //卡在这个while函数里
  while ((HAL_GetTick() - tickstart) < wait)
  {
  }
}

再跟踪发现 HAL_GetTick() - tickstart 永远等于0

这就很奇怪了.

于是再深入看一下HAL_GetTick()函数. 代码如下

c 复制代码
__weak uint32_t HAL_GetTick(void)
{
  return uwTick;
}

也就是说, uwTick 不再更新了. 数值永远是某个固定数值.

那uwTick 到底是怎么更新的呢?

最后发现

在这里更新的.

c 复制代码
__weak void HAL_IncTick(void)
{ 
  uwTick += uwTickFreq;
}

调试发现 uwTickFreq ===0

也就是说, uwTick 不再增加了.

所以导致外层的while死循环了.

那么uwTickFreq又是什么时候变成0的呢?

我跟踪了很久也没有拦截到uwTickFreq 是什么时候更新的. keil工具也拦截不到是什么时候更新的.

最后索性, 给uwTickFreq 一个默认值. 只要发现 uwTickFreq 为0了.

就给它个默认值., 然后就把代码改成了下面这样的函数.

由于源代码函数是__weak 的, 也就是说, 可以被覆盖的.

于是我在自己的main.c 文件代码中重新写了一下. 如下:

c 复制代码
void HAL_IncTick(void)
{
	if(uwTickFreq==0)
	{
		uwTickFreq = HAL_TICK_FREQ_DEFAULT;
	}
  uwTick += uwTickFreq;
}

如果不在乎延迟时间的精准度, 可以考虑.写成下面的这种, 更快一点

c 复制代码
void HAL_IncTick(void)
{ 
  uwTick += HAL_TICK_FREQ_DEFAULT;
} 

后来经过调试, 我猜测是因为定时器的停止和开启导致的.

具体中间的原因就不再深入细究了. 有时间精力的朋友可以再追踪下去.

找到原因欢迎分享.

我用的是STM32F103C8T6 , 其中的定时器TIM3用来驱动ADC的采样频率.

在循环中不停的停止和开启Tim3. 我估计是因为这个原因导致的. uwTickFreq 重新计算.

而且我这里做了自动计算Tim3的自动重载计数值. 估计是跟它有关.

具体的不再深入探究了.

延迟时间就写死吧...

相关推荐
scilwb6 小时前
RoboCon考核题——scilwb
单片机
点灯小铭7 小时前
基于STM32单片机智能RFID刷卡汽车位锁桩设计
stm32·单片机·汽车·毕业设计·课程设计
bai5459368 小时前
STM32 软件I2C读写MPU6050
stm32·单片机·嵌入式硬件
逼子格10 小时前
AT89C52单片机介绍
单片机·嵌入式硬件·51单片机·硬件工程师·硬件工程师真题·at89c52·器件手册
生涯にわたる学び12 小时前
ARM 实操 流水灯 按键控制 day53
arm开发·嵌入式硬件
whaosoft-14312 小时前
w嵌入式分享合集68
嵌入式硬件
竹照煜_ysn15 小时前
STM32——软硬件I2C
stm32·嵌入式硬件·mongodb
Ronin-Lotus16 小时前
嵌入式硬件篇---电感串并联
嵌入式硬件
Wallace Zhang17 小时前
STM32 - Embedded IDE - GCC - 显著减少固件的体积
stm32·单片机·嵌入式硬件
fengfuyao9851 天前
STM32如何定位HardFault错误,一种实用方法
stm32·单片机·嵌入式硬件