STM32 HAL库 中断处理中使用延时函数(HAL_Delay)

这篇具有很好参考价值的文章主要介绍了STM32 HAL库 中断处理中使用延时函数(HAL_Delay)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

问题描述

今天在学习STM32 HAL库外部中断,使用的是按键触发外部中断,想在外部中断里面写一个按键消抖,也就是在HAL库外部中断处理函数中使用了HAL_Delay() 函数,后来经过实验,在外部中断处理函数(void EXTI1_IRQHandler(void))和中断回调函数(void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin))里面都不能使用HAL_Delay(),使用就会卡死在延时这一步;

经过分析,也参考了别人的一些参考资料,发现网上的写的比较乱一点,自己总结了一下,以我理解的角度分析一下这些问题,(如有质疑之处,还请各位大佬批评指正);

首先详细描述一下这个问题,使用中断方式检测按键,程序运行后,按键产生的中断只能被触发一次,之后无法触发,而且一直卡在中断位置,无法退出中断;


原因分析:

认真看一下HAL_Delay函数,就可以分析出来问题:

/** * @brief This function provides minimum delay (in milliseconds) based * on variable incremented. * @note In the default implementation , SysTick timer is the source of time base. * It is used to generate interrupts at regular time intervals where uwTick * is incremented. * @note This function is declared as __weak to be overwritten in case of other * implementations in user file. * @param Delay specifies the delay time length, in milliseconds. * @retval None */
__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((HAL_GetTick() - tickstart) < wait)
  { 
   
  }
}

这是延时函数的原型,有着 __weak 的标识,意味着你可以自己写一个延时函数并用同样的函数名。同时可以看到函数上方有说明,第二条注意事项清楚地说道:计时器的时基来源是 SysTick定时器,且在固定时间间隔内产生中断。Interrupt这一词是问题的关键,既然是中断,势必就有优先级,如果在中断里面HAL_Delay会卡死,而main函数则不会,那可能是优先级问题造成的。

系统滴答定时器(System tick timer)的优先级默认就是最低
外部中断处理的优先级比系统滴答定时器优先级高;

在整个按键触发的过程中,按键按下触发了外部中断,转去执行外部中断函数,但是在外部中断里面调用了HAL_Delay()这个延时程序来消除按键抖动。HAL_Delay()使用了系统滴答定时器来精确定时。外部中断处理的优先级比系统滴答定时器优先级高。所以系统滴答定时器又被按键中断打断,HAL_Delay()遭到了阻塞。所以,程序卡死在HAL_Delay()这里,整个程序处于卡死状态。

按键触发中断处理程序 --> HAL_Delay() --> 系统滴答定时器(未执行)–>外部中断处理 --> HAL_Delay() (卡死)

如果HAL_Delay()需要被外部中断处理程序调用,系统滴答定时器必须比外部中断要高,否则调用者的中断处理程序将被阻塞。


解决方案:

一种解决办法是:

采用while(t–);代替延时函数;
经过查资料:

t=3127;
while(t--);

大致相当于HAL_Delay(1);即延时一毫秒;
参考别人计算的t值,可能并不准确

可以自习写一个函数:

void ms_Delay(uint16_t t_ms)
{
	uint32_t t=t_ms*3127;
	while(t--);
}

也可以在函数里面直接写:

uint16_t t=3127*ms;
while(t--);

还有另一种解决办法是更改系统滴答定时器和外部中断的优先级,将系统滴答定时器的优先级设置的比外部中断要高

hal_delay,stm32,单片机,嵌入式硬件
将外部中断的优先级设置的比系统滴答定时器优先级要高文章来源地址https://www.toymoban.com/news/detail-840427.html

