| 设计目标: 1. 单片机时钟10MHz,串口波特率115200
 2. 由于波特率较高,串口必须采用中断方式接收
 3. 串口接受完数据必须对数据进行解帧,即判断出帧头和帧尾,这部分放while循环里面处理
 
 搜索了下,发现下面的代码比较符合要求
 但是根据信息有几个问题
 1. UART_Receive_Size在中断函数和一般函数都出现,会产生其真实值被中断后覆盖掉的问题,导致值出错(最终结果是有可能丢帧)
 2. 可不可以不用UART_Receive_Size,而是定义两个指针,分别指向接收位置和处理位置,则缓冲区的满(full)
 不用UART_Receive_Size进行判断,而是利用这两个指针的关系进行判断。这样子可以避免问题1?()
 3. 求测试过的健壮性好的代码,谢谢
 
 
 //系统可修改参数宏定义
 #define BUFFER_SIEZ 64
 //控制命令定义
 #define COMMUNCIATE 0
 #define SET_SYSTEM_CAL_FULL 1
 #define SET_SYSTEM_CAL_MV_V 2
 #define SET_SYSTEM_OL 3
 #define SET_POWER_OFF_TIME 4 //设定系统关机时间
 #define READ_SYSTEM_DATA 5
 
 //变量定义
 //串口缓冲区 建立一个环形缓冲区,收发
 unsigned char xdata UART_Receive_Size=0;//串口缓冲区接收字节数
 unsigned char xdata UART_Receive_First=0;//串口缓冲区接收字节开始位置
 unsigned char xdata UART_Read_First=0;
 unsigned char xdata UART_Buffer[BUFFER_SIEZ];//串口缓冲区
 unsigned char xdata UART_Send_Byte_Ok=0;//发送一字节成功
 //中断处理
 //串口初始化根据自己的单片机写就行
 void UART0_Interrupt (void) interrupt 4
 {
 if(RI0)                         //如果是发中断,返回
 {
 RI0=0;  //清除中断标志
 if(UART_Receive_Size<=BUFFER_SIEZ)//缓冲区未满,装载数据
 {
 UART_Buffer[UART_Receive_First++]=SBUF0;
 UART_Receive_Size++;//串口缓冲区接收字节数
 if(UART_Receive_First>=BUFFER_SIEZ)//循环装入缓冲区
 UART_Receive_First = 0;
 }
 }
 if(TI0)
 {
 TI0=0;
 UART_Send_Byte_Ok=1;
 }
 }
 
 //在缓冲区中读取一帧数据
 void Do_Commend()
 {
 unsigned char Buf[8]={0,0,0,0,0,0,0,0};//帧数据缓冲区
 unsigned char i=0;
 unsigned char data_packge_flag=0;
 
 if(UART_Receive_Size>=8)//缓冲区字节数大于等于一个包字节数
 {
 while(UART_Receive_Size!=0)//寻找帧数据头
 {
 if(UART_Buffer[UART_Read_First]==0xaa)
 {
 if(UART_Read_First+7<BUFFER_SIEZ)
 {
 if(UART_Buffer[UART_Read_First+7]==0x55)
 {
 data_packge_flag=1;
 break;
 }
 }
 else
 {
 if(UART_Buffer[7-(BUFFER_SIEZ-UART_Read_First)]==0x55)
 data_packge_flag=1;
 break;
 }
 }
 UART_Read_First++;
 if(UART_Read_First>=BUFFER_SIEZ)//环形 缓冲区折行
 UART_Read_First=0;
 UART_Receive_Size--;
 }
 if(data_packge_flag==1)//寻找到枕头
 {
 for(i=0;i<8;i++)//读取帧数据
 {
 Buf=UART_Buffer[UART_Read_First];
 UART_Receive_Size--;
 UART_Read_First++;
 if(UART_Read_First>=BUFFER_SIEZ)//环形 缓冲区折行
 UART_Read_First=0;
 }
 data_packge_flag=0;
 }
 if(Buf[7]==0x55&&Buf[0]==0xaa)  //接收到一个正确的数据包
 {
 switch(Buf[1])
 {
 ...
 }
 }
 }
 }
 复制代码转载
 
 
 |