串口監(jiān)視系統(tǒng)設(shè)計(jì)
實(shí)驗(yàn)任務(wù)
實(shí)驗(yàn)?zāi)康?/h4>本實(shí)驗(yàn)主要學(xué)習(xí)串口(UART)總線工作原理、協(xié)議及相關(guān)知識(shí),練習(xí)如何使用FPGA驅(qū)動(dòng)CP2102模塊實(shí)現(xiàn)串口通信設(shè)計(jì),同時(shí)復(fù)習(xí)上節(jié)中掃描式數(shù)碼管模塊的實(shí)例化應(yīng)用。
本文引用地址:http://2s4d.com/article/202312/453843.htm設(shè)計(jì)框圖
根據(jù)前面的實(shí)驗(yàn)解析我們可以得知,該設(shè)計(jì)可以拆分成三個(gè)功能模塊實(shí)現(xiàn),
頂層模塊DisplayCtl通過(guò)實(shí)例化兩個(gè)子模塊并將對(duì)應(yīng)的信號(hào)連接,最終實(shí)現(xiàn)串口監(jiān)視系統(tǒng)的總體設(shè)計(jì)。UART通信是全雙工的,接收和發(fā)送是兩個(gè)獨(dú)立的設(shè)計(jì),本實(shí)驗(yàn)只需要接收數(shù)據(jù),串口通信有兩個(gè)關(guān)鍵因素:傳輸格式和傳輸速率,我們可以用兩個(gè)模塊分別實(shí)現(xiàn): * Baud:控制UART通信數(shù)據(jù)傳輸速率。 * UartRx:根據(jù)數(shù)據(jù)傳輸速率節(jié)拍控制UART通信數(shù)據(jù)格式。
實(shí)驗(yàn)原理
UART接口介紹
在嵌入式領(lǐng)域里說(shuō)的串口一般就是說(shuō)的UART接口,通用異步收發(fā)傳輸器(Universal Asynchronous Receiver/Transmitter),通常稱作UART,是一種通用串行數(shù)據(jù)總線,用于異步通信。該總線雙向通信,可以實(shí)現(xiàn)全雙工傳輸和接收。
在系統(tǒng)或計(jì)算機(jī)中說(shuō)的串口一般就是說(shuō)的RS232接口,也叫COM口,也叫DB9,老式的電腦和臺(tái)式機(jī)上一般都有這個(gè)接口,接口有9個(gè)引腳,最重要的三個(gè)引腳:TXD、RXD、GND,基本通信邏輯與UART完全一致,為了增加串口通信的抗干擾能力,RS232串行通信接口定義了自己的電平標(biāo)準(zhǔn),采用負(fù)邏輯電平,它定義+5~+12V為低電平,而-12~-5V為高電平,相當(dāng)于在UART的基礎(chǔ)上增加驅(qū)動(dòng)器,將原來(lái)UART通信電平標(biāo)準(zhǔn)調(diào)整為RS232的電平標(biāo)準(zhǔn),通信原理如下:
隨著技術(shù)的發(fā)展,各種通信接口種類越來(lái)越多,方案越來(lái)越穩(wěn)定,成本越來(lái)越低,體積越來(lái)越小巧,RS232串口通信接口方案逐漸被拋棄,取而代之的是各種更高速,更穩(wěn)定,更小巧的接口,USB就是其中應(yīng)用較廣的,為了實(shí)現(xiàn)UART通信,一種USB轉(zhuǎn)UART的方案被廣泛應(yīng)用,常用的USB轉(zhuǎn)UART方案有CP2102、FT232、CH340等等
我們STEP BaseBoard V3.0底板集成的UART通信模塊就是采用CP2102方案,F(xiàn)PGA通過(guò)UART總線驅(qū)動(dòng)CP2102實(shí)現(xiàn)USB和UART之間的數(shù)據(jù)通信,最終實(shí)現(xiàn)FPGA與電腦之間的數(shù)據(jù)傳輸,UART通信的時(shí)序如下。
UART模塊連接
STEP BaseBoard V3.0底板上的基于CP2102方案的UART通信模塊電路圖如下:
上圖為基于CP2102方案的UART通信模塊電路圖,可以看到CP2102方案非常簡(jiǎn)潔,無(wú)需外置USB通信時(shí)鐘晶體(內(nèi)部集成),CP2102芯片TXD和RXD分別與FPGA芯片RXD和TXD連接,同時(shí)兩個(gè)信號(hào)都連接了LED燈,這樣當(dāng)UART通信時(shí),隨著數(shù)據(jù)傳輸對(duì)應(yīng)LED燈也會(huì)快速閃爍,起到UART通信指示燈的作用。CP2102芯片DTR和RTS通過(guò)兩個(gè)三極管搭建流控電路,連接WIFI模塊ESP8266-12F,使用UART模塊燒寫ESP8266模塊的固件時(shí)就無(wú)需手動(dòng)進(jìn)入固件燒寫模式了,這個(gè)會(huì)在后續(xù)涉及WIFI通信的實(shí)驗(yàn)中詳細(xì)介紹,這里可以不用理會(huì)。
UART驅(qū)動(dòng)實(shí)現(xiàn)
SPI、I2C、UART總線對(duì)比表:
SPI總線 I2C總線 UART總線 SS SCL TXD SCK SDA RXD MOSI/MISO
對(duì)于SPI總線,通信雙方在總線使能的情況下,通過(guò)SCK的上升沿或下降沿觸發(fā)完成總線數(shù)據(jù)的采樣,這樣通信雙方就可以準(zhǔn)確的接收到對(duì)方傳送的數(shù)據(jù)了。對(duì)于I2C總線,通信接收方通過(guò)SCL的高電平觸發(fā)完成總線數(shù)據(jù)的采樣。綜上,SPI總線中的SCK和I2C總線中的SCL在通信中起到時(shí)鐘的作用,接收方都是根據(jù)時(shí)鐘的對(duì)應(yīng)狀態(tài)采樣數(shù)據(jù),最終保證通信能夠正常進(jìn)行。
對(duì)于UART總線,TXD和RXD分別用于發(fā)送和接收數(shù)據(jù),相當(dāng)于兩根獨(dú)立工作的單線總線,沒(méi)有了時(shí)鐘線的配合,那么接收端應(yīng)該怎樣獲取發(fā)送端傳輸?shù)臄?shù)據(jù)呢?其實(shí)也是有方法的,那就是通信雙方需要約定好UART總線數(shù)據(jù)傳輸?shù)?span id="fvwiygh" class="wrap_hi" style="box-sizing: border-box; background-color: rgb(255, 255, 153); overflow: hidden;">通信速率和時(shí)序格式。
通信速率
UART的數(shù)據(jù)傳輸速度用波特率來(lái)描述,也就是UART每秒接收或發(fā)送的數(shù)據(jù)位。例如9600波特率表示每秒鐘發(fā)送或接收9600比特的數(shù)據(jù),即發(fā)送端需要將發(fā)送的每個(gè)數(shù)據(jù)位保持對(duì)應(yīng)的時(shí)間,計(jì)算如下:
小腳丫硬件上使用12MHz的時(shí)鐘晶振,如果以12MHz時(shí)鐘信號(hào)作為系統(tǒng)時(shí)鐘,使用計(jì)數(shù)器延時(shí)完成UART通信數(shù)據(jù)采樣,那么計(jì)數(shù)器延時(shí)計(jì)數(shù)終值計(jì)算如下:
因?yàn)椴ㄌ芈适菂f(xié)議里約定的,為保證協(xié)議的通用性和靈活性,波特率參數(shù)有固定的選項(xiàng),不可以隨意設(shè)置(如果UART通信雙方都是自己編程的,可以根據(jù)自己的要求定義自己需要的波特率,這種情況除外),波特率參數(shù)選項(xiàng)很多,大家可以打開(kāi)串口調(diào)試助手工具找到波特率配置列表查看,我們比較常用的波特率值有以下幾種:
UART常用波特率:
1200 4800 9600 38400 115200
時(shí)序格式
關(guān)于時(shí)序格式在前面UART接口介紹部分也簡(jiǎn)單說(shuō)了一下,通信過(guò)程中時(shí)序依次為:起始位、數(shù)據(jù)位、校驗(yàn)位、停止位、空閑位,其中數(shù)據(jù)位可以是5~8位,本設(shè)計(jì)我們使用8位數(shù)據(jù),校驗(yàn)位可以省略,最后確定的時(shí)序格式如下:
前面所說(shuō)的通信速率和時(shí)序格式其實(shí)就是UART通信中的兩個(gè)重要的參數(shù),需要傳輸?shù)臄?shù)據(jù)根據(jù)通信速率的節(jié)拍按照UART的時(shí)序格式輸出,就可以實(shí)現(xiàn)UART通信了,可以按照下面三個(gè)步驟實(shí)現(xiàn)。
例如,將8‘h73和8’h5a通過(guò)UART發(fā)送的時(shí)序,紅色箭頭為波特率對(duì)應(yīng)的節(jié)拍點(diǎn)
對(duì)于UART發(fā)送數(shù)據(jù)來(lái)說(shuō),波特率節(jié)拍是自己產(chǎn)生的,數(shù)據(jù)是自己主動(dòng)發(fā)出的,邏輯相對(duì)簡(jiǎn)單,而當(dāng)UART接收數(shù)據(jù)的時(shí)候,因?yàn)椴淮_定對(duì)方什么時(shí)候發(fā)送數(shù)據(jù),所以需要對(duì)RX信號(hào)持續(xù)檢測(cè),當(dāng)檢測(cè)到有數(shù)據(jù)傳送時(shí),根據(jù)約定的波特率節(jié)拍采樣,可以按照下面三個(gè)步驟實(shí)現(xiàn)。
例如,當(dāng)UART的RX端接收到數(shù)據(jù)8‘h73和8’h5a的時(shí)候,紅色箭頭為檢測(cè)到數(shù)據(jù)傳輸?shù)狞c(diǎn),綠色箭頭為對(duì)應(yīng)的采樣節(jié)拍點(diǎn)(采樣點(diǎn)在數(shù)據(jù)中間最是穩(wěn)定)。
通過(guò)以上理論,我們了解了UART發(fā)送和接收數(shù)據(jù)的整個(gè)流程,兩個(gè)過(guò)程中我們都需要波特率節(jié)拍,那么我們就可以設(shè)計(jì)一個(gè)節(jié)拍模塊Baud,這樣我們的發(fā)送和接收都可以實(shí)例化節(jié)拍模塊用于產(chǎn)生對(duì)應(yīng)波特率的節(jié)拍信號(hào)。
節(jié)拍模塊Baud設(shè)計(jì)實(shí)現(xiàn):
節(jié)拍模塊Baud的端口程序?qū)崿F(xiàn)如下:
module Baud #
(
parameter BPS_PARA = 1250 //12MHz時(shí)鐘時(shí)參數(shù)1250對(duì)應(yīng)9600的波特率
)
(
input clk, //系統(tǒng)時(shí)鐘
input rst_n, //系統(tǒng)復(fù)位,低有效
input bps_en, //接收或發(fā)送時(shí)鐘使能
output reg bps_clk //接收或發(fā)送時(shí)鐘輸出
);
設(shè)計(jì)一個(gè)計(jì)數(shù)器用于分頻產(chǎn)生對(duì)應(yīng)波特率節(jié)拍信號(hào),因?yàn)閁ART隨時(shí)可能接收數(shù)據(jù),所以節(jié)拍模塊必須隨時(shí)待命,保持計(jì)數(shù)器清零,當(dāng)需要節(jié)拍信號(hào)時(shí)精準(zhǔn)地輸出。
計(jì)數(shù)器設(shè)計(jì)程序?qū)崿F(xiàn)如下:
reg [12:0] cnt;//計(jì)數(shù)器計(jì)數(shù)滿足波特率時(shí)鐘要求
always @ (posedge clk or negedge rst_n) begin
if(!rst_n)
cnt <= 1'b0;
else if((cnt >= BPS_PARA-1)||(!bps_en)) //當(dāng)時(shí)鐘信號(hào)不使能(bps_en為低電平)時(shí),計(jì)數(shù)器清零并停止計(jì)數(shù)
cnt <= 1'b0; //當(dāng)時(shí)鐘信號(hào)使能時(shí),計(jì)數(shù)器對(duì)系統(tǒng)時(shí)鐘計(jì)數(shù),周期為BPS_PARA個(gè)系統(tǒng)時(shí)鐘周期
else
cnt <= cnt + 1'b1;
end
當(dāng)bpsen(高有效)使能,計(jì)數(shù)器計(jì)數(shù)周期由參數(shù)BPSPARA來(lái)決定,前面數(shù)據(jù)接收時(shí)序部分了解到,從RX檢測(cè)到下降沿開(kāi)始計(jì)數(shù)器工作,到數(shù)據(jù)采樣點(diǎn)需要半個(gè)節(jié)拍的時(shí)間,而數(shù)據(jù)發(fā)送時(shí)只要保證相鄰兩個(gè)節(jié)拍點(diǎn)之間的時(shí)間為一個(gè)計(jì)數(shù)器周期即可,所以我們可以在計(jì)數(shù)器計(jì)數(shù)到中值時(shí)產(chǎn)生一個(gè)脈沖信號(hào)充當(dāng)節(jié)拍信號(hào)。
節(jié)拍信號(hào)產(chǎn)生程序?qū)崿F(xiàn)如下:
//產(chǎn)生相應(yīng)波特率的時(shí)鐘節(jié)拍,接收模塊將以此節(jié)拍進(jìn)行UART數(shù)據(jù)接收
always @ (posedge clk or negedge rst_n) begin
if(!rst_n)
bps_clk <= 1'b0;
else if(cnt == (BPS_PARA>>1)) //右移一位等于除以2,終值BPS_PARA為數(shù)據(jù)更替點(diǎn),中值數(shù)據(jù)穩(wěn)定,做采樣點(diǎn)
bps_clk <= 1'b1;
else
bps_clk <= 1'b0;
end
發(fā)送模塊Uart_Tx設(shè)計(jì)實(shí)現(xiàn):
前級(jí)電路通過(guò)txdatavalid和txdatain將需要發(fā)送的數(shù)據(jù)傳輸進(jìn)來(lái),當(dāng)txdatavalid有脈沖信號(hào)時(shí),txdatain信號(hào)為有效數(shù)據(jù),拼接起始位和停止位后賦值給txdatar,同時(shí)控制節(jié)拍使能信號(hào)使能并自鎖,然后等發(fā)送完10bit數(shù)據(jù)后解除使能。
數(shù)據(jù)發(fā)送控制程序?qū)崿F(xiàn)如下:
output reg bps_en; //發(fā)送時(shí)鐘使能
input bps_clk; //發(fā)送時(shí)鐘輸入
input tx_data_valid; //發(fā)送數(shù)據(jù)有效脈沖
input [7:0] tx_data_in; //要發(fā)送的數(shù)據(jù)
output reg uart_tx; //UART發(fā)送輸出
reg [3:0] num;
reg [9:0] tx_data_r; //融合了起始位和停止位的數(shù)據(jù)//驅(qū)動(dòng)發(fā)送數(shù)據(jù)操作
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
bps_en <= 1'b0;
tx_data_r <= 10'd0;
end else if(tx_data_valid && (!bps_en))begin
bps_en <= 1'b1; //當(dāng)檢測(cè)到接收時(shí)鐘使能信號(hào)的下降沿,表明接收完成,需要發(fā)送數(shù)據(jù),使能發(fā)送時(shí)鐘使能信號(hào)
tx_data_r <= {1'b1,tx_data_in,1'b0};
end else if(num==4'd10) begin
bps_en <= 1'b0; //一次UART發(fā)送需要10個(gè)時(shí)鐘信號(hào),然后結(jié)束
end
end
UART數(shù)據(jù)發(fā)送時(shí)序程序?qū)崿F(xiàn)如下:
//當(dāng)處于工作狀態(tài)中時(shí),按照發(fā)送時(shí)鐘的節(jié)拍發(fā)送數(shù)據(jù)
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
num <= 1'b0;
uart_tx <= 1'b1;
end else if(bps_en) begin
if(bps_clk) begin
num <= num + 1'b1;
uart_tx <= tx_data_r[num];
end else if(num>=4'd10)
num <= 4'd0;
end
end
將節(jié)拍模塊Baud和發(fā)送模塊Uart_tx實(shí)例化并連接,完成發(fā)送功能的設(shè)計(jì),如下
接收模塊Uart_Rx設(shè)計(jì)實(shí)現(xiàn):
首先對(duì)RX信號(hào)多級(jí)緩存消除亞穩(wěn)態(tài),同時(shí)檢測(cè)下降沿,程序?qū)崿F(xiàn)如下:
input uart_rx; //UART接收輸入
reg uart_rx0,uart_rx1,uart_rx2; //多級(jí)延時(shí)鎖存去除亞穩(wěn)態(tài)
always @ (posedge clk) begin
uart_rx0 <= uart_rx;
uart_rx1 <= uart_rx0;
uart_rx2 <= uart_rx1;
end //檢測(cè)UART接收輸入信號(hào)的下降沿
wire neg_uart_rx = uart_rx2 & ~uart_rx1;
當(dāng)檢測(cè)RX有下降沿后,使能節(jié)拍使能信號(hào),同時(shí)自鎖直到完成接收操作后再?gòu)?fù)位節(jié)拍使能信號(hào)。程序?qū)崿F(xiàn)如下:
reg [3:0] num; //接收時(shí)鐘使能信號(hào)的控制
always @ (posedge clk or negedge rst_n) begin
if(!rst_n)
bps_en <= 1'b0;
else if(neg_uart_rx && (!bps_en))
//當(dāng)空閑狀態(tài)(bps_en為低電平)時(shí)檢測(cè)到UART接收信號(hào)下降沿,進(jìn)入工作狀態(tài)(bps_en為高電平),控制時(shí)鐘模塊產(chǎn)生接收時(shí)鐘
bps_en <= 1'b1;
else if(num==4'd9) //當(dāng)完成一次UART接收操作后,退出工作狀態(tài),恢復(fù)空閑狀態(tài)
bps_en <= 1'b0;
end
根據(jù)節(jié)拍信號(hào)完成UART總線的數(shù)據(jù)采樣,得到8位有效數(shù)據(jù),程序?qū)崿F(xiàn)如下:
reg [7:0] rx_data;//當(dāng)處于工作狀態(tài)中時(shí),按照接收時(shí)鐘的節(jié)拍獲取數(shù)據(jù)
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
num <= 4'd0;
rx_data <= 8'd0;
end else if(bps_en) begin
if(bps_clk) begin
num <= num + 1'b1;
if(num<=4'd8) rx_data[num-1] <= uart_rx1; //先接受低位再接收高位,8位有效數(shù)據(jù)
end else if(num == 4'd9) begin //完成一次UART接收操作后,將獲取的數(shù)據(jù)輸出
num <= 4'd0;
end
end else begin
num <= 4'd0;
end
end
當(dāng)UART接收操作完成后,將得到的8位有效數(shù)據(jù)輸出給后級(jí)電路,程序?qū)崿F(xiàn)如下:
//將接收的數(shù)據(jù)輸出,同時(shí)控制輸出有效信號(hào)產(chǎn)生脈沖
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
rx_data_out <= 8'd0;
rx_data_valid <= 1'b0;
end else if(num == 4'd9) begin
rx_data_out <= rx_data;
rx_data_valid <= 1'b1;
end else begin
rx_data_out <= rx_data_out;
rx_data_valid <= 1'b0;
end
end
最后將節(jié)拍模塊Baud和接收模塊Uart_rx實(shí)例化并連接,完成發(fā)送功能的設(shè)計(jì),如下
整個(gè)UART驅(qū)動(dòng)設(shè)計(jì)是由兩個(gè)獨(dú)立的功能組合而成:發(fā)送功能部分和接收功能部分。UART功能總體設(shè)計(jì)框圖如下:
當(dāng)我們需要UART發(fā)送數(shù)據(jù)的時(shí)候只需要實(shí)例化發(fā)送功能部分設(shè)計(jì),需要UART接收數(shù)據(jù)的時(shí)候只需要實(shí)例化接收功能部分設(shè)計(jì),例如本設(shè)計(jì)中FPGA驅(qū)動(dòng)UART模塊接收電腦串口調(diào)試助手發(fā)出的數(shù)據(jù),所以我們就只需要實(shí)例化接收功能部分設(shè)計(jì)即可。
系統(tǒng)總體實(shí)現(xiàn)
剛剛學(xué)習(xí)了UART通信模塊,本設(shè)計(jì)只需要使用接收功能部分設(shè)計(jì),每一次通信都會(huì)得到一個(gè)8位數(shù)據(jù),怎樣將8位數(shù)據(jù)對(duì)應(yīng)得數(shù)據(jù)顯示在數(shù)碼管上呢?我來(lái)先來(lái)了解一下UART接受到的8位數(shù)據(jù)與要顯示數(shù)字的關(guān)系
上圖為電腦端友善串口調(diào)試助手的界面,當(dāng)我們將硬件連接,在串口設(shè)置串口選定串口對(duì)應(yīng)的端口,并按上圖配置波特率、數(shù)據(jù)位、校驗(yàn)位、停止位、流控等,點(diǎn)擊開(kāi)始建立連接,接下來(lái)我們就可以在串口發(fā)送窗口輸入要發(fā)送的數(shù)據(jù),點(diǎn)擊發(fā)送后數(shù)據(jù)傳輸出去。在發(fā)送設(shè)置有兩個(gè)選項(xiàng):ASCII和Hex ,
我們?cè)O(shè)計(jì)一個(gè)32位的移位寄存器對(duì)應(yīng)8位數(shù)碼管,按照BCD碼格式每4位表示一個(gè)數(shù)字,每次接收到UART數(shù)據(jù)都存到移位寄存器中,同時(shí)控制數(shù)碼管顯示相應(yīng)的數(shù)碼管位,Decoder程序?qū)崿F(xiàn)如下:
`ifdef HEX_FORMAT //如果用define定義過(guò)HEX_FORMAT
//采用16進(jìn)制格式,接收到的數(shù)據(jù)等于數(shù)值本身
wire [7:0] seg_data_r = rx_data_out; //移位寄存器,對(duì)應(yīng)8位數(shù)碼管數(shù)據(jù)BCD碼
always @ (posedge rx_data_valid or negedge rst_n) begin
if(!rst_n) seg_data <= 1'b0;
else seg_data <= {seg_data[23:0],seg_data_r};
end //移位寄存器,對(duì)應(yīng)8位數(shù)碼管數(shù)據(jù)顯示使能
always @ (posedge rx_data_valid or negedge rst_n) begin
if(!rst_n) data_en <= 1'b0;
else data_en <= {data_en[5:0],2'b11};
end`else
//采用字符格式,接收到的數(shù)據(jù)為字符ASCII碼值,與數(shù)字值相差48
wire [7:0] seg_data_r = rx_data_out - 8'd48; //移位寄存器,對(duì)應(yīng)8位數(shù)碼管數(shù)據(jù)BCD碼
always @ (posedge rx_data_valid or negedge rst_n) begin
if(!rst_n) seg_data <= 1'b0;
else seg_data <= {seg_data[27:0],seg_data_r[3:0]};
end //移位寄存器,對(duì)應(yīng)8位數(shù)碼管數(shù)據(jù)顯示使能
always @ (posedge rx_data_valid or negedge rst_n) begin
if(!rst_n) data_en <= 1'b0;
else data_en <= {data_en[6:0],1'b1};
end
`endif
上面程序中ifdef……
else……endif語(yǔ)句為預(yù)編譯指令,與C預(yù)演類似。如果我們使用串口助手Hex(16進(jìn)制)格式發(fā)送數(shù)據(jù),需要在程序中使用define定義參數(shù)HEX_FORMAT,如果使用ASCII格式發(fā)送數(shù)據(jù),則不需要定義。 <code verilog>
define HEXFORMAT 串口助手使用Hex格式發(fā)送時(shí)定義HEX_FORMAT,否則不定義 </code> 綜合后的設(shè)計(jì)框圖如下:
#### 實(shí)驗(yàn)步驟 - 雙擊打開(kāi)Quartus Prime工具軟件; - 新建工程:File → New Project Wizard(工程命名,工程目錄選擇,設(shè)備型號(hào)選擇,EDA工具選擇); - 新建文件:File → New → Verilog HDL File,鍵入設(shè)計(jì)代碼并保存; - 設(shè)計(jì)綜合:雙擊Tasks窗口頁(yè)面下的Analysis & Synthesis對(duì)代碼進(jìn)行綜合; - 管腳約束:Assignments → Assignment Editor,根據(jù)項(xiàng)目需求分配管腳; - 設(shè)計(jì)編譯:雙擊Tasks窗口頁(yè)面下的Compile Design對(duì)設(shè)計(jì)進(jìn)行整體編譯并生成配置文件; - 程序燒錄:點(diǎn)擊Tools → Programmer打開(kāi)配置工具,Program進(jìn)行下載; - 觀察設(shè)計(jì)運(yùn)行結(jié)果。 #### 實(shí)驗(yàn)現(xiàn)象 使用兩根Micro-USB線同時(shí)連接核心板和底板的USB接口,將程序下載到FPGA中,數(shù)碼管處于不顯示的狀態(tài),打開(kāi)電腦上的串口調(diào)試助手,按照前面圖片配置相應(yīng)參數(shù),在數(shù)據(jù)發(fā)送窗口輸入數(shù)字,點(diǎn)擊發(fā)送觀察底板數(shù)碼管的變化,重新輸入數(shù)字,點(diǎn)擊發(fā)送再次觀察底板數(shù)碼管的變化。
本實(shí)驗(yàn)主要學(xué)習(xí)串口(UART)總線工作原理、協(xié)議及相關(guān)知識(shí),練習(xí)如何使用FPGA驅(qū)動(dòng)CP2102模塊實(shí)現(xiàn)串口通信設(shè)計(jì),同時(shí)復(fù)習(xí)上節(jié)中掃描式數(shù)碼管模塊的實(shí)例化應(yīng)用。
本文引用地址:http://2s4d.com/article/202312/453843.htm根據(jù)前面的實(shí)驗(yàn)解析我們可以得知,該設(shè)計(jì)可以拆分成三個(gè)功能模塊實(shí)現(xiàn),
頂層模塊DisplayCtl通過(guò)實(shí)例化兩個(gè)子模塊并將對(duì)應(yīng)的信號(hào)連接,最終實(shí)現(xiàn)串口監(jiān)視系統(tǒng)的總體設(shè)計(jì)。UART通信是全雙工的,接收和發(fā)送是兩個(gè)獨(dú)立的設(shè)計(jì),本實(shí)驗(yàn)只需要接收數(shù)據(jù),串口通信有兩個(gè)關(guān)鍵因素:傳輸格式和傳輸速率,我們可以用兩個(gè)模塊分別實(shí)現(xiàn): * Baud:控制UART通信數(shù)據(jù)傳輸速率。 * UartRx:根據(jù)數(shù)據(jù)傳輸速率節(jié)拍控制UART通信數(shù)據(jù)格式。
在嵌入式領(lǐng)域里說(shuō)的串口一般就是說(shuō)的UART接口,通用異步收發(fā)傳輸器(Universal Asynchronous Receiver/Transmitter),通常稱作UART,是一種通用串行數(shù)據(jù)總線,用于異步通信。該總線雙向通信,可以實(shí)現(xiàn)全雙工傳輸和接收。
在系統(tǒng)或計(jì)算機(jī)中說(shuō)的串口一般就是說(shuō)的RS232接口,也叫COM口,也叫DB9,老式的電腦和臺(tái)式機(jī)上一般都有這個(gè)接口,接口有9個(gè)引腳,最重要的三個(gè)引腳:TXD、RXD、GND,基本通信邏輯與UART完全一致,為了增加串口通信的抗干擾能力,RS232串行通信接口定義了自己的電平標(biāo)準(zhǔn),采用負(fù)邏輯電平,它定義+5~+12V為低電平,而-12~-5V為高電平,相當(dāng)于在UART的基礎(chǔ)上增加驅(qū)動(dòng)器,將原來(lái)UART通信電平標(biāo)準(zhǔn)調(diào)整為RS232的電平標(biāo)準(zhǔn),通信原理如下:
隨著技術(shù)的發(fā)展,各種通信接口種類越來(lái)越多,方案越來(lái)越穩(wěn)定,成本越來(lái)越低,體積越來(lái)越小巧,RS232串口通信接口方案逐漸被拋棄,取而代之的是各種更高速,更穩(wěn)定,更小巧的接口,USB就是其中應(yīng)用較廣的,為了實(shí)現(xiàn)UART通信,一種USB轉(zhuǎn)UART的方案被廣泛應(yīng)用,常用的USB轉(zhuǎn)UART方案有CP2102、FT232、CH340等等
我們STEP BaseBoard V3.0底板集成的UART通信模塊就是采用CP2102方案,F(xiàn)PGA通過(guò)UART總線驅(qū)動(dòng)CP2102實(shí)現(xiàn)USB和UART之間的數(shù)據(jù)通信,最終實(shí)現(xiàn)FPGA與電腦之間的數(shù)據(jù)傳輸,UART通信的時(shí)序如下。
STEP BaseBoard V3.0底板上的基于CP2102方案的UART通信模塊電路圖如下:
上圖為基于CP2102方案的UART通信模塊電路圖,可以看到CP2102方案非常簡(jiǎn)潔,無(wú)需外置USB通信時(shí)鐘晶體(內(nèi)部集成),CP2102芯片TXD和RXD分別與FPGA芯片RXD和TXD連接,同時(shí)兩個(gè)信號(hào)都連接了LED燈,這樣當(dāng)UART通信時(shí),隨著數(shù)據(jù)傳輸對(duì)應(yīng)LED燈也會(huì)快速閃爍,起到UART通信指示燈的作用。CP2102芯片DTR和RTS通過(guò)兩個(gè)三極管搭建流控電路,連接WIFI模塊ESP8266-12F,使用UART模塊燒寫ESP8266模塊的固件時(shí)就無(wú)需手動(dòng)進(jìn)入固件燒寫模式了,這個(gè)會(huì)在后續(xù)涉及WIFI通信的實(shí)驗(yàn)中詳細(xì)介紹,這里可以不用理會(huì)。
SPI、I2C、UART總線對(duì)比表:
SPI總線 | I2C總線 | UART總線 |
SS | SCL | TXD |
SCK | SDA | RXD |
MOSI/MISO |
對(duì)于SPI總線,通信雙方在總線使能的情況下,通過(guò)SCK的上升沿或下降沿觸發(fā)完成總線數(shù)據(jù)的采樣,這樣通信雙方就可以準(zhǔn)確的接收到對(duì)方傳送的數(shù)據(jù)了。對(duì)于I2C總線,通信接收方通過(guò)SCL的高電平觸發(fā)完成總線數(shù)據(jù)的采樣。綜上,SPI總線中的SCK和I2C總線中的SCL在通信中起到時(shí)鐘的作用,接收方都是根據(jù)時(shí)鐘的對(duì)應(yīng)狀態(tài)采樣數(shù)據(jù),最終保證通信能夠正常進(jìn)行。
對(duì)于UART總線,TXD和RXD分別用于發(fā)送和接收數(shù)據(jù),相當(dāng)于兩根獨(dú)立工作的單線總線,沒(méi)有了時(shí)鐘線的配合,那么接收端應(yīng)該怎樣獲取發(fā)送端傳輸?shù)臄?shù)據(jù)呢?其實(shí)也是有方法的,那就是通信雙方需要約定好UART總線數(shù)據(jù)傳輸?shù)?span id="fvwiygh" class="wrap_hi" style="box-sizing: border-box; background-color: rgb(255, 255, 153); overflow: hidden;">通信速率和時(shí)序格式。
通信速率
UART的數(shù)據(jù)傳輸速度用波特率來(lái)描述,也就是UART每秒接收或發(fā)送的數(shù)據(jù)位。例如9600波特率表示每秒鐘發(fā)送或接收9600比特的數(shù)據(jù),即發(fā)送端需要將發(fā)送的每個(gè)數(shù)據(jù)位保持對(duì)應(yīng)的時(shí)間,計(jì)算如下:
小腳丫硬件上使用12MHz的時(shí)鐘晶振,如果以12MHz時(shí)鐘信號(hào)作為系統(tǒng)時(shí)鐘,使用計(jì)數(shù)器延時(shí)完成UART通信數(shù)據(jù)采樣,那么計(jì)數(shù)器延時(shí)計(jì)數(shù)終值計(jì)算如下:
因?yàn)椴ㄌ芈适菂f(xié)議里約定的,為保證協(xié)議的通用性和靈活性,波特率參數(shù)有固定的選項(xiàng),不可以隨意設(shè)置(如果UART通信雙方都是自己編程的,可以根據(jù)自己的要求定義自己需要的波特率,這種情況除外),波特率參數(shù)選項(xiàng)很多,大家可以打開(kāi)串口調(diào)試助手工具找到波特率配置列表查看,我們比較常用的波特率值有以下幾種:
UART常用波特率:
1200 | 4800 | 9600 | 38400 | 115200 |
時(shí)序格式
關(guān)于時(shí)序格式在前面UART接口介紹部分也簡(jiǎn)單說(shuō)了一下,通信過(guò)程中時(shí)序依次為:起始位、數(shù)據(jù)位、校驗(yàn)位、停止位、空閑位,其中數(shù)據(jù)位可以是5~8位,本設(shè)計(jì)我們使用8位數(shù)據(jù),校驗(yàn)位可以省略,最后確定的時(shí)序格式如下:
前面所說(shuō)的通信速率和時(shí)序格式其實(shí)就是UART通信中的兩個(gè)重要的參數(shù),需要傳輸?shù)臄?shù)據(jù)根據(jù)通信速率的節(jié)拍按照UART的時(shí)序格式輸出,就可以實(shí)現(xiàn)UART通信了,可以按照下面三個(gè)步驟實(shí)現(xiàn)。
例如,將8‘h73和8’h5a通過(guò)UART發(fā)送的時(shí)序,紅色箭頭為波特率對(duì)應(yīng)的節(jié)拍點(diǎn)
對(duì)于UART發(fā)送數(shù)據(jù)來(lái)說(shuō),波特率節(jié)拍是自己產(chǎn)生的,數(shù)據(jù)是自己主動(dòng)發(fā)出的,邏輯相對(duì)簡(jiǎn)單,而當(dāng)UART接收數(shù)據(jù)的時(shí)候,因?yàn)椴淮_定對(duì)方什么時(shí)候發(fā)送數(shù)據(jù),所以需要對(duì)RX信號(hào)持續(xù)檢測(cè),當(dāng)檢測(cè)到有數(shù)據(jù)傳送時(shí),根據(jù)約定的波特率節(jié)拍采樣,可以按照下面三個(gè)步驟實(shí)現(xiàn)。
例如,當(dāng)UART的RX端接收到數(shù)據(jù)8‘h73和8’h5a的時(shí)候,紅色箭頭為檢測(cè)到數(shù)據(jù)傳輸?shù)狞c(diǎn),綠色箭頭為對(duì)應(yīng)的采樣節(jié)拍點(diǎn)(采樣點(diǎn)在數(shù)據(jù)中間最是穩(wěn)定)。
通過(guò)以上理論,我們了解了UART發(fā)送和接收數(shù)據(jù)的整個(gè)流程,兩個(gè)過(guò)程中我們都需要波特率節(jié)拍,那么我們就可以設(shè)計(jì)一個(gè)節(jié)拍模塊Baud,這樣我們的發(fā)送和接收都可以實(shí)例化節(jié)拍模塊用于產(chǎn)生對(duì)應(yīng)波特率的節(jié)拍信號(hào)。
節(jié)拍模塊Baud設(shè)計(jì)實(shí)現(xiàn):
節(jié)拍模塊Baud的端口程序?qū)崿F(xiàn)如下:
module Baud # ( parameter BPS_PARA = 1250 //12MHz時(shí)鐘時(shí)參數(shù)1250對(duì)應(yīng)9600的波特率 ) ( input clk, //系統(tǒng)時(shí)鐘 input rst_n, //系統(tǒng)復(fù)位,低有效 input bps_en, //接收或發(fā)送時(shí)鐘使能 output reg bps_clk //接收或發(fā)送時(shí)鐘輸出 );
設(shè)計(jì)一個(gè)計(jì)數(shù)器用于分頻產(chǎn)生對(duì)應(yīng)波特率節(jié)拍信號(hào),因?yàn)閁ART隨時(shí)可能接收數(shù)據(jù),所以節(jié)拍模塊必須隨時(shí)待命,保持計(jì)數(shù)器清零,當(dāng)需要節(jié)拍信號(hào)時(shí)精準(zhǔn)地輸出。
計(jì)數(shù)器設(shè)計(jì)程序?qū)崿F(xiàn)如下:
reg [12:0] cnt;//計(jì)數(shù)器計(jì)數(shù)滿足波特率時(shí)鐘要求 always @ (posedge clk or negedge rst_n) begin if(!rst_n) cnt <= 1'b0; else if((cnt >= BPS_PARA-1)||(!bps_en)) //當(dāng)時(shí)鐘信號(hào)不使能(bps_en為低電平)時(shí),計(jì)數(shù)器清零并停止計(jì)數(shù) cnt <= 1'b0; //當(dāng)時(shí)鐘信號(hào)使能時(shí),計(jì)數(shù)器對(duì)系統(tǒng)時(shí)鐘計(jì)數(shù),周期為BPS_PARA個(gè)系統(tǒng)時(shí)鐘周期 else cnt <= cnt + 1'b1; end
當(dāng)bpsen(高有效)使能,計(jì)數(shù)器計(jì)數(shù)周期由參數(shù)BPSPARA來(lái)決定,前面數(shù)據(jù)接收時(shí)序部分了解到,從RX檢測(cè)到下降沿開(kāi)始計(jì)數(shù)器工作,到數(shù)據(jù)采樣點(diǎn)需要半個(gè)節(jié)拍的時(shí)間,而數(shù)據(jù)發(fā)送時(shí)只要保證相鄰兩個(gè)節(jié)拍點(diǎn)之間的時(shí)間為一個(gè)計(jì)數(shù)器周期即可,所以我們可以在計(jì)數(shù)器計(jì)數(shù)到中值時(shí)產(chǎn)生一個(gè)脈沖信號(hào)充當(dāng)節(jié)拍信號(hào)。
節(jié)拍信號(hào)產(chǎn)生程序?qū)崿F(xiàn)如下:
//產(chǎn)生相應(yīng)波特率的時(shí)鐘節(jié)拍,接收模塊將以此節(jié)拍進(jìn)行UART數(shù)據(jù)接收 always @ (posedge clk or negedge rst_n) begin if(!rst_n) bps_clk <= 1'b0; else if(cnt == (BPS_PARA>>1)) //右移一位等于除以2,終值BPS_PARA為數(shù)據(jù)更替點(diǎn),中值數(shù)據(jù)穩(wěn)定,做采樣點(diǎn) bps_clk <= 1'b1; else bps_clk <= 1'b0; end
發(fā)送模塊Uart_Tx設(shè)計(jì)實(shí)現(xiàn):
前級(jí)電路通過(guò)txdatavalid和txdatain將需要發(fā)送的數(shù)據(jù)傳輸進(jìn)來(lái),當(dāng)txdatavalid有脈沖信號(hào)時(shí),txdatain信號(hào)為有效數(shù)據(jù),拼接起始位和停止位后賦值給txdatar,同時(shí)控制節(jié)拍使能信號(hào)使能并自鎖,然后等發(fā)送完10bit數(shù)據(jù)后解除使能。
數(shù)據(jù)發(fā)送控制程序?qū)崿F(xiàn)如下:
output reg bps_en; //發(fā)送時(shí)鐘使能 input bps_clk; //發(fā)送時(shí)鐘輸入 input tx_data_valid; //發(fā)送數(shù)據(jù)有效脈沖 input [7:0] tx_data_in; //要發(fā)送的數(shù)據(jù) output reg uart_tx; //UART發(fā)送輸出 reg [3:0] num; reg [9:0] tx_data_r; //融合了起始位和停止位的數(shù)據(jù)//驅(qū)動(dòng)發(fā)送數(shù)據(jù)操作 always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin bps_en <= 1'b0; tx_data_r <= 10'd0; end else if(tx_data_valid && (!bps_en))begin bps_en <= 1'b1; //當(dāng)檢測(cè)到接收時(shí)鐘使能信號(hào)的下降沿,表明接收完成,需要發(fā)送數(shù)據(jù),使能發(fā)送時(shí)鐘使能信號(hào) tx_data_r <= {1'b1,tx_data_in,1'b0}; end else if(num==4'd10) begin bps_en <= 1'b0; //一次UART發(fā)送需要10個(gè)時(shí)鐘信號(hào),然后結(jié)束 end end
UART數(shù)據(jù)發(fā)送時(shí)序程序?qū)崿F(xiàn)如下:
//當(dāng)處于工作狀態(tài)中時(shí),按照發(fā)送時(shí)鐘的節(jié)拍發(fā)送數(shù)據(jù) always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin num <= 1'b0; uart_tx <= 1'b1; end else if(bps_en) begin if(bps_clk) begin num <= num + 1'b1; uart_tx <= tx_data_r[num]; end else if(num>=4'd10) num <= 4'd0; end end
將節(jié)拍模塊Baud和發(fā)送模塊Uart_tx實(shí)例化并連接,完成發(fā)送功能的設(shè)計(jì),如下
接收模塊Uart_Rx設(shè)計(jì)實(shí)現(xiàn):
首先對(duì)RX信號(hào)多級(jí)緩存消除亞穩(wěn)態(tài),同時(shí)檢測(cè)下降沿,程序?qū)崿F(xiàn)如下:
input uart_rx; //UART接收輸入 reg uart_rx0,uart_rx1,uart_rx2; //多級(jí)延時(shí)鎖存去除亞穩(wěn)態(tài) always @ (posedge clk) begin uart_rx0 <= uart_rx; uart_rx1 <= uart_rx0; uart_rx2 <= uart_rx1; end //檢測(cè)UART接收輸入信號(hào)的下降沿 wire neg_uart_rx = uart_rx2 & ~uart_rx1;
當(dāng)檢測(cè)RX有下降沿后,使能節(jié)拍使能信號(hào),同時(shí)自鎖直到完成接收操作后再?gòu)?fù)位節(jié)拍使能信號(hào)。程序?qū)崿F(xiàn)如下:
reg [3:0] num; //接收時(shí)鐘使能信號(hào)的控制 always @ (posedge clk or negedge rst_n) begin if(!rst_n) bps_en <= 1'b0; else if(neg_uart_rx && (!bps_en)) //當(dāng)空閑狀態(tài)(bps_en為低電平)時(shí)檢測(cè)到UART接收信號(hào)下降沿,進(jìn)入工作狀態(tài)(bps_en為高電平),控制時(shí)鐘模塊產(chǎn)生接收時(shí)鐘 bps_en <= 1'b1; else if(num==4'd9) //當(dāng)完成一次UART接收操作后,退出工作狀態(tài),恢復(fù)空閑狀態(tài) bps_en <= 1'b0; end
根據(jù)節(jié)拍信號(hào)完成UART總線的數(shù)據(jù)采樣,得到8位有效數(shù)據(jù),程序?qū)崿F(xiàn)如下:
reg [7:0] rx_data;//當(dāng)處于工作狀態(tài)中時(shí),按照接收時(shí)鐘的節(jié)拍獲取數(shù)據(jù) always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin num <= 4'd0; rx_data <= 8'd0; end else if(bps_en) begin if(bps_clk) begin num <= num + 1'b1; if(num<=4'd8) rx_data[num-1] <= uart_rx1; //先接受低位再接收高位,8位有效數(shù)據(jù) end else if(num == 4'd9) begin //完成一次UART接收操作后,將獲取的數(shù)據(jù)輸出 num <= 4'd0; end end else begin num <= 4'd0; end end
當(dāng)UART接收操作完成后,將得到的8位有效數(shù)據(jù)輸出給后級(jí)電路,程序?qū)崿F(xiàn)如下:
//將接收的數(shù)據(jù)輸出,同時(shí)控制輸出有效信號(hào)產(chǎn)生脈沖 always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin rx_data_out <= 8'd0; rx_data_valid <= 1'b0; end else if(num == 4'd9) begin rx_data_out <= rx_data; rx_data_valid <= 1'b1; end else begin rx_data_out <= rx_data_out; rx_data_valid <= 1'b0; end end
最后將節(jié)拍模塊Baud和接收模塊Uart_rx實(shí)例化并連接,完成發(fā)送功能的設(shè)計(jì),如下
整個(gè)UART驅(qū)動(dòng)設(shè)計(jì)是由兩個(gè)獨(dú)立的功能組合而成:發(fā)送功能部分和接收功能部分。UART功能總體設(shè)計(jì)框圖如下:
當(dāng)我們需要UART發(fā)送數(shù)據(jù)的時(shí)候只需要實(shí)例化發(fā)送功能部分設(shè)計(jì),需要UART接收數(shù)據(jù)的時(shí)候只需要實(shí)例化接收功能部分設(shè)計(jì),例如本設(shè)計(jì)中FPGA驅(qū)動(dòng)UART模塊接收電腦串口調(diào)試助手發(fā)出的數(shù)據(jù),所以我們就只需要實(shí)例化接收功能部分設(shè)計(jì)即可。
剛剛學(xué)習(xí)了UART通信模塊,本設(shè)計(jì)只需要使用接收功能部分設(shè)計(jì),每一次通信都會(huì)得到一個(gè)8位數(shù)據(jù),怎樣將8位數(shù)據(jù)對(duì)應(yīng)得數(shù)據(jù)顯示在數(shù)碼管上呢?我來(lái)先來(lái)了解一下UART接受到的8位數(shù)據(jù)與要顯示數(shù)字的關(guān)系
上圖為電腦端友善串口調(diào)試助手的界面,當(dāng)我們將硬件連接,在串口設(shè)置串口選定串口對(duì)應(yīng)的端口,并按上圖配置波特率、數(shù)據(jù)位、校驗(yàn)位、停止位、流控等,點(diǎn)擊開(kāi)始建立連接,接下來(lái)我們就可以在串口發(fā)送窗口輸入要發(fā)送的數(shù)據(jù),點(diǎn)擊發(fā)送后數(shù)據(jù)傳輸出去。在發(fā)送設(shè)置有兩個(gè)選項(xiàng):ASCII和Hex ,
我們?cè)O(shè)計(jì)一個(gè)32位的移位寄存器對(duì)應(yīng)8位數(shù)碼管,按照BCD碼格式每4位表示一個(gè)數(shù)字,每次接收到UART數(shù)據(jù)都存到移位寄存器中,同時(shí)控制數(shù)碼管顯示相應(yīng)的數(shù)碼管位,Decoder程序?qū)崿F(xiàn)如下:
`ifdef HEX_FORMAT //如果用define定義過(guò)HEX_FORMAT //采用16進(jìn)制格式,接收到的數(shù)據(jù)等于數(shù)值本身 wire [7:0] seg_data_r = rx_data_out; //移位寄存器,對(duì)應(yīng)8位數(shù)碼管數(shù)據(jù)BCD碼 always @ (posedge rx_data_valid or negedge rst_n) begin if(!rst_n) seg_data <= 1'b0; else seg_data <= {seg_data[23:0],seg_data_r}; end //移位寄存器,對(duì)應(yīng)8位數(shù)碼管數(shù)據(jù)顯示使能 always @ (posedge rx_data_valid or negedge rst_n) begin if(!rst_n) data_en <= 1'b0; else data_en <= {data_en[5:0],2'b11}; end`else //采用字符格式,接收到的數(shù)據(jù)為字符ASCII碼值,與數(shù)字值相差48 wire [7:0] seg_data_r = rx_data_out - 8'd48; //移位寄存器,對(duì)應(yīng)8位數(shù)碼管數(shù)據(jù)BCD碼 always @ (posedge rx_data_valid or negedge rst_n) begin if(!rst_n) seg_data <= 1'b0; else seg_data <= {seg_data[27:0],seg_data_r[3:0]}; end //移位寄存器,對(duì)應(yīng)8位數(shù)碼管數(shù)據(jù)顯示使能 always @ (posedge rx_data_valid or negedge rst_n) begin if(!rst_n) data_en <= 1'b0; else data_en <= {data_en[6:0],1'b1}; end `endif
上面程序中ifdef……
else……endif語(yǔ)句為預(yù)編譯指令,與C預(yù)演類似。如果我們使用串口助手Hex(16進(jìn)制)格式發(fā)送數(shù)據(jù),需要在程序中使用define定義參數(shù)HEX_FORMAT,如果使用ASCII格式發(fā)送數(shù)據(jù),則不需要定義。 <code verilog>
define HEXFORMAT 串口助手使用Hex格式發(fā)送時(shí)定義HEX_FORMAT,否則不定義 </code> 綜合后的設(shè)計(jì)框圖如下:
#### 實(shí)驗(yàn)步驟 - 雙擊打開(kāi)Quartus Prime工具軟件; - 新建工程:File → New Project Wizard(工程命名,工程目錄選擇,設(shè)備型號(hào)選擇,EDA工具選擇); - 新建文件:File → New → Verilog HDL File,鍵入設(shè)計(jì)代碼并保存; - 設(shè)計(jì)綜合:雙擊Tasks窗口頁(yè)面下的Analysis & Synthesis對(duì)代碼進(jìn)行綜合; - 管腳約束:Assignments → Assignment Editor,根據(jù)項(xiàng)目需求分配管腳; - 設(shè)計(jì)編譯:雙擊Tasks窗口頁(yè)面下的Compile Design對(duì)設(shè)計(jì)進(jìn)行整體編譯并生成配置文件; - 程序燒錄:點(diǎn)擊Tools → Programmer打開(kāi)配置工具,Program進(jìn)行下載; - 觀察設(shè)計(jì)運(yùn)行結(jié)果。 #### 實(shí)驗(yàn)現(xiàn)象 使用兩根Micro-USB線同時(shí)連接核心板和底板的USB接口,將程序下載到FPGA中,數(shù)碼管處于不顯示的狀態(tài),打開(kāi)電腦上的串口調(diào)試助手,按照前面圖片配置相應(yīng)參數(shù),在數(shù)據(jù)發(fā)送窗口輸入數(shù)字,點(diǎn)擊發(fā)送觀察底板數(shù)碼管的變化,重新輸入數(shù)字,點(diǎn)擊發(fā)送再次觀察底板數(shù)碼管的變化。
評(píng)論