到了这里,关于STM32 HAL库 中断处理中使用延时函数(HAL_Delay)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【HAL库】STM32CubeMX开发----非阻塞延时实验----SysTick(滴答定时器)中断

    STM32CubeMX 下载和安装 详细教程 【HAL库】STM32CubeMX开发----STM32F103/F207/F407----目录 HAL库 有自带的 ms级 延时函数: HAL_Delay(); 缺点: 这是 阻塞延时 方式,就是延时期间,什么都不能干,这样很浪费资源。 这篇文章主要介绍,利用 SysTick(滴答定时器)中断 实现 非阻塞延时 的实验

    2024年02月16日
    浏览(40)
  • STM32cubeIDE HAL库中断服务函数解读

    以stm32f103为例 在开启一个中断后,首先会在stm32f1xx_it.c找到自动生成的中断处理函数,这里是TIM1产生的定时器中断:  这个函数又调用了 stm32f1xx_hal_tim.c 中的 HAL_TIM_IRQHandler(htim1),这个htim1是通用定时器的结构体,其定义为 这个结构体的意义可以参考第25章 STM32F429的TIM定时器

    2024年02月02日
    浏览(55)
  • STM32 HAL库的串口中断服务函数详解

    最近在实现利用上位机通过串口发送指令给下位机执行操作的实验,在之前学习串口的过程中我就一直有一个疑惑,那就是为什么在串口中断回调函数内除了要加上自己的操作以外还要在末尾再执行一次 接收中断 ,在查阅了一些资料后我才发现原来和 中断服务函数 有关 我

    2024年02月10日
    浏览(31)
  • STM32 HAL库常用GPIO函数以及外部中断配置与响应流程

    Hello,大家好,这是我第一篇博客,写的不好请大家包涵指教,话不多说直接看内容: HAL库常用GPIO函数: void HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init) 这个函数主要用来初始化我们需要用到的引脚,设置其工作频率、工作模式、上下拉等参数。如果使用CubeMX配置工程

    2024年02月03日
    浏览(38)
  • STM32不使用中断实现定时器微秒级精确延时

    我们在写代码的时候避免不了要使用延时函数,很多延时函数都是使用中断或者tick来实现的,tick的方式最大到毫秒ms级别,通过中断方式的通用定时器来实现,如果实现1us的延时那么每1us就来一次中断,很影响cpu的效率。 本文提供一种 不使用中断 ,并且很简单的方式实现的

    2024年04月11日
    浏览(33)
  • STM32CubeMX-HAL库-UART串口接收中断回调函数代码分析

            CubeMx中HAL库函数的调用不同于库函数调用,在学习CubeMx串口通信时,不理解HAL库中的回调函数是怎么被调用的,于是查看每个的定义,参考其他人写的博客,总算弄明白了HAL库中断调用与库函数不同之处。写下这篇博客一是加深自己的理解,二是希望对不理解HA

    2024年02月02日
    浏览(42)
  • 【STM32】CUBEMX之串口:串口三种模式(轮询模式、中断模式、DMA模式)的配置与使用示例 + 串口重定向 + 使用HAL扩展函数实现不定长数据接收

    目录   总览 使用CUBEMX创建工程的基本配置 CUBEMX中的配置 Keil中的配置 实物连接 串口轮询模式 轮询模式HAL库函数 特点 实验一:发送数据给单片机并让其返回相同值 串口重定向 串口中断模式 在CUBEMX中打开串口中断 中断模式HAL库函数 特点 实验二:使用中断回调完成实验一

    2024年04月10日
    浏览(40)
  • STM32 hal库使用笔记(二)中断—定时器中断

    目录 一、定时器简介 二、HAL库配置 1.时钟树的配置 2. CubeMX的配置 三、代码编写 四、拓展实验 五、实验效果 实验目的:利用定时器6控制LED灯的亮灭,间隔500ms 实验平台:正点原子精英板 一、定时器简介     定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发

    2024年01月19日
    浏览(43)
  • STM32学习笔记-SMT32使用HAL库UART中断方式使用

    目录 1、引言 2、配置 3、流程 近来需要使用蓝牙模块,再了解到蓝牙模块等无线模块许多使用串口透传,便决定在研究一下串口UART 的使用方法。 由于用的板子种类每次都不一样,有F103 有G0 有G4 还有公司的8位自研芯片,所以每次用起来都需要重头开始复习 每次使用UART的目

    2023年04月12日
    浏览(37)
  • stm32使用HAL库配置串口中断收发数据(保姆级教程)

    最近在学习使用hal库,之前都是用标准库来写32代码,所以发个帖子记录一下学习过程,同时也希望能帮助到一些也在学习HAL库的同学。 接下来进入正题 串口中断是指当单片机收到一个串口数据时,单片机会产生一个中断信号,通知处理器中断服务程序去处理这个接收到的数

    2024年02月07日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包