STM32Cube HAL库中断处理机制,以及回调函数实现原理

发布者:和谐共处最新更新时间:2019-09-29 来源: eefocus关键字:STM32Cube  HAL库  中断处理机制  回调函数 手机看文章 扫描二维码
随时随地手机看文章

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.

关键字:STM32Cube  HAL库  中断处理机制  回调函数 引用地址:STM32Cube HAL库中断处理机制,以及回调函数实现原理

上一篇:再造STM32---第一部分:如何正规的安装KEIL5?
下一篇:stm32库函数学习篇----通用定时器(PWM功能)

推荐阅读最新更新时间:2024-11-06 20:17

【STM32Cube_07】使用USART发送和接收数据(中断模式)
1. 准备工作 硬件准备 首先需要准备一个开发板,这里我准备的是STM32L4的开发板(BearPi): 软件准备 需要安装好Keil - MDK及芯片对应的包,以便编译和下载生成的代码; 准备一个串口调试助手,这里我使用的是Serial Port Utility; Keil MDK和串口助手Serial Port Utility 的安装包都可以在文末关注公众号获取,回复关键字获取相应的安装包: 2.生成MDK工程 — 初始化GPIO为输入 选择芯片型号 打开STM32CubeMX,打开MCU选择器: 搜索并选中芯片STM32L431RCT6: 配置时钟源 如果选择使用外部高速时钟(HSE),则需要在
[单片机]
【STM32Cube_07】使用USART发送和接收数据(中断模式)
STm32 使用 stm32cube GPIO 点亮 led 的
一、API说明 HAL库一共包含如下6个IO操作函数: 1、读取某个引脚的电平状态: HAL_GPIO_ReadPin() 2、写入某个引脚的电平状态: HAL_GPIO_WritePin() 3、翻转某个引脚的电平状态: HAL_GPIO_TogglePin() 4、锁定某个引脚的配置状态(直到下次复位): HAL_GPIO_LockPin() 5、外部中断服务函数: HAL_GPIO_EXTI_IRQHandler() 6、外部中断回调函数: HAL_GPIO_EXTI_Callback() 具体使用方法参见 STM32F4xx HAL驱动说明书 。 二、GPIO使用示例 示例功能:使用按键(PC13)翻转LED(PA5)
[单片机]
STm32 使用 <font color='red'>stm32cube</font> GPIO 点亮 led 的
STM32 HAL库 串口DMA发送完成中断
近期使用STM32驱动MAX3485进行485通信,发现STM32F103C8并不自带硬件485首发功能,需要软件上控制IO高低来驱动MAX3485进行485接收、485发送。 根据MAX3485手册可得,进行485发送时给相应引脚高电平。其余时间为低电平进行485接收。因此需要找到串口DMA发送完成的回调函数,在发送完成后将引脚拉低。 在stm32f1xx_hal_uart.c中 /** @defgroup UART_Exported_Functions_Group2 IO operation functions * @brief UART Transmit and Receive functions * @verb
[单片机]
STM32CUBE相关技术手册哪里找
凡接触过STM32的人,估计对STM32CUBE神器多少都会有些了解。 STM32CUBE包含两部分,一部分是指图形化配置工具软件STM32CubeMX,它可以让STM32开发者通过图形化界面进行有关管脚、时钟等基本配置并最终生成初始化C语言代码。整个操作非常简单,往往只需动动鼠标或个别数据填写即可完成。 另外一部分就是指基于STM32各系列的固件库套件,或者说是一个软件平台。每个系列的固件库套件由STM32CUBE HAL 和Middleware 组成。所谓硬件抽象层可以理解为兼容整个STM32系列的驱动代码,不受各系列间差异的影响。那些中间件主要指RTOS、USB、TCP/IP、GUI等接口或协议驱动。
[单片机]
<font color='red'>STM32CUBE</font>相关技术手册哪里找
HAL库教程10:定时器的PWM模式应用
  本节通过定时器的PWM模式驱动无源蜂鸣器,来演奏一段音乐。本博客在掌机的系列教程中介绍过蜂鸣器的驱动原理,感兴趣的可以参考电子琴 无源蜂鸣器驱动电路   蜂鸣器按照有无震荡源(不是电源),可以分为有源蜂鸣器和无源蜂鸣器。有源蜂鸣器上电就能工作,控制简单,但是只有一个音调。无源蜂鸣器需要单片机提供震荡源,虽然控制稍微复杂一点,但是可以发出不同频率的声音。 PWM原理   根据我们的电路,引脚输出高电平时,驱动电路为蜂鸣器提供了闭合回路,则引脚给高电平,蜂鸣器就能响。然而,只给高电平,无源蜂鸣器不能持续发出声音,只有一瞬间有声音;需要马上给低电平,然后再给一个高电平。即在一个很短的周期内,无源蜂鸣器在高电平持续期间工作,
[单片机]
<font color='red'>HAL库</font>教程10:定时器的PWM模式应用
【STM32】HAL库-ADC
12位ADC是一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。 模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。 ADC的输入时钟不得超过14MHz ADC开关控制 通过设置ADC_CR2寄存器的ADON位可给ADC上电。当第一次设置ADON位时,它将ADC从断电状态下唤醒。 ADC上电延迟一段时间后(tSTAB),再次设置ADON位时开始进行转换。 tSTAB可查询数据手册 一般来说是1us 通过清除ADON位可以停止转换,并将ADC置
[单片机]
【STM32】<font color='red'>HAL库</font>-ADC
用STM32Cube.AI部署ONNX模型实操示例:风扇堵塞检测
在之前的文章中,我们介绍了没有AI基础知识的工程师如何使用NanoEdge AI快速训练一个用于风扇异常检测的模型 该模型根据来自电机控制板的电流信号,检测风扇过滤单元的堵塞百分比。我们知道,当风扇发生堵塞时,电机的电流信号形状会与正常时不同,而传统算法很难有效地处理这种差异。因此,机器学习算法成为解决该问题的明智选择。对于机器学习算法,我们通常使用scikit-learn库来训练模型。今天我们将展示如何自行训练机器学习模型,然后使用STM32Cube.AI 将其部署到同一设备上,以便让大家充分了解两种工具的不同之处。 NanoEdgeAI是一款端到端工具,允许对数据进行一些预处理,并进行训练和算法选择,而STM32Cub
[单片机]
用STM32Cube.AI部署ONNX模型实操示例:风扇堵塞检测
使用STM32F1xx_HAL库实现CAN通信的问题
硬件平台:处理器为STM32F103R8,板子为自设计电路板,数码管显示+CAN通信。 软件开发平台:Keil V5 操作系统:FreeRTOS 问题描述: 使用HAL硬件库实现CAN通信时,CAN中断无法进入,不能够使用中断方式进行数据的接收。CAN的发送是没有问题,寄存器也接收到了响应的数据,就是中断没有被触发。研究了一天没有搞定,现把问题放下,先改用轮训读取的方式实现。 主要的代码如下: 1、接收中断 /** * @brief This function handles CAN1 RX0 interrupt request. * @param None * @retval None */ void
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved