串口通訊你真的會了嗎?不妨看看這些經(jīng)驗(yàn)

平時(shí)使用串口打印出現(xiàn)亂碼的絕大部分原因是串口波特率沒對。那么我們怎么測量實(shí)際的波特率呢?在這之前,順便一起回顧一下波特率的概念。

什么是波特率、比特率?

  • 比特率(Bitrate)表示每秒鐘傳輸?shù)?code>二進(jìn)制位數(shù),單位為比特每秒(bit/s)。

  • 波特率(Baudrate)表示每秒鐘傳送的碼元符號的個(gè)數(shù),是衡量數(shù)據(jù)傳送速率的指標(biāo)。

  • 碼元是通訊信號調(diào)制的概念,通訊中常用時(shí)間間隔相同的符號來表示一個(gè)二進(jìn)制數(shù)字,這樣的信號稱為碼元。

常見的通訊傳輸中,用 0V 表示數(shù)字 0, 5V 表示數(shù)字 1,那么一個(gè)碼元可以表示兩種狀態(tài) 0 和 1,所以一個(gè)碼元等于一個(gè)二進(jìn)制比特位,此時(shí)波特率的大小與比特率一致。

如果在通訊傳輸中,有 0V、2V、 4V 以及 6V 分別表示二進(jìn)制數(shù) 00、 01、 10、 11,那么每個(gè)碼元可以表示四種狀態(tài),即兩個(gè)二進(jìn)制比特位,所以碼元數(shù)是二進(jìn)制比特位數(shù)的一半,這個(gè)時(shí)候的波特率為比特率的一半。

因?yàn)楹芏喑R姷耐ㄓ崳?code>比如串口通訊)中一個(gè)碼元都是表示兩種狀態(tài),所以大家常常直接以波特率來表示比特率 。

串口通訊協(xié)議

在串口通訊的協(xié)議層中,規(guī)定了數(shù)據(jù)包的內(nèi)容,它由啟始位、主體數(shù)據(jù)、校驗(yàn)位以及停止位組成,通訊雙方的數(shù)據(jù)包格式要約定一致才能正常收發(fā)數(shù)據(jù),其數(shù)據(jù)幀組成如下:

001.png

下面我們來實(shí)際驗(yàn)證一下其數(shù)據(jù)幀是不是真的是這樣的。編寫如下代碼:

002.png

代碼很簡單,就是使用串口不斷地往外發(fā)數(shù)據(jù)0xAA(當(dāng)然發(fā)送其它數(shù)據(jù)也是可以的) 。我們的串口配置如下:

003.png

我們可以使用示波器或者邏輯分析儀抓取實(shí)際信號看看數(shù)據(jù)是不是符合上面的幀格式。這里,我們使用邏輯分析儀抓取USART1的發(fā)送信號線(TX)

004.png

從實(shí)際結(jié)果中我們可以看到的確是按幀格式來發(fā)的。這里可能會有人有疑問,上面那個(gè)數(shù)據(jù)幀的圖片中有個(gè)空閑狀態(tài),這個(gè)又是什么呢?空閑、空閑,當(dāng)然是沒有在發(fā)數(shù)據(jù)時(shí)候的狀態(tài)呀,我們把我們的代碼改為:

009.png

在初始化完成之后只發(fā)送一次0xAA,邏輯分析儀抓到的數(shù)據(jù)為:

010.png

可見,空閑狀態(tài)是個(gè)高電平。在上一個(gè)的范例中,我們一直在while循環(huán)中發(fā)送數(shù)據(jù)0xAA,所以就沒有空閑狀態(tài)。

在這個(gè)實(shí)驗(yàn)中我們需要知道的是兩個(gè)點(diǎn)是:

  • 串口發(fā)送數(shù)據(jù)是低位先發(fā)的。我們單片機(jī)發(fā)0xAA(10101010B),所以邏輯分析儀抓到的有效數(shù)據(jù)是01010101B。

  • 單片機(jī)的串口使用的是TTL電平,為正邏輯電平信號。邏輯分析儀抓到的數(shù)據(jù)0對應(yīng)著實(shí)際電壓0~0.5V,數(shù)據(jù)1對應(yīng)著實(shí)際電壓2.4V-5V,

經(jīng)常與TTL電平標(biāo)準(zhǔn)做對比的是RS-232電平標(biāo)準(zhǔn),如:

005.png

常見的電子電路中常使用 TTL 的電平標(biāo)準(zhǔn),理想狀態(tài)下,使用 5V 表示二進(jìn)制邏輯 1,使用 0V 表示邏輯 0;而為了增加串口通訊的遠(yuǎn)距離傳輸及抗干擾能力,RS-232電平標(biāo)準(zhǔn)使用-15V 表示邏輯 1, +15V 表示邏輯 0。

在舊式的臺式計(jì)算機(jī)中一般會有 RS-232 標(biāo)準(zhǔn)的 COM 口(也稱 DB9 接口) :

006.png

