文章目錄
- 背景
- 協議補充說明
- 如何用代碼求解
- 嘗試窮舉尋找規律
- 經人指點得到良方
背景
做上位機開發時,上位機和下位機如何進行通訊,一般取決于下位機,有這樣一個通信協議:
- 當上位機給下位機發送 19 02 01 時,代表讀故障碼
- 當下位機回應 59 02 01 DD 時,代表肯定回應,其中 DD 代表故障碼
- 故障碼用4個位元組表示
- 每一幀資料為8個位元組
- 當無故障碼或僅有一個故障碼時,一個資料幀8個位元組就夠了
- 當無故障碼或僅有一個故障碼時,第一個位元組代表有效位元組資料長度
例如:03 59 02 01 FF FF FF FF 這一幀,03代表有效位元組資料長度,其中有效位元組資料為 59 02 01 - 當有多個故障碼時,首幀的第二個位元組代表有效位元組資料長度,第一個位元組10標識該資料幀為首幀
- 當有多個故障碼時,從首幀第二個位元組可得知有多少個有效位元組資料長度,例如十六進制的 0B 代表 11 個有效位元組資料長度
- 當有多個資料幀時,需要發送 30 00 14 來請求 連續幀
- 當發送 30 00 14 時,下位機回應連續幀,如:21 09 84 02 05 09 FF FF ,其中 21 表示第一個連續幀(在僅有兩個資料幀的情況下,第一個連續幀,代表第二幀資料)
那么問題來了,當上位機給下位機發送 19 02 01 讀故障碼時,如何讀出所有故障碼呢?換句話說,在有多個故障碼的前提下,如何根據首幀的第二個位元組,來計算有多少個資料幀或者連續幀呢?
注意:之所以要計算有多少個資料幀或連續幀,是因為要根據這些幀,來回圈請求接下來要回應的資料,從而得到完整的故障碼資料
協議補充說明
描述的有點晦澀難懂,我舉個例子,當設備有兩個故障碼時(注意這里已經告訴你有多個了,實際情況下,需要我們計算,應該有多少個故障碼和資料幀):
- 上位機給下位機發送:03 19 02 01 FF FF FF FF 讀故障碼
- 下位機回應的資料幀:10 0B 59 02 01 83 02 05,由該資料幀的第一和第二個位元組可知,需要多個資料幀來回應故障碼,其中有效位元組資料長度為 0B ,即 11 個有效位元組長度
- 上位機給下位機發送:30 00 14 FF FF FF FF FF 請求第一個連續幀(在這個例子里總共就兩幀資料)
- 下位機回應的資料幀:21 09 84 02 05 09 FF FF,(因為這個例子里,總共就兩個故障碼,需要占用8個位元組,所以這里是第一個連續幀,也就是第二幀資料,也是最后幀資料)
我們根據協議來觀察,下位機回應的首幀資料 10 0B 59 02 01 83 02 05 中,10 代表首幀標識,0B 代表有效位元組資料長度,也就是十進制的 11,這里的有效位元組資料長度指的是:59 02 01 83 02 05 09 84 02 05 09 ,
注意:第一個連續幀(也就是第二幀,也是最后一幀)的第一個位元組,不算做有效位元組資料,它算作連續幀的標識,21 代表第一個連續幀,假如是 22 則代表第二個連續幀,以此類推,
那么我們得知了有效位元組資料是:59 02 01 83 02 05 09 84 02 05 09 ,根據協議,一個故障碼4個位元組,除去開頭的肯定回應 59 02 01 外,那么第一個故障碼為 83 02 05 09 ,第二個故障碼為 84 02 05 09 ,
如何用代碼求解
根據上述的舉例說明,應該對上位機下位機通訊的協議,有了一定的了解,在此基礎上,請你求出有多少個資料幀或連續幀,并且求出有多少個故障碼,每個故障碼是什么,以及如何用代碼解決這些問題?
嘗試窮舉尋找規律
我試圖嘗試用窮舉法來找尋規律以解決該問題,假設我們羅列處十個資料幀的資料,如下:

假設當有2個故障碼的情況下,我數了一下共有11個有效位元組長度,實際回應的位元組則有14個,此時需要兩個資料幀來傳輸,以此類推,
我苦思冥想,但似乎沒有規律可循?看到這里你是否有了答案?別著急先想想,再往下看,
經人指點得到良方
這樣一個小問題,竟然困擾我將近兩個小時之久,實在尋不到答案,遂找他人尋求幫助,經過高人指點,我發現我似乎遺漏了一個重要的問題,那就是:在有多幀資料的情況下,首幀資料的有效位元組長度為 6(除去首幀的第1、2個位元組,還剩下6個位元組),
還有重要的一點,我似乎在通過尋找規律,來求出所有的資料幀,這一點思路不太正確,實際上,我只需要求出有多少個連續幀就可以了,因為有多少個連續幀,才真正是我要回圈發送請求連續幀的次數!!
那么答案就出來了,想要求出有多少個連續幀,有兩種情況:
-
(首幀第二個位元組代表的有效位元組資料長度 - 6)% 7 = 0 的情況下
連續幀個數 = (首幀第二個位元組代表的有效位元組資料長度 - 6)/ 7 -
(首幀第二個位元組代表的有效位元組資料長度 - 6)% 7 > 0 的情況下
連續幀個數 = (首幀第二個位元組代表的有效位元組資料長度 - 6)/ 7 + 1
注意:之所以要除以7,是因為,連續幀的第一個位元組,不是有效位元組資料
可以驗證一下,當首幀第二個位元組為 0x23 也就是十進制的 35 時,有效位元組長度為 35 個,通過上述的公式計算出 連續幀個數 = (35 -6)/ 7 = 4.1 ,所以需要 5 個連續幀,
通過下面的圖片我們數一下,進行驗證發現,確實需要5個連續幀:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/301240.html
標籤:其他
