历史上的今天
返回首页

历史上的今天

今天是:2024年09月29日(星期日)

正在发生

2019年09月29日 | STM32Cube HAL库中断处理机制,以及回调函数实现原理

2019-09-29 来源:eefocus

1写在前面

很多人都知道STM32CubeMX这套工具的一个目的:减少开发者对STM32底层驱动的开发时间,把重心放在应用代码上。


但是,STM32CubeMX只是生成了底层驱动的初始化代码。所以,我们还需要掌握:应用层代码如何调用HAL库函数接口,以及HAL库中断处理机制等相关知识。


HAL库牵涉的内容较多,本文拿HAL库中断处理来讲解,以及相关的回调函数。


HAL库中断处理机制

之前使用标准外设库开发时,中断程序(函数)由我们自己实现。


而HAL库的中断处理函数是按照HAL处理机制来实现,如USART1,统一由HAL_UART_IRQHandler来进行处理,如下图:

640?wx_fmt=png

其它大部分外设(TIM、SPI、CAN...)中断都类似,HAL进行统一处理。


也就是说,HAL已经帮我们把中断处理函数写好了,我们只需要调用相应函数来编写应用程序就行了。


HAL_xxx_IRQHandler里面做了哪些处理? 我们以STM32F1的HAL_UART_IRQHandler为例:


void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)

{

   uint32_t isrflags   = READ_REG(huart->Instance->SR);

   uint32_t cr1its     = READ_REG(huart->Instance->CR1);

   uint32_t cr3its     = READ_REG(huart->Instance->CR3);

   uint32_t errorflags = 0x00U;

   uint32_t dmarequest = 0x00U;

 

  /* If no error occurs */

  errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));

  if(errorflags == RESET)

  {

    /* UART in mode Receiver -------------------------------------------------*/

    if(((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))

    {

      UART_Receive_IT(huart);

      return;

    }

  }

 

  /* If some errors occur */

  if((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))

  {

  /*

  ·

  ·删减了部分代码

  ·

  */

  } /* End if some error occurs */

 

  /* UART in mode Transmitter ------------------------------------------------*/

  if(((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))

  {

    UART_Transmit_IT(huart);

    return;

  }

  /* UART in mode Transmitter end --------------------------------------------*/

  if(((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))

  {

    UART_EndTransmit_IT(huart);

    return;

  }

}


其实,大家认真看一下代码应该能明白,这些和我们编写的中断处理函数是不是有类似之处?


这是无非就是接收中断、发送中断、错误中断等一系列处理。只是这里又进行了再次封装,比如接收中断UART_Receive_IT。


当然,这个UART_Receive_IT接收中断实现方式又可能存在不同。像F0、F1...就是直接调用这个接收中断函数来进一步处理。


像L0、G0...是通过执行指针函数RxISR来进一步处理。G0的接收中断处理为:huart->RxISR(huart);


void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)

{

  //删除了前面代码

  /* If no error occurs */

  errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE));

  if (errorflags == 0U)

  {

    /* UART in mode Receiver ---------------------------------------------------*/

    if (((isrflags & USART_ISR_RXNE_RXFNE) != 0U)

        && (((cr1its & USART_CR1_RXNEIE_RXFNEIE) != 0U)

            || ((cr3its & USART_CR3_RXFTIE) != 0U)))

    {

      if (huart->RxISR != NULL)

      {

        huart->RxISR(huart);

      }

      return;

    }

  }

  //删除了后面代码

}

看了上面USART中断处理的函数,大家有没有得到什么启发?


其实,HAL库里面处理机制基本一致,只是实现方式上有所不同。


如果你摸清楚了HAL库基本原理,相信阅读HAL库,或者使用HAL库编写应用代码不是问题。


回调函数实现原理

在HAL库中存在大量类似HAL_XXX_XXXCallback这样的函数,这些都是回调函数。


回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。


回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。


---来自百度百科


HAL库中断处理使用了较多的回调函数,还是拿UART接收中断来举例说明。


初始化配置好UART中断接收,如果有中断请求,就会执行回调函数HAL_UART_RxCpltCallback。


看上面回调函数的定义,通过特定条件调用『回调函数』,这里触发的条件就是中断。


扩展说明

这里也简单说几点:


1.初学者想直接使用HAL不是不行,需要有一定C语言功底


针对大部分初学者来说,是不建议直接上手HAL。但是,有部分C功底较好的,还是建议直接上手。


2.学HAL,建议参看官网例程


很多人不知道如何找资源,我不止一次强调,官方的才是最好。在HAL库中Projects目录下就有很多例程Examples。


3.我们追求效率,可以HAL库源码


如果你想修改HAL库源码,允许修改少部分。如果要大量修改,还是别折腾了。


4.实际项目需做一定修改


STM32CubeMX仅仅是生成初始化代码和工程,你实际项目中一般都有自己的软件架构。


特别是项目越大,软件架构就需要更加规范。


比如:生成的gpio.c文件名,你需要修改成bsp_gpio.c.


再比如:函数MX_USART2_UART_Init改成MX_DEBUG_UART_Init.

推荐阅读

史海拾趣

China Semiconductor Corp公司的发展小趣事

随着公司实力的不断增强,CSC开始将目光投向海外市场。公司积极实施国际化战略,在海外设立研发中心和生产基地,拓展国际市场。同时,CSC也加强了与国际同行的交流与合作,吸收借鉴国际先进经验和技术,不断提升自身的国际竞争力。通过国际化布局和全球视野的拓展,CSC逐渐成为了国际半导体产业的重要一员。

