最近用VC在写一个Activex小插件。其实是操作串口数据通信,通过某个硬件读取串口数据,然后把数据上传到B/S平台。仪器硬件底层是用C语言编写,具体怎么写法,不是我重点关注的东西,我主要负责仪器与PC接口的开发。
每一个原器件的串口通讯都有一套协议,这个协议是由硬件方定制提供。
声明:在这里只希望通过博客日志记录的方式总结记录一点东西,以方便本人总结一下,希望各路高手们不要取笑,如果你有更好建议请给我留言,非常感谢!
下面插件读取的数据进行一个简单的分析,
从串口读到数据如下:
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]);//转为by[]
}
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俺是菜鸟,很多东西是摸着石头过河。经过几番瞎折腾,总算也能完成任务。。。