单片机 stm32 接收数据和处理

背景

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);
}













  • 7
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值