串列埠通訊二 串列埠通訊使用的一點心得

2021-05-26 17:17:11 字數 2705 閱讀 4541

串列埠是我的最愛,成本低,容易實現,連線簡單方便。在我設計的硬體中,無一不配置乙個串列埠,在主要功能完成之後,我會在計算機上再編寫乙個終端軟體。這個軟體可不只用來監控,我用這個軟體完全控制硬體的所有功能,直到能夠監測到硬體盡可能多的狀態資訊,只要一看這些資訊,我就能知道硬體的工作狀態如何,故障可能發生在**。

近來發現論壇裡提問頻率較高、問題也五花八門的問題之一就是串列埠通訊問題,因此想在這裡寫點心得,也只是一點心得,對於網上很容易查到的資訊,這裡就不談了。

問題一:緩衝區大小的問題。

現在絕大多數cpu都包含串列埠功能,同時也為串列埠配置了fifo緩衝區,對於fifo緩衝區的使用存在著些誤區。

單就串列埠來說,通訊也分為很多方式,緩衝區大小影響較大的有兩種:突發通訊和連續的資料流通訊。突發通訊的主要特點是:資料量小、持續時間短、通訊發生時間不確定,通常的裝置狀態監控就屬於這一型別。相對的資料流通訊的特點是:資料量大、持續時間長等,如影象通訊、音訊採集等。

對於突發通訊,應該不使用fifo緩衝區,或者把fifo大小設定為1。因為在如果把緩衝區大小設定為應該接收的資料的大小,那麼發生通訊錯誤如丟失資料時就不會產生中斷,接收方會認為未發生通訊事件,而傳送方只能靠超時認為通訊中斷。這和接收到資料並判斷出通訊資料發生錯誤的性質是不同的,如果接收到資料我們就可以判斷出發生錯誤的原因,如果接收不資料,那麼怎麼判斷,硬體連線?fifo設定?軟體錯誤?軟體存在隱藏的bug?所以對於突發通訊不應該使用fifo。

對於資料流通訊,由於資料量大,如果還是用單位元組產生中斷的方式來接收,那cpu就會疲於處理串列埠中斷事件,而且這種情況下單位元組是無法作資料處理的,而使用fifo緩衝區,一次接收多個位元組後再產生中斷就會節約cpu時間用於資料處理,這裡就不多說了。

問題二:串列埠通訊軟體的編寫。

好的硬體配上好的軟體才能有好的效果,我發現有些編寫了幾年軟體的人串列埠通訊軟體也寫不好,我這裡就把這幾年編寫串列埠通訊軟體的一點小小的心得拿出來分享。

我們常用的tcp/ip協議是一種分層的協議,在編寫串列埠通訊軟體時也可以借鑑這種分層協議的程式設計思想。另外對於協議的使用,不同的人有不同的看法,區別較大,這裡只介紹相當於物理層和協議層之間的資料鏈路層程式。

由於沒有使用fifo功能,就要在記憶體中劃出一塊記憶體作為傳送緩衝區,由傳送中斷服務程式把資料傳送到接收方。**如下:

// 定義傳送緩衝區大小,可以根據系統ram的大小的資料量來定義

#define u0tx_buf_size 1024

// 定義傳送緩衝區

char u0tx_buf[u0tx_buf_size];

// 定義串列埠發射忙標誌,當串列埠正在傳送資料且傳送緩衝區不空時為1

char u0tx_busy_bit;

// 緩衝區中資料長度

unsigned int u0tx_length;

// 傳送緩衝區資料指標,指向下乙個傳送的資料

unsigned int u0tx_buf_pointer;

// 準備傳送資料

// data是要傳送的資料

// length資料的長度

char u0tx_send_packet( char *data, int length )

// 把要傳送的資料轉移到傳送緩衝區

for( i=0; i// 資料準備完畢,把u0tx_busy_bit置1,表示正在使用串列埠

u0tx_busy_bit = 1;

// 設定傳送緩衝區中資料的長度

u0tx_length = length;

// 把資料緩衝區的指標指到第乙個資料

u0tx_buf_pointer = 0;

// 為了保證程式的可移植性,這裡封裝了乙個串列埠傳送中斷觸發標誌,

// 設定這個標誌後,立即進入串列埠傳送中斷服務程式

set_u0tx_int_flag();

// 返回0x00表示成功進行了一次串列埠傳送操作

return 0x00;

}// 串列埠傳送中斷服務程式,逐一把傳送緩衝區中的資料傳送出去

__interrupt void u0tx_int_handler( void )

else

// 資料傳送完畢,把u0tx_busy_bit置0

u0tx_busy_bit = 0;

}在接收端,由於沒有使用fifo功能,同樣要在記憶體中劃出一塊記憶體作為接收緩衝區,由接收中斷服務程式把資料存入接收緩衝區。這個接收緩衝區是乙個先入先出的環形佇列,要根據cpu的執行速度和資料流量的大小來設定,太大會浪費記憶體資源,太小則會出現追尾現象,造成資料丟失。具體**如下:

#define u0rx_buf_size 128

// 定義接收緩衝區

char u0rx_buf[u0rx_buf_size];

// 串列埠接收緩衝區有資料標誌,當接收緩衝區不空時為1

char u0rx_flag;

// 資料有效標誌,因為使用的流通訊協議,且包括全範圍值,所有要用標誌指出資料是否可用

char u0rx_data_valid_flag;

// 接收緩衝區入佇列指標,指向下乙個儲存單元

unsigned int u0rx_in_pointer;

// 接收緩衝區出佇列指標,指向下乙個儲存單元

unsigned int u0rx_out_pointer;

// 串列埠接收中斷服務程式,把接收的資料逐一存入接收緩衝區中

// 在這裡使用的是覆蓋舊資料模式,可以根據情況加入丟棄新資料的**

__interrupt void u0rx_int_handler( void )

串列埠通訊二 串列埠通訊使用的一點心得

串列埠是我的最愛,成本低,容易實現,連線簡單方便。在我設計的硬體中,無一不配置乙個串列埠,在主要功能完成之後,我會在計算機上再編寫乙個終端軟體。這個軟體可不只用來監控,我用這個軟體完全控制硬體的所有功能,直到能夠監測到硬體盡可能多的狀態資訊,只要一看這些資訊,我就能知道硬體的工作狀態如何,故障可能發...

linux串列埠通訊(一) 串列埠的概念

二 串列埠內部 序列介面 serial inte ce 是指資料一位一位地順序傳送,其特點是通訊線路簡單,只要一對傳輸線就可以實現雙向通訊 可以直接利用 線作為傳輸線 從而大大降低了成本,特別適用於遠距離通訊,但傳送速度較慢。一條資訊的各位資料被逐位按順序傳送的通訊方式稱為序列通訊。序列通訊的特點是...

vivado學習第二 串列埠通訊

奇偶校驗位 奇偶校驗位分為奇數校驗位和偶數校驗位,奇數和偶數的判斷標準是依據傳送一串或者一幀資料中 1 的個數。奇數校驗 傳送的資料位 奇數校驗位中 1 的個數為奇數個,也就是說如果資料位的 1 的個數為奇數個,則奇數校驗位為數字0 如果資料位的 1 的個數為偶數個,則奇數校驗位為數字1。偶數校驗 ...