前言
上一篇文章 详细介绍了 USART 串口 不使用中断 发送接收数据 ,这篇文章 将介绍如何 使用中断控制 USART 串口 发送接收数据。
对于如何根据 CubeMX 生成 USART 的工程,可以参考我的上篇文章,也介绍了 关于生成 usart.c 代码的解析 : STM32Cube串口USART发送接收数据
一、中断控制
中断: 是一种特殊的处理程序,能够 临时中断 正在运行的程序,以 处理紧急 的事件,然后 恢复 正在运行的程序。当 外部事件发生 时,中断程序 会被 调用,以 处理这些事件。
USART 收发数据时,可以 在数据接收之后立即触发中断,以此提高数据传输效率。
中断优先级 :
抢占优先级 :抢占优先级可以实现中断嵌套,抢占 优先级级数低的可抢占级数高的。
子优先级 :子优先级无法实现中断嵌套,同一时刻 两个子 优先级不同 的 中断 来临,则 先处理优先级高的 即优先级级数低的中断。若 先后发生 则先处理 上一个中断,再 处理后面的中断。
一旦确定了优先级组别,抢占优先级和子优先级的范围就确定下来了且除非复位否则无法更改。
二、USART中断使用
1. 中断优先级设置 :
①使用 CubeMX 设置优先级。
②也可以使用 HAL_NVIC_SetPriority() 设置优先级:
HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority) 1
比如将 USART1 的中断设置为次高级优先级: HAL_NVIC_SetPriority(USART1_IRQn, 0, 1);
2. 使能中断
①使用 CubeMX 使能中断:
②使用 HAL_NVIC_EnableIRQ() 使能中断。
HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
1
3. 使能UART的发送、接收中断
__HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__)
1
例如:设置 USART1 为 传输完成中断,接收数据寄存器不为空中断。
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE | UART_IT_RXNE);
1
4. 中断收发函数
//中断发送 HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); //中断接收 HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
5. 中断处理函数
在中断回调函数 USART1_IRQHandler ( ) 中进行中断处理,可以调用 HAL_UART_IRQHandler ( )。
/*中断处理函数*/ void USART1_IRQHandler(void) { HAL_UART_IRQHandler(&huart1); }
6. 中断收发回调函数
重定向 HAL_UART_RxCpltCallback( ) 或 HAL_UART_TxCpltCallback( ) 函数进行进一步任务处理。
/* 中断接收回调函数 */ __weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) /* 中断发送回调函数 */ __weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
三、串口中断实验
串口中断发送数据点亮 led:
对 LED 代码不理解的可以参考我之前的文章,详细介绍了 LED:STM32f103 CubeMX封装 led程序
void Enable(void) /*使能*/ { HAL_NVIC_SetPriority(USART1_IRQn, 0, 1); //中断优先级设置 HAL_NVIC_EnableIRQ(USART1_IRQn); //使能中断 __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE | UART_IT_RXNE); } void Disable(void) /*失能*/ { __HAL_UART_DISABLE_IT(&huart1, UART_IT_RXNE | UART_IT_RXNE); HAL_NVIC_DisableIRQ(USART1_IRQn); } void USART1_IRQHandler(void) /*中断处理函数*/ { HAL_UART_IRQHandler(&huart1); } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) //中断接收 { if(huart->Instance == USART1) { re_data = 1; } } void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) //中断发送 { if(huart->Instance == USART1) { tr_data = 1; } }
这里我就不介绍 printf 的重定向问题了,我之前的文章 已详细介绍了 printf 的内容:STM32Cube串口USART发送接收数据
a = getchar(); //获得一个字符 switch(a) { case 'B': { GREEN_ON(); //点亮LED printf("Led is on!\r\n"); } break; case 'b': { GREEN_OFF(); //熄灭LED printf("Led is off!\r\n"); } break; default: break; }
实验现象:
实验现象 我放在了 B占,有兴趣的可以看看:
STM32 串口USART 发送数据控制led亮灭
总结
如果有不理解的可以 评论留言 也可以 私信我 ,大家一起讨论。