最近用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俺是菜鳥,很多東西是摸著石頭過河。經過幾番瞎折騰,總算也能完成任務。。。