??
字號(hào):
C51編程:串口數(shù)據(jù)收發(fā)的算法問題 [lemonskin] [89次] 01-6-6 上午 09:55:30
C51單片機(jī)在同PC機(jī)進(jìn)行串口通信時(shí)所采用的數(shù)據(jù)包協(xié)議如下所示:(以字節(jié)為單位)
消息類型(有限個(gè)消息代號(hào))
消息長度(高字節(jié))
消息長度(低字節(jié))
消息內(nèi)容(消息長度所指示的字節(jié)數(shù))
校驗(yàn)字(從消息類型開始到消息內(nèi)容結(jié)束所有字節(jié)的按位異或值)
串口速率4800bps
現(xiàn)在有下面兩種算法可供采用:
1.超時(shí)(超長)廢棄
使用單個(gè)的數(shù)據(jù)緩沖區(qū),長度稍大于所有消息中的最大長度。首先初始化串口的狀態(tài)為
等待態(tài),發(fā)生串口中斷時(shí)狀態(tài)轉(zhuǎn)移到接受態(tài),判斷一個(gè)消息包結(jié)束的標(biāo)志是接收到的字節(jié)數(shù)
等于消息長度所指示的字節(jié)數(shù),這時(shí)狀態(tài)轉(zhuǎn)移到結(jié)束態(tài)。在程序的主循環(huán)中有一個(gè)函數(shù)用來
檢驗(yàn)并處理接收到的一個(gè)完整的數(shù)據(jù)包,只有當(dāng)狀態(tài)處在結(jié)束態(tài)時(shí),才進(jìn)行數(shù)據(jù)包的類型和
校驗(yàn)字的檢驗(yàn),正確就繼續(xù)處理,否則將數(shù)據(jù)包廢棄掉,再把狀態(tài)該為等待態(tài)。同時(shí)在接受
數(shù)據(jù)時(shí)(處于接受態(tài)),預(yù)先設(shè)置的一個(gè)定時(shí)器開始計(jì)時(shí)。存在一個(gè)最大時(shí)間值用來反映可
能接受的最大的數(shù)據(jù)包所需要的時(shí)間,當(dāng)計(jì)數(shù)值超過了這一最大值也認(rèn)為消息包出錯(cuò)予以廢
棄,定時(shí)器清零,狀態(tài)仍然返回到等待態(tài)。
這一算法的優(yōu)點(diǎn)是處理實(shí)時(shí)性好,速度快,占用RAM空間少;缺點(diǎn)是可靠性不好,當(dāng)一
條消息出錯(cuò)時(shí),緊接著到來的下一條消息即使是正確的也很可能被廢棄掉。
2.緩存消息,逐個(gè)檢驗(yàn)
使用大量的空間(同時(shí)能容納很多條消息)組成循環(huán)消息隊(duì)列。只要發(fā)生串口中斷就保
存數(shù)據(jù)到隊(duì)列中(從隊(duì)尾插入)。主程序循環(huán)中有一個(gè)函數(shù)從隊(duì)列中取出數(shù)據(jù)(從隊(duì)頭取
出)進(jìn)行檢驗(yàn)。依次搜索每一個(gè)字節(jié),當(dāng)屬于某一種消息類型時(shí)再取出長度字段,按照長度
的指示尋找到校驗(yàn)字,正確就繼續(xù)處理,否則恢復(fù)原先的隊(duì)頭位置并后移一個(gè)字節(jié),繼續(xù)下
一輪消息頭的搜索。當(dāng)搜索成功或者當(dāng)隊(duì)列中的數(shù)據(jù)已經(jīng)少于最短消息的長度時(shí)退出函數(shù)。
這一算法的優(yōu)點(diǎn)是可靠性好,不易造成數(shù)據(jù)包的丟失;缺點(diǎn)是處理實(shí)時(shí)性不好,后臺(tái)PC
往往得不到及時(shí)的響應(yīng),另外當(dāng)遇到最壞的情況時(shí)付出的代價(jià)是相當(dāng)大的。當(dāng)隊(duì)列中存有大
量數(shù)據(jù)時(shí),如果一旦接收數(shù)據(jù)發(fā)生了失步(重新搜索消息頭),則必須逐字節(jié)的進(jìn)行檢測,
同時(shí)要是消息類型較多的話,執(zhí)行效率就更低了。
不知道大蝦們?cè)谔幚泶谕ㄐ艜r(shí)采用什么樣的算法,有什么好的經(jīng)驗(yàn)請(qǐng)多多傳授,在下
感激不盡,先行謝過。
我的方式 [yaodong_wu] [72次] 01-6-6 上午 10:40:44
對(duì)于比較簡單的應(yīng)用,我一般傾向于使用簡單的通信方式。
我的方式是:
1、通信協(xié)議
楨頭(一個(gè)或兩個(gè)固定的字節(jié)來表示一楨的開始)
信息類型
信息內(nèi)容
校驗(yàn)
這里去除了信息長度,每一楨采用固定的長度,可以防止由于信息長度接收錯(cuò)誤沖掉RAM
使用中斷的方式來檢測楨頭,檢測到楨頭后就進(jìn)入查詢接收狀態(tài),查詢接收時(shí)可以設(shè)一個(gè)超
時(shí)退出,防止等死,接收完一楨后校驗(yàn),正確就處理,不正確就退出
如果數(shù)據(jù)量不大的話,這樣做一般是可以接受的,并且簡單可靠
2、使用半雙工的通信方式
一般采用半雙工的通信方式,一方發(fā)出數(shù)據(jù)請(qǐng)求后,另一方在固定時(shí)間內(nèi)響應(yīng)請(qǐng)求,如果不
響應(yīng)請(qǐng)求方就放棄本次請(qǐng)求,轉(zhuǎn)入下一輪循環(huán)。也就是說,讓通信的發(fā)生是可預(yù)測的
你這個(gè)協(xié)議很合理,可惜我們單位已經(jīng)把協(xié)議固定下來了,沒辦法啦 [lemonskin] [6次] 01-6-6 上午 10:47:25
大家多出出主意嘛,串口通信的應(yīng)用應(yīng)該是很廣泛的。 [lemonskin] [11次] 01-6-6 下午 02:27:52
點(diǎn)擊這里回復(fù)這篇貼子>>
_____________________________________________________________________________
Copyright?,C51BBS論壇 2000-2001
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -