三种方法实现串口接收不定长度的数据

描述

下面三种方式都亲测可用,实际使用时应采用第三种方法,更有效率。

方法一:

先说重点:

1)RXNE,表示一个字节产生一次中断,这里要着重说明一下,是一个字节。原因是DR寄存器是32位,有效位是8位。比如串口发送的字符或字符串,其对应的ASICC码的二进制都是8位的,所以不管是发送“1”,都是8位

2)IDLE,表示DR先有数据(可以是一个字节的数据,也可以是N个字节的数据连续发过来),然后空闲了一个字节的时间,就会产生中断。

字符串

如果要让串口发送不定长度的的数据,则先通过RXNE,把数据一个字节一个字节地存起来,当一串信息发送完时,因为要停顿一下,则会产生IDLE中断,利用IDLE中断,表示完成接收数据,具体方法如下:

先定义一个数组和数组长度:

uint8_t Rx1_Buff[50]={'0'};

uint8_t rx_buffer_len=0;

字符串

方法二:

使用STM32串口中断实现非阻塞方式接收不定长数据

一、简介

1.1、开发环境

STM32CubeIDE V1.9。

1.2、实现功能

使用STM32的串口1,接收不定长数据,并返回接收数据

二、步骤解析

2.1、配置串口

打开“Device Configuration Tool”(即STM32CubeMX),配置串口1。

字符串

注:一定要在“NVIC Settings”栏,勾选“USART1 global interrupt”打开串口中断。

2.2、初始化

初始化过程中,调用函数“HAL_UARTEx_ReceiveToIdle_IT”。

HAL库中对该函数的定义:

HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)。

huart:定义串口,一般填写 &huartx(x为串口号,取1、2、3……)。本案例使用串口1,则填写&huart1;

pData:接收数据存放的首地址,一般填写一维数组名;

Size:定义接收的字节长度,填写接收数据的最大字节数。

2.3、回调函数

调用函数“HAL_UARTEx_ReceiveToIdle_IT”后,当接收长度等于Size,或者串口接收数据过程中产生空闲时,会执行回调函数"HAL_UARTEx_RxEventCallback"。

HAL库中对该函数的定义:

__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)

huart:回调串口号;

Size:实际接收的字节长度。

注:该回调函数为空的弱函数,函数主体需自己重新定义。

三、实例

从串口1接收不定长数据,存放在数组array[50]中,并返回所接收的数据。

3.1、定义

定义一维数组array:

uint8_t array[50];

3.2、主函数

在主函数的初始化过程,调用函数“HAL_UARTEx_ReceiveToIdle_IT”:

void main()

{

HAL_UARTEx_ReceiveToIdle_IT(&huart1, array, 50); //初始化开启串口接收

while(1);

}

3.3、重新定义回调函数

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)

{

if(huart==&huart1) //判定:串口1接收

{

HAL_UART_Transmit(&huart1,Rx1_Buff,strlen((constchar*)Rx1_Buff),0x000A); //把接收到的数据发送出去

memset(Rx1_Buff,0,strlen((const char*)Rx1_Buff));//清空数组

HAL_UARTEx_ReceiveToIdle_IT(&huart1, array, 50) ; //重新开启串口接收

}

}

初始化打开串口接收中断,当串口接收满50字节,或串口产生空闲时,会执行回调函数。回调函数里判断串口后正确后,执行对应的功能函数,并再次开启串口接收中断。

HAL_UARTEx_ReceiveToIdle_IT(),其实是实现RXNE和IDLE中断,和方式一是一样的原理

字符串

字符串

以上两种方式,每一个字符都会中断一次,效率不高,采用DMA接收的方式会更高一点,DMA空闲中断的方式见这份文档《STM32F103用hal库使用DMA+串口空闲中断接收数据_L》,或下方第三种方式.

方法三:

1.CUBE的设置就不讲了,CUBE设置完后,就进行第二步。

2.生成代码后,在main函数中打开串口空闲中断,单个字符中断用于接收用的,因为我这例程作用是串口1发送数据并把数据发送回来。

字符串

3.在串口中断中添加如下:

字符串

4.DMA发送完后,要清除数组Rx1_Buff里的数据,不然下次接收的数据会重复覆盖,有可能覆盖不全。其实HAL_UART_Transmit_DMA(), 这个函数接收完会调用回调函数。

HAL_UART_Transmit_DMA() - >

UART_DMATransmitCplt - >

HAL_UART_TxCpltCallback() - >

__weak void HAL_UART_TxCpltCallback()

5.构造HAL_UART_TxCpltCallback()函数,不需要添加申明

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分