⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.h

📁 MCU串口接收源码 通用于各MCU 带CRC校验
💻 H
字号:
#define uchar unsigned char 
#define uint unsigned int 
//设置缓冲区最大长度
#define Buf_Len_Max 12
///////////状态定义
#define Data_ok 0x80 
#define Busy_fail 0x40  
#define Len_fail 0x20 
#define End_fail 0x10 
#define CRC_fail 0x08 
//全局
bit REC_Flag;
uchar UR_Control,UR_Datalen,Data[Buf_Len_Max];
uchar UR_Status;
//内部
uchar UR_CRC,Fuc_Point,Data_Point;
//***************************************************************************//
//描述:串口发送 uchar
//参数:入:d 发送数据
//声明:Juggler	20071013	Xi,An  EPGC
//注意:
//***************************************************************************//
void UART_Out(unsigned char d)
{	     
	SBUF=(d);
	while(!TI);
  	TI=0;
}
//***************************************************************************//
//描述:串口发送 word
//参数:入:d 发送数据
//声明:Juggler	20071013	Xi,An  EPGC
//注意:
//***************************************************************************//
void UART_Out_Int(int d)      
{
    unsigned char d0,d1;
    d0=d;
    d1=d>>8;
    UART_Out(d1);
    UART_Out(d0);
}
/*
//***************************************************************************
//描述:串口发送 uchar 以ASCII码
//参数:入:d 发送数据  0-255
//声明:Juggler	20071013	Xi,An  EPGC
//注意:
//***************************************************************************
void UART_Char_Uchar(uchar d)  //串口发送 int
{
    uchar NUM[3],UCU_i;
	bit UCU_Flag0=0; 	//显示开关
	NUM[0]=d/100;		//逐位取码
	d%=100;
	NUM[1]=d/10;		
	d%=10;
	NUM[2]=d;
	for(UCU_i=0;UCU_i<3;UCU_i++)
	{
		if(NUM[UCU_i]>0)UCU_Flag0=1;
		if(UCU_Flag0==1)
		{
			UART_Out(0x30+NUM[UCU_i]); 	//数字转换为ASCII码
		}
		else if(UCU_i==2)UART_Out('0');	//为0则输出'0'
	}
}
//***************************************************************************
//描述:串口发送 int 以ASCII码
//参数:入:d 发送数据  有符号区别
//声明:Juggler	20071013	Xi,An  EPGC
//注意:
//***************************************************************************
void UART_Char_Int(int d)      //串口发送 int
{
    uchar NUM[5],i;
	bit UCI_Flag0;
	if(d<0)
	{
	UART_Out('-');
	d=d*(-1);
	}
	NUM[0]=d/10000;
	d%=10000;
	NUM[1]=d/1000;
	d%=1000;
	NUM[2]=d/100;
	d%=100;
	NUM[3]=d/10;
	d%=10;
	NUM[4]=d;
	UCI_Flag0=0;
	for(i=0;i<5;i++)
	{
		if(NUM[i]>0)UCI_Flag0=1;
		if(UCI_Flag0==1)
		{
			UART_Out(0x30+NUM[i]);
		}
		else if(i==4)UART_Out('0');
	}
}
//***************************************************************************
//描述:串口发送 Uint 以ASCII码
//参数:入:d 发送数据  有符号区别
//声明:Juggler	20071013	Xi,An  EPGC
//注意:
//***************************************************************************
void UART_Char_Uint(uint d)      //串口发送 int
{
    uchar NUM[5],i;
	bit UCI_Flag0;
	NUM[0]=d/10000;
	d%=10000;
	NUM[1]=d/1000;
	d%=1000;
	NUM[2]=d/100;
	d%=100;
	NUM[3]=d/10;
	d%=10;
	NUM[4]=d;
	UCI_Flag0=0;
	for(i=0;i<5;i++)
	{
		if(NUM[i]>0)UCI_Flag0=1;
		if(UCI_Flag0==1)
		{
			UART_Out(0x30+NUM[i]);
		}
		else if(i==4)UART_Out('0');
	}
}
*/
//***************************************************************************//
//描述:串口初始化
//参数:无
//声明:Juggler	20071013	Xi,An  EPGC
//注意:
//***************************************************************************//
void UART_Init(void)
{
    SCON  = 0x50;       //SCON: 8位异步收发,波特率可变,允许串口接收;
    TMOD  = 0x20;       //TMOD: timer 1, mode 2, 8-bit reload 
    PCON  = 0x80;       //SMOD=1; 
    TH1   = 0xFF;       //Baud:115200  fosc=22.1184MHz
    TR1   = 1;          //timer 1 run
    RI=0;				//清标志
    TI=0;				//清标志
    PS=1;				//高优先级
   	ES=1;				//中断允许位
}
//***************************************************************************//
//描述:协议接收
//参数:无
//声明:Juggler	20071013	Xi,An  EPGC
//注意:
//***************************************************************************//
void UART_REC(void) interrupt 4 using 3		  //串口接收
{
	uchar UR_temp;
  	EA=0;
   	if(RI)
   	{
	    RI=0;
		UR_temp=SBUF;        
	    if(REC_Flag==1)//系统正在处理旧数据,数据无效
	    {
	        UR_Status=Busy_fail;
	        Fuc_Point=0 ;
	    }
	    else 
	    {   
	        if(Fuc_Point==0)//帧起始
	        {                
	            if(UR_temp==0x55)//帧起始字节
	            {
	                Fuc_Point=1 ;//开始接收                    
	            }
	            else ;           //无效
	        }  
			else if(Fuc_Point==1)	//控制码
	        {
	            UR_Control=UR_temp; //获取控制码                
	            Fuc_Point=2 ;		//指针指向数据长度域                
	        }           
	        else if(Fuc_Point==2)   //数据长度
	        {
	        	if(UR_temp==0)      //没有数据的命令帧
	        	{   
					UR_Datalen=0;
       	  		    UR_CRC=0;
	        	  	Fuc_Point=4;	
	        	} 
	            else if((UR_temp>0)&&(UR_temp<=Buf_Len_Max))  //数据长度大于0且小于缓冲区长度
	            {
	                UR_Datalen=UR_temp;                    //获取长度
					UR_CRC=0;
	                Fuc_Point=3;                    //指针指向数据域
	                Data_Point=0;                    //数据指针复位
	            }
	            else 
	            {
	                UR_Status=Len_fail;
					UART_Out(UR_Status);
	                Fuc_Point=0 ;					//接收复位
	            }
	        }           
	        else if(Fuc_Point==3)//有效数据
	        {
				UR_CRC+=UR_temp;
	            Data[Data_Point++]=UR_temp;                //获取数据

	            if(Data_Point==UR_Datalen)
	            {
	                Fuc_Point=4 ;                    //指向校验码域
	            }            
	        } 
			else if(Fuc_Point==4)//校验
            {
            	if(UR_CRC==UR_temp)
                {
                    Fuc_Point=5 ;                        //校验成功,指向结束码域
                }
                else 
                {
                    UR_Status=CRC_fail ;//校验失败,无功而返
 				    UART_Out(UR_Status);
                    Fuc_Point=0; 
                }
            }
	        else if(Fuc_Point==5)
	        {                
	            if(UR_temp==0x99)					//得到结束码
	            {
	                REC_Flag=1;
	                Fuc_Point=0;                    //接收复位
	                UR_Status=Data_ok;
					UART_Out(UR_Status);
	            }                
	            else 								//不是结束码,无功而返
	            {
	                UR_Status=End_fail;
					UART_Out(UR_Status);
	                Fuc_Point=0; 
	            }
	        }
	    }
  	}
	//else TI=0;
 	EA=1;
}
//***************************************************************************//
//描述:响应上位机
//参数:入:RSP 响应字 LEN 返回数据长度
//声明:Juggler	20071013	Xi,An  EPGC
//注意:如有返回数据(LEN不为0)则接收缓冲共用存储空间Data[i],无冲突
//***************************************************************************//
void UART_Back(uchar RSP,uchar LEN)
{
	uchar UB_i,UB_CRC;
	UART_Out(0x55);
	UART_Out(RSP);
	UART_Out(LEN);
	for(UB_i=0;UB_i<LEN;UB_i++)
	{
		UB_CRC+=Data[UB_i];
		UART_Out(Data[UB_i]);
	}
	UART_Out(UB_CRC);
	UART_Out(0x99);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -