1開(kāi)發(fā)板串口簡(jiǎn)介
DE23-Lite開(kāi)發(fā)板提供了一個(gè)UART通信接口(物理接口是下圖的Type C接口),用戶(hù)能夠通過(guò)主機(jī)與Agilex 3 FPGA進(jìn)行串口通信。

該接口使用DE23-Lite板載的USB Blaster III電路中的FT2232H芯片作為UART轉(zhuǎn)USB的橋梁。將USB線連接到DE23-Lite板的Type-C接口和主機(jī)之間,即可啟用USB Blaster III和FPGA UART功能,此時(shí)無(wú)需串行驅(qū)動(dòng)程序,但用戶(hù)在使用UART功能前需要確保已安裝USB Blaster III驅(qū)動(dòng)程序。

連接USB線后,通常在PC設(shè)備管理器中會(huì)顯示USB Blaster III和一個(gè)COM端口號(hào)。

2實(shí)驗(yàn)任務(wù)
設(shè)計(jì)一個(gè)串口回環(huán)實(shí)驗(yàn),實(shí)現(xiàn)上位機(jī)發(fā)送數(shù)據(jù)給開(kāi)發(fā)板串口,串口接收數(shù)據(jù)后又通過(guò)串口發(fā)送給上位機(jī)。

串口時(shí)序圖如下:

要求:數(shù)據(jù)位為8位, 停止位1位,無(wú)校驗(yàn)位,波特率115200bps。
3模塊設(shè)計(jì)
DE23-Lite的串口回環(huán)設(shè)計(jì)主要是2個(gè)模塊:串口發(fā)送模塊(發(fā)送數(shù)據(jù)時(shí)將并行的數(shù)據(jù)轉(zhuǎn)換成串行數(shù)據(jù)進(jìn)行傳輸)和串口接收模塊(在接收數(shù)據(jù)時(shí)將接收到的串行數(shù)據(jù)轉(zhuǎn)換成并行數(shù)據(jù))。

系統(tǒng)時(shí)鐘是50MHz,波特率是115200bps,那么串口發(fā)送和接收時(shí),數(shù)據(jù)的每個(gè)位將占用50000000/115200 ≈ 434個(gè)時(shí)鐘周期。
在串口接收模塊設(shè)置一個(gè)4狀態(tài)的狀態(tài)機(jī):
空閑狀態(tài):在空閑狀態(tài)下,檢測(cè)起始位(低電平)。一旦檢測(cè)到起始位,進(jìn)入START狀態(tài),并設(shè)置計(jì)數(shù)器在半位時(shí)間后采樣,這樣可以確保在位的中心點(diǎn)采樣,提高抗噪能力。
起始位檢測(cè)狀態(tài):等待半個(gè)位周期后,再次檢查線路狀態(tài)。如果仍然是低電平,確認(rèn)是有效的起始位,進(jìn)入DATA狀態(tài);否則認(rèn)為是噪聲干擾,返回IDLE狀態(tài)。
數(shù)據(jù)位接收狀態(tài):在每個(gè)位周期的中心點(diǎn)采樣數(shù)據(jù)位,并存入移位寄存器。接收完8位數(shù)據(jù)后,進(jìn)入STOP狀態(tài)。
停止位處理狀態(tài):等待一個(gè)完整的位周期(停止位),然后將接收到的數(shù)據(jù)輸出,并產(chǎn)生一個(gè)時(shí)鐘周期的接收完成信號(hào)。

