帶有FIFO硬體快取的串列埠

2022-10-01 14:12:15 字數 2617 閱讀 6104

51微控制器的串列埠並沒有配置fifo硬體,故收發資料時只能一位元組一位元組地收發。最近接觸了fifo(先進先出)的硬體快取,這樣串列埠的配置就更多了乙個維度。

以ch58x系列微控制器為例,在ch583的手冊中(筆者手頭的是ch582m的板子,與ch583用法一致,只有部分硬體不同),有關於串列埠和fifo配置的說明。具體應用可以檢視筆者關於串列埠透傳的一篇隨筆。

9.3.1 波特率計算

1)計算串列埠內部基準時鐘 fuart,設定 r8_uartx_div 暫存器,最大值 127,通常寫入 1。

2)計算波特率,設定 r16_uartx_dl 暫存器。 波特率公式 =fsys * 2 / r8_uartx_div / 16 / r16_uartx_dl。    //通過getsysclock()這個函式獲得主頻

9.3.2 串列埠傳送

串列埠傳送的「thr 暫存器空」中斷 uart_ii_thr_empty 是指當前傳送 fifo 空。

當讀取 iir 暫存器後,該中斷被清除,或者當向 thr 寫入下乙個資料後,該中斷也能被清除。     //iir:中斷識別暫存器 thr:傳送儲存暫存器

如果僅僅是向 thr寫入 乙個位元組,那麼由於該位元組很快被轉移到傳送移位暫存器 tsr 中開始傳送,所以很快會再次產生傳送 thr 暫存器空中斷的請求,此時可以寫入下乙個準備傳送的資料。

當 tsr 暫存器中的資料被全部移出 後,串列埠傳送才真正完成,此時 lsr 暫存器的 rb_lsr_tx_all_emp 位變為 1 有效。      //tsr:傳送移位暫存器

在中斷觸發方式下,當收到串列埠傳送保持暫存器 thr 空的中斷後,如果已使能 fifo,那麼可以向 thr 暫存器及 fifo 一次寫入最多 8 位元組,然後控制器會按順序自動傳送;

如果禁止 fifo,那麼一 次只能寫入乙個位元組;        //使能fifo後,向thr寫入的資料先存放於fifo中,自動以此傳送,一次可以寫入多個位元組

如果沒有資料需要傳送,那麼可以直接退出(之前讀取 iir 時已經自動清除中斷)。

在查詢方式下,可以根據 lsr 暫存器的 rb_lsr_tx_fifo_emp 位判斷傳送 fifo 是否為空,當此位 為 1 則可以向 thr 暫存器及 fifo 寫入資料,如果使能 fifo,那麼一次可以寫入最多 8 個位元組。

也可讀取 r8_uartx_tfc 暫存器判斷當前 fifo 中待傳送的剩餘資料個數,如果不等於8,則可繼 續向 fifo 中寫入待傳送資料,這種方式可以節約填充時間。

9.3.3 串列埠接收      //假設設定fifo設定為7個位元組的快取

串列埠接收資料可用中斷 uart_ii_recv_rdy 是指接收 fifo 中的已有資料位元組數已經到或超過由fcr 暫存器的 rb_fcr_fifo_trig 設定選擇的 fifo 觸發點。        //fifo中的資料達到了設定的7個位元組,會觸發_recv_rdy ,若取出這7個位元組,fifo中會空

當從 rbr 讀取資料使 fifo 字數低於 fifo 觸發點時,該中斷被清除。      //rbr:接收快取暫存器

串列埠接收資料超時中斷 uart_ii_recv_tout 是指接收 fifo 中至少有乙個位元組的資料,

並且從上一次串列埠接收到資料和從上一次被系統取走資料開始,已經等待了相當於接收 4 個資料的時間。      //這裡的「4」個資料的時間與fifo觸發設定的「4」位元組無關,注意:fifo中要留有乙個資料進行比較,該標誌才能有效

當再次接收到乙個新的資料後,該中斷被清除,或者當單片讀取一次 rbr 暫存器後,該中斷也能被清除。      //接收到新資料或者讀取rbr後,超時標誌位清除

當接收fifo全空時, lsr暫存器的rb_lsr_data_rdy位為0,當接收fifo中有資料時, rb_lsr_data_rdy 位為 1 有效。      //lsr:線路狀態暫存器 _rdy標誌位為1時有效,表示fifo中有資料

在中斷觸發方式下,當收到串列埠接收資料超時的中斷後,可以讀取 r8_uartx_rfc 暫存器查詢當前 fifo 中剩餘資料計數,直接讀取全部資料,     //超時中斷後,判斷為沒有資料了,一次全部讀取fifo中的資料或者不斷查詢lsr的標誌位不斷讀取

或者不斷查詢 lsr 暫存器的 rb_lsr_data_rdy,如果 此位有效則讀資料,直到此位無效。

當收到串列埠接收資料可用的中斷後,可以先從 rbr 暫存器一次性讀取 rb_fcr_fifo_trig 設定位元組個數的資料,     //收到可用中斷後,可以從_trig暫存器讀取設定位元組的個數,亦可以結合_rdy和_rfc讀取所有數

或者也可以根據 rb_lsr_data_rdy 位和 r8_uartx_rfc 暫存器讀取當前 fifo 中所有資料。

在查詢方式下,可以根據 lsr 暫存器的 rb_lsr_data_rdy 位判斷接收 fifo 是否為空,或讀取 r8_uartx_rfc 暫存器獲取當前 fifo 中資料計數,來獲取串列埠接收的所有資料。

//以下為串列埠1初始化函式

void u1_init()

break;

case uart_ii_recv_tout: // 接收超時,暫時一幀資料接收完成

i = uart1_recvstring(rxbuff);

uart1_sendstring(rxbuff, i);

break;

//略掉幾個case分支

default:

break;}}

Socket通訊 和 串列埠通訊 (有人的硬體)

硬體採用的是 有人公司 的串列埠轉wifi模組。該模組可以實現串列埠透傳。軟體如下 硬體模組設定為 tcp server using system using system.windows.forms using system.io.ports using system.io using syste...

linux下串列埠通訊的除錯和硬體檢測

我第一次在在這裡寫我的動手經歷,緊張而又機動,活波而又蕭瑟,我只是記錄我的工作歷程,希望有機會看到文章的人可以指點,加深我的印象,謝謝您。我們開始吧,首先,我們既然要實現讀取linux下串列埠的東西,我們就得先了解在linux下的這些串列埠是怎樣的東西。linux下,存在乙個 dev的裝置目錄,該目...

c 串列埠快取位元組數 C 串列埠連線的讀取與傳送

一 串列埠連線的開啟與關閉 串列埠,即com口,在.net中使用 serialport 類進行操作。串列埠開啟與關閉,是涉及慢速硬體的io操作,頻繁開啟或關閉會影響整體處理速度,甚至導致開啟或關閉串列埠失敗。非特殊情況,串列埠一次性開啟後,在退出程式時關閉串列埠即可。在開啟串列埠前,可以設定一些常用...