串口作为 MCU 的重要外部接口,同时也是软件开发重要的调试手段,其重要性不言而喻。STM32 的串口资源相当丰富的,功能也相当强劲。
这里要配置串口2,所以首先要使能串口2然后设置相应通信模式。
打开 Pinout&Configuration 选项卡界面,左侧依次进入 Connectivity->USART2 配置栏。USART2配置栏有2个选项。第一个选项 Mode 用来设置串口2的模式或者关闭串口2。 第二个选项 Hardware Flow Control(RS232)用来开启/关闭串口2的硬件流控制,该选项只有在 Mode 选项值为 Asynchronous(异步通信)模式的前提下才有效。这里要开启串口2的异步模式,并且不使用硬件流控制,所以这里直接选择 Mode 值为 Asynchronous 即可。配置好的 USART2界面如下图 :
配置好串口2为异步通信模式后,在硬件上会使用到 PA2 和 PA3 作为串口2的发送接收引脚。在 STM32CubeMX中,当选择好外设的工作模式之后,软件会自动配置 GPIO口的相关模式和参数。
接下来需要配置 USART2外设相关的参数,包括波特率,停止位等。首先,再次进入 Connectivity->USART2 配置栏,进入Configuration选项卡,会发现 USART2 Configuration 界面里有5个配置选项卡。
NVIC 选项卡用来使能 USART2中断。这里勾上 Enabled 选项。
DMA Setting 是在使用 USART2 DMA 的情况才需要配置,这里不配置。
GPIO Setting 是查看和配置 USART2参数之后,如果使用到串口中断,那么还需要设置中断优先级分组。
Parameter Settings 选项卡用来配置 USART2的初始化参数,包括波特率停止位等等。
这里将 USART2配置为:波特率 115200,8 位字节模式,无奇偶校验位,发送/接收均开
启。
User Constats 是用来配置用户常量。
接下来是配置 NVIC 相关参数。左侧依次点击 System Core->NVIC 按钮,然后在弹出的 NVIC Configuration 界面设置中断优先级分组级别。
系统初始化设置为分组 4,那么就是 4 位抢占优先级和 4 位响应优先级。所以这里的参数选择“4 bits for pre-emption priority”,也就是 4 位抢占优先级。
首先,在 usart.h 文件中加入如下定义:
#include "stdio.h"
#define USART_REC_LEN 200 //定义最大接收字节数 200
#define EN_USART2_RX 1 //使能(1)/禁止(0)串口2接收
extern u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大 USART_REC_LEN 个字节末字节为换行符
extern u16 USART_RX_STA; //接收状态标记
#define RXBUFFERSIZE 1 //缓存大小
extern u8 aRxBuffer[RXBUFFERSIZE];//HAL 库 USART 接收 Buffer
除此之外,还要在 usart.c 文件中加入部分代码,定义初始化串口句柄的缓存相关参数和回调函数 HAL_UART_RxCpltCallback,代码如下:
#if EN_USART2_RX //如果使能了接收
u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
u16 USART_RX_STA=0; //接收状态标记
u8 aRxBuffer[RXBUFFERSIZE];//HAL库使用的串口接收缓冲
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance==USART2)//如果是串口2
{
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(aRxBuffer[0]!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(aRxBuffer[0]==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=aRxBuffer[0] ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))
USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
HAL_UART_Receive_IT(&huart2, (u8 *)aRxBuffer, RXBUFFERSIZE);//该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量
}
}
#endif
最后在主程序中填写被测代码
int main(void)
{
u8 len;
u16 times=0;
HAL_Init();
SystemClock_Config();
delay_init();
MX_GPIO_Init();
MX_USART2_UART_Init();
while (1)
{
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
printf("\r\n 您发送的消息为:\r\n");
HAL_UART_Transmit(&huart2,(uint8_t*)USART_RX_BUF,len,1000); //发送接收到的数据
while(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_TC)!=SET); //等待发送结束
printf("\r\n\r\n");//插入换行
USART_RX_STA=0;
}else
{
times++;
if(times%1000==0)
{
printf("\r\n 串口实验\r\n");
}
if(times%200==0)printf("请输入数据,以回车键结束\r\n");
if(times%30==0);
delay_ms(10);
}
}
}
果演示如下