1開發(fā)板串口簡介
DE23-Lite開發(fā)板提供了一個UART通信接口(物理接口是下圖的Type C接口),用戶能夠通過主機與Agilex 3 FPGA進行串口通信。

該接口使用DE23-Lite板載的USB Blaster III電路中的FT2232H芯片作為UART轉USB的橋梁。將USB線連接到DE23-Lite板的Type-C接口和主機之間,即可啟用USB Blaster III和FPGA UART功能,此時無需串行驅動程序,但用戶在使用UART功能前需要確保已安裝USB Blaster III驅動程序。

連接USB線后,通常在PC設備管理器中會顯示USB Blaster III和一個COM端口號。

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

串口時序圖如下:

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

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

接收模塊工程代碼:
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; //波特率計數(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; //同步輸入信號 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)機 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??//?檢測起始位 ? ? ? ? ? state?<=?START; ? ? ? ? ? baud_cnt?<=?HALF_BAUD_CNT?-?1; ?//?半位時間后采樣 ? ? ? ??end ? ? ??end ? ? ? ? ? ? ? ?? ? ? ??START:?begin ? ? ? ? if(baud_cnt?==?0)?begin ? ? ? ? ? if(uart_rx_sync2?==?1'b0) begin ?// 確認起始位 ? ? ? ? ? ? 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ā)送模塊同樣設置了一個4狀態(tài)的狀態(tài)機:
空閑狀態(tài):空閑狀態(tài)保持高電平。
起始位發(fā)送狀態(tài):發(fā)送起始位,低電平。
數(shù)據(jù)發(fā)送狀態(tài):數(shù)據(jù)位從最低位(LSB)開始發(fā)送,這是UART的標準格式。
停止位發(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; // 波特率計數(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; // 波特率計數(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)機 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文件代碼要完成的任務是:
只有在檢測到接收完成信號的上升沿時才啟動發(fā)送
只有在發(fā)送器不忙時才啟動新的發(fā)送
實現(xiàn)了接收數(shù)據(jù)到發(fā)送數(shù)據(jù)的無縫銜接
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 ? ?? ? ??// 檢測接收完成的上升沿 ? assign rx_done_rise = rx_done && !rx_done_reg; ? ?? ? ??// 發(fā)送啟動信號 ? 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;
// 測試參數(shù)
parameter CLK_PERIOD =20; // 50MHz時鐘周期
parameter BIT_PERIOD =8680;// 115200波特率的位周期(1/115200 ≈ 8.68μs)
// 實例化頂層模塊
DE23_Lite_uartuut(
.clk(clk),
.rst_n(rst_n),
.uart_rx(uart_rx),
.uart_tx(uart_tx)
);
// 時鐘生成
always begin
clk =0;
#(CLK_PERIOD/2);
clk =1;
#(CLK_PERIOD/2);
end
// 測試任務:發(fā)送一個字節(jié)
task send_byte;
input [7:0] data;
integer i;
begin
// 發(fā)送起始位
uart_rx =0;
#(BIT_PERIOD);
// 發(fā)送8個數(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
? ??
? ??// 主測試程序
? initial begin
? ? ? ??// 初始化
? ? rst_n =?0;
? ? uart_rx =?1;
? ? ? ??
? ? ? ??// 復位
? ??#100;
? ? rst_n =?1;
? ??#100;
? ? ? ??
? ? ? ??// 測試1:發(fā)送字節(jié) 8'h55
? ? send_byte(8'h55);
? ? ? ??
? ? ? ??// 測試2:發(fā)送字節(jié) 8'hAA
? ? send_byte(8'hAA);
? ? ? ??
? ? ? ??// 測試3:發(fā)送字節(jié) 8'hF0
? ? send_byte(8'hF0);
? ? ? ??
? ? ? ??// 測試4:發(fā)送字節(jié) 8'h0F
? ? send_byte(8'h0F);
? ? ? ??
? ? ? ??// 結束仿真
? ??#10000;
? ? $stop;
? end
endmodule
modelsim仿真波形:

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

4下板測試

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

-
FPGA
+關注
關注
1650文章
22217瀏覽量
628048 -
接口
+關注
關注
33文章
9307瀏覽量
155713 -
串口通信
+關注
關注
34文章
1653瀏覽量
57458 -
開發(fā)板
+關注
關注
25文章
6027瀏覽量
110731 -
Agilex
+關注
關注
0文章
23瀏覽量
3960
原文標題:2-基于FPGA開發(fā)板DE23-Lite的串口通信設計 (FT2232H)
文章出處:【微信號:友晶FPGA,微信公眾號:友晶FPGA】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
基于FPGA開發(fā)板TSP的串口通信設計
出售DE2-70 FPGA開發(fā)板
Altera DE2 開發(fā)板測試說明
基于FPGA了解DE2開發(fā)板
fpga開發(fā)板用途,fpga開發(fā)板價格
ALTERA公司的DE1 SoC FPGA開發(fā)板的培訓教程免費下載
上位機和FPGA開發(fā)板--串口通信實驗
基于STM32F4開發(fā)板的激光測距模塊串口通信(三)

基于FPGA開發(fā)板DE23-Lite的串口通信設計
評論