1、引言
单片机串口、按键等等这种外部输入的, 用轮询的方式非常浪费资源,所以最好的方法就是使用中断接收数据。
2、串口
对于串口中断, 使用的非常频繁。
1. 基本原理
串口中断接收通过以下方式工作:
-
当串口接收到一个字节数据时,触发RXNE(接收缓冲区非空)中断。
-
在中断服务函数中读取数据,并重新使能中断以等待下一次接收。
2. 配置步骤(以HAL库为例)
(1) CubeMX配置
-
启用USART/UART外设,配置波特率、数据位、停止位、校验位等。
-
在NVIC Settings中使能串口接收中断(USARTx_IRQn)。
-
生成代码。
(2) 代码初始化
// 初始化UART(CubeMX自动生成)
MX_USART1_UART_Init();
// 启动接收中断(需手动添加)
HAL_UART_Receive_IT(&huart1, &rx_buffer, 1); // 每次接收1字节
(3) 中断服务函数
HAL库自动处理中断,用户只需实现回调函数:
// 接收完成回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART1) {
// 处理接收到的数据(rx_buffer)
process_data(rx_buffer);
// 重新启动接收中断
HAL_UART_Receive_IT(huart, &rx_buffer, 1);
}
}
3. 接收不定长数据(IDLE中断)
对于不定长数据帧,结合IDLE(空闲线路)中断:
// 在初始化后启用IDLE中断
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
// 中断服务函数中处理IDLE事件
void USART1_IRQHandler(void) {
HAL_UART_IRQHandler(&huart1);
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)) {
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
// 处理接收到的数据
process_rx_data();
}
}
4. 关键函数和技巧
-
HAL_UART_Receive_IT(): 启动中断接收。
-
HAL_UART_IRQHandler(): HAL库的中断统一处理函数。
-
错误处理: 检查
huart->ErrorCode
,如HAL_UART_ERROR_ORE
(溢出错误)。
5. 示例代码(完整流程)
uint8_t rx_buffer;
uint8_t rx_data[256];
uint16_t rx_index = 0;
int main(void) {
HAL_Init();
MX_USART1_UART_Init();
HAL_UART_Receive_IT(&huart1, &rx_buffer, 1); // 启动中断接收
while (1) {
// 主循环处理其他任务
}
}
// 接收完成回调
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART1) {
rx_data[rx_index++] = rx_buffer;
if (rx_index >= 256) rx_index = 0; // 防止溢出
HAL_UART_Receive_IT(huart, &rx_buffer, 1); // 重新使能中断
}
}