STM32串口通信入门
STM32串口通信入门
实验任务
- 使用HAL库方式,配合Keil,设置USART1 波特率为115200,1位停止位,无校验位,完成下列任务:
- STM32系统给上位机(win10)连续发送“hello windows!”。win10采用“串口助手”工具接收。
- 在完成以上任务基础,继续扩展功能:当上位机给stm32发送一个字符“#”后,stm32暂停发送“hello windows!”;发送一个字符“*”后,stm32继续发送;
- 使用Keil的软件仿真逻辑分析仪功能观察串口输出波形,并分析时序状态正确与否,计算波特率实际为多少。
实验过程
STM32CubeMX实现串口通信
-
配置STM32CubeMX
-
设置串口。这里选择USART1。串口配置的引脚为PA9、PA10。并设置MODE为 异步通信(Asynchronous),以及参数设置:波特率为115200 Bits/s,传输数据长度为8Bit,奇偶检验无,停止位1。
-
点击GENERATE CODE,生成Keil项目并打开,编译无误。
-
-
UART函数库介绍
UART结构体以及函数定义均在头文件:
stm32f1xx_hal_uart.h
-
UART结构体定义:
UART_HandleTypeDef huart1;
-
串口发送函数:
HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); /* 功能:功能:串口发送指定长度的数据。如果超时没发送完成,则不再发送,返回超时标志(HAL_TIMEOUT)。 参数: *UART_HandleTypeDef huart:UART结构体( huart1) *pData:需要发送的数据 Size:发送的字节数 Timeout:最大发送时间,发送数据超过该时间退出发送 */
-
-
代码编写
在main.c文件的while循环中添加如下代码:
while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ //添加下面两行代码 HAL_UART_Transmit(&huart1, (uint8_t *)"hello windows!\r\n", 16 , 0xffff); HAL_Delay(1000); //延时1s }
-
接线
将面包板、STM32最小系统板、ST-Link以及USB转串口模块按照如下方式接线:
-
运行效果
将代码编译、烧录后,打开串口助手,选择端口号以后,打开串口,查看接收到的数据(注意波特率、停止位、数据位、校验位要与配置的一致)。
STM32CubeMX实现串口中断通信
下面介绍使用中断来实现上位机控制核心板的数据发送。具体目标:当上位机给stm32发送一个字符“#”后,核心板暂停发送“hello windows!”;发送一个字符“*****”后,核心板继续发送。
-
配置STM32CubeMX
该任务只是在前面串口通信的基础上,多了个开启串口中断使能。
-
中断函数介绍
串口中断函数:
HAL_UART_IRQHandler(UART_HandleTypeDef *huart); //串口中断处理函数 HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); //串口发送中断回调函数 HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart); //串口发送一半中断回调函数 HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); //串口接收中断回调函数 HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);//串口接收一半回调函数 HAL_UART_ErrorCallback(); // 串口接收错误函数
-
代码编写
-
在main.c文件的main函数外部定义如下变量:
#define LENGTH 1 //接收缓冲区大小 uint8_t RxBuffer[LENGTH]; //接收缓冲区 uint8_t RxFlag = 0; //接收完成标志;0表示接受未完成,1表示接收完成
-
在main函数外部定义中断回调函数:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance == USART1 && *RxBuffer == '#') // 发生接收中断的串口为USART1且接收到的字符为'#' { RxFlag = 1; // 停止发送 } else if (huart->Instance == USART1 && *RxBuffer == '*') // 接收到的字符为'*' { RxFlag = 0; // 继续发送 } }
-
在while循环内添加代码:
while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_UART_Receive_IT(&huart1, (uint8_t *)RxBuffer,LENGTH); //使能接收中断 if(RxFlag == 0) // 如果是0,才发送 { HAL_UART_Transmit(&huart1, (uint8_t *)"hello windows!\r\n", 16 , 0xffff); HAL_Delay(1000); //延时1s } }
-
-
实际效果
如图,程序一开始,核心板每隔1秒给上位机发送“hello windows!”。当上位机给stm32发送一个字符“#”后,核心板暂停发送;发送一个字符“*****”后,核心板继续发送。