背景
1、单片机串口接收数据处理,这个代码已经过很多项目验证,没有问题。用这个代码帮了好几个同事解决数据接收久了就异常。
2、这个代码做到接收和处理分开。避免不必要的处理逻辑问题。
3、也可用于网口tcp,udp,spi,iic等方式。
缺陷 :
1、接收和处理两个缓存区,比较吃内存,不过现在单片机内存大,不是问题。
2、接收和处理分开,响应没那么及时。现在芯片主频都高,可以忽略。
实现
#include "Code_UART_1.h"
#include "stdio.h"
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart3;
//缓存区根据实际情况修改
#define UART_1_RX_BUFSIZE 16*4 // receive
volatile uint8_t UART_1_RXBuffer[UART_1_RX_BUFSIZE]; // receive
volatile uint16_t UART_1_RXReadIndex = 0, UART_1_RXWriteIndex = 0; // receive buffer indexes :
volatile uint16_t UART_1_RXCharCount = 0; // count of received bytes:
#define UART_1_Rec_BUFSIZE 8*2 // receive
volatile uint8_t UART_1_rec_buffer[UART_1_Rec_BUFSIZE];
volatile uint16_t UART_1_rec_count = 0;
volatile uint16_t UART_1_timeout_count = 0;
uint8_t UART_1_RxData=0;
//中断接收,根据实际芯片修改
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance==USART3)
{
}
else if(huart->Instance==USART1)
{
UART_1_RXBuffer[UART_1_RXWriteIndex++] =UART_1_RxData;
UART_1_RXWriteIndex &= UART_1_RX_BUFSIZE - 1;
UART_1_RXCharCount++;
HAL_UART_Receive_IT(huart,&UART_1_RxData,1); // 重新使能串口1接收中断
}
}
//读取缓存数据
uint8_t UART_1_Ci_ReadChar ( void )
{
uint8_t vByte;
if ( UART_1_RXCharCount )
{
vByte = UART_1_RXBuffer[UART_1_RXReadIndex++];
UART_1_RXReadIndex &= UART_1_RX_BUFSIZE - 1;
UART_1_RXCharCount--;
return vByte ;
}
return 0;
}
void UART_1_Init(void)
{
HAL_UART_Receive_IT(&huart1,&UART_1_RxData,1); // 重新使能串口1接收中断
}
void UART_3_Init(void)
{
//HAL_UART_Receive_IT(&huart3,&RxBuffUart3,1); // 重新使能串口1接收中断
}
uint16_t UART_1_RecLen=0;
void UART_1_process_rec_data(void)
{
uint16_t vLen=0;
uint32_t vRecData=0;
if ( UART_1_RXCharCount )
{
UART_1_rec_count &= UART_1_Rec_BUFSIZE - 1;
//设置超时初值
UART_1_timeout_count = 50000;
UART_1_rec_buffer[UART_1_rec_count++] = UART_1_Ci_ReadChar();
UART_1_SendOneByte(&huart1,UART_1_rec_buffer[UART_1_rec_count-1]);
}
//添加超时处理
if(UART_1_timeout_count>0 )
{
UART_1_timeout_count--;
}
else
{
UART_1_rec_count = 0;
}
if ( UART_1_rec_count > 0 && UART_1_rec_buffer[0] == 0x55 )
{
//这里添加类型处理
if(UART_1_rec_count==2)
{
switch(UART_1_rec_buffer[1])
{
case 0x01:UART_1_RecLen =2; break;
default:UART_1_rec_count=0;break;
}
}
else if(UART_1_rec_count>=3)
{
vLen=UART_1_rec_buffer[2];
if(UART_1_rec_count>=(vLen+4))
{
//记得清0
UART_1_rec_count = 0;
if(UART_1_rec_buffer[vLen+4-1]==0xAA)
{
//数据处理
}
}
}
}
else
{
UART_1_rec_count = 0;
}
}
void UART_1_SendOneByte(UART_HandleTypeDef *pUART_Handle,uint8_t pData)
{
WRITE_REG(pUART_Handle->Instance->DR, pData);
while (READ_BIT(pUART_Handle->Instance->SR, UART_FLAG_TXE) == DISABLE);
}
int fputc(int ch,FILE *f)
{
UART_1_SendOneByte(&huart1, (uint8_t)ch);
return(ch);
}