Verilog串口通訊設(shè)計
隨著多微機系統(tǒng)的應(yīng)用和微機網(wǎng)絡(luò)的發(fā)展,通信功能越來越顯得重要。串行通信是在一根傳輸線上一位一位地傳送信息.這根線既作數(shù)據(jù)線又作聯(lián)絡(luò)線。串行通信作為一種主要的通信方式,由于所用的傳輸線少,并且可以借助現(xiàn)存的電話網(wǎng)進行信息傳送,因此特別適合于遠距離傳送。在串行傳輸中,通信雙方都按通信協(xié)議進行,所謂通信協(xié)議是指通信雙方的一種約定。約定對數(shù)據(jù)格式、同步方式、傳送速度、傳送步驟、糾錯方式以及控制字符定義等問題做出統(tǒng)一規(guī)定,通信雙方必須共同遵守。異步起止式的禎信息格式為:每禎信息由四部分組成:
a.1位起始位。
b.5~8位數(shù)據(jù)位。傳送順序是低位在前,高位在后.依次傳送。
c.一位校驗位,也可以沒有。
d.最后是1位或是2位停止位。
FPGA(Field Pmgrammable Gate Array)現(xiàn)場可編程門陣列在數(shù)字電路的設(shè)計中已經(jīng)被廣泛使用。這種設(shè)計方式可以將以前需要多塊集成芯片的電路設(shè)計到一塊大模塊可編程邏輯器件中,大大減少了電路板的尺寸,增強了系統(tǒng)的可靠性和設(shè)計的靈活性。本文詳細介紹了已在實際項目中應(yīng)用的基于FPGA的串口通訊設(shè)計。
本設(shè)計分為硬件電路設(shè)計和軟件設(shè)計兩部分,最后用仿真驗證了程序設(shè)計的正確性。
2 系統(tǒng)的硬件設(shè)計
本方案的異步串行通信的硬件接口電路圖如圖1所示,主要由四部分組成:RS-485數(shù)據(jù)發(fā)送模塊、FPGA串口模塊、MAX3223和DB9。各部分功能簡述如下:
RS-485數(shù)據(jù)發(fā)送模塊是將前續(xù)電路的數(shù)據(jù)發(fā)送到FPGA,供本電路處理,亦即本電路的輸入。RS485是符合RS-485和RS-4225串口標(biāo)準的低功耗半雙工收發(fā)器件,有3.3V和5V兩種,在本設(shè)計中選用了3.3V的器件SP3485。SP3485的內(nèi)部結(jié)構(gòu)示意圖如圖2所示
在本設(shè)計中。485的7腳和8腳與前端信號相連接,用于接收輸入的數(shù)據(jù)。數(shù)據(jù)格式是這樣的:一幀數(shù)據(jù)有25位,報頭是16個高電平和1個低電平,接下來是 8位有效的數(shù)據(jù)。傳輸速率為700k波特率。2腳是使能端,與FPGA的I/O口相連,由FPGA提供邏輯控制信號。1腳和4腳也與FPGA相連,由 FPGA對輸入數(shù)據(jù)進行處理。
本文引用地址:http://m.butianyuan.cn/article/201706/349427.htm圖1異步串行通信硬件接口功能框圖
圖2 SP3485的內(nèi)部結(jié)構(gòu)示意圖
FPGA串口模塊是將由RS-485發(fā)送過來的數(shù)據(jù)進行處理,提取出8位有效數(shù)據(jù),并按異步串口通訊的格式要求輸出到MAX3223的12腳。FPGA選用Xilinx公司的Spartan II系列xc2s50。此部分為該設(shè)計的主體。如上所述,輸入數(shù)據(jù)的傳輸速率為700k波特率。為了使FPGA能夠正確地對輸入數(shù)據(jù)進行采樣,提高分辨率能力和抗干擾能力,采樣時鐘必須選用比波特率更高的時鐘,理論上至少是波特率時鐘的2倍。在本設(shè)計中選用4倍于波特率的時鐘,利用這種4倍于波特率的接收時鐘對串行數(shù)據(jù)流進行檢測和定位采樣,接收器能在一個位周期內(nèi)采樣4次。如果沒有這種倍頻關(guān)系,定位采樣頻率和傳送波特率相同,則在一個位周期中,只能采樣一次,分辨率會差。比如,為了檢測起始位下降沿的出現(xiàn),在起始位的前夕采樣一次之后,下次采樣要到起始位結(jié)束前夕才進行。而假若在這個周期期間,因某種原因恰恰使接收時鐘往后偏移了一點點,就會錯過起始位。造成整個后面位的檢測和識別錯誤。針對本設(shè)計,F(xiàn)PGA的軟件共分了三個模塊:
1.時鐘分頻模塊。模塊的功能是用來產(chǎn)生所需要的數(shù)據(jù)采集時鐘和數(shù)據(jù)傳輸時鐘。系統(tǒng)主頻是40M的。數(shù)據(jù)采集時鐘是2.8M的,發(fā)送時鐘是11.2k。
2. 提取數(shù)據(jù)模塊。由RS485發(fā)送過來的數(shù)據(jù)共有25位,其中只有8位是有效數(shù)據(jù)。為了發(fā)送這8位有效數(shù)據(jù)。必須先將其提取出來。提取的辦法是這樣的:通過連續(xù)檢測到的16個高電平和一個低電平。判斷8位有效數(shù)據(jù)的到來。然后按照串行數(shù)據(jù)傳輸?shù)母袷?,在加上起始位和停止位后,將其存儲于輸出緩沖寄存器中。在這里,我們的串行數(shù)據(jù)輸出格式是這樣規(guī)定的,一位起始位,八位數(shù)據(jù)位,一位停止位,無校驗位。
3.串行數(shù)據(jù)輸出模塊。這一模塊相對比較簡單,波特率選為11.2k,模塊的功能是在移位輸出脈沖的作用下,將輸出緩沖寄存器中的數(shù)據(jù)移位輸出。
MAX3223是實現(xiàn)電平轉(zhuǎn)換的芯片。由于RS-232c是用正負電壓來表示邏輯狀態(tài)。與TTL以高低電平表示邏輯狀態(tài)的規(guī)定不同。因此,為了能夠同計算機接口或終端的TTL器件連接,必須在RS-232與TTL電路之間進行電平和邏輯關(guān)系的變換。實現(xiàn)這種變換的方法可用分立元件,也可用集成電路芯片。 MAXIM公司的MAX3223是為滿足RS-232c的標(biāo)準而設(shè)計的具有功耗低、波特率高、價格低等優(yōu)點,外接電容僅為0.1uF或1uF,為雙組 RS232收發(fā)器。由MAX3223的12腳輸入的數(shù)據(jù),經(jīng)過電平轉(zhuǎn)換后由8腳輸出,再經(jīng)過DB9的TxD端輸出,由PC機接收并做后續(xù)處理。
3 系統(tǒng)軟件設(shè)計
FPGA模塊是本設(shè)計的主體,使用Verilog硬件描述語言進行編寫,本段代碼共有兩個子模塊,分別實現(xiàn)提取八位數(shù)據(jù)和串行數(shù)據(jù)發(fā)送的功能。
下面是verilog源代碼
module SIMO(din,clk,rst,dout_ser);
input din; //串行輸入數(shù)據(jù)
input clk; //時鐘信號
input vat; 復(fù)位信號
reg[7:0] indata_buf; //輸入緩沖寄存器,存提取的有效位
reg[9:0] dout_buf; //輸出緩沖寄存器,加了起停位
output reg dout_ser; //串行數(shù)據(jù)輸出
reg nclk; //提取八位有效數(shù)據(jù)的采樣時鐘.是4倍于波特率的時鐘
reg txclk; //發(fā)送數(shù)據(jù)時鐘。發(fā)數(shù)據(jù)取11.2k的波特率
integer bitpos=7; //當(dāng)前位
parameter s0=0,s1=1,s2=2,s3=3;
reg[2:0]state;
reg[4:0]counter; //用來計算報頭報尾中1的個數(shù)
reg tag,tag1;
reg[2:0]cnt3;
reg txdone=1'b1;//一個字節(jié)數(shù)據(jù)傳輸完畢標(biāo)志
*********提取有效數(shù)據(jù)位并按串行通訊格式裝載數(shù)據(jù)********
always@ (posedge nclk or posedge rst) begin
if(rst)
begin
state=0;
counter=0;
tag1=0;
tag=0;
indata_buf=8'bz;
dout_buf=10'bz;
bitpos=7;
cnt3=0;
end
else case(state)
s0:begin
tag=0;//表示數(shù)據(jù)沒有裝好
if(din)
begin
counter=counter+1;
state=s0;
if(counter==15)//如果檢測到16個1則轉(zhuǎn)入s1狀態(tài)檢測接下來的是不是0
begin
state=s1;
counter=0;
end
end
else begin
counter=0;
state=s0;
end
end
s1:if(!din)//如果是0的話,轉(zhuǎn)入s2狀態(tài),提取八位有效數(shù)據(jù)
state=s2;
else //否則轉(zhuǎn)到s0狀態(tài)重新檢測
state=s0;
s2:if(cnt3==3)//是否采集四次數(shù)據(jù)
begin
cnt2=0;
indata_buf[bitpos]=din; //先進來的是高位數(shù)據(jù)
bitpos=bitpos-1;
if(bitpos==-1)
begin
bitpos=7;state=s3;end
end
else cnt3=cnt3+1;
s3:begin
tag1=tag;
tag=1'b1; //標(biāo)志輸入寄存器滿。表明已把有用數(shù)據(jù)裝入寄存器
if(tag~tag1)txdone) //檢測到tag的上升沿以及txdone為高才把輸入緩沖數(shù)據(jù)放到輸出緩沖去
dout_buf={1'b1,indata_buf[7:0],1'b0};//停止位,高位,低位,起始位
state=s0;
end
endcase
end
//***********發(fā)送數(shù)據(jù)模塊
reg[3:0] state_tx=0;
always@(posedge txclk or posedge rst)
begin
if(rst)
begin
dout_ser=1'bz;
state_tx=0;
txdone=1;
end
else
case(state_tx)
0:begin
dout_ser=dout_buf[0];state_tx=state_tx+1;txdone=1'b0;end
1:begin
dout_ser=dout_buf[1];state_tx=state_tx+1;end
2:begin
dout_ser=dout_buf[2];state_tx=state_tx+1;end
3:begin
dout_ser=dout_buf[3];state_tx=state_tx+1;end
4:begin
dout_ser=dout_buf[4];state_tx=state_tx+1;end
5:begin
dout_ser=dout_buf[5];state_tx=state_tx+1;end
6:begin
dout_ser=dout_buf[6];state_tx=state_tx+1;end
7:begin
dout_ser=dout_buf[7];state_tx=state_tx+1;end
8:begin
dout_ser=dout_buf[8];state_tx=state_tx+1;end
9:begin
dout_ser=dout_buf[9];state_tx=state_tx+1;end
endcase
end
endmodule
注:兩個頻率信號nclk、txclk由相應(yīng)的分頻程序產(chǎn)生。由于篇幅所限未在文中列出。
FPGA模塊接收從RS-485發(fā)送過來的串行數(shù)據(jù)。25位為一個字符。數(shù)據(jù)的傳輸速率是700kbps,用四倍于波特率的速率進行采樣,這樣可以大大降低系統(tǒng)的噪聲。數(shù)據(jù)的串行輸出波特率選為11200bps。
由輸入輸出波形圖可以看出:本段程序?qū)崿F(xiàn)了對輸入數(shù)據(jù)的有效數(shù)據(jù)位的提取,并按照一定的波特率進行串行輸出。程序中,波特率可以根據(jù)需要通過分頻程序進行改動。硬件電路搭建簡單,程序代碼書寫容易。數(shù)據(jù)傳輸穩(wěn)定可靠,可以滿足串口通信的要求。
評論