UART全稱Universal Asynchronous Receiver/Transmitter,通用異步收發器,是一種非常常見的異步收發協議,在嵌入式領域應用十分廣泛。收發雙方按照約定好通訊波特率進行配置,如果波特率不匹配會導致失敗。
2、分頻與波特率
使用單片機的朋友,經常使用4800、9600、38400、115200等波特率。設計電路時經常采用11.0592Mhz這樣“不規則”晶振,看起來不規則,實際上很規則,原因是可以精確分頻成常用波特率。
11.0592MHz=11059200=115200*96
11.0592MHz=11059200=57600*192
11.0592MHz=11059200=19200*576
有細心的朋友經常采用11.0592Mhz晶體設計電路,調試完串口通訊之后更換為12MHz后單片機依然能夠正常通訊,并沒有出現通訊異常。可見波特率有少許誤差也是能夠容忍的。
3、串口如何采樣
串口接收方,在收到起始位后,延時1.5個位周期進行第1位采樣,然后依次隔一個位周期采樣一位,直至把所有數據位采樣完成。如果接收方采樣位置正好在數據位的中間位置,那么采樣非常完美,不會出現問題。以下是8bit串口通訊數據格式示意圖。
注意,這里的采樣并不是只采樣一次,有些芯片會采樣多次,這里僅做示意。
4、誤差原因
如果接收方位周期略微大于發送方位周期,就會出現下圖所示的情況。采樣位置逐漸偏移數據位中心,bit7采樣位置偏移最嚴重。這就是波特率誤差。采樣點移位過多就會導致位錯誤,導致通訊失敗。當然如果接收方位周期略微小于發送方位周期,也是同樣道理。一般測特率誤差2%-3%是沒有問題的。
5、舉例
筆者正在使用的某款cortex-M3內核芯片,需求的波特率是460800bps。串口時鐘頻率是36MHz。此款芯片波特率配置方法是串口時鐘頻率除以16,再除以分頻因子。計算出分頻因子(分頻因子只能是整數),然后寫入相應寄存器即可。算來算去,無論如何計算都不能準確分頻出460800bps。按照如下代碼計算出的分頻因子是4。然后反推出波特率是562500bps,整除失去了小數位,導致差距巨大,根本無法通訊。
// baud rate = (serial clock freq) / (16 * divisor).
tmpBaudRateDiv = (clocks.PCLK_Frequency / 16) / UART_InitStruct->UART_BaudRate;
于是乎做了個優化,如下代碼,計算出的分頻因子是5。然后反推出波特率是450,000bps,差距比較小,測試了一下通訊性能沒問題。
// baud rate = (serial clock freq) / (16 * divisor).
tmpBaudRateDiv = ((clocks.PCLK_Frequency / 16) + UART_InitStruct->UART_BaudRate / 2) / UART_InitStruct->UART_BaudRate;
6、不建議串口高速使用
串口畢竟是一個低速的數據傳輸協議,這種異步傳輸,沒有時鐘同步信號,在傳輸的每個字節中采樣有誤差積累,不建議高速使用,筆者使用過幾種高波特率460800、921600、1500000等。原因是低端的單片機主頻速率較低,處理高速數據流效率低下,如需高速使用,可根據自己需求開啟串口FIFO、串口DMA、串口流控等。
-
嵌入式
+關注
關注
5082文章
19126瀏覽量
305201 -
晶振
+關注
關注
34文章
2866瀏覽量
68036 -
串口
+關注
關注
14文章
1554瀏覽量
76517 -
uart
+關注
關注
22文章
1235瀏覽量
101395 -
波特率
+關注
關注
2文章
307瀏覽量
34142
發布評論請先 登錄
相關推薦
評論