前言
上一章节讲解了如何通过STM32CubeMx配置LED,本节课将介绍在单片机中常用的串口功能。串口是一种在单片机,传感器,执行模块等诸多设备上常用的通讯接口,在比赛中,可以通过串口读取遥控器发送来的数据,也可以通过串口读取超声波等传感器的数据,也可以使用串口在单片机和运行计算机视觉的电脑之间进行通讯。
通过本节课的学习, 将掌握如何通过 APB 时钟计算串口的波特率,串口在 cubeMX 中的配置方法,串口的接收中断与空闲中断功能,串口的发送函数与发送中断。
准备工具
软件:STM32CubeMx、Keil5 MDK、串口调试助手XCOM
硬件:STM32F103C8T6核心板、下载器ST_LINK、USB转TTL或J-LINK
本章节工程已上传至百度网盘,此链接永久有效
链接:https://pan.baidu.com/s/108QKIltQ-aZ94inuvKylGg?pwd=b8l3
提取码:b8l3
CubeMx配置
打开上一章节建立好的工程模板,配置串口通信模式为异步通信,波特率115200,开启全局中断
最后生成代码,打开工程
HAL库UART函数库介绍
1、串口发送/接收函数
- HAL_UART_Transmit();串口发送数据,使用超时管理机制
- HAL_UART_Receive();串口接收数据,使用超时管理机制
- HAL_UART_Transmit_IT();串口中断模式发送
- HAL_UART_Receive_IT();串口中断模式接收
- HAL_UART_Transmit_DMA();串口DMA模式发送
- HAL_UART_Transmit_DMA();串口DMA模式接收
HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
功能:串口发送指定长度的数据。如果超时没发送完成,则不再发送,返回超时标志(HAL_TIMEOUT)。
参数:
UART_HandleTypeDef *huart huart句柄,如 : UART_HandleTypeDef huart1; 别名就是huart1
*pData 需要发送的数据
Size 发送的字节数
Timeout 最大发送时间,发送数据超过该时间退出发送
HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
功能:串口中断接收,以中断方式接收指定长度数据。
大致过程是,设置数据存放位置,接收数据长度,然后使能串口接收中断。接收到数据时,会触发串口中断。
再然后,串口中断函数处理,直到接收到指定长度数据,而后关闭中断,进入中断接收回调函数,不再触发接收中断。(只触发一次中断)
参数:UART_HandleTypeDef *huart huart句柄,如 : UART_HandleTypeDef huart1; 别名就是huart1
*pData 接收到的数据存放地址
Size 接收的字节数
2、串口中断函数
- 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();串口接收错误函数
HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
功能:HAL库的中断进行完之后,并不会直接退出,而是会进入中断回调函数中,用户可以在其中设置代码,串口中断接收完成之后,会进入该函数,该函数为空函数,用户需自行修改,
参数:UART_HandleTypeDef *huart huart句柄,如 : UART_HandleTypeDef huart1; 别名就是huart1
串口收发
函数初始化部分需添加串口接收中断开启函数
/* USER CODE BEGIN 2 */
UART_Start_Receive_IT(&huart1,(uint8_t *)&rec_buffer,1);
/* USER CODE END 2 */
用户自定义串口接收是在中断回调函数中进行,所以需要在工程中添加如下代码
uint8_t rec_buffer;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//中断回调函数
{
UNUSED(huart);
if(huart->Instance == USART1)//判断串口号
{
static uint8_t temp;
temp = rec_buffer;
if(temp == 0x01)
HAL_GPIO_WritePin(LEDD_GPIO_Port, LEDD_Pin, GPIO_PIN_SET);
else if(temp == 0x02)
HAL_GPIO_WritePin(LEDD_GPIO_Port, LEDD_Pin, GPIO_PIN_RESET);
HAL_UART_Transmit(&huart1,(uint8_t *)&rec_buffer,1,100); // 将接收到的数据再通过串口发送出去
HAL_UART_Receive_IT(&huart1, (uint8_t *)&rec_buffer, 1); //重新使能接收中断
}
}
将串口CH340上的TXD接到主控上的PA10,RXD接到主控对应的PA9。通过XCOM发送可以0x01或0X02即可看到LED变化。
重定义printf函数
需要包含stdio.h库文件
#include "bsp_usart.h"
#include <stdio.h>
extern UART_HandleTypeDef huart1;
重定向c库函数printf
/**
* 函数功能: 重定向c库函数printf到DEBUG_USARTx
* 输入参数: 无
* 返 回 值: 无
* 说 明:无
*/
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
重定向c库函数getchar,scanf
/**
* 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx
* 输入参数: 无
* 返 回 值: 无
* 说 明:无
*/
int fgetc(FILE *f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
return ch;
}
printf函数用法和c库一样,可输出字符、字符串和变量,如下图所示
通过XCOM可以通过串口发送、接收字符