溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么進行UART傳輸實現(xiàn)FPGA

發(fā)布時間:2021-12-18 14:23:44 來源:億速云 閱讀:183 作者:柒染 欄目:互聯(lián)網(wǎng)科技

本篇文章為大家展示了怎么進行UART傳輸實現(xiàn)FPGA,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

怎么進行UART傳輸實現(xiàn)FPGA

??????圖2 34 FPGA發(fā)送一幀串口數(shù)據(jù)(考慮波特率)
??如果圖2 34考慮 115200 的波特率,結(jié)果如圖2 34所示,每一位數(shù)據(jù)都保持 434 個時鐘,為此 Verilog 可以這樣表示,如代碼2 11所示:
?????????         代碼2 11

1.	reg [10:0]D1;
2. reg [8:0]C1;
3. always @( posedge CLOCK)
4.      case( i)
5.      0,1,2,3,4,5,6,7,8,9,10:
6.      if( C1 == 9’ d434 -1 ) begin C1 <= 9’ d0; i <= i + 1’ b1; endelse begin TXD <= D1[i]; C1 <= C1 + 1'b1; end
7. ......
8. endcase

??如代碼2 11所示,步驟 1~8 不再保持一個時鐘,換之每個步驟都保持 434 個時鐘,因此每位 TXD 的發(fā)送數(shù)據(jù)也保持 8.68us。
??除此此外,串口傳輸協(xié)議不僅可以自定義波特率,串口傳輸協(xié)議也可以自定義一幀數(shù)據(jù)的位寬,自定義內(nèi)容如表2 8所示:
??????             表2 8 自定義一幀數(shù)據(jù)

怎么進行UART傳輸實現(xiàn)FPGA
??如表2 8所示,可以自定義的數(shù)據(jù)其中便包含數(shù)據(jù)位,默認下為 1 字節(jié),自定義內(nèi)容則是 5~9 位,校驗位也可以設置為有或者無( 默認下是有),停止位也可以增至 2 位(默認下是 1 位)。
怎么進行UART傳輸實現(xiàn)FPGA
??????????圖2 35 TX 功能模塊的建模圖
??如圖2 35所示,該模塊的左方有問答信號,還有 8 位的 iData,至于右方則是 TXD 頂層信號。此外,一幀數(shù)據(jù)的波特率為 115200 bps。
?????????? 代碼 2 12 TX 功能模塊代碼

1.	//****************************************************************************//
2. //# @Author: 碎碎思
3. //# @Date:   2019-04-21 21:14:51
4. //# @Last Modified by:   zlk
5. //# @WeChat Official Account: OpenFPGA
6. //# @Last Modified time: 2019-08-04 02:48:17
7. //# Description:
8. //# @Modification History: 2014-05-10 13:42:27
9. //# Date                By             Version             Change Description:
10. //# ========================================================================= #
11. //# 2014-05-10 13:42:27
12. //# ========================================================================= #
13. //# |                                                                       | #
14. //# |                                OpenFPGA                               | #
15. //****************************************************************************//
16. module tx_funcmod
17. (
18.    input CLOCK, RESET,
19.     output TXD,
20.     input iCall,
21.     output oDone,
22.     input [7:0]iData
23. );
24.     parameter B115K2 = 9'd434; // formula : ( 1/115200 )/( 1/50E+6 )
25.  
26.     reg [3:0]i;
27.     reg [8:0]C1;
28.     reg [10:0]D1;
29.     reg rTXD;
30.     reg isDone;
31.      
32.     always @( posedge CLOCK or negedge RESET )
33.         if( !RESET )
34.              begin
35.                  i <= 4'd0;
36.                  C1 <= 9'd0;
37.                   D1 <= 11'd0;
38.                     rTXD <= 1'b1;
39.                     isDone <= 1'b0;
40.              end
41.          else if( iCall )
42.              case( i )
43.                  
44.                    0:
45.                     begin D1 <= { 2'b11 , iData , 1'b0 }; i <= i + 1'b1; end
46.                      
47.                     1,2,3,4,5,6,7,8,9,10,11:
48.                     if( C1 == B115K2 -1 ) begin C1 <= 8'd0; i <= i + 1'b1; end
49.                     else begin rTXD <= D1[i - 1]; C1 <= C1 + 1'b1; end
50.  
51.                    12:
52.                     begin isDone <= 1'b1; i <= i + 1'b1; end
53.                      
54.                     13:
55.                     begin isDone <= 1'b0; i <= 4'd0; end
56.                  
57.                endcase
58.      
59.    assign TXD = rTXD;
60.    assign oDone = isDone;
61.      
62. endmodule