这五个故事只是CSC公司发展历程中的一部分缩影,但它们却充分展示了CSC在电子行业中的崛起之路。从初创时期的艰辛与突破,到技术创新的不断突破,再到市场拓展与品牌建设、产业链整合与协同发展以及国际化布局与全球视野的拓展,每一个阶段都凝聚了CSC人的智慧和汗水。正是这些努力和付出,使得CSC在激烈的国际竞争中脱颖而出,成为了中国半导体产业的佼佼者。

Burr-Brown公司的发展小趣事

进入20世纪70年代中期,Burr-Brown敏锐地意识到数字技术将对音频行业产生深远影响。公司迅速抓住CD播放机市场的机遇,通过技术创新,成功引领音频行业进入数字时代。这一转型不仅巩固了Burr-Brown在音频领域的领先地位,也为公司带来了更广阔的发展空间。

FIDELIX公司的发展小趣事

在东芯半导体的支持下,FIDELIX开始将其一部分技术团队迁移到国内,加速了存储芯片的国产替代进程。这些技术团队的加入,不仅提升了国内半导体产业的技术水平,也促进了FIDELIX与国内企业的深度融合和协同发展。

HTSEMI( Jin Yu Semiconductor )公司的发展小趣事

金宇半导体成立于2005年,由一群来自国内外顶尖高校的半导体专家共同创立。在成立初期,公司面临着资金短缺和技术瓶颈的双重挑战。创始人团队凭借在微处理器设计领域的深厚积累,成功研发出了一款低功耗、高性能的嵌入式处理器芯片,迅速获得了市场的关注。这款芯片不仅在国内智能手机市场占据了一席之地,还成功打入国际市场,为公司的后续发展奠定了坚实基础。

Chicago Miniature公司的发展小趣事

随着LED技术的兴起,CML敏锐地捕捉到了这一趋势,并成为第一家引进LED灯具的公司。这一决策为公司带来了巨大的发展机遇。CML不断投入研发资源,推出了一系列具有创新性的LED产品,不仅提高了照明效率,还降低了能耗。这使得CML在微型照明领域逐渐取得了领先地位,并赢得了广泛的客户基础。

Chemtronics公司的发展小趣事

自1958年成立以来,Chemtronics公司在电子维护和维修领域不断进取。最初,公司专注于生产一系列清洁剂产品,以其高效清洁能力获得了市场的认可。随着时间的推移,Chemtronics逐渐将产品线扩展至超纯溶剂、净化室级别擦拭棒和擦拭布等领域,进而又扩展到电子电气和电信工业的精密返工和维修工具。这一转变不仅体现了公司对市场需求的敏锐洞察,也彰显了其不断创新的精神。

问答坊 | AI 解惑

微型传感器在汽车工程中的应用

现代汽车正由一个单纯交通工具朝着能满足人类需求和安全、舒适、方便及无污染的方向发展。要实现这些目标的关键在于汽车的电子化和智能化,先决条件则是各种信息的及时获取,这势必要求在汽车中大量采用各种传感器。传统的传感器往往体积和重量大、 ...…

查看全部问答>

基于单片机的复杂可编程逻辑器件快速配置方法

摘要:介绍基于SRAM的可重配置CPLD的原理,通过对多种串行配置的比较,提出了由单片机和FLASH存储器组成的串行配置方式,并从系统复杂度、可靠性和经济性等方面进行了比较和分析。 关键词:复杂可编程逻辑器件 静态随机存储器 被动串行 基于SRAM ...…

查看全部问答>

OPA228

    幅值为1v,频率为1kHz的交流信号经过OPA228实现反向后变成直流了。。晕。线路没问题。问题就出在这个运放身上了,但是不知道它哪里出问题了。高手们帮忙。 图片如上。 高手们用简单的运放试试,可以出现正弦。 [ 本帖最后由 vote ...…

查看全部问答>

ADS 中常用的数据文件

刚开心学习使用ADS,与大家共享下这个资料~~…

查看全部问答>

关于中断向量表的傻问题,麻烦各位了

本人新手,见笑了! .extern main .text .global _start _start: @****************************************************************************** @ 中断向量,本程序中,除Reset和HandleIRQ外,其它异常都没有使用 @****************** ...…

查看全部问答>

如何学习电子方面

小弟是计算机的专科2年级学生,学校教的很少,现在想学习关于硬件方面。以后希望自己有能力设计电路。可是以前都没有接触过这方面,不知道从哪里开始学起,和学一些什么内容。 请那位大大指条明路 …

查看全部问答>

LED显示屏采购的常见误区

replyreload += \',\' + 693698;Timson,如果您要查看本帖隐藏内容请回复…

查看全部问答>

最新的RTT0.4.0 LM3S分支驱动LM3S8962 SD卡问题

更新了RTT 0.4.0,发现SD卡不能初始化了。检查了下sd_card.c这个文件,发现是SD卡片选引脚定义的问题,TI那块LM3S8962 SD卡片选应该定义成PG0。有很多人都在抱怨8962这个芯片只有一个SPI,同时带SD卡和OLED的确很麻烦,我目前的解决办法就是在SD卡 ...…

查看全部问答>

请教F2812的几个问题

小弟最近按照EEWORLDDEC f2812实验板的原理图自己刷了一块PCB 在调试中遇到了一点问题 1。片内flash在烧写时总是不成功,用EEWORLD提供的FLASH测试程序提示FLASH无法写入。小弟想请问在烧写片内FLASH要注意些什么,F2812的引脚定义要注意些什么 2 ...…

查看全部问答>

PCB板过孔电阻过大什么原因

碰到一个很棘手的问题,整版沉金仍出现一些过孔电阻过大,不知道是不是板厂没沉金而是沉的铜导致过孔氧化电阻过大。 现在2K板子看着慢慢的从良品走向不良品,请问有什么方法解决这个问题,是否是板厂沉金没沉好,还是其他问题导致过孔电阻大,求大 ...…

查看全部问答>