STM32CubeMX串口USART中断发送接收数据

举报
糖果罐子 发表于 2023/10/31 20:37:31 2023/10/31
【摘要】 > 本文代码使用 `HAL `库。@[TOC](文章目录)# 前言上一篇文章 详细介绍了 ***USART*** 串口 **不使用中断** 发送接收数据 ,这篇文章 将介绍如何 **使用中断控制** ***USART*** 串口 发送接收数据。对于如何根据 CubeMX 生成 USART 的工程,可以参考我的上篇文章,也介绍了 关于生成 *usart.c* 代码的解析 :  [STM32Cu...

> 本文代码使用 `HAL `库。

@[TOC](文章目录)



# 前言

上一篇文章 详细介绍了 ***USART*** 串口 **不使用中断** 发送接收数据 ,这篇文章 将介绍如何 **使用中断控制** ***USART*** 串口 发送接收数据。

对于如何根据 CubeMX 生成 USART 的工程,可以参考我的上篇文章,也介绍了 关于生成 *usart.c* 代码的解析 :  [STM32Cube串口USART发送接收数据](https://blog.csdn.net/wuyiyu_/article/details/129219018)

---
# 一、中断控制 
![在这里插入图片描述](https://img-blog.csdnimg.cn/6dde8bd5588442c286048c07c8475619.png)

1. **中断**: 是一种特殊的处理程序,能够 临时中断 正在运行的程序,以 处理紧急 的事件,然后 恢复 正在运行的程序。当 外部事件发生 时,中断程序 会被 调用,以 处理这些事件。

***USART*** 收发数据时,可以 ==在数据接收之后立即触发中断==,以此提高数据传输效率。

2. **中断优先级** :

- 抢占优先级 :抢占优先级可以实现中断嵌套,抢占 ==优先级级数低的可抢占级数高的==。

- 子优先级 :子优先级无法实现中断嵌套,同一时刻 两个子 优先级不同 的 中断 来临,则 ==先处理优先级高的== 即优先级级数低的中断。若 先后发生 则先处理 上一个中断,再 处理后面的中断。

`一旦确定了优先级组别,抢占优先级和子优先级的范围就确定下来了且除非复位否则无法更改`。


# 二、USART中断使用

### 1. 中断优先级设置 :
①使用 CubeMX 设置优先级。
![在这里插入图片描述](https://img-blog.csdnimg.cn/e116645ce8c449a9bb2c6dec47111bdc.png)

②也可以使用 ***HAL_NVIC_SetPriority()***  设置优先级:

```c
HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
```

>比如将 ***USART1*** 的中断设置为次高级优先级: ***HAL_NVIC_SetPriority(USART1_IRQn, 0, 1);***
     
### 2. 使能中断
①使用 CubeMX 使能中断:
![在这里插入图片描述](https://img-blog.csdnimg.cn/7e7640ca11254a65a3bc714c88394355.png)
②使用 ***HAL_NVIC_EnableIRQ()*** 使能中断。

```c
HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
```
### 3. 使能UART的发送、接收中断

```c
__HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__)
```
例如:设置 USART1 为 传输完成中断,接收数据寄存器不为空中断。
![在这里插入图片描述](https://img-blog.csdnimg.cn/651f0d6cf1a54b0696de5df97564cd80.png)
```c
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE | UART_IT_RXNE);
```

### 4. 中断收发函数
```c
//中断发送
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 ( )***。

```c
/*中断处理函数*/
void USART1_IRQHandler(void)
{
HAL_UART_IRQHandler(&huart1);
}
```
### 6. 中断收发回调函数
重定向 ***HAL_UART_RxCpltCallback( )*** 或 ***HAL_UART_TxCpltCallback( )*** 函数进行进一步任务处理。

```c
/* 中断接收回调函数 */
__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

/* 中断发送回调函数 */
__weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
```


# 三、串口中断实验
### 串口中断发送数据点亮 led:
对 LED 代码不理解的可以参考我之前的文章,详细介绍了 LED:[STM32f103 CubeMX封装 led程序](https://blog.csdn.net/wuyiyu_/article/details/129108738)
```c
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发送接收数据](https://blog.csdn.net/wuyiyu_/article/details/129219018)
```c
  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亮灭](https://www.bilibili.com/video/BV1vY4y127c4/?vd_source=986c364d205fa1124b337bc665f57c4f)

---

# 总结
如果有不理解的可以 评论留言 也可以 私信我  ,大家一起讨论。
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。