1. 程式人生 > >STM32串列埠通訊協議淺析

STM32串列埠通訊協議淺析

通訊協議是指在嵌入式開發中,不同的硬體系統或者作業系統之間進行資料交換的方式,是一種資料通訊的規約。

通訊協議有很多種,而我今天要說的是串列埠通訊協議,而且是基於STM32來說的。

首先說串列埠通訊,串列埠是微控制器最常見的外設。常見的UART串列埠主要有兩個線,一個線是傳送、一個是接收。至於串列埠傳送資料的時候資料線上的高低電平是怎麼變化的,這個大家可以自行查閱相關知識,我們常見的微控制器自帶的串列埠已經把這個最底層的電平級別的協議做好了,我們使用的時候,收發都是以一個位元組為單位來進行的。

舉個例子,我們想使用串列埠連線STM32的串列埠1到PC機,然後通過PC上位機給STM32傳送一個位元組0x01,然後在STM32接收到之後,判斷一下是不是0x01,如果是的話,點亮一個小燈,如果不是的話,就不點亮燈。這個很多人都可以理解而且實現起來非常容易,基本上幾行程式碼就實現了。

那麼把剛才的例子擴充套件一下,假如STM32連線了很多很多燈,然後我們要使用串列埠傳送一個指令來控制所有燈,這時候應該怎麼操作?

把問題再擴充套件一下,假如我們要控制或通訊的不是一個燈,而是一個更復雜的東西,比如是一個電機控制模組、是一個GPS模組、是一個物聯網模組呢,這些東西在資料互動的時候都有很大的資料量,不可能一個一個位元組去傳送資料。

這時候我們就可以聯想一下人類是怎麼互動的,首先經過上萬年的潛移默化,人類形成了很多種語言,同一個國家的人說話基本上都可以聽懂,而不同國家的人說話的時候,如果不懂外語是聽不懂的。這是為什麼呢,因為同一個國家的人,說話的時候使用的協議是相同的,你說桌子,我就知道是桌子。而不同國家的人,通訊協議是不一樣的,所以說話的時候不能理解,比如你說apple,我如果沒有學過英語,我就不知道你說的是蘋果。但是我學習了你的語言,也就是協議。就可以聽懂你說的是蘋果了。

所以,STM32和PC通訊,或者擴充套件到更多的場景,STM32和GPS,其他微控制器和WIFI等等,這樣的通訊都需要通訊雙方執行同樣的協議。那麼對於剛接觸微控制器的人而言,就產生了幾個問題,協議是什麼樣的,如何執行協議?

還是以最簡單的場景來舉例子。以使用PC機發指令來控制STM32點亮8個小燈中的若干個小燈固定時長(一秒到255秒之間)然後關閉這樣一個實際小專案為例,我們現在明白了,如果只發一個指令,是沒辦法完成以上任務的。所以我們需要制定一個簡單的協議。比如我STM32的程式這麼寫:當串列埠收到0xAA然後又收到0x55的時候,我就開始不斷收集,並把收集到的所有資料都放在一個數字中,直到收到0xA5x5A這兩個的時候就停止收集。接下來我把收集到的數組裡面的第一個拿出來,使用if進行判斷,如果是0x01的話就點亮第一個小燈,如果是0x00或者其他的話,就不點亮燈,然後看看陣列的第二個位元組是多少,是多少就給延時多少。相當於通過前兩個位元組來控制第一個燈亮滅固定時間長度。同樣的接下來的兩個位元組是第二個燈的亮滅和時間長度。按這樣的節奏來,要控制這8個燈需要16個位元組。那麼我們是否可以優化一下這個協議呢?

假如把8個燈的亮滅資訊只用一個位元組來表示,後面加8個位元組,分別用來表示每個燈的亮滅時間長度,這樣的話,就可以用9個位元組來完成這個任務。

