本文实现了串口不定长接收字符串,仅采用串口中断。但是这种方法具有一定的局限性。谨慎使用。
由于最近在学习过程中需要使用不定长接收字符串数据,从网上看到的资料大多数是使用空闲中断+DMA传输的、环形缓冲队列等方法。
因为需要接收的数据为字符串数据,且有固定的结束符 \r\n,因此就打算使用串口中断,检测接收到的字符串是否含有结束符标志。如果串口接收到的数据不是\r或者\n,说明数据接受的是有效数据。这种实现方法初步是可行的。
接收到的数据主要分为三个部分:1.有效数据字符 2. \r回车字符 3.\n换行字符
于是我们可以将这个数据拆分为3个状态。
中断函数接收代码
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance==USART1)
{
if (RxData != '\r'&&RxData != '\n')
{
RxState = 1;
Serial_RxPacket[pRxPacket] = RxData;
pRxPacket++;
}
if(RxData == '\r')
{
RxState = 2;
Serial_RxPacket[pRxPacket] = RxData;
pRxPacket++;
}
if(RxData == '\n')
{
if(RxState == 2 )
{
RxState = 0;
Serial_RxPacket[pRxPacket] = RxData;
pRxPacket++;
Serial_RxFlag = 1;
}
}
}
HAL_UART_Receive_IT(&huart1,(uint8_t *)&RxData,1);
}
信息处理函数
static void vTaskMsgPro(void *pvParameters)
{
while(1)
{
if(Serial_RxFlag == 1 )
{
HAL_UART_Transmit_IT(&huart1,(uint8_t *)Serial_RxPacket,pRxPacket);
//ArraryClear(Serial_RxPacket,pRxPacket);
pRxPacket = 0;
Serial_RxFlag = 0;
}
vTaskDelay(20);
}
}
对代码进行测试:
使用开源的串口助手,在发送区随意输入一大串字符串,并使用定时发送进行验证,设置100ms进行定时发送,并自动发送换行符。经验证,发送数据为6565,接收数据也为6565。因此可以看到数据并没有丢失。