接收模塊工程代碼:
moduleuart_rx( input clk, input rst_n, input uart_rx, output reg [7:0] rx_data, output reg rx_done ); parameterCLK_FREQ=50000000; parameterBAUD_RATE=115200; //波特率計(jì)數(shù)器 localparam BAUD_CNT_MAX=CLK_FREQ/BAUD_RATE; localparam HALF_BAUD_CNT=BAUD_CNT_MAX/2; reg [15:0] baud_cnt; //狀態(tài)定義 localparam IDLE=2'd0; localparam START = 2'd1; localparam DATA=2'd2; localparam STOP = 2'd3; reg [1:0] state; reg [2:0] bit_cnt; reg [7:0] rx_reg; reg uart_rx_sync1, uart_rx_sync2; //同步輸入信號(hào) always @(posedge clkornegedge rst_n)begin if(!rst_n)begin uart_rx_sync1<=?1'b1; ? ? uart_rx_sync2 <= 1'b1; ??end?else?begin ? ? uart_rx_sync1?<=?uart_rx; ? ? uart_rx_sync2?<=?uart_rx_sync1; ??end end ? ?? ? ??//?狀態(tài)機(jī) always @(posedge clk?or?negedge rst_n)?begin ? if(!rst_n)?begin ? ? state?<=?IDLE; ? ? rx_data?<=?8'd0; ? ? rx_done <= 1'b0; ? ? baud_cnt?<=?0; ? ? bit_cnt?<=?0; ? ? rx_reg?<=?0; ??end ??else?begin ? ? rx_done?<=?1'b0; ? ?? ? ? case (state) ? ? ? IDLE: begin ? ? ? ? if(uart_rx_sync2 == 1'b0)?begin??//?檢測(cè)起始位 ? ? ? ? ? state?<=?START; ? ? ? ? ? baud_cnt?<=?HALF_BAUD_CNT?-?1; ?//?半位時(shí)間后采樣 ? ? ? ??end ? ? ??end ? ? ? ? ? ? ? ?? ? ? ??START:?begin ? ? ? ? if(baud_cnt?==?0)?begin ? ? ? ? ? if(uart_rx_sync2?==?1'b0) begin ?// 確認(rèn)起始位 ? ? ? ? ? ? state <= DATA; ? ? ? ? ? ? baud_cnt <= BAUD_CNT_MAX - 1; ? ? ? ? ? ? bit_cnt <= 0; ? ? ? ? ? end ? ? ? ? ? else begin ? ? ? ? ? ? state <= IDLE; ?// 假起始位 ? ? ? ? ? end ? ? ? ? end else begin ? ? ? ? ? baud_cnt <= baud_cnt - 1; ? ? ? ? end ? ? ? end ? ? ? ? ? ? ? ?? ? ? ? DATA: begin ? ? ? ? if(baud_cnt == 0) begin ? ? ? ? ? rx_reg[bit_cnt] <= uart_rx_sync2; ? ? ? ? ? if (bit_cnt == 3'd7)?begin ? ? ? ? ? ? state?<=?STOP; ? ? ? ? ??end ? ? ? ? ??else?begin ? ? ? ? ? ? bit_cnt?<=?bit_cnt?+?1; ? ? ? ? ??end ? ? ? ? ? baud_cnt?<=?BAUD_CNT_MAX?-?1; ? ? ? ??end? ? ? ? ??else?begin ? ? ? ? ? baud_cnt?<=?baud_cnt?-?1; ? ? ? ??end ? ? ??end ? ? ? ? ? ? ? ?? ? ? ? STOP:?begin ? ? ? ? if(baud_cnt?==?0)?begin ? ? ? ? ? rx_data?<=?rx_reg; ? ? ? ? ? rx_done?<=?1'b1; ? ? ? ? ? state <= IDLE; ? ? ? ? end ? ? ? ? else begin ? ? ? ? ? baud_cnt <= baud_cnt - 1; ? ? ? ? end ? ? ? end ? ? endcase ? end end endmodule
串口發(fā)送模塊同樣設(shè)置了一個(gè)4狀態(tài)的狀態(tài)機(jī):
空閑狀態(tài):空閑狀態(tài)保持高電平。
起始位發(fā)送狀態(tài):發(fā)送起始位,低電平。
數(shù)據(jù)發(fā)送狀態(tài):數(shù)據(jù)位從最低位(LSB)開(kāi)始發(fā)送,這是UART的標(biāo)準(zhǔn)格式。
停止位發(fā)送狀態(tài):發(fā)送停止位,高電平。