現在我們再想想,假如在這個資料傳輸的過程中,出了一點小錯誤,其中有一個電平在跳變的時候受到了干擾,沒有按照發送方的資料跳變,這時候接收方接收到的資料就是錯誤的,假如這個錯誤發生在第一個燈的亮滅位上,那這個燈就會發生錯誤的反應,這不是傳送方想要的結果。那如何避免這種情況發生呢?使用校驗位,校驗位是什麼意思呢,就是我在給你發的時候,我把9個位元組的資料做一個運算。運算有很多種方式,以求和為例子,把9個位元組的資料求和,然後拿出裡面低八位的資料,放在我要傳送的9個位元組後面。這樣,傳送的內容除了0xAA,0x55,0xA5和x5A之外,還多了一個位,我們把多出來的這個通過資料位運算得到的這一位元組稱為校驗位。當傳送出去之後,接收方在接收完這些資料之後,也對資料位做一個求和,然後取出低八位,和傳送方傳送過來的那個校驗位做比較,如果相等,說明資料傳送過程中沒有出錯,如果不相等,說明資料傳送過程中有地方出錯了,那麼我們整個不要這一包資料了,然後給傳送方通知一下,告訴他讓他重新發送一下剛才的資料。

現在回到資料收發,PC端發資料,STM32端接收,這時候STM32也就要每過一會兒(很短暫的時間)就去看看串列埠是否有資料收到,這種方式稱為掃描。掃描有一個缺點,就是需要不斷的去看,結果可能去看了一百次,才有一次有資料收到,這樣效率太低了,老闆(cpu)肯定不高興,就給串列埠說,以後你自己處理,有資料來了給我說一下我去處理就行,別讓我自己去看,手裡事情多著呢。所以就有了中斷,中斷就是當串列埠上有資料接了,就會產生一個接收中斷,這時候串列埠就去通知老闆來處理。原本要不斷過來看看有沒有資料,現在他有資料了才通知老闆,老闆開始還感覺不錯,比以前掃描的時候輕鬆了點。

過了一段時間,老闆想,這樣每來一包資料,我得去拿幾十次呀,太累,於是扔給串列埠一個倉庫(陣列),然後說,我給你一個特殊的通道(DMA)你以後收完一包資料直接通過這個通道把資料放在這個倉庫裡,放完了再通知我來處理,別讓我來一次處理一個,手裡事情多著呢。然後就有了串列埠空閒中斷,串列埠每次收到一幀資料之後,才會產生一箇中斷通知cpu處理。串列埠空閒中斷+DMA的方式簡直是處理串列埠通訊的神器,沒有之二。

接下來我們再想想,如果我們有一天突然覺得只控制8個燈不夠用了,需要擴充套件幾個呢,這時候,燈加上去之後,協議上還要有很大的改動,比如要把燈的控制位插在資料位的後面,就要把校驗位往後挪挪,這樣程式就需要改改,那麼有沒有一種方式,可以允許你在一定範圍之內隨意改燈的數量而不需要修改協議呢?這就需要設計一個不定長的通訊協議了。既然不定長,那也就意味著,傳送方每次都可能傳送出不同長度的資料給接收方,這也就要求傳送方在傳送資料的時候,在這個資料包的前面要加上資料有幾個位元組,這樣接收方才好根據這個數量去接收(串列埠空閒中斷+dma的方式不需要根據這個數量去接收),並且根據這個數量去解析,進而控制燈。

以上就是串列埠通訊協議中一些簡單的知識的簡單表述,覺得看了不懂了,可以私信我.

感謝您閱讀“電子開發學習”的文章,如果您覺得圖文能幫助您學習,歡迎關注我們。請點選右上角按鈕,選擇“檢視公眾號”,再點選關注即可。或者可以通過搜尋公眾號的方式關注: electricstudy  。您可以通過掃碼下面的二維碼關注我們。如果您想閱讀往期文章,可點選“檢視歷史訊息”。

歷史好文推薦(點選文章標題可跳轉):