STM32 串口接收拼帧
串口数据 指令 协议格式
起始帧 (1个字节) |
数据帧 (5个字节) |
结束帧 (2 个字节) |
||
AA |
0D 0A |
typedef enum { STATUS_IDLE = (uint8_t)0, STATUS_HEAD, /* Rx Head */ STATUS_TYPE, /* Rx Type */ STATUS_DATA, /* Data filed */ STATUS_TAIL, /* Tail */ STATUS_END, /* End of this frame */ } COMM_TRM_STATUS_TypeDef;
数据帧长度
#define CMD_DATA_LEN 8 /* 数据帧长度 */
定义串口接收状态
uint8_t CMD_UART_RX_STATUS = STATUS_IDLE;
串口接收函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
UNUSED(huart);
if(huart == &CMD_UART)
{
switch(CMD_UART_RX_STATUS)
{
case STATUS_IDLE:
if(0xAA == Cmd_Uart_Rx_data) //AA 起始帧
{
CMD_UART_RX_STATUS = STATUS_DATA;
cmd_uart_recv_cnt = 0;
cmd_uart_recv_buf[cmd_uart_recv_cnt] = Cmd_Uart_Rx_data;
cmd_uart_recv_cnt++;
}
break;
case STATUS_DATA:
if(cmd_uart_recv_cnt < UART_RECV_BUF_SIZE)
{
cmd_uart_recv_buf[cmd_uart_recv_cnt] = Cmd_Uart_Rx_data;
if(0x0D == Cmd_Uart_Rx_data)
{
if(cmd_uart_recv_cnt >= (CMD_DATA_LEN - 2))
{
CMD_UART_RX_STATUS = STATUS_TAIL;
}
}
cmd_uart_recv_cnt++;
}
else
{
cmd_uart_recv_cnt = 0;
memset(cmd_uart_recv_buf, 0, sizeof(cmd_uart_recv_buf)); //接收缓冲区清零
CMD_UART_RX_STATUS = STATUS_IDLE;
}
break;
case STATUS_TAIL:
if(cmd_uart_recv_cnt < UART_RECV_BUF_SIZE)
{
cmd_uart_recv_buf[cmd_uart_recv_cnt] = Cmd_Uart_Rx_data;
if(0x0A == Cmd_Uart_Rx_data)
{
if((cmd_uart_recv_cnt >= (CMD_DATA_LEN - 1)) && (0xAA == cmd_uart_recv_buf[cmd_uart_recv_cnt - (CMD_DATA_LEN - 1)]))
{
/* 完整一帧数据,此处添加处理函数,本例程是freeRTOS系统,使用消息队列来处理数据帧 */
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xQueueSendFromISR(xUartQueue, (void *)&cmd_uart_recv_buf[cmd_uart_recv_cnt - (CMD_DATA_LEN - 1)], &xHigherPriorityTaskWoken); //接收完一帧数据后,将数据发送到队列中
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
else
{
/* 错误数据帧*/
}
CMD_UART_RX_STATUS = STATUS_IDLE;
cmd_uart_recv_cnt = 0;
memset(cmd_uart_recv_buf, 0, sizeof(cmd_uart_recv_buf)); //接收缓冲区清零
}
else if(0x0D == Cmd_Uart_Rx_data)
{
CMD_UART_RX_STATUS = STATUS_TAIL;
cmd_uart_recv_cnt++;
}
else
{
CMD_UART_RX_STATUS = STATUS_DATA;
cmd_uart_recv_cnt++;
}
}
else
{
cmd_uart_recv_cnt = 0;
memset(cmd_uart_recv_buf, 0, sizeof(cmd_uart_recv_buf)); //接收缓冲区清零
CMD_UART_RX_STATUS = STATUS_IDLE;
}
break;
default:
break;
}
HAL_UART_Receive_IT(&CMD_UART, (uint8_t *)&Cmd_Uart_Rx_data, 1); //重新开启接收中断
}
}
Talk is cheap, show me the code