在上下位机的串口通讯中,数据传送协议是十分重要的。能不能准确找到一帧数据的帧头数据是保证能否正确建立数据传送的根本保证。
实验总结了一个相对简单的办法,没有复杂的搜寻办法,但是很实用。
大概的思想是假设数据帧的长度是30个字节(包含了帧头帧尾),那么上位机端放进来的缓存数据长度就设置成为60字节,两倍的关系。然后要做的工作是在前30个字节中搜寻数据帧头的位置,采用循环搜寻的办法。当找到帧头的首字节位置后,另外经判断帧头数据正确无误,那么就可以记住帧头首字节的地址了,然后相对于既定的位置关系确定每一位的具体含义。
1 void checkFrame(Byte[] Rev) 2 { 3 int header = 0; 4 int headerFlag = 0; 5 for (int i = 0; i < 50; i++) 6 { 7 if (Rev[i] == '$' && Rev[i + 1] == 'G' && Rev[i + 2] == 'P' && Rev[i + 3] == 'R' && Rev[i + 4] == 'M' && Rev[i+5] == 'C') 8 { 9 if (Rev[i + 17] == 'A' && Rev[i + 30] == 'N' && Rev[i + 44] == 'E')10 {11 header = i;12 headerFlag = 1;13 break;14 }15 }16 }17 if (headerFlag == 1)18 {19 try20 {21 string str = Encoding.ASCII.GetString(Rev);22 23 string UTC = str.Substring(header + 7, 9);24 string Latitude = str.Substring(header + 19, 10);25 string Longitude = str.Substring(header + 32, 11);26 27 Double UTC_Value = Convert.ToDouble(UTC);28 Double Latitude_Value = Convert.ToDouble(Latitude);29 Double Longitude_Value = Convert.ToDouble(Longitude);30 31 //处理UTC时间信息32 int UTC_HH = (int)(UTC_Value / 10000) + 8;33 int UTC_MM = (int)(UTC_Value % 10000 / 100);34 int UTC_SS = (int)(UTC_Value % 100);35 36 textBox1.Text = UTC_HH.ToString() + "时" + UTC_MM.ToString() + "分" + UTC_SS + "秒";37 toolStripLabel1.Text = UTC_HH.ToString() + "时" + UTC_MM.ToString() + "分" + UTC_SS + "秒";38 39 //处理纬度信息40 int LatDu = (int)(Latitude_Value / 100);41 int LatFen = (int)(Latitude_Value % 100);42 int LatInt = (int)(Latitude_Value);43 Double LatMiao = (Double)((Latitude_Value - LatInt) * 60);44 string LatMiaoStr = LatMiao.ToString();45 LatMiaoStr = LatMiaoStr.Substring(0, 5);46 47 //实际的纬度信息值48 Double LatActVal = (Double)(LatDu + (Double)((double)LatFen / 60) + (Double)((double)LatMiao / 3600));49 50 //处理经度信息51 int LongDu = (int)(Longitude_Value / 100);52 int LongFen = (int)(Longitude_Value % 100);53 int LongInt = (int)(Longitude_Value);54 Double LongMiao = (Double)((Longitude_Value - LongInt) * 60);55 string LongMiaoStr = LongMiao.ToString();56 LongMiaoStr = LongMiaoStr.Substring(0, 5);57 58 //实际的经度信息值59 Double LongActVal = (Double)(LongDu + (Double)((double)LongFen / 60) + (Double)((double)LongMiao / 3600));60 61 textBox2.Text = LongDu.ToString() + "度" + LongFen.ToString() + "分" + LongMiaoStr + "秒";62 textBox3.Text = LatDu.ToString() + "度" + LatFen.ToString() + "分" + LatMiaoStr + "秒";63 64 this.BeginInvoke(new UpdateStatusDelegate(UpdateStatus), new object[] { LongActVal.ToString(), LatActVal.ToString() });65 }66 catch67 { 68 69 }70 }71 }