在這個(gè)示例程序中,我們設(shè)置的串口波特率為115200bps。在串口通訊中,碼元只用1個(gè)二進(jìn)制數(shù)來表示(即只有0 和 1兩種狀態(tài)),所以波特率與比特率在數(shù)值上是相等的。而比特率表示的是每秒鐘傳輸?shù)?code>二進(jìn)制位數(shù),那我們知道傳一位數(shù)據(jù)的時(shí)間豈不是就可以反推出波特率是多少了嗎?從邏輯分析儀中,我們可以知道發(fā)送一位數(shù)據(jù)的時(shí)間如下:

007.png

發(fā)送一位數(shù)據(jù)的時(shí)間大約為8.667us,所以1秒鐘發(fā)送多少位數(shù)據(jù)是可以算出來的:
1000000/8.667 = 115380
算出來的波特率為115380bps,與115200bps很相近。最終肯定是有一定的誤差,這個(gè)誤差產(chǎn)生的原因包括邏輯分析儀的質(zhì)量及我們的測量環(huán)境等等因素。但是這個(gè)誤差也是在允許的范圍內(nèi)的,可以看看串口助手接收到的數(shù)據(jù)是不是正確的:

008.png

可見,數(shù)據(jù)接收正確,也就是波特率對的上了。

串口波特率對不上怎么解決?

在實(shí)際中。我們可能會遇到這樣的情況,代碼里配置的波特率與串口助手上設(shè)置的波特率一樣了,但還是出現(xiàn)異常。

異常情況如我們往串口助手發(fā)送字符串,串口助手上本該顯示的字符串出現(xiàn)了亂碼?;蛘呶覀兺谥职l(fā)送一個(gè)數(shù)據(jù),發(fā)現(xiàn)數(shù)據(jù)移位了。

出這種情況大多是波特率對應(yīng)不上,我們就得自己檢查我們的底層文件了,代碼中的某個(gè)與波特率計(jì)算相關(guān)的值(時(shí)鐘)與實(shí)際不匹配了,就會出現(xiàn)這樣的現(xiàn)象,比如之前我的一位同事就遇到這樣的情況就是這個(gè)原因?qū)е碌摹?/p>

我們用STM32的時(shí)候,一般都是使用外部晶振,比如STM32F103系列,可輸入的外部晶振的范圍是4~16MHz

011.png

經(jīng)驗(yàn)值往往是8MHz,而且一般的demo工程底層代碼里默認(rèn)的也是設(shè)置為8MHz,比如:

012.png

但是,如果實(shí)際晶振貼的不是8MHz的話,就出問題了(比如串口波特率就不正確了)。追根溯源,串口波特率是配進(jìn)USART_Init函數(shù)中的,打開這個(gè)函數(shù):

013.png

計(jì)算串口波特率需要一個(gè)apbclock變量,而這個(gè)值得來源從RCC_GetClocksFreq函數(shù)來,再打開這個(gè)函數(shù):

014.png

所以要注意的是,HSE_VALUE這個(gè)值要與實(shí)際做對應(yīng)。

遇到這種問題找誰說理去。。經(jīng)驗(yàn)就是不斷采坑不斷積累的一個(gè)過程,早點(diǎn)遇到坑可能也是一件好事。像類似底層的問題很少遇到,但是一旦遇到那就得比較棘手的問題了,需要很有耐心地去查找。

能用穩(wěn)定的芯片是一件很幸福的事情,用不穩(wěn)定、不成熟的芯片的時(shí)候,那個(gè)才是真的難啊,真讓人懷疑人生啊。。。

以上就是本次的筆記分享,希望各位喜歡!如有錯(cuò)誤歡迎指出,謝謝!

原創(chuàng)不易,希望能得到各位的支持,順手轉(zhuǎn)發(fā)、在看,謝謝!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 期末慶典。一完畢之后,我和媽媽立馬上了車,向西安飛機(jī)場開去。 心想“這一次體驗(yàn)拍戲會不會有意外的收...
    足球大俠張博棟閱讀 273評論 0 0
  • 平靜從我開始~ 最近在覺察自己~我是不是個(gè)女人,原來需要堅(jiān)強(qiáng),需要隱忍,需要強(qiáng)顏歡笑,需要硬撐著。如今自己感覺一下...
    梅心梅肺_c708閱讀 675評論 1 2
  • 五言格律會寫不?反正我是不會,但是我會拆臺,要稱五言格律得做到以下八點(diǎn)。相信我,我是中文系的娃,親生的。 ...
    江南老少女閱讀 1,258評論 0 0
  • 01 真的嗎? 以前看偶像劇時(shí),看到英俊帥氣多金的男主這么深情款款地說,我都覺得特別感動(dòng)。你想啊,這個(gè)世界上有那么...
    靈林玖玖閱讀 1,061評論 17 14
  • 晚上還是忍不住咳,我打算煮碗肉湯喝了藥就睡了。今天藥房的導(dǎo)購讓我不要吃牛羊肉,但我昨天已經(jīng)買了,她說那就只吃肉,別...
    郝晶讀書會閱讀 559評論 7 12

友情鏈接更多精彩內(nèi)容