stm32 中断函数里使用 HAL_Delay() 导致程序卡死的原因

由于 HAL_Delay() 是依靠嘀嗒定时器(sysTick)的中断实现的,这个中断优先级默认为最低,所以如果调用了其它中断,就会导致嘀嗒定时器的中断程序无法进入,从而导致 HAL_Delay() 失灵。

下面是详细解释:

HAL_Delay() 实现原理

HAL_Delay() 定义:
HAL_Delay() 函数定义
HAL_Delay 通过 HAL_GetTick() 获取嘀嗒定时器的值,当 HAL_GetTick() 返回的值超过 Delay 的值的时候,退出当前函数。

下面看 HAL_GetTick() 的定义:
HAL_GetTick() 函数定义
可以看见它返回变量 uwTick 的值,全局查找 uwTick,可以找到下列函数:
HAL_IncTick 函数定义
可以看到,每次调用这个函数 HAL_IncTick,uwTick 的值就会增加 uwTickFreq。
继续往下找,可以找到是谁调用了这个函数 HAL_IncTick:
系统嘀嗒定时器的中断函数
这个 SysTick_Handler 是系统嘀嗒定时器的中断函数。系统嘀嗒定时器和普通定时器差不多,一定时间(用户设定)后就会产生中断(如果使能了嘀嗒定时器中断)。

讲到这里,可以总结 HAL_Delay 函数的实现原理:uwTick 每隔一段时间就会增加,通过读取 uwTick 的值保存,过一段时间再读取 uwTick 的值,两次读取的时间相减,就可以知道过去了多长时间。这段时间与用户设定的值(Delay)比较,如果大于就退出 HAL_Delay 函数,从而实现延迟。

出错原因

嘀嗒定时器的中断也受 NVIC 管理,也有优先级,而通过 keil 调试我们可以看到:
嘀嗒定时器的优先级
嘀嗒定时器(System Tick Timer)的中断优先级设置为 15,优先级非常低,所以在其他中断(例如串口接收中断)运行时,不会进入嘀嗒定时器的中断,导致 uwTick 无法更新,那么 HAL_Delay() 自然无法工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值