- 金属膜电阻
- 新闻中心
- HAL库中断处理和相关的回调函数
HAL库中断处理和相关的回调函数
STM32CubeHAL已经使用了六到七年,但仍然有许多初学者不适应它。今天,我将分享读者提出的有关中断处理的问题。
许多人知道STM32CubeMX工具的一个目的:减少STM32低级驱动程序的开发人员开发时间,并专注于应用程序代码。但是,STM32CubeMX仅为基础驱动程序生成初始化代码。
因此,我们还需要掌握:应用程序层代码如何调用HAL库函数(API接口),以及有关HAL库中断处理机制的相关知识。 HAL库涉及很多内容。
下面简要介绍HAL库和相关回调函数的中断处理。当使用标准外设库开发HAL库中断处理机制时,中断程序(功能)由我们自己实现。
HAL库的中断处理功能是根据HAL处理机制(例如USART1)实现的,该机制由HAL_UART_IRQHandler统一进行处理,如下图所示:其他大多数外围设备(TIM,SPI,CAN ... )中断类似,并且HAL是统一处理的。换句话说,HAL已经为我们编写了中断处理函数,我们只需要调用相应的函数来编写应用程序即可。
在HAL_xxx_IRQHandler中完成什么处理?让我们以STM32F1的HAL_UART_IRQHandler为例:voidHAL_UART_IRQHandler(UART_HandleTypeDef * huart){uint32_tisrflags = READ_REG(huart-> Instance-> Instance-> SR); uint32_tcr1its = READ_REG(huart-> CR-Instance- ->实例-> CRREG(huart->实例-cr3huart)> CR3); uint32_terrorflags = 0x00U; uint32_tdmarequest = 0x00U; / *如果出现错误* / errorflags =(isrflags&(uint32_t)(USART_SR_PE | USART_SR_NE)); UART = RESET = RESET ----------------------------------------- ---- * / if((((isrflags& USART_SR_RXNE)!= RESET)&&(((cr1its& USART_CR1_RXNEIE)!= RESET)){UART_Receive_IT(huart); return;))/ *如果发生某些错误* / if( (errorflags!= RESET)&&(((cr3its& USART_CR3_E)||((cr1its&(USART_CR1_RXNEIE | USART_CR1_PEIE)!= RESET)!))){/ *··部分代码已删除·* /} / *发生Endifsome错误* // * UARTinmodeTransmitter ----------- -------------------------------- ----- * / if((((isrflags& USART_SR_TXE)!= RESET)&&(((cr1its& USART_CR1_TXEIE)!= RESET)){UART_Transm it_IT(huart); return;} / * UARTinmodeTransmitterend ----------------------------- ---------- ----- * / if((((i srflags& USART_SR_TC)!= RESET)&&((cr1its& USART_CR1_TCIE)!= RESET)){UART_EndTransmit_IT(huart); return;}}实际上,如果您仔细查看代码,您应该能够理解这些代码是否类似于我们编写的中断处理程序。地方?这无非是一系列处理,例如接收中断,发送中断和错误中断。
只是它再次被封装在这里,例如接收中断UART_Receive_IT。当然,UART_Receive_IT接收中断的实现方法可能有所不同。
与F0一样,F1 ...将直接调用接收中断函数以进行进一步处理。像L0一样,通过执行指针函数RxISR进一步处理G0...。
G0接收中断处理为:huart-> RxISR(huart); voidHAL_UART_IRQHandler(UART_HandleTypeDef * huart){//删除先前的代码/ * Ifnoerroroccurs * / errorflags =(isrflags&(uint32_t)(USART_ISR_PE | ART_IS_R) ; if(errorflags == 0U){/ * UARTinmodeReceiver -------------------------------------- ------------- * / 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库中编写应用程序代码不是问题2回调函数的实现原理HAL库中的HAL_XXX_XXXCallback之类的函数,这些都是回调函数。
回调函数是通过函数指针调用的函数。如果将函数指针(地址)作为参数传递给另一个函数,则当此指针用于调用它所指向的函数时,我们说这是一个回调函数。
回调函数不是由函数的实现者直接调用的,而是在发生特定事件或条件时由另一方调用的,并用于响应事件或条件。 ---来自百度百科的HAL库中断处理使用更多的回调函数。
让我们以UART接收。
许多人知道STM32CubeMX工具的一个目的:减少STM32低级驱动程序的开发人员开发时间,并专注于应用程序代码。但是,STM32CubeMX仅为基础驱动程序生成初始化代码。
因此,我们还需要掌握:应用程序层代码如何调用HAL库函数(API接口),以及有关HAL库中断处理机制的相关知识。 HAL库涉及很多内容。
下面简要介绍HAL库和相关回调函数的中断处理。当使用标准外设库开发HAL库中断处理机制时,中断程序(功能)由我们自己实现。
HAL库的中断处理功能是根据HAL处理机制(例如USART1)实现的,该机制由HAL_UART_IRQHandler统一进行处理,如下图所示:其他大多数外围设备(TIM,SPI,CAN ... )中断类似,并且HAL是统一处理的。换句话说,HAL已经为我们编写了中断处理函数,我们只需要调用相应的函数来编写应用程序即可。
在HAL_xxx_IRQHandler中完成什么处理?让我们以STM32F1的HAL_UART_IRQHandler为例:voidHAL_UART_IRQHandler(UART_HandleTypeDef * huart){uint32_tisrflags = READ_REG(huart-> Instance-> Instance-> SR); uint32_tcr1its = READ_REG(huart-> CR-Instance- ->实例-> CRREG(huart->实例-cr3huart)> CR3); uint32_terrorflags = 0x00U; uint32_tdmarequest = 0x00U; / *如果出现错误* / errorflags =(isrflags&(uint32_t)(USART_SR_PE | USART_SR_NE)); UART = RESET = RESET ----------------------------------------- ---- * / if((((isrflags& USART_SR_RXNE)!= RESET)&&(((cr1its& USART_CR1_RXNEIE)!= RESET)){UART_Receive_IT(huart); return;))/ *如果发生某些错误* / if( (errorflags!= RESET)&&(((cr3its& USART_CR3_E)||((cr1its&(USART_CR1_RXNEIE | USART_CR1_PEIE)!= RESET)!))){/ *··部分代码已删除·* /} / *发生Endifsome错误* // * UARTinmodeTransmitter ----------- -------------------------------- ----- * / if((((isrflags& USART_SR_TXE)!= RESET)&&(((cr1its& USART_CR1_TXEIE)!= RESET)){UART_Transm it_IT(huart); return;} / * UARTinmodeTransmitterend ----------------------------- ---------- ----- * / if((((i srflags& USART_SR_TC)!= RESET)&&((cr1its& USART_CR1_TCIE)!= RESET)){UART_EndTransmit_IT(huart); return;}}实际上,如果您仔细查看代码,您应该能够理解这些代码是否类似于我们编写的中断处理程序。地方?这无非是一系列处理,例如接收中断,发送中断和错误中断。
只是它再次被封装在这里,例如接收中断UART_Receive_IT。当然,UART_Receive_IT接收中断的实现方法可能有所不同。
与F0一样,F1 ...将直接调用接收中断函数以进行进一步处理。像L0一样,通过执行指针函数RxISR进一步处理G0...。
G0接收中断处理为:huart-> RxISR(huart); voidHAL_UART_IRQHandler(UART_HandleTypeDef * huart){//删除先前的代码/ * Ifnoerroroccurs * / errorflags =(isrflags&(uint32_t)(USART_ISR_PE | ART_IS_R) ; if(errorflags == 0U){/ * UARTinmodeReceiver -------------------------------------- ------------- * / 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库中编写应用程序代码不是问题2回调函数的实现原理HAL库中的HAL_XXX_XXXCallback之类的函数,这些都是回调函数。
回调函数是通过函数指针调用的函数。如果将函数指针(地址)作为参数传递给另一个函数,则当此指针用于调用它所指向的函数时,我们说这是一个回调函数。
回调函数不是由函数的实现者直接调用的,而是在发生特定事件或条件时由另一方调用的,并用于响应事件或条件。 ---来自百度百科的HAL库中断处理使用更多的回调函数。
让我们以UART接收。