串口带协议收发(双串口收发)

        完整注释,有问题可以私聊。也可用作两个串口通信。

1.定义标志位

u16 temp1 = 0;								
u16 temp2 = 0;         //定义中断标志位和数据缓存位
u8 rbuff_1[30];			  //数据储存数组
u8 r_count_1 =0;		  //计数收了多少数
u8 r_flag_1 =0;			  //数据完成标志位
u8 state_1 =0;		  	//状态标志位
u16 r_num = 0;		   	//数据帧长度



u16 check = 0;        //校验位
u16 check_1 = 0;			
u16 check_2 = 0;

u8 flag2 = 0;         //串口2中断标志位
u8 count = 0;         // TIM 1

u8 i = 0;
u8 j = 0;



#define FOSC 11059200L      //系统频率
#define BAUD 9600 

2.串口初始化

void InitUART(void)  
{  

  PCON &= 0x7F;		//波特率不倍速
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x04;		//独立波特率发生器时钟为Fosc,即1T
	BRT = 0xDC;		  //设定独立波特率发生器重装值
	AUXR |= 0x01;		//串口1选择独立波特率发生器为波特率发生器
	AUXR |= 0x10;		//启动独立波特率发生器

  AUXR &= 0xF7;		//波特率不倍速
	S2CON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x04;		//
	BRT = 0xDC;		  //设定独立波特率发生器重装值
	AUXR |= 0x10;		//启动独立波特率发生器
	IE2 =0x01;      //开串口2中断  ES2=1  
     
	EA = 1;				  //开启总中断
	ES = 1;				  //开启串口1中断
	
}  

3.收发函数

/****************串口1发送********************/

void UART_1SendOneByte(unsigned char c)  
{  
    SBUF = c;  
    while(!TI);                               //若TI=0,在此等待  
    TI = 0;    
}  
/****************串行口2发送****************/  
void UART_2SendOneByte(unsigned char c)  
{  
    S2BUF = c;  
    while(!(S2CON&S2TI));                    //若S2TI=0,在此等待  
    S2CON&=~S2TI;                            //S2TI=0  

4.中断处理函数

void UART_1Interrupt(void) interrupt 4  
{  
	  
    if(RI==1)  
    {  
/******************带协议收发状态机程序***********************/
        temp1=SBUF;        //寄存器值赋给数据位
				switch (state_1)   //状态判断
				{
					case 0:          //状态0
									if(temp1 == 0xA5)               //判断数据头
									{   						             
										rbuff_1[r_count_1++] = temp1; //把第一个数据存到数组里
									  state_1 = 1;                  //收到数据头正确状态变为1
									}
									else 
									{
										state_1 = 0;									// 数据头不对  重新获取数据
										r_count_1 = 0;                // 标志位不变
									}
								break;
					case 1:
									if(temp1 == 0xB6)               //数据头多加一位,防止出错
									{
									
										rbuff_1[r_count_1++] = temp1; //把第第二个数据存到数组
										state_1 = 2;					        //收到数据头正确,状态变为2
									}
									else														//数据头不对重新获取数,从头开始获取
									{
										state_1 = 0;
										r_count_1 = 0;
									}
								break;
					case 2:
								   rbuff_1[r_count_1++] = temp1;  //保存数据长度位到数组第三位
									 state_1 = 3;										//状态进行到3
									 r_num=rbuff_1[2];              //数据长度存入
					      break;
					case 3:
								   if(r_count_1<(r_num+2))						//	判断是否符合数据长度
									 {
										 rbuff_1[r_count_1++] = temp1;  //不符合继续存入
					           state_1 = 3;										//继续跳转的状态4 继续接收完数据
									 }
									 else                             //数据接收完成
									 {
										 rbuff_1[r_count_1++] = temp1;						//数组最后一位保存完成其余状态位清0			
										 state_1 = 4;									  //状态位变为0
									 }
								break;
					case 4:
						         rbuff_1[r_count_1] = temp1;		  
										 check_2 = temp1;									
										 r_flag_1 = 1;										
										 r_num = 0;										
									   state_1 = 0;
				  default:
										 state_1 = 0;									  
					      break;
				}
										
				RI = 0;                                    //中断标志位清0
    }  
}  
/************串行口2中断处理函数*************/  
void UART_2Interrupt(void) interrupt 8  
{  
	
    if(S2CON&S2RI)  
    {  
        S2CON&=~S2RI;  
        flag2=1;  
        temp2=S2BUF;  
    }   
}

5.主程序

void main(void)  
{  
    InitUART(); //串行口初始化  
    while(1)  
    {  
			
        if(r_flag_1==1)  
        {  
						
              r_flag_1=0; 
						for(j=3;j<(r_count_1);j++)
						{
							check += rbuff_1[j];
						}
						check_1 = check % 6;
						if(check_1 == check_2)
						{
										check = 0;
										for(i=0;i<(r_count_1+1);i++)
									{
										UART_1SendOneByte(rbuff_1[i]);
									}
						}
						else
						{
							UART_1SendOneByte(0xbb);
						}
						r_count_1=0;
			  }
           
          
        //如果串口2接收到数据,将此数据由串口1发送  
        if(flag2==1)  
        {  
            flag2=0;  
            UART_1SendOneByte(temp2);  
        }  
//     }  
		}  
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值