串口發(fā)送模塊的工程代碼:
module uart_tx( input clk, input rst_n, input tx_start, input [7:0] tx_data, output reg uart_tx, output tx_busy ); parameterCLK_FREQ =50000000; parameterBAUD_RATE =115200; // 波特率計(jì)數(shù)器 localparam BAUD_CNT_MAX = CLK_FREQ / BAUD_RATE; reg [15:0] baud_cnt; wire baud_tick = (baud_cnt ==0); // 狀態(tài)定義 localparam IDLE =2'd0; localparam START = 2'd1; localparamDATA=2'd2; localparam STOP = 2'd3; reg [1:0] state; reg [2:0] bit_cnt; reg [7:0] tx_reg; // 波特率計(jì)數(shù)器 always@(posedge clk or negedge rst_n)begin if(!rst_n)begin baud_cnt <=?0; ??end ??elseif(state != IDLE)?begin ? ??if(baud_cnt ==?0)?begin ? ? ? baud_cnt <= BAUD_CNT_MAX -?1; ? ??end ? ??else?begin ? ? ? baud_cnt <= baud_cnt -?1; ? ??end ??end ??else?begin ? ? baud_cnt <=?0; ??end end ? ?? ? ? // 狀態(tài)機(jī) always?@(posedge clk or negedge rst_n)?begin ??if(!rst_n)?begin ? ? state <= IDLE; ? ? uart_tx <=?1'b1; ? ? bit_cnt <= 0; ? ? tx_reg <= 0; ? end ? else begin ? ? case(state) ? ? ? IDLE: begin ? ? ? ? uart_tx <= 1'b1; ? ? ? ??if?(tx_start)?begin ? ? ? ? ? state <=?START; ? ? ? ? ? tx_reg <= tx_data; ? ? ? ??end ? ? ??end ? ? ? ? ? ? ? ?? ? ? ??START:?begin ? ? ? ??if(baud_tick)?begin ? ? ? ? ? uart_tx <=?1'b0; ? ? ? ? ? state <= DATA; ? ? ? ? ? bit_cnt <= 0; ? ? ? ? end ? ? ? end ? ? ? ? ? ? ? ?? ? ? ? DATA: begin ? ? ? ? if(baud_tick) begin ? ? ? ? ? uart_tx <= tx_reg[bit_cnt]; ? ? ? ? ? if (bit_cnt == 3'd7)?begin ? ? ? ? ? ? state <= STOP; ? ? ? ? ??end ? ? ? ? ??else?begin ? ? ? ? ? ? bit_cnt <= bit_cnt +?1; ? ? ? ? ??end ? ? ? ??end ? ? ??end ? ? ? ? ? ? ? ?? ? ? ? STOP:?begin ? ? ? ??if(baud_tick)?begin ? ? ? ? ? uart_tx <=?1'b1; ? ? ? ? ? state <= IDLE; ? ? ? ? end ? ? ? end ? ? endcase ? end end ? ?? ? ? assign tx_busy = (state != IDLE); endmodule
top文件代碼要完成的任務(wù)是:
只有在檢測(cè)到接收完成信號(hào)的上升沿時(shí)才啟動(dòng)發(fā)送
只有在發(fā)送器不忙時(shí)才啟動(dòng)新的發(fā)送
實(shí)現(xiàn)了接收數(shù)據(jù)到發(fā)送數(shù)據(jù)的無(wú)縫銜接
moduleDE23_Lite_uart( input clk, input rst_n, input uart_rx, output uart_tx ); /* synthesis keep */wire [7:0] rx_data; wire rx_done; wire rx_done_rise,tx_start; wire tx_busy; // UART接收模塊 uart_rx#( .CLK_FREQ(50000000), .BAUD_RATE(115200) ) uart_rx_inst ( .clk(clk), .rst_n(rst_n), .uart_rx(uart_rx), .rx_data(rx_data), .rx_done(rx_done) ); // UART發(fā)送模塊 uart_tx#( .CLK_FREQ(50000000), .BAUD_RATE(115200) ) uart_tx_inst ( .clk(clk), .rst_n(rst_n), .tx_start(tx_start), .tx_data(rx_data), .uart_tx(uart_tx), .tx_busy(tx_busy) ); // 回環(huán)控制邏輯 reg rx_done_reg; always @(posedge clkornegedge rst_n)begin if(!rst_n) begin rx_done_reg <=?1'b0; ? ? end?else?begin ? ? ? rx_done_reg <= rx_done; ? ? end ? end ? ?? ? ??// 檢測(cè)接收完成的上升沿 ? assign rx_done_rise = rx_done && !rx_done_reg; ? ?? ? ??// 發(fā)送啟動(dòng)信號(hào) ? assign tx_start = rx_done_rise && !tx_busy; endmodule
仿真代碼:
`timescale1ns/1ps
module DE23_Lite_uart_tb;
// 輸入
reg clk;
reg rst_n;
reg uart_rx;
// 輸出
wire uart_tx;
// 測(cè)試參數(shù)
parameter CLK_PERIOD =20; // 50MHz時(shí)鐘周期
parameter BIT_PERIOD =8680;// 115200波特率的位周期(1/115200 ≈ 8.68μs)
// 實(shí)例化頂層模塊
DE23_Lite_uartuut(
.clk(clk),
.rst_n(rst_n),
.uart_rx(uart_rx),
.uart_tx(uart_tx)
);
// 時(shí)鐘生成
always begin
clk =0;
#(CLK_PERIOD/2);
clk =1;
#(CLK_PERIOD/2);
end
// 測(cè)試任務(wù):發(fā)送一個(gè)字節(jié)
task send_byte;
input [7:0] data;
integer i;
begin
// 發(fā)送起始位
uart_rx =0;
#(BIT_PERIOD);
// 發(fā)送8個(gè)數(shù)據(jù)位
for(i =0; i 8; i = i +?1) begin
? ? ? ? uart_rx = data[i];
? ? ? ??#(BIT_PERIOD);
? ? ? end
? ? ? ? ? ??
? ? ? ? ? ??// 發(fā)送停止位
? ? ? uart_rx =?1;
? ? ??#(BIT_PERIOD);
? ? end
? endtask
? ??
? ??// 主測(cè)試程序
? initial begin
? ? ? ??// 初始化
? ? rst_n =?0;
? ? uart_rx =?1;
? ? ? ??
? ? ? ??// 復(fù)位
? ??#100;
? ? rst_n =?1;
? ??#100;
? ? ? ??
? ? ? ??// 測(cè)試1:發(fā)送字節(jié) 8'h55
? ? send_byte(8'h55);
? ? ? ??
? ? ? ??// 測(cè)試2:發(fā)送字節(jié) 8'hAA
? ? send_byte(8'hAA);
? ? ? ??
? ? ? ??// 測(cè)試3:發(fā)送字節(jié) 8'hF0
? ? send_byte(8'hF0);
? ? ? ??
? ? ? ??// 測(cè)試4:發(fā)送字節(jié) 8'h0F
? ? send_byte(8'h0F);
? ? ? ??
? ? ? ??// 結(jié)束仿真
? ??#10000;
? ? $stop;
? end
endmodule
modelsim仿真波形:

可以看到:
第一個(gè)波特位時(shí)間內(nèi),rx先發(fā)送低電平起始位,然后發(fā)送8bit數(shù)據(jù)01010101(低位在前,8'h55),最后發(fā)送高電平停止位;tx則一直是高電平。
第二個(gè)波特位時(shí)間內(nèi),rx先發(fā)送低電平起始位,然后rx發(fā)送第二個(gè)測(cè)試數(shù)據(jù)10101010(低位在前,8'hAA),最后發(fā)送高電平停止位;tx則接收到8bit數(shù)據(jù)01010101。
第三個(gè)波特位時(shí)間內(nèi),rx先發(fā)送低電平起始位,然后rx接收第二個(gè)測(cè)試數(shù)據(jù)11110000(低位在前,8'hF0),最后發(fā)送高電平停止位;tx則接收到8bit數(shù)據(jù)10101010。
第四個(gè)波特位時(shí)間內(nèi),rx先發(fā)送低電平起始位,然后rx接收第二個(gè)測(cè)試數(shù)據(jù)00001111(低位在前,8'h0F),最后發(fā)送高電平停止位;tx則接收到8bit數(shù)據(jù)11110000。
第五個(gè)波特位時(shí)間內(nèi),rx保持高電平;tx則接收到8bit數(shù)據(jù)00001111。
Quartus版本選擇:25.1,具體操作參考文章最新版Quartus Prime Pro 25.1 的安裝和使用演示(含Questa仿真)
引腳分配:

4下板測(cè)試

打開(kāi)串口工具比如Putty或者是下面截圖所示的XCOM,然后按照如下操作去測(cè)試:
選擇正確的COM口
波特率設(shè)置為115200
停止位設(shè)置為1位
無(wú)校驗(yàn)位
點(diǎn)擊打開(kāi)串口
在發(fā)送窗口隨便發(fā)送數(shù)據(jù),可以看到上面接收窗口得到同樣的數(shù)據(jù)顯示,表示測(cè)試成功。

-
FPGA
+關(guān)注
關(guān)注
1650文章
22214瀏覽量
627648 -
接口
+關(guān)注
關(guān)注
33文章
9296瀏覽量
155592 -
串口通信
+關(guān)注
關(guān)注
34文章
1653瀏覽量
57417 -
開(kāi)發(fā)板
+關(guān)注
關(guān)注
25文章
6021瀏覽量
110457 -
Agilex
+關(guān)注
關(guān)注
0文章
23瀏覽量
3956
原文標(biāo)題:2-基于FPGA開(kāi)發(fā)板DE23-Lite的串口通信設(shè)計(jì) (FT2232H)
文章出處:【微信號(hào):友晶FPGA,微信公眾號(hào):友晶FPGA】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
基于FPGA開(kāi)發(fā)板TSP的串口通信設(shè)計(jì)
基于DE1-SOC開(kāi)發(fā)板的太空射擊游戲
出售DE2-70 FPGA開(kāi)發(fā)板
Altera DE2 開(kāi)發(fā)板測(cè)試說(shuō)明
基于FPGA了解DE2開(kāi)發(fā)板
fpga開(kāi)發(fā)板用途,fpga開(kāi)發(fā)板價(jià)格
ALTERA公司的DE1 SoC FPGA開(kāi)發(fā)板的培訓(xùn)教程免費(fèi)下載
使用小凌派開(kāi)發(fā)板wifi進(jìn)行tcp通信的步驟
上位機(jī)和FPGA開(kāi)發(fā)板--串口通信實(shí)驗(yàn)
基于STM32F4開(kāi)發(fā)板的激光測(cè)距模塊串口通信(三)

基于FPGA開(kāi)發(fā)板DE23-Lite的串口通信設(shè)計(jì)
評(píng)論