最近用VC在写一个Activex小项目。其实是操作串口,通过硬件读取串口数据,然后把数据上传到B/S平台。
从串口读到数据如下:
0003FE4500000000004000F81E
A8000000
838BE614
0080000000000000
01803804A9A10100
02803A0733F10200
0380000000000000
0480000000000000
0580000000000000
204E0000E8030000
0D0A7265733D323530283130305229
从这一串数据来看,完全不知是什么东西,也不知道个所以然。
拿到硬件协议对比。
对数据包进行解包
0003FE4500000000004000F81E 这一串代表包头。
其中
0003FE:代表包的标识和方向,从下位机到上位机。
4500:代表命令
00000000:代表命令参数
4000:代表包长度
F8:代表包头检验和
1E:代表包数据部分检验和
包数据分析
A8:列号
00:检测项目代号
0000:空白对照值
838BE614:检测日期时间
0080000000000000:第一通道数据
01803804A9A10100:第二通道数据
02803A0733F10200:第三通道数据
0380000000000000:第四通道数据
0480000000000000:第五通道数据
0580000000000000:第六通道数据
204E0000E8030000:补充数据(包尾补充数据)
0D0A7265733D323530283130305229 这一串完全是没用数据。相当于无效数据返回的特征码
这样一分析下来清晰多了。可还是不能知道具体什么东西。
那么接下来的工作就是数据转换和处理
由于数据存储是采用小端模式的,即是低位放在前面,高位放在后面。
对于包头不用做太多的处理,只是数据据检验和没有问题即可。
对于数据包的数据部分。即是我们想要得的有效数据,要做重点处理
看日期时间串:838BE614
要把一子串解释成有效易懂的日期时间字符串如:2010-01-01 30:20:12等
那么下面看一段处理代码。
//时间日期处理代码片段
CString checkDate ;//存储日期时间字符串
CString str1,str2,str3,str4,str5,str6;//中间处理过程临时变量
UINT utDate=0;
BYTE by[4];//转化为字节数组
for(int k=0;k<checkDate.GetLength();k++)
{
str1=checkDate.Mid(k*2,2);
sscanf(str1,"%02X",&by[k]);
}
utDate=by[0]|(by[1]<<8)|(by[2]<<16)|(by[3]<<24);//高位/低位转换
str1.Format("%d",(utDate>>25)&0x7f);//year
str2.Format("%d",(utDate>>21)&0x0f);//month
str3.Format("%d",(utDate>>16)&0x1f);//day
str4.Format("%d",(utDate>>11)&0x1f);//hour
str5.Format("%d",(utDate>>5)&0x3f);//minute
str6.Format("%d",(utDate<<1)&0x3f);//second
checkDate=str1+"-"+str2+"-"+str3+" "+str4+":"+str5+":"+str6;//得到例如 10-3-2 30:1:33 的结果
COleDateTime dtStart;
dtStart.ParseDateTime(checkDate);//标准格式化日期时间
checkDate=dtStart.Format("%Y-%m-%d %H:%M:%S");//得到最后标准输出的格式
其他数据处理不多说了。。。
看似简单的一串东西,要它变成有用的数据,还是真是经过几番周折的。。。。
VC俺是菜鸟,很多东西是摸着石头过河。经过几番瞎折腾,总算也能完成任务。。。