目录
一、函数接收
1、堵塞式接收
堵塞模式也叫轮询模式,hal库里面堵塞式接收数据的函数为HAL_UART_Receive(),具体使用方法如下:
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
它的作用是从UART接收数据,并将接收到的数据存储到指定的缓冲区中。
参数说明:
第一个参数是要使用的串口句柄地址
第二个参数是要接收的数据缓冲区首地址
第三个参数是接收的数据长度,这里可以直接用sizeof()函数获取接收缓冲区的长度
第四个参数是超时时间,单位是ms,如果超过设置的时间,则函数返回HAL_TIMEOUT,如果设置为HAL_MAX_DELAY,处理器就会一直等到数据接收完成再执行下一条语句。
2、中断方式接收
hal库里面的串口中断发送函数为HAL_UART_Receive_IT(),具体用法和说明如下:
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
这个函数的目的是启动UART中断接收并以非阻塞的方式接收一定数量的数据。
参数说明:中断方式的收发函数只有三个参数
第一个参数是要使用的串口句柄地址第二个参数是接收缓冲区的首地址,用于存放要接收的数据
第三个参数是接收缓冲区长度
3、串口重定向scanf
在PC上进行C语言程序开发时,我们可以利用C语言的利用格式化输人函数 scanf()读取由键盘输入的信息。在嵌入式系统的开发中,我们也希望能够在程序运行的时候读取由键盘输入的信息,实现良好的人机交互。
HAL库提供的串口收发函数,功能比较简单,不能进行格式化的输入。如果要实现类似 C语言中的格式化输入函数,需要把scanf()函数的输入重新定向到串口。
由于scanf()函数通过调用fgetc()函数来实现数据的输入,因此用户需要改写这个函数来实现串口输入的重定向。
二、配置STM32CubeMX
第一步:选择SYS的Debug-Serial Wire模式,开启SWD调试:
第二步:配置时钟,选择RCC的HSE(高速时钟)为 Crystal/Ceramic Resonator(外部晶振),接着再配置时钟树,将时钟频率配置为最大值168MHZ:
第三步:配置串口,这里我们使用串口一,将串口一的模式配置为Asynchronous(异步)模式,配置串口一波特率为115200,接着开启串口一中断:
接下来就是生成工程文件,初始化代码
三代码编写及测试
1、堵塞式接收
首先定义一个数据接收缓冲数组Rx_Buff[5],由于堵塞式接收只能定长接收,所以我们要指定接收缓冲数组的大小,这里我们设定接收缓冲数组的大小为5个字节,等会我们可以通过串口发送hello或者发送十六进制01 02 03 04 05来测试接收是否正常。
uint8_t Rx_Buff1[5];
接着在main函数里面循环调用HAL_UART_Receive()函数接收数据,如果接收到数据就把接收到的数据发送到串口。
if(HAL_UART_Receive(&huart1,Rx_Buff1,sizeof(Rx_Buff1),100) == HAL_OK)
{
HAL_UART_Transmit(&huart1,Rx_Buff1,sizeof(Rx_Buff1),100);
}
最后,测试结果如下:
2、中断方式接收
hal库的中断接收函数有三个参数,和轮询接收的函数前三个参数一样,只是没有了超时时间管理,因为中断(IT)方式配置完成寄存器之后不需要再占用CPU,会在接收/发送数据完成后触发中断,因此不需要超时时间管理机制。
首先定义一个数据接收缓冲数组Rx_Buff[5],由于中断方式接收只能定长接收,所以我们要指定接收缓冲数组的大小,这里我们设定接收缓冲数组的大小为4个字节,等会我们可以通过串口发送word或者发送十六进制06 07 08 09来测试接收是否正常。
uint8_t Rx_Buff2[4];
接着在main函数的while(1)循环前调用HAL_UART_Receive_IT()函数,启用中断接收。
HAL_UART_Receive_IT(&huart1,Rx_Buff2,sizeof(Rx_Buff2));
然后再重新编写串口中断回调函数去处理接收的数据,将接收到的数据重新发送到串口。
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart == &huart1) // 判断串口号是否为 huart1
{
// 发送Rx_Buff2的缓冲区的数据到 UART1,使用中断模式发送
HAL_UART_Transmit_IT(&huart1, Rx_Buff2, sizeof(Rx_Buff2));
}
// 重新启动 UART1 的中断接收,将接收到的数据存放到 RxBuf 的缓冲区中
HAL_UART_Receive_IT(&huart1, Rx_Buff2, sizeof(Rx_Buff2));
}
最后,测试结果如下:
3、串口重定向scanf函数
第一步:在进行重定向之前,需要配置好串口,使用到串口的轮询模式。由于 scanf()函数是由MDK 软件所提供的 C语言标准库函数,在完成程序编写后,用户还需要在MDK 软件的工程设置窗口中选择“Target”标签页勾选其中的“Use MicroLIB”选项。如果不勾选“Use MicroLIB”选项,则无法使用。
第二步:由于需要调用printf()函数,因此需要添加标准输入输出头文件:stdio.h。
第三步:重写fgetc()函数
int fgetc(FILE *f)
{
uint8_t ch;
// 采用轮询方式接收 1字节数据,超时时间设置为无限等待
HAL_UART_Receive( &huart1,(uint8_t*)&ch,1, HAL_MAX_DELAY );
return ch;
}
第四步:在main函数里面调用scanf()函数读取串口数据,然后将读到的数据重新发送到串口
scanf("%s",Rx_Buff1);
printf("%s\n",Rx_Buff1);
最后,在串口助手上发送abcd,发送数据的时候记得换行,否则读取的数据就会不正常,测试结果如下: