基于HAL库的STM32串口定长接收数据

本文介绍了STM32CubeMX中如何使用堵塞式和中断方式接收数据,以及如何通过串口重定向scanf函数实现格式化输入,同时详细说明了配置步骤和代码实现。
摘要由CSDN通过智能技术生成

目录

一、函数接收

1、堵塞式接收

2、中断方式接收

3、串口重定向scanf

二、配置STM32CubeMX

三代码编写及测试

1、堵塞式接收

2、中断方式接收

3、串口重定向scanf函数


一、函数接收

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,发送数据的时候记得换行,否则读取的数据就会不正常,测试结果如下:

  • 52
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值