下面三种方式都亲测可用,实际使用时应采用第三种方法,更有效率。
方法一:
先说重点:
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串口中断实现非阻塞方式接收不定长数据
STM32CubeIDE V1.9。
使用STM32的串口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:定义接收的字节长度,填写接收数据的最大字节数。
调用函数“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]中,并返回所接收的数据。
定义一维数组array:
uint8_t array[50];
在主函数的初始化过程,调用函数“HAL_UARTEx_ReceiveToIdle_IT”:
void main()
{
HAL_UARTEx_ReceiveToIdle_IT(&huart1, array, 50); //初始化开启串口接收
while(1);
}
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()函数,不需要添加申明
全部0条评论
快来发表一下你的评论吧 !