作者|更强大的黄微信公共帐户嵌入式列STM32Cube HAL已经使用了六到七年,但仍然有许多初学者不适应它。

今天,我将分享读者提出的有关中断处理的问题。

许多人知道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为例:void HAL_UART_IRQHandler(UART_HandleTypeDef * huart){uint32_t isrflags = READ_REG(huart-实例实例SR); uint32_t cr1its = READ_CR1its = READ_CR1its = READ_CR1its(huart-> Instance)-> uint32_t cr3its = READ_REG(huart-& Instance-& CR3); uint32_t errorflags = 0x00U; uint32_t dmarequest = 0x00U; / *如果未发生错误* / errorflags =(isrflags&(uint32_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE)); if(errorflags == RESET){/ * UART在Receiver模式下-------------------------------- ---- ------------- * / if((((isrflags& USART_SR_RXNE)!= RESET)& amp& amp;((cr1its& USART_CR1_RXNEIE)!= RESET )){UART_Receive_IT(huart); return;}} / *如果发生某些错误* / if(((errorflags!= RESET)& amp; amp;(((cr3its& amp; USART_CR3_EIE)!= RESET)||((cr1its& amp; ;((USART_CR1_RXNEIE | USART_CR1_PEIE))=重置))){/ *··一些代码被删除·* /} / *如果发生某些错误,则结束* / / * UART在发送器模式下--------- --- ------------------------------------ * / if(((isrf lags& amp ; USART_SR_TXE)!= RESET)& amp; amp;((cr1its& amp; USART_CR1_TXEIE)!= RESET)){UART_Transmit_IT(huart); return;} / * UART在模式下发射器端--------- ------------------------------- ---- * / if((((isrflags& USART_SR_TC)!= RESET)& amp; amp;(((cr1its& USART_CR1_TCIE)!= RESET)){UART_EndTransmit_IT(huart);返回; }}实际上,如果仔细看一下代码,您应该能够理解这些代码是否类似于我们编写的Place的中断处理函数?这无非是一系列处理,例如接收中断,发送中断和错误中断。

只是它再次被封装在这里,例如接收中断UART_Receive_IT。

当然,UART_Receive_IT接收中断的实现方法可能有所不同。

与F0一样,F1 ...将直接调用接收中断函数以进行进一步处理。

像L0一样,通过执行指针函数RxISR进一步处理G0...。

G0&#39的接收中断处理是:huart-> RxISR(huart); void HAL_UART_IRQHandler(UART_HandleTypeDef * huart){//删除前一个代码/ *如果没有发生错误* / errorflags =(isrflags&(uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE)); if(错误标志== 0U){/ * UART在接收器模式下---------------------------- -------- --------------- * / if((((isrflags& USART_ISR_RXNE_RXFNE)!= 0U)& amp; amp;((((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,这些都是回调函数。

回调函数是通过函数指针调用的函数。

如果将函数指针(地址)作为参数传递