??第16~24行為相關(guān)的出入端聲明,第 9 行則是波特率為 115200 的常量聲明。
??第26~40行為相關(guān)的寄存器聲明以及復位操作。
??第41~62行為部分核心操作。第 41 行的 if( iCall ) 表示該模塊不使能就不工作。步驟 0 用來準備發(fā)送數(shù)據(jù),其中 2’b11 是停止位與校驗位(隨便填),1’b0 則是起始位。步驟 1~11用來發(fā)送一幀數(shù)據(jù)。步驟 12~13 用來反饋完成信號并返回步驟。
??這樣發(fā)送模塊就完成了,理想時序如下圖所示:
怎么進行UART傳輸實現(xiàn)FPGA

????????圖2 36 串口發(fā)送模塊功能邏輯示意圖
??由上圖可知,串口發(fā)送模塊是“定時發(fā)送”的過程。波特率模塊產(chǎn)生的時間間隔是通過計數(shù)器實現(xiàn)的,由圖2 37可知,每隔一定時間波特率模塊就會產(chǎn)生一個高脈沖給TX_Pin_Out引腳。
??串口發(fā)送的框圖如圖2 37所示:
怎么進行UART傳輸實現(xiàn)FPGA

??????????圖2 37 串口模塊RTL框圖
??對于FPGA實現(xiàn)UART的RX模塊功能主要就是電平采集。那么它到底是如何實現(xiàn)采集的呢?
怎么進行UART傳輸實現(xiàn)FPGA
???????????圖 2 38 RX模塊電平采集示意圖
??說到底,在發(fā)送模塊中一位數(shù)據(jù)發(fā)送的時間間隔是通過波特率進行控制的,同理,在接受模塊中采集一位數(shù)據(jù)的間隔同樣也要通過波特率進行控制,具體如上圖所示。
??上圖中,數(shù)據(jù)采集都是在“每位數(shù)據(jù)的中間”進行著。RX_Pin_In 輸入一幀數(shù)據(jù),當檢測到低電平(起始位), 在第 0 位數(shù)據(jù),采取忽略的態(tài)度,然后接下來的 8 位數(shù)據(jù)位都被采集,最后校驗位和停止位,卻是采取了忽略的操作。有一點必須好好注意,串口傳輸數(shù)據(jù)“從最低位開始,到最高位結(jié)束”。
??因為 Verilog 無法描述理想以外的時序, 對此所有時序活動都必須看成理想時序。
怎么進行UART傳輸實現(xiàn)FPGA
??????圖2 39 FPGA接收一幀波特率為115200的數(shù)據(jù)
??當FPGA接收一幀數(shù)據(jù)為波特率115200之際,情況差不多如圖2 41所示。50Mhz是FPGA的時鐘源,也是一幀數(shù)據(jù)的采集時鐘, RXD 則是一幀數(shù)據(jù)的輸入端。波特率為 115200的一位數(shù)據(jù)經(jīng)過 50Mhz 的時鐘量化以后,每一位數(shù)據(jù)大約保持 8.68us,即 434 個時鐘。串口傳輸沒有自己的時鐘信號,所以我們必須利用 FPGA 的時鐘源“跟蹤”每一位數(shù)據(jù)。對此, FPGA 只能借用計數(shù)器“同步跟蹤”而已,至于 Verilog 則可以這樣描述,結(jié)果如代碼2 13所示:
??????????          代碼2 13

