串列埠 接收端_硬核分析串列埠通訊協議
技術標籤:串列埠 接收端
串列埠通訊協議,基本上是每個微控制器開發人員必會的協議,是所有通訊協議裡面最最常用的。但是很多人並沒有去研究過細節,這篇文章乾貨滿滿,將帶你深入串列埠協議的內部。
1、串列埠協議簡介
什麼是串列埠通訊?
簡而言之,串列埠通訊就是通過一根導線(TX,只討論傳送,當然一定還包括GND),將需要的資料按bit流傳送給接收端,既然是通訊,參與的雙方當然要制定資料的傳輸方式以及規範。
隨便開啟一個串列埠助手都可以看到,如果需要使用串列埠就需要配置埠、波特率、資料位、停止位、校驗位、流控這些引數。
如果接收端和傳送端的設定不同,就可能會導致資料異常。
埠:這個就不用解釋了,使用串列埠晶片安裝驅動後就可以在電腦上看到埠號了。
現在,我們從電平訊號角度分析一下波特率、資料位、停止位、校驗位、流控(由於用的比較少,暫不分析)的作用。
2、電平訊號分析
開啟串列埠工具,分別調整如下引數
①調整引數9600/8/N/1,傳送十六進位制資料55 AA
②調整引數115200/8/N/1傳送十六進位制資料55 AA
③調整引數9600/7/N/1傳送十六進位制資料55 AA
④調整引數9600/8/O/1傳送十六進位制資料55 BA
⑤調整引數9600/8/E/1傳送十六進位制資料55 BA
⑥調整引數9600/8/N/2傳送十六進位制資料55 AA
其中B代表起始位,E代表停止位,很明顯看出是先傳輸的低bit,再傳輸的高bit。
根據①②分析,調整波特率並不會影響整體波形形狀,只有bit的持續時長不同,9600波特率時的一個bit大概佔104us,115200波特率大概是9us,這是可以算出來的9600:1000ms/9600 = 104.1us,115200:1000/115200=8.6us。分析可知波特率越大,傳輸速度越快。
根據①③分析,調整資料位後,55本來應該是01010101但是資料位調整到7之後,55變成了1010101,AA本來是10101010變成了0101010,分析可知錯誤的資料位會將傳輸的位元組從高位開始截斷,可能導致資料丟失。一般來說除非特殊需求,否則不會調整資料位引數。
根據①④⑤分析,將校驗位調整至奇校驗(ODD)後,傳輸的bit多了一個奇校驗位,就是說如果本來的8個bit的bit位按位加起來是偶數,則在最高位需要補一位1,否則補0,55傳輸變成了 (1)01010101,BA變成(0)10111010,同樣偶校驗(EVEN)、MASK校驗(校驗位始終為1)、SPACE校驗(校驗位始終為0)是相同的道理。
根據①⑥分析,將停止位設定為2後,傳輸的結束位(圖片中的E)變成之前的2倍,分析可知,設定停止位,可改變資料傳輸完成後的停止位bit持續的時間。
3、為什麼需要起始位和停止位?
波特率、資料位、校驗位很好理解,都是為了實現不同的業務需求,但是起始位和停止位存在的意義是什麼呢?
起始位:平時這根導線上是高電平,如果接收方檢測到低電平了,說明要開始接受資料了,是傳送方通知接收方開始接受的一種方式。(不考慮流控)
停止位:傳送方通知接收方傳送完成的一種方式。傳送方傳送完一個位元組後,“暫停一會”再繼續傳送下一個位元組。
這時帥氣的小夥伴就要問了,起始位存在的意義可以理解,但是為什麼需要停止位呢?不是提前都約定好了傳輸8個bit,接收方不能就接受到8個bit後認為一個位元組傳輸結束就OK了嗎?
能思考到這一步的小夥伴已經很棒了。如果我們是設計師,我們從設計的角度設計一下接收方接受資料的虛擬碼
//接收端接收資料執行緒
while(1) {
//接收到起始位下降沿電平
if((isGetStartFlag == 0) && getDownEdge()) {
Delayus(52);
//檢測起始位低電平
if(isLowPin()) {
isGetStartFlag = 1;
getBitIndex = 0;
}
}
//已經接收到起始位
if(isGetStartFlag) {
Delayus(104);
if(getHighOrLow() == high) {
//接收到1bit
}else {
//接收到0bit
}
getBitIndex++;
if(getBitIndex == 8) {
//位元組接收完成
isGetStartFlag = 0;
getBitIndex = 0;
}
}
}
按照這種虛擬碼邏輯,如果不存在停止位,會產生兩個問題。
1、可能無法檢查下降沿
如果上一個位元組最後一次傳輸是0,而下一個位元組的起始位也是0,那麼下一個位元組的起始位就檢測不到下降沿,無法觸發下一個位元組的傳輸,就會丟失資料。這時帥氣的小夥伴又要問了,那我不檢查下降沿,只檢查低電平不行嗎?直接把getDownEdge換成isLowPin函式不就可以了嗎,確實可以,這樣又會引入第二個問題。
2、時鐘同步問題
假設A跟B說,10分鐘後你提醒我喝水,然後B就看著自己的表,10分鐘後提醒A,這時A一看錶,才過去9分鐘。這種場景現實也會出現,造成的原因是A和B的表不同步或者有誤差這個誤差的引入就導致了A和B所指的“10分鐘”不相同,在我們這個串列埠的場景裡,就是傳送方和接收方約定了9600波特率,也就相當於約定了104.1us傳輸一個位元組,按照上面的虛擬碼,幾個採集點應該是
但是由於誤差,可能導致採集點偏移為
這兩個圖能大致表達時鐘不同步,導致接收裝置的採集點後移,如果這時引入了停止位,第二個BYTE開始時,由於還是從下降沿開始採集,所以會重置上一個BYTE引入的誤差。
4、總結
這篇乾貨基本把串列埠協議分析透徹了,大家在分析協議的時候,最好是從設計的角度去思考這樣設計的作用,如果有什麼分析不對的地方,歡迎大家指正。希望這篇文章能給你帶來一點作用。