【中断回调函数】

stm32hal库入门@[toc]

概要

通过中断回调函数实现与中断交互

整体架构流程

交互函数:
usart_test_.c

#include "usart_test.h"
#include "stm32f1xx_hal_gpio.h"

uint8_t  USART1_RX_BUF[USART1_REC_LEN]; 	//接受缓冲,最大USART_REC_LEN个字节
uint16_t USART1_RX_STA=0;								  //接受状态标记、、bit15:接收完成标志,bit14:接收到0x0d,bit13~0:接受到的有效字节数目
uint8_t  USART1_NewData;									//当前串口中断接受的1个字节数据缓存


void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)		//串口中断回调函数
{
	if(huart == &huart1)
	{
		printf("%c",USART1_NewData);			//把收到的数据以a符号变量发送给电脑
		if((USART1_RX_STA&0x8000)==0)					//接受未完成
		{
			if(USART1_RX_STA&0x4000)				//接受到了0x0d
			{
				if(USART1_NewData!=0x0a)USART1_RX_STA=0;	//接受错误重新开始
				else USART1_RX_STA |=0x8000;							//接受完成了
			}
			else
			{
				if(USART1_NewData==0x0d)USART1_RX_STA|=0x4000;
				else
				{
					USART1_RX_BUF[USART1_RX_STA&0X3FFF]=USART1_NewData;		//将收到的数据放回数组
					USART1_RX_STA++;	//数据长度计数加1
					if(USART1_RX_STA>(USART1_REC_LEN - 1))USART1_RX_STA=0;	//接收数据错误,重新开始接受
				}
			}			
		}
			HAL_UART_Receive_IT(&huart1,(uint8_t *)&USART1_NewData,1);	//再开启接受中断
	}

}


usart_test_.h

#ifndef __USART_TEST_H
#define __USART_TEST_H


#include "stm32f1xx_hal.h"
#include "main.h"
#include "usart.h"
#include "stm32f1xx_hal_gpio.h"
#include "stm32f1xx_hal_uart.h"

#define USART_n   USART1		//定义使用printf函数的串口
#define USART1_REC_LEN 200	//定义USART1最大接受字节数
#define USART2_REC_LEN 200
#define USART3_REC_LEN 200
//不使用某个串口时要禁止此串口,以减少编译量
#define EN_USART1     1
#define EN_USART2     0
#define EN_USART3     0

extern uint8_t USART1_RX_BUF[USART1_REC_LEN];	//接收缓冲

extern uint16_t USART1_RX_STA;		//接收状态标记位

extern uint8_t  USART1_NewData;
//函数声明
//void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);

#endif

主函数:

```c
while (1)
  {
    /* USER CODE END WHILE */
			if(USART1_RX_STA&0x0001)	//串口1判断中断接收标志位
			{
				if(USART1_RX_BUF[0]=='1')
				{
					HAL_GPIO_WritePin(LED_B_GPIO_Port, LED_B_Pin, GPIO_PIN_SET);
					BUZZER_SOLO1();
				}
				if(USART1_RX_BUF[0]=='0')
				{
					HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_SET);
					BUZZER_SOLO1();
				}
				USART1_RX_STA=0;	//串口接收标志位清0,即开启下一轮接收
			}
    /* USER CODE BEGIN 3 */
//		if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_SET) 
//			{ 
//        HAL_Delay(10);
//				HAL_GPIO_WritePin(LED_B_GPIO_Port, LED_B_Pin, GPIO_PIN_SET);
//        BUZZER_SOLO1();
////				HAL_UART_Transmit(&huart1,(uint8_t*)&"KEY1\r\n",6,0xffff);		//串口发送:串口号1,内容“ABC”,数量3,溢出时间0xffff
//				printf("KEY1\r\n");
//       }
  }
  /* USER CODE END 3 */
}

`
#
## 小结
根据杨桃hal库例程编写

### 中断回调函数的实现方式及示例代码 中断回调函数是一种在特定事件或中断触发时执行用户定义逻辑的机制。以下将详细介绍中断回调函数的实现方式,并提供相关示例代码。 #### 1. 回调函数的基本概念 回调函数是一种被作为参数传递给另一个函数的函数,在接收函数中会在特定条件达成或者特定事件发生时调用这个被传入的函数[^2]。这种机制允许开发者在不修改库函数代码的前提下,自定义中断或事件发生时的处理逻辑。 #### 2. 中断回调函数的实现步骤 以下是实现中断回调函数的一般步骤: - 定义一个函数指针类型。 - 声明一个全局变量用于存储回调函数指针。 - 提供一个注册函数,允许用户将自定义的回调函数赋值给该全局变量。 - 在中断服务程序中检查回调函数指针是否已被赋值,如果已赋值则调用它。 #### 3. 示例代码:基于STM32的UART中断回调函数 以下是一个基于STM32 HAL库的UART中断回调函数实现示例: ```c // 1. 定义回调函数类型 typedef void (*CallbackFunc_t)(void); // 2. 声明全局回调函数指针 static CallbackFunc_t UART1_RxCpltCallback = NULL; // 3. 注册回调函数的函数 void Register_UART1_RxCpltCallback(CallbackFunc_t callback_func) { UART1_RxCpltCallback = callback_func; } // 4. 中断服务函数(由HAL库生成) void USART1_IRQHandler(void) { HAL_UART_IRQHandler(&huart1); // 调用HAL库的中断处理函数 } // 5. HAL库内部处理中断后,调用回调函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { if (UART1_RxCpltCallback != NULL) { // 检查回调函数是否已注册 UART1_RxCpltCallback(); // 调用回调函数 } } } // 6. 用户定义的回调函数逻辑 void My_UART1_RxCpltCallback(void) { // 用户实现的具体业务逻辑 processData(rxBuffer); } ``` #### 4. 示例代码:QNX中的GPIO中断回调函数 以下是一个基于QNX系统的GPIO中断回调函数实现示例: ```c // 1. 定义回调函数类型 typedef void (*IRQCallbackFunc_t)(int); // 2. 注册中断回调函数 int register_gpio_irq_callback(int gpio, IRQCallbackFunc_t callback_func) { struct _qnx_irq_ctx *ctx = malloc(sizeof(struct _qnx_irq_ctx)); ctx->callback = callback_func; return InterruptAttachEvent(gpio, ctx, 0); } // 3. 用户定义的回调函数逻辑 void My_GPIO_IRQ_Callback(int gpio) { // 用户实现的具体业务逻辑 handle_gpio_interrupt(gpio); } // 4. 注册回调函数 register_gpio_irq_callback(GPIO_PIN_15, My_GPIO_IRQ_Callback); ``` #### 5. 总结 通过上述示例可以看出,中断回调函数的核心思想是将用户定义的函数作为参数传递给中断处理系统,并在中断触发时调用这些函数。这种方式极大地提高了代码的灵活性和可扩展性[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值