51单片机串口数据分包

2020-06-21 14:55

#include #include\#include\#include\#include\

#define IAP_ADDRESS1 0x0000 #define IAP_ADDRESS2 0x0100 #define IAP_ADDRESS3 0x0200 #define IAP_ADDRESS4 0x0300

#define IAP_ADDRESS5 0x03F0 //EEPROM 扇区划分

uint Rec_Flag=0; //解析状态标志

uchar Rec_len;//接收数据长度值寄存器 uchar length;//数据长度变量

uchar ok=0xff;//擦除正确返回字节 uchar error=0xee;//擦除不成功返回字节 uchar tail=0xee; //帧尾字节

uchar rcvdat;//串口接收数据寄存器 uchar Addr;//地址识别中间变量 uint Address;//地址变量

bit read_flag=0; //串口接收完毕标志位 bit OK_flag1=0;

bit OK_flag2=0; //擦除成功判断标志位 bit order_read; //读取命令标志位 bit order_save; //存储命令标志位 bit order_eraser; //擦出命令标志位

//串口接收中断函数

/********************************************************************************************

数据读取帧:0xaa 0xab 0xaa 0xab 0x00 0x0a 0x01 数据包类型 0xee 0xee

数据存储帧:0xaa 0xab 0xaa 0xab 0x00 数据存储帧总包长 0x02 数据包类型 数据包(长度根据数据类型来判断) 0xee 0xee

数据擦除:0xaa 0xab 0xaa 0xab 0xea 0xee 0xee (数据擦除为内部EEPROM的两个扇区的数据擦除,此为以后数据更改预留)

********************************************************************************************/

void serial () interrupt 4 //数据帧判别与命令解析 { if (RI) {

RI=0; rcvdat=SBUF; if(Rec_Flag==0) { if(rcvdat==0xaa) Rec_Flag=1; else Rec_Flag=0; } else if(Rec_Flag==1) { if(rcvdat==0xab) Rec_Flag=2; else Rec_Flag=0; } else if(Rec_Flag==2) { if(rcvdat==0xaa) Rec_Flag=3; else Rec_Flag=0; } else if(Rec_Flag==3) { if(rcvdat==0xab) //帧头为0xaa 0xab 0xaa 0xab Rec_Flag=4; else Rec_Flag=0; } else if(Rec_Flag==4) { if(rcvdat==0xea) //擦除命令 { Rec_Flag=10; order_eraser=1; //擦除命令标志位置1 }

else if(rcvdat==0x00) Rec_Flag=5; else Rec_Flag=0; } else if(Rec_Flag==5) { length=0; Rec_Flag=6; } else if(Rec_Flag==6) //读写命令解析 :0x02为数据存储 0x01为数据读取 { if(rcvdat==0x01) { order_read=1; Rec_Flag=7; } else if(rcvdat==0x02) { order_save=1; Rec_Flag=7; } else Rec_Flag=0; } else if(Rec_Flag==7) { switch(rcvdat) //数据长度识别 起始地址识别 { case 0x01: Address=IAP_ADDRESS1;Rec_len=0x08;break; //数据长度依次为:8、128、24、24、4 case 0x02: Address=IAP_ADDRESS2;Rec_len=0x80;break; case 0x03: Address=IAP_ADDRESS3;Rec_len=0x18;break; case 0x04: Address=IAP_ADDRESS4;Rec_len=0x18;break; case 0x05: Address=IAP_ADDRESS5;Rec_len=0x04;break; } Addr=rcvdat;

if(order_save) Rec_Flag=8; if(order_read) Rec_Flag=10; } else if((Rec_Flag==8)||(Rec_Flag==9)) //数据接收,直到达到规定长度 { IapProgramByte(Address+length,rcvdat); EEPROM length++; if(length==Rec_len) //数据长度判断 Rec_Flag=10; else Rec_Flag=9; } else if(Rec_Flag==10) //帧尾 0xee { if(rcvdat==0xee) Rec_Flag=11; else Rec_Flag=0; } else if(Rec_Flag==11) //帧尾 0xee { if(rcvdat==0xee) { read_flag=1; Rec_Flag=0; } else Rec_Flag=0; }

} }

// 主函数 :数据存储及命令解析

//数据字节的写入 void main() {

uint i; Init(); //初始化 while(1) { if(read_flag) { read_flag=0; //清除串口接收状态标志位 Rec_Flag=0; if(order_eraser) //预留EEPROM擦除命令入口 { order_eraser=0; IapEraseSector(IAP_ADDRESS1);//擦除EEPROM for(i=0;i<512;i++) {

if(IapReadByte(IAP_ADDRESS1+i)==0xff) //擦除成功判断 OK_flag1=1; else OK_flag1=0;

}

IapEraseSector(IAP_ADDRESS3);//擦除EEPROM for(i=0;i<512;i++) {

if(IapReadByte(IAP_ADDRESS3+i)==0xff) //擦除成功判断 OK_flag2=1; else OK_flag2=0;

} if((OK_flag1==1)&&(OK_flag2==1)) //擦除成功返回0xff { OK_flag1=0; OK_flag2=0; HexUartSend(ok); } else HexUartSend(error);//擦除不成功返回0xee }

if(order_read) //执行读取命令,并发送数据 { // 发送数据帧:0xaa 0xab 0xaa 0xab 0x00 数据存储帧总包长 数据包类型 数据包(长度根据数据类型来判断) 0xee 0xee uchar Send_Head0; } } }

uchar Send_Head1; uchar Data_length1; uchar Data_length2; Send_Head0=0xaa; Send_Head1=0xab; Data_length1=0x00; Data_length2=Rec_len+9; order_read=0; switch(Addr) //地址解析 { case 0x01: Address=IAP_ADDRESS1;break; case 0x02: Address=IAP_ADDRESS2;break; case 0x03: Address=IAP_ADDRESS3;break; case 0x04: Address=IAP_ADDRESS4;break; } HexUartSend(Send_Head0); HexUartSend(Send_Head1); HexUartSend(Send_Head0); HexUartSend(Send_Head1); //发送帧头字节 HexUartSend(Data_length1); HexUartSend(Data_length2); //发送二字节的数据包长 HexUartSend(Addr); //发送数据地址信息 for(i=0;i

51单片机串口数据分包.doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:《兵车行》教学实录

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: