51 單片機(jī)串行通訊中波特率的自動(dòng)檢測(cè)
本文介紹一種在 80C51 串行通訊應(yīng)用中自動(dòng)檢測(cè)波特率的方法。按照經(jīng)驗(yàn),程序起動(dòng)后所接收到的第1個(gè)字符用于測(cè)量波特率。
這種方法可以不用設(shè)定難于記憶的開關(guān),還可以免去在有關(guān)應(yīng)用中使用多種不同波特率的煩惱。人們可以設(shè)想:一種可靠地實(shí)現(xiàn)自動(dòng)波特檢測(cè)的方法是可能的,它無須嚴(yán)格限制可被確認(rèn)的字符。問題是:在各種的條件下,如何可以在大量允許出現(xiàn)的字符中找出波特率的定時(shí)間隔。
顯然,最快捷的方法是檢測(cè)一個(gè)單獨(dú)位時(shí)間(single bit time),以確定接收波特率應(yīng)該是多少??墒?,在 RS-232 模式下,許多 ASCII 字符并不能測(cè)量出一個(gè)單獨(dú)位時(shí)間。對(duì)于大多數(shù)字符來說,只要波特率存在合理波動(dòng)(這里的波特率是指標(biāo)準(zhǔn)波特率),從起始位到最后一位“可見”位的數(shù)據(jù)傳輸周期就會(huì)在一定范圍內(nèi)發(fā)生變化。此外,許多系統(tǒng)采用 8 位數(shù)據(jù)、無奇偶校驗(yàn)的格式傳輸 ASCII 字符。在這種格式里,普通 ASCII 字節(jié)不會(huì)有 MSB 設(shè)定,并且,UART總是先發(fā)送數(shù)據(jù)低位(LSB),后發(fā)送數(shù)據(jù)高位(MSB),我們總會(huì)看見數(shù)據(jù)的停止位。
在下面的波特率檢測(cè)程序中,先等待串行通訊輸入管腳的起始信號(hào)(下降沿),然后起動(dòng)定時(shí)器T0。在其后的串行數(shù)據(jù)的每一個(gè)上升沿,將定時(shí)器 T0的數(shù)值捕獲并保存。當(dāng)定時(shí)器T0溢出時(shí),其最后一次捕獲的數(shù)值即為從串行數(shù)據(jù)起始位到最后一個(gè)上升沿(我們假設(shè)是停止位)過程所持續(xù)的時(shí)間。
CmpTable 表格列出了每一波特率的最大測(cè)量時(shí)間。這些數(shù)據(jù)是經(jīng)過選擇的,所以,4 個(gè)數(shù)據(jù)位時(shí)間(加上起始位時(shí)間)仍可產(chǎn)生正確的波特率。
使用這種方法時(shí),必須遵守一個(gè)假設(shè):這種技術(shù)僅取決于所接收到的一個(gè)字符,接收這個(gè)字符的波特率必須大于最低波特率。本質(zhì)上來說,這意味著這個(gè)字符必須來自正常敲擊鍵盤時(shí)所產(chǎn)生的字符。
在PC上,我們不可能快速、連續(xù)地敲擊兩個(gè)字符,以欺騙程序。但是,PC的功能鍵具有一個(gè)問題,因?yàn)樗鼤?huì)連續(xù)發(fā)送兩個(gè)緊挨著的字符,使程序檢測(cè)得到錯(cuò)誤的波特率。在為 12MHz時(shí)鐘頻率而設(shè)計(jì)的的例子程序中,其總采樣時(shí)間大約為 65mS,大約可以在 RS-232 通訊中以300bps的速度發(fā)送兩個(gè)字符。
假如使用了奇偶校驗(yàn),當(dāng)4 個(gè)MSB以及所接收字節(jié)的奇偶校驗(yàn)位均這同一值時(shí),就可能會(huì)發(fā)生錯(cuò)誤。這類錯(cuò)誤的發(fā)生取決于系統(tǒng)是使用了奇校驗(yàn)或偶校驗(yàn),可能發(fā)生于小寫的字母“p”到“z”,還有花括號(hào)({})、垂直條(|)、波紋線(~),以及刪除鍵“delete”。值得注意的是,慣常的提示符按鍵(如,空格鍵、回車鍵、及返回鍵),是沒有這些限制的(奇數(shù)還是偶數(shù)的限制?)。
在以此方式運(yùn)行程序時(shí),如第一個(gè)字節(jié)已經(jīng)過去,但串行口(UART)的波特率未能正確設(shè)置,那將造成用于檢測(cè)波特率的第一個(gè)字符丟失。同樣,如果在正常通訊中檢測(cè)到串行口的通訊“幀”錯(cuò)誤,絕大部分“實(shí)時(shí)”程序必須重復(fù)這一檢測(cè)波特率的過程。
如需采用另外設(shè)定的晶體振蕩頻率、波特率,請(qǐng)使用下列公式計(jì)算 CmpTable的表項(xiàng)目:
記住,表項(xiàng)目是兩個(gè)字節(jié)的數(shù)值,所以上述公式的結(jié)果一定要分成高位字節(jié)及低位字節(jié)(如果采用十六進(jìn)制,則容易得出高位、低位字節(jié))。當(dāng)然,也可以用匯編程序來完成所有的運(yùn)算。
上述的公式是由以下得來的:
備注:在 8-N-1 格式的數(shù)據(jù)通訊中,‘#-of-bits’(“可見”位數(shù))是 9,以及‘bits-to-recognize’(最小認(rèn)可位數(shù))是5。
;**********************************************
;自動(dòng)的波特率檢測(cè)程序
;**********************************************************
$ Title(Automatic Baud Rate Detection Test)
$ Date(12–16–91)
$ MOD552
;*******************************************************
; Definitions
;*************************************************
RX BIT P3.0 ;串行口的接收管腳
CharH DATA 30h ;捕獲定時(shí)器T0的高位字節(jié)
CharL DATA 31h ;捕獲定時(shí)器T0的低位字節(jié)
BaudRate DATA 32h ;存貯最終確定的波特率
Display EQU P4 ;顯示結(jié)果的端口
;*******************************************************
; Reset and Interrupt Vectors
;***************************************************
ORG 8000h
Start: ACALL AutoBaud ;檢測(cè)波特率
MOV Display, BaudRate ;顯示波特率值
SJMP Start
;**********************************************************
; Subroutines
;**********************************************************
;AutoBaud Rate Detect Routine.
;通過測(cè)量接收第一個(gè)字符所需要的時(shí)間來確定波特率。部分接收字符可能會(huì)發(fā)生錯(cuò)誤,
;主要是那些以3(4?)位同樣數(shù)值結(jié)束的字符。波特率指針(檢測(cè)結(jié)果)保存在ACC中。
;********************************************************
評(píng)論