1.	0,1,2,3,4,5,6,7,8,9,10: //同步跟蹤中 ...
2.      if( C1 == 434 -1 ) begin C1 <= 8'd0; i <= i + 1'b1; end
3.      else C1 <= C1 + 1'b1;

??如代碼2 13所示,所謂同步跟蹤,就是利用計數(shù)器估計每一位數(shù)據(jù) … 期間,步驟 0~10表示每一位數(shù)據(jù),至于 C1 計數(shù) 434 個時鐘則是同步跟蹤中。其中-1考慮了步驟之間的跳轉(zhuǎn)所耗掉的時鐘。
怎么進行UART傳輸實現(xiàn)FPGA
?????????     ?圖2 40 讀取起始位
??知道串口的一幀數(shù)據(jù)都是從拉低的起始位開始,然而為了完美尾行,亦即實現(xiàn)精密控時,起始位的讀取往往都是關(guān)鍵。如圖2 40所示,當我們在第一個時鐘讀?。ú杉┢鹗嘉坏臅r候,由于 Verilog 的讀取只能經(jīng)過讀取過去值而已,余下起始位還有 433 個時鐘需要我們跟蹤,為此 Verilog 可以這樣描述,結(jié)果如代碼2 14所示:
???????????        代碼2 14

1.	0:
2.    if( RXD == 1'b0 ) begin i <= i + 1'b1; C1 <= C1 + 4'd1; end
3. 1: // stalk start bit
4.    if( C1 == BPS115K2 -1 ) begin C1 <= 8'd0; i <= i + 1'b1; end
5.    else C1 <= C1 + 1'b1;

??如代碼2 14所示,步驟 0 用來檢測起始位,如果 RXD 的電平為拉低狀態(tài), C1 立即遞增以示同步跟蹤已經(jīng)用掉一個時鐘,同樣也可以看成 i 進入下一個步驟用掉一個時鐘。然而步驟 1 是用來跟蹤余下的 433 個時鐘,但是計數(shù)器 C1 不是從 0 開始計數(shù),而是從 1開始計算,因為 C1 在步驟已經(jīng)遞增的緣故。
怎么進行UART傳輸實現(xiàn)FPGA

??????????圖2 41 讀取一幀數(shù)據(jù)當中的數(shù)據(jù)位
??一幀數(shù)據(jù)的跟蹤結(jié)果與讀取結(jié)果如圖2 41所示 … 除了起始位,我們使用了兩個步驟采集并跟蹤之余,接下來便用 8 個步驟數(shù)據(jù)一邊跟蹤一邊采集所有數(shù)據(jù)位,然而采集的時候則是 1/4 周期,即每位數(shù)據(jù)的第 108 個時鐘。最后的校驗位及結(jié)束位則是跟蹤而已。
??對此, Verilog 可以這樣表示,結(jié)果如代碼2 15所示:
?????????????代碼2 15

1.	0:
2. if( RXD == 1'b0 ) begin i <= i + 1'b1; C1 <= C1 + 4'd1; end
3.  
4. 1: // start bit
5. if( C1 == BPS115K2 -1 ) begin C1 <= 8'd0; i <= i + 1'b1; end
6. else C1 <= C1 + 1'b1;
7.  
8. 2,3,4,5,6,7,8,9: //stalk and count 1~8 data's bit , sample data at 1/2 for bps
9. begin
10. if( C1 == SAMPLE ) D1[i-2] <= RXD;
11.   if( C1 == BPS115K2 -1 ) begin C1 <= 8'd0; i <= i + 1'b1; end
12.      else C1 <= C1 + 1'b1;
13. end
14.  
15. 10,11: // parity bit & stop bit
16. if( C1 == BPS115K2 -1 ) begin C1 <= 8'd0; i <= i + 1'b1; end
17. else C1 <= C1 + 1'b1;
18.  
19. 12:
20. begin isDone <= 1'b1; i <= i + 1'b1; end
21.  
22. 13:
23. begin isDone <= 1'b0; i <= 4'd0; end

??如代碼2 15所示,步驟 0~1 用來采集與跟蹤起始位,步驟 2~9 則用來跟蹤數(shù)據(jù)位,并且采集為 1/4 周期。步驟 10~11 則用來跟蹤校驗位于結(jié)束位。

怎么進行UART傳輸實現(xiàn)FPGA????????????圖2 42 RX功能模塊的建模圖
??圖2 42是 RX 功能模塊的建模圖,左方鏈接至頂層信號 RXD,右方則是問答信號還有 8位的 oData。
????????????代碼2 16 RX模塊實現(xiàn)代碼

1.	//****************************************************************************//
2. //# @Author: 碎碎思
3. //# @Date:   2019-04-21 22:46:15
4. //# @Last Modified by:   zlk
5. //# @WeChat Official Account: OpenFPGA
6. //# @Last Modified time: 2019-08-04 03:21:38
7. //# Description:
8. //# @Modification History: 2014-05-10 13:44:28
9. //# Date                By             Version             Change Description:
10. //# ========================================================================= #
11. //# 2014-05-10 13:44:28
12. //# ========================================================================= #
13. //# |                                                                       | #
14. //# |                                OpenFPGA                               | #
15. //****************************************************************************//
16. module rx_funcmod
17. (
18.    input CLOCK, RESET,
19.     input RXD,
20.     input iCall,
21.     output oDone,
22.     output [7:0]oData
23. );
24.    parameter BPS115K2 = 9'd434, SAMPLE = 9'd108;
25.
26.    reg [3:0]i;
27.     reg [8:0]C1;
28.     reg [7:0]D1;
29.     reg isDone;
30.      
31.     always @ ( posedge CLOCK or negedge RESET )
32.         if( !RESET )
33.              begin
34.                    i <= 4'd0;
35.                     C1 <= 9'd0;
36.                     D1 <= 8'd0;
37.                     isDone <= 1'b0;
38.                end
39.          else if( iCall )
40.              case( i )
41.                      
42.                     0:
43.                     if( RXD == 1'b0 ) begin i <= i + 1'b1; C1 <= C1 + 4'd1; end
44.                      
45.                     1: // start bit
46.                     if( C1 == BPS115K2 -1 ) begin C1 <= 8'd0; i <= i + 1'b1; end
47.                     else C1 <= C1 + 1'b1;
48.                      
49.                     2,3,4,5,6,7,8,9: //stalk and count 1~8 data's bit , sample data at 1/2 for bps
50.                     begin
51.                        if( C1 == SAMPLE ) D1[i-2] <= RXD;
52.                        if( C1 == BPS115K2 -1 ) begin C1 <= 8'd0; i <= i + 1'b1; end
53.                        else C1 <= C1 + 1'b1;
54.                     end
55.                      
56.                     10,11: // parity bit & stop bit
57.                     if( C1 == BPS115K2 -1 ) begin C1 <= 8'd0; i <= i + 1'b1; end
58.                     else C1 <= C1 + 1'b1;
59.                      
60.                     12:
61.                     begin isDone <= 1'b1; i <= i + 1'b1; end
62.                      
63.                     13:
64.                     begin isDone <= 1'b0; i <= 4'd0; end
65.                  
66.                endcase
67.                  
68.    assign oDone = isDone;
69.    assign oData = D1;
70.      
71. endmodule

??第 16~24 行是相關(guān)的出入端聲明,第 24 行則是波特率為 115200 的常量聲明,其外還有采集的周期。
??第 26~38 行是相關(guān)的寄存器聲明,第 32~38 行則是這些寄存器的復位操作。
??第 39~46 行是核心操作。第 39 行的 if( iCall ) 表示該模塊不使能便不工作。步驟 0~1 用來判斷與跟蹤起始位;

??步驟 2~9 用來跟蹤并且讀取當中的數(shù)據(jù)位;步驟 10 至 11 則是用來跟蹤校驗位與停止位而已。步驟 12~13 則用來反饋完成信號,以示一次性的接收工作已經(jīng)完成。
??第 68~69 行是輸出驅(qū)動聲明。

上述內(nèi)容就是怎么進行UART傳輸實現(xiàn)FPGA,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI