FPGA實(shí)現(xiàn)串行接口 RS232_第1頁
FPGA實(shí)現(xiàn)串行接口 RS232_第2頁
FPGA實(shí)現(xiàn)串行接口 RS232_第3頁
FPGA實(shí)現(xiàn)串行接口 RS232_第4頁
FPGA實(shí)現(xiàn)串行接口 RS232_第5頁
已閱讀5頁,還剩3頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、FPGA實(shí)現(xiàn)串行接口 RS232串行接口(RS-232)串行接口是連接FPGA和PC機(jī)的一種簡單方式。這個項目向大家展示了如果使用FPGA來創(chuàng)建RS-232收發(fā)器。 整個項目包括5個部分1 RS232是怎樣工作的2 如何產(chǎn)生需要的波特率3 發(fā)送模塊4 接收模塊5 應(yīng)用實(shí)例RS-232接口是怎樣工作的作為標(biāo)準(zhǔn)設(shè)備,大多數(shù)的計算機(jī)都有1到2個RS-232串口。特性RS-232有下列特性: 使用9針的DB-9插頭(舊式計算機(jī)使用25針的DB-25插頭). 允許全雙工的雙向通訊(也就是說計算機(jī)可以在接收數(shù)據(jù)的同時發(fā)送數(shù)據(jù)). 最大可支持的傳輸速率為10KBytes/s.DB-9插頭你可能已經(jīng)在你的計算

2、機(jī)背后見到過這種插頭 它一共有9個引腳,但是最重要的3個引腳是: 引腳2: RxD (接收數(shù)據(jù)). 引腳3: TxD (發(fā)送數(shù)據(jù)). 引腳5: GND (地).僅使用3跟電纜,你就可以發(fā)送和接收數(shù)據(jù).串行通訊數(shù)據(jù)以每次一位的方式傳輸;每條線用來傳輸一個方向的數(shù)據(jù)。由于計算機(jī)通常至少需要若干位數(shù)據(jù),因此數(shù)據(jù)在發(fā)送之前先“串行化”。通常是以8位數(shù)據(jù)為1組的。 。先發(fā)送最低有效位,最后發(fā)送最高有效位。異步通訊RS-232使用異步通訊協(xié)議。也就是說數(shù)據(jù)的傳輸沒有時鐘信號。接收端必須有某種方式,使之與接收數(shù)據(jù)同步。對于RS-232來說,是這樣處理的:6 串行線纜的兩端事先約定好串行傳輸?shù)膮?shù)(傳輸速度、

3、傳輸格式等)7 當(dāng)沒有數(shù)據(jù)傳輸?shù)臅r候,發(fā)送端向數(shù)據(jù)線上發(fā)送18 每傳輸一個字節(jié)之前,發(fā)送端先發(fā)送一個0來表示傳輸已經(jīng)開始。這樣接收端便可以知道有數(shù)據(jù)到來了。9 開始傳輸后,數(shù)據(jù)以約定的速度和格式傳輸,所以接收端可以與之同步10 每次傳輸完成一個字節(jié)之后,都在其后發(fā)送一個停止位(1)讓我們來看看0x55是如何傳輸?shù)? 0x55的二進(jìn)制表示為:01010101。但是由于先發(fā)送的是最低有效位,所以發(fā)送序列是這樣的: 1-0-1-0-1-0-1-0.下面是另外一個例子 : 傳輸?shù)臄?shù)據(jù)為0xC4,你能看出來嗎?從圖中很難看出來所傳輸?shù)臄?shù)據(jù),這也說明了事先知道傳輸?shù)乃俾蕦τ诮邮斩擞卸嗝粗匾?shù)據(jù)傳輸可以多

4、快?數(shù)據(jù)的傳輸速度是用波特來描述的,亦即每秒鐘傳輸?shù)臄?shù)據(jù)位,例如1000波特表示每秒鐘傳輸100比特的數(shù)據(jù), 或者說每個數(shù)據(jù)位持續(xù)1毫秒。波特率不是隨意的,必須服從一定的標(biāo)準(zhǔn),如果希望設(shè)計123456波特的RS-232接口,對不起,你很不幸運(yùn),這是不行的。常用的串行傳輸速率值包括以下幾種: 1200 波特. 9600 波特. 38400 波特. 115200 波特 (通常情況下是你可以使用的最高速度).在115200 波特傳輸速度下, 每位數(shù)據(jù)持續(xù) (1/115200) = 8.7s. 如果傳輸8位數(shù)據(jù),共持續(xù) 8 x 8.7s = 69s。但是每個字節(jié)的傳輸又要求額外的“開始位”和“停止位”

5、,所以實(shí)際上需要花費(fèi)10 x 8.7s = 87s的時間。最大的有效數(shù)據(jù)傳輸率只能達(dá)到 11.5KBytes每秒。在115200 波特傳輸速度下,一些使用了不好的芯片的計算機(jī)要求一個長的停止位(1.5或2位數(shù)據(jù)的長度),這使得最大傳輸速度降到大約10.5KBytes每秒物理層電纜上的信號使用正負(fù)電壓的機(jī)制: 1 用 -10V 的電壓表示(或者在 -5V 與 -15V之間的電壓). 0 用 +10V 的電壓表示(或者在 5V 與 15V之間的電壓).所以沒有數(shù)據(jù)傳輸?shù)碾娎|上的電壓應(yīng)該為-10V或-5到-10之間的某個電壓。波特率發(fā)生器這里我們使用串行連接的最大速度115200波特,其他較慢的波特

6、也很容易由此產(chǎn)生。FPGA通常運(yùn)行在遠(yuǎn)高于115200Hz的時鐘頻率上(對于今天的標(biāo)準(zhǔn)的來說RS-232真是太慢了),這就意味著我們需要用一個較高的時鐘來分頻產(chǎn)生盡量接近于115200Hz的時鐘信號。從1.8432MHz的時鐘產(chǎn)生通常RS-232芯片使用1.8432MHz的時鐘,以為這個時鐘很容易產(chǎn)生標(biāo)準(zhǔn)的波特率,所以我們假設(shè)已經(jīng)擁有了一個這樣的時鐘源。只需要將 1.8432MHz 16分頻便可得到 115200Hz的時鐘,多方便??!reg 3:0 BaudDivCnt;always (posedge clk) BaudDivCnt =2000000) printf(*); else prin

7、tf( );acc %= 2000000;這段代碼會精確的以平均每 17.361111111. 個時鐘間隔打印出一個*。為了從FPGA得到同樣的效果,考慮到串行接口可以容忍一定的波特率誤差,所以即使我們使用17.3或者17.4這樣的分頻比也是沒有關(guān)系的。FPGA波特率發(fā)生器我們希望2000000是2的整數(shù)冪,但很可惜,它不是。所以我們改變分頻比,2000000/115200 約等于 1024/59 = 17.356. 這跟我們要求的分頻比很接近,并且使得在FPGA上實(shí)現(xiàn)起來相當(dāng)有效。/10 位的累加器 (9:0), 1位進(jìn)位輸出 (10)reg 10:0 acc; /一共11位!always

8、(posedge clk)acc = acc9:0 + 59; /我們使用上一次結(jié)果的低10位,但是保留11位結(jié)果wire BaudTick = acc10; /第11位作為進(jìn)位輸出使用 2MHz 時鐘, BaudTick 為 115234 波特, 跟理想的115200波特存在 0.03% 的誤差。參數(shù)化的FPGA波特率發(fā)生器前面的設(shè)計我們使用的是10位的累加器,如果時鐘頻率提高的話,需要更多的位數(shù)。下面是一個使用 25MHz 時鐘和 16 位累加器的設(shè)計,該設(shè)計是參數(shù)化的,所以很容易根據(jù)具體情況修改。parameter ClkFrequency = 25000000; / 25MHzpara

9、meter Baud = 115200;parameter BaudGeneratorAccWidth = 16;parameter BaudGeneratorInc = (BaudBaudGeneratorAccWidth)/ClkFrequency;reg BaudGeneratorAccWidth:0 BaudGeneratorAcc;always (posedge clk)BaudGeneratorAcc = BaudGeneratorAccBaudGeneratorAccWidth-1:0 + BaudGeneratorInc;wire BaudTick = BaudGenerato

10、rAccBaudGeneratorAccWidth;上面的設(shè)計中存在一個錯誤: BaudGeneratorInc的計算是錯誤的, 因為 Verilog 使用 32 位的默認(rèn)結(jié)果, 但實(shí)際計算過程中的某些數(shù)據(jù)超過了32位,所以改變一種計算方法。parameter BaudGeneratorInc = (Baud5)/(ClkFrequency4);這行程序也使得結(jié)果成為整數(shù),從而避免截斷。這就是整個的設(shè)計方法了?,F(xiàn)在我們已經(jīng)得到了足夠精確的波特率,可以繼續(xù)設(shè)計串行接收和發(fā)送模塊了。RS-232發(fā)送模塊下面是我們所想要實(shí)現(xiàn)的:它應(yīng)該能像這樣工作: 發(fā)送器接收8位的數(shù)據(jù),并將其串行輸出。(TxD_s

11、tart置位后開始傳輸). 當(dāng)有數(shù)傳輸?shù)臅r候,使busy信號有效,此時“TxD_start”信號被忽略.RS-232模塊的參數(shù)是固定的: 8位數(shù)據(jù), 2個停止位, 無奇偶校驗.數(shù)據(jù)串行化假設(shè)我們已經(jīng)有了一個115200波特的BaudTick信號.我們需要產(chǎn)生開始位、8位數(shù)據(jù)以及停止位。用狀態(tài)機(jī)來實(shí)現(xiàn)看起來比較合適。reg 3:0 state;always (posedge clk)case(state)4b0000: if(TxD_start) state = 4b0100;4b0100: if(BaudTick) state = 4b1000; / 開始位4b1000: if(BaudTic

12、k) state = 4b1001; / bit 04b1001: if(BaudTick) state = 4b1010; / bit 14b1010: if(BaudTick) state = 4b1011; / bit 24b1011: if(BaudTick) state = 4b1100; / bit 34b1100: if(BaudTick) state = 4b1101; / bit 44b1101: if(BaudTick) state = 4b1110; / bit 54b1110: if(BaudTick) state = 4b1111; / bit 64b1111: if

13、(BaudTick) state = 4b0001; / bit 74b0001: if(BaudTick) state = 4b0010; / 停止位14b0010: if(BaudTick) state = 4b0000; / 停止位2default: if(BaudTick) state = 4b0000;endcase注意看這個狀態(tài)機(jī)是怎樣實(shí)現(xiàn)當(dāng)TxD_start有效就開始,但只在BaudTick有效的時候才轉(zhuǎn)換狀態(tài)的。.現(xiàn)在,我們只需要產(chǎn)生TxD輸出即可.reg muxbit;always (state2:0)case(state2:0)0: muxbit = TxD_data0;1

14、: muxbit = TxD_data1;2: muxbit = TxD_data2;3: muxbit = TxD_data3;4: muxbit = TxD_data4;5: muxbit = TxD_data5;6: muxbit = TxD_data6;7: muxbit = TxD_data7;endcase/將開始位、數(shù)據(jù)以及停止位結(jié)合起來assign TxD = (state4) | (state3 & muxbit);RS232接收模塊下面是我們想要實(shí)現(xiàn)的模塊:我們的設(shè)計目的是這樣的: 1.當(dāng)RxD線上有數(shù)據(jù)時,接收模塊負(fù)責(zé)識別RxD線上的數(shù)據(jù) 2.當(dāng)收到一個字節(jié)的數(shù)據(jù)時,鎖存

15、接收到的數(shù)據(jù)到data總線,并使data_ready有效一個周期。注意:只有當(dāng)data_ready有效時,data總線的數(shù)據(jù)才有效,其他的時間里不要使用data總線上的數(shù)據(jù),因為新的數(shù)據(jù)可能已經(jīng)改變了其中的部分?jǐn)?shù)據(jù)。過采樣異步接收機(jī)必須通過一定的機(jī)制與接收到的輸入信號同步(接收端沒有辦法得到發(fā)送斷的時鐘)。這里采用如下辦法。 1.為了確定新數(shù)據(jù)的到來,即檢測開始位,我們使用幾倍于波特率的采樣時鐘對接收到的信號進(jìn)行采樣。 2.一旦檢測到開始位,再將采樣時鐘頻率降為已知的發(fā)送端的波特率。典型的過采樣時鐘頻率為接收到的信號的波特率的16倍,這里我們使用8倍的采樣時鐘。當(dāng)波特率為115200時,采樣時

16、鐘為921600Hz。假設(shè)我們已經(jīng)有了一個8倍于波特率的時鐘信號 Baud8Tick,其頻率為 921600Hz。具體設(shè)計首先,接受到的RxD信號與我們的時鐘沒有任何關(guān)系,所以采用兩個D觸發(fā)器對其進(jìn)行過采樣,并且使之我我們的時鐘同步。reg 1:0 RxD_sync;always (posedge clk) if(Baud8Tick) RxD_sync = RxD_sync0, RxD;首先我們對接收到的數(shù)據(jù)進(jìn)行濾波,這樣可以防止毛刺信號被誤認(rèn)為是開始信號。reg 1:0 RxD_cnt;reg RxD_bit;always (posedge clk)if(Baud8Tick)begin if

17、(RxD_sync1 & RxD_cnt!=2b11) RxD_cnt = RxD_cnt + 1; else if(RxD_sync1 & RxD_cnt!=2b00) RxD_cnt = RxD_cnt - 1; if(RxD_cnt=2b00) RxD_bit = 0; else if(RxD_cnt=2b11) RxD_bit = 1;end一旦檢測到開始位,使用如下的狀態(tài)機(jī)可以檢測出接收到每一位數(shù)據(jù)。reg 3:0 state;always (posedge clk)if(Baud8Tick)case(state) 4b0000: if(RxD_bit) state = 4b1000

18、; / start bit found? 4b1000: if(next_bit) state = 4b1001; / bit 0 4b1001: if(next_bit) state = 4b1010; / bit 1 4b1010: if(next_bit) state = 4b1011; / bit 2 4b1011: if(next_bit) state = 4b1100; / bit 3 4b1100: if(next_bit) state = 4b1101; / bit 4 4b1101: if(next_bit) state = 4b1110; / bit 5 4b1110: i

19、f(next_bit) state = 4b1111; / bit 6 4b1111: if(next_bit) state = 4b0001; / bit 7 4b0001: if(next_bit) state = 4b0000; / stop bit default: state = 4b0000;endcase注意,我們使用了next_bit 來遍歷所有數(shù)據(jù)位。reg 2:0 bit_spacing;always (posedge clk)if(state=0) bit_spacing = 0;elseif(Baud8Tick) bit_spacing = bit_spacing + 1;wire next_bit = (bit_spacing=7);最后我們使用一個移位寄存器來存儲接受到的數(shù)據(jù)。reg 7:0 RxD_data;always (posedge clk) if(Baud8Tick & next_bit & state3) RxD_data = RxD_bit, RxD_data7:1;怎樣使用發(fā)送和接收模塊這個設(shè)計似的我們可以通過計算機(jī)的串行口來控制

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論