单片机中为什么中断函数内部不能使用延时函数?

相信大家在学习STM32的过程中有可能听过这样子一句话:不要再中断函数中使用延时。这已经是形成了一种规范,因为这样子做可能会造成程序的死机,也有很多地方会以这个问题来考察面试者的基础知识是否扎实。

但是,为什么会出现这个情况呢,本期我们就来详细的介绍和讨论一下这个情况。

首先我们介绍一下中断函数的特点:

  1. 中断的优先级高:中断服务程序(ISR, Interrupt Service Routine)通常在中断发生时立即执行,打断当前正在执行的主程序或其他低优先级的中断服务程序

  2. 执行时间应尽可能短:为了确保系统能够快速响应其他中断,ISR的执行时间应该尽可能短。长时间的中断处理可能会导致其他中断被延迟处理,甚至丢失。

    

而延时函数,通常依赖于一些硬件资源,例如STM32中的默认系统滴答定时器也就是Systick。

其优先级属于最低级的15级,因此我们在中断函数中调用HAL_Delay时他会等待Systick计数到一定时间而退出延时。

在它的中断回调函数中,他的每次中断都会为增加uwTick来增加计数。而HAL_Delay则是等待uwTick增加到一定的值推出循环,这也就是STM32默认的延时原理。

但是我们在中断服务函数中等待延时的时候,则会出现一种情况:在高优先级任务中等待低优先级任务完成。这个问题俗称优先级转(倒反天罡),这个问题在RTOS中会着重提到,并且有专门的解决方式,而在逻辑开发中遇到这个问题则会导致,在高优先级的中断函数中,低优先级的系统滴答定时器中断无法进入中断函数,也自然无法增加uwTick的值,导致HAL_Delay无法退出等待。

解决办法

到这里想必大家已经知道这个问题是如何产生的了,而为了解决这个问题,我们主要需要解决的就是优先级翻转。

所以解决方式主要有三个:

1.换一种延时方式,我们使用空跑选择浪费CPU的方式来实现延时,当然这个方式比较的笨,也不方便精准的把控延时时间。

2.使用硬件定时器,这里就不得不提一下什么是TimeBase了,时基。在STM32微控制器的编程中,TimeBase指的是一个用来生成系统时基的机制,通常用于实现定时功能,比如系统滴答(SysTick)、延时函数(如HAL_Delay)和其他需要周期性执行的任务。如果使用CubeMX编程的时候,可以看到一个切换时基的选项。

默认使用的是SysTick,而我们可以选择硬件定时器,使用硬件定时器的好处在于可以独立于CPU​运行时钟,不易受到阻塞和干扰。同样的,可以做到比Systick更加丰富的功能,例如Systick的频率好像固定是1ms,这也就是为什么Delay中没有us级的Delay,而使用硬件定时器则可以产生us级的Delay​。

3.第三则是修改Systick的中断优先级,Systick的中断优先级默认是15,当然是可以修改的,我们可以修改成0最高优先级,之后将其他的中断优先级修改为比0低的优先级,这样子就不会出现在其他中断回调函数中无法​进行Systick中断的情况了。​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值