一. 簡介
這是FPGA之旅的第四個設(shè)計實例了,在上一例中,也就是第三例,串口通信,實現(xiàn)了單byte的傳輸。也就是每次只能傳輸一個btye的數(shù)據(jù)。在實際使用過程中,需要發(fā)送多byte的數(shù)據(jù)為一包數(shù)據(jù),里面包含各種信息,例如最常見的包頭和包尾。本例將在第三例的基礎(chǔ)上,實現(xiàn)多byte的接收實例,以滿足具體的需求。
二. 實現(xiàn)方法
在串口通信中數(shù)據(jù)一般為:1 bit的起始位 + 5,6,7,8bit的數(shù)據(jù)位 + 1 bit的停止位。最多一包數(shù)據(jù)為 10 bit。
其實串口協(xié)議中,并沒有規(guī)定數(shù)據(jù)位為5,6,7,8,理想情況下可以為任意位。例如,兩塊FPGA之間通過串口通信,就可以自定義。但是呢?上位機(jī)軟件支持位數(shù)只有這么幾種。為了通用性,還是以上位機(jī)軟件為標(biāo)準(zhǔn)。
假如說我要一次性發(fā)送5 bytes的數(shù)據(jù) 或者 一次性接收 5 bytes的數(shù)據(jù),然后交給FPGA進(jìn)行處理,那么該怎么做呢?其實也是比較容易的。只需要再設(shè)計一個模塊,重復(fù)調(diào)用 5 次串口發(fā)送模塊,和串口接收模塊接收了 5 bytes的數(shù)據(jù)后,再進(jìn)行對應(yīng)的處理,就可以了。
基礎(chǔ)的串口通信模塊完成后,就只需要完成這個多bytes 的模塊了。
三. Verilog 代碼實現(xiàn)
先來看一下發(fā)送的頂層模塊,頂層模塊,可以說和普通的串口發(fā)送模塊一樣,只是多出了一個參數(shù),來控制發(fā)送字節(jié)的位寬,具體定義如下。MulTXNum通過這個參數(shù)可以在實例化這個模塊的時候,自行確定每次測試字節(jié)的個數(shù),非常靈活。
module UART_MulTX #(
parameter MulTXNum = 3) /*每次發(fā)送的字節(jié)數(shù)*/
(
input sys_clk,
input rst_n,
input uart_tx_req, /*串口發(fā)送請求*/
output uart_txs_done, /*串口發(fā)送完成*/
input[MulTXNum*'d8 - 'd1:0] idats, /*發(fā)送的數(shù)據(jù)*/
output uarttx /*uart tx數(shù)據(jù)線*/
);
2. 在這個頂層模塊中調(diào)用基本的串口發(fā)送模塊。波特率也通過參數(shù)進(jìn)行控制,在實例化的時候,方便修改波特率。
UART_TX #(
.UARTBaud(115200) /*設(shè)置波特率*/
)UART_TXHP
(
.sys_clk (sys_clk), /*系統(tǒng)時鐘 50M*/
.rst_n (rst_n), /*系統(tǒng)復(fù)位 低電平有效*/
.uart_tx_req (UART_TX_Reg), /*串口發(fā)送請求*/
.uart_tx_done (uart_tx_done), /*串口發(fā)送完成*/
.idat (txdata), /*發(fā)送數(shù)據(jù)*/
.uarttx (uarttx) /*uart tx數(shù)據(jù)線*/
);
3. 串口接收模塊定義也一樣,具體的實現(xiàn)過程可以看完整的過程項目,就不粘貼上來了。需要的可以自行獲取。簡單看看模塊圖吧!
四. testbeach編寫
寫完各個模塊后,怎么能少得了仿真呢?也是調(diào)了幾次才沒有bug,嗐,直接上仿真。這里測試的是每次發(fā)送3個字節(jié)的數(shù)據(jù),每次發(fā)送完成后,發(fā)送完成后,發(fā)送數(shù)據(jù)加上2323,然后繼續(xù)發(fā)送,具體的可以看看仿真波形。
`timescale 1ns/1ps
module testbeach();
reg clk;
reg rst;
reg uart_tx_req;
wire uart_txs_done;
reg[23:0] idats;
wire uart;
wire[23:0] odats;
wire uart_rxs_done;
always #50 clk = ~clk;
initial begin
clk = 1'b1;
rst = 1'b1;
idats = 'd12256;
uart_tx_req = 1'b0;
#100
rst = 1'b0; /*手動復(fù)位*/
#100
rst = 1'b1;
#100
uart_tx_req <= 1'b1;
end
always@(posedge clk)
if(uart_txs_done == 1'b1)
idats <= idats + 'd2323;
UART_MulRX #(
.MulRXNum (3)
)UART_MulRXHP(
.sys_clk (clk), /*系統(tǒng)時鐘 50M*/
.rst_n (rst), /*系統(tǒng)復(fù)位*/
.uart_rxs_done (uart_rxs_done), /*串口接收完成*/
.odats (odats), /*接收數(shù)據(jù)*/
.uartrx (uart) /*uart rx數(shù)據(jù)線*/
);
UART_MulTX #(
.MulTXNum(3)) /*每次發(fā)送的比特數(shù)*/
UART_MulTXHP(
.sys_clk (clk), /*系統(tǒng)時鐘 50M*/
.rst_n (rst), /*系統(tǒng)復(fù)位*/
.uart_tx_req (uart_tx_req), /*串口發(fā)送請求*/
.uart_txs_done (uart_txs_done), /*串口發(fā)送完成*/
.idats (idats), /*發(fā)送的數(shù)據(jù)*/
.uarttx (uart) /*uart tx數(shù)據(jù)線*/
);
endmodule
通過波形可以看到,程序編寫正確?。?!(已上板驗證)
需要完整代碼的可以在公眾號FPGA之旅中回復(fù) :FPGA之旅設(shè)計99例之第四例
更多信息可以來這里獲取==>>電子技術(shù)應(yīng)用-AET<<
電子技術(shù)應(yīng)用專欄作家FPGA之旅
原文鏈接:https://mp.weixin.qq.com/s/-SgBkJTbW-nRkG_eqjatWQ