FPGA實現串行接口-RS232_第1頁
FPGA實現串行接口-RS232_第2頁
FPGA實現串行接口-RS232_第3頁
已閱讀5頁,還剩2頁未讀, 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、FPGA實現串行接口 RS232串行接口 RS-232FPGA 來串行接口是連接 FPGA和PC機的一種簡單方式。這個工程向大家展示了如果使用 創立RS-232收發器。 RxD.* 1沁kFartr書!14疔Async RaL-eiYBr整個工程包括5個局部塔 ThD 叮曰se帕117erAV辺A .busvAsync TrftnsiritierRS232是怎樣工作的如何產生需要的波特率發送模塊接收模塊應用實例RS-232接口是怎樣工作的作為標準設備,大多數的電腦都有1到2個RS-232串口。特性RS-232有以下特性:? 使用9針的"DB-9"插頭舊式電腦使用25針的&q

2、uot;DB-25"插頭.?允許全雙工的雙向通訊也就是說電腦可以在接收數據的同時發送數據?最大可支持的傳輸速率為10KBytes/s.DB-9插頭你可能已經在你的電腦背后見到過這種插頭它一共有9個引腳,但是最重要的 3個引腳是:?弓I腳2: RxD 接收數據.?弓I腳3: TxD 發送數據.? 引腳5: GND 地.僅使用3跟電纜,你就可以發送和接收數據.串行通訊數據以每次一位的方式傳輸;每條線用來傳輸一個方向的數據。由于電腦通常至少需要假設干位數據,因此數據在發送之前先串行化。通常是以8位數據為1組的。先發送最低有效位,最后發送最高有效位。異步通訊RS-232使用異步通訊協議。也就

3、是說數據的傳輸沒有時鐘信號。接收端必須有某種方式, 使之與接收數據同步。對于RS-232來說,是這樣處理的:串行線纜的兩端事先約定好串行傳輸的參數傳輸速度、傳輸格式等當沒有數據傳輸的時候,發送端向數據線上發送"1"每傳輸一個字節之前,發送端先發送一個"0"來表示傳輸已經開始。這樣接收端便可以知道有數據到來了。開始傳輸后,數據以約定的速度和格式傳輸,所以接收端可以與之同步每次傳輸完成一個字節之后,都在其后發送一個停止位("1")讓我們來看看0x55是如何傳輸的"LrLrLTLruline i 歛 ideline is idle

4、 agan0x55的二進制表示為:01010101。但是由于先發送的是最低有效位,所以發送序列是這樣的:1-0-1-0-1-0-1-0.下面是另外一個例子 :/ line is idlestart 器 口甜 $ stopline is icJte 密inbit' bit傳輸的數據為0xC4,你能看出來嗎?從圖中很難看出來所傳輸的數據,這也說明了事先知道傳輸的速率對于接收端有多么重要。數據傳輸可以多快?數據的傳輸速度是用波特來描述的,亦即每秒鐘傳輸的數據位,例如1000波特表示每秒鐘傳輸100比特的數據,或者說每個數據位持續1毫秒。波特率不是隨意的,必須服從一定的標準,如果希望設計123

5、456波特的RS-232接口,對不起,你很不幸運,這是不行的。常用的串行傳輸速率值包括以下幾種:?1200波特.?9600波特.?38400 波特.?115200波特(通常情況下是你可以使用的最高速度).在115200波特傳輸速度下,每位數據持續(1/115200) = 8.7卩s如果傳輸8位數據,共持續8 x 8.7卩s = 6Q但是每個字節的傳輸又要求額外的開始位"和 停止位所以實際上需要花費10 x 8.7卩s = 8的時間。最大的有效數據傳輸率只能到達11.5KBytes每秒。在115200波特傳輸速度下,一些使用了不好的芯片的電腦要求一個長的停止位(1.5或2位數據的長度)

6、,這使得最大傳輸速度降到大約10.5KBytes每秒物理層電纜上的信號使用正負電壓的機制?"1" 用 -10V 的電壓表示 ( 或者在 -5V 與 -15V 之間的電壓 ).?"0" 用 +10V 的電壓表示 ( 或者在 5V 與 15V 之間的電壓 ).所以沒有數據傳輸的電纜上的電壓應該為 -10V 或-5到 -10之間的某個電壓。 波特率發生器這里我們使用串行連接的最大速度115200波特,其他較慢的波特也很容易由此產生。FPGA通常運行在遠高于115200Hz的時鐘頻率上對于今天的標準的來說RS-232真是太慢了,這就意味著我們需要用一個較高的時鐘

7、來分頻產生盡量接近于115200Hz的時鐘信號。從1.8432 MHz的時鐘產生通常RS-232芯片使用1.8432MHz的時鐘,以為這個時鐘很容易產生標準的波特率,所以我 們假設已經擁有了一個這樣的時鐘源。只需要將1.8432MHz 16分頻便可得到 115200Hz的時鐘,多方便啊!reg 3:0 BaudDivCnt;always (posedge clk) BaudDivCnt <= BaudDivCnt + 1;wire BaudTick = (BaudDivCnt=15);所以 "BaudTick" 每16個時鐘周期需要置位一次,從而從 1.8432MHz

8、 的時鐘得到 115200Hz 的時鐘。從任意頻率產生早 期的發生器假設使用 1.8432MHz 的時鐘。但如果我們使用 2MHz 的時鐘怎么辦呢?要從 2MHz的時鐘得到115200Hz,需要將時鐘 "17.361111111"分頻,并不是一個整數。我的 解決方法是有時候 17分頻,有時候 18分頻,使得整體的分頻比保持在"17.361111111"。這是很容易做到的。下面是實現這個想法的 C 語言代碼 :while(1) / 死循環acc += 115200;if(acc >=2000000) printf("*"); el

9、se printf(" ");acc %= 2000000;這段代碼會精確的以平均每"17.361111111." 個時鐘間隔打印出一個 "*"。為了從 FPGA 得到同樣的效果,考慮到串行接口可以容忍一定的波特率誤差,所以即使我 們使用 17.3或者17.4這樣的分頻比也是沒有關系的。FPGA 波特率發生器我們希望 2000000是2的整數冪, 但很可惜, 它不是。 所以我們改變分頻比, "2000000/115200" 約等于 "1024/59" = 17.356. 這跟我們要求的分頻比很接

10、近,并且使得在 FPGA 上實現起來 相當有效。/10 位的累加器 (9:0), 1 位進位輸出 (10)reg 10:0 acc; / 一共 11位!always (posedge clk)acc <= acc9:0 + 59; /我們使用上一次結果的低10位,但是保存11位結果wire BaudTick = acc10; / 第 11位作為進位輸出使用2MHz時鐘,"BaudTick"為115234波特,跟理想的115200波特存在 0.03%的誤差。參數化的FPGA波特率發生器前面的設計我們使用的是10位的累加器,如果時鐘頻率提高的話,需要更多的位數。下面是一個

11、使用25MHz時鐘和16位累加器的設計,該設計是參數化的,所以很容易根據具體情況修改。parameter ClkFreque ncy = 25000000; / 25MHzparameter Baud = 115200;parameter BaudGe neratorAccWidth = 16;parameter BaudGe neratorl nc = (Baud<<BaudGe neratorAccWidth)/ClkFreque ncy;reg BaudGe neratorAccWidth:。 BaudGe neratorAcc;always (posedge clk)Bau

12、dGe neratorAcc <= BaudGe neratorAccBaudGe neratorAccWidth-1:0 + BaudGe neratorl nc;wire BaudTick = BaudGe neratorAccBaudGe neratorAccWidth;上面的設計中存在一個錯誤:"BaudGeneratorlnc"的計算是錯誤的,因為 Verilog使用32位的默認結果,但實際計算過程中的某些數據超過了32位,所以改變一種計算方法。parameterBaudGe neratorl nc=(Baud<<(BaudGe neratorA

13、ccWidth-4)+(ClkFreque ncy»5)/(ClkFreque ncy>>4);這行程序也使得結果成為整數,從而防止截斷。這就是整個的設計方法了?,F在我們已經得到了足夠精確的波特率,可以繼續設計串行接收和發送模塊了。RS-232發送模塊F面是我們所想要實現的TxO-ria liz erTrary1 .TXDr Ixjsy£!K>ASyncis-Tirrtier它應該能像這樣工作:? 發送器接收8位的數據,并將其串行輸出。("TxD_start"置位后開始傳輸).?當有數傳輸的時候,使"busy"信號有

14、效,此時“ TxD_start信號被忽略.RS-232模塊的參數是固定的:8位數據,2個停止位,無奇偶校驗.數據串行化假設我們已經有了一個 115200波特的"BaudTick"信號.我們需要產生開始位、8位數據以及停止位。用狀態機來實現看起來比擬適宜。reg 3:0 state;always (posedge elk)case(state)4'b0000: if(TxD_start) state <= 4'b0100;4'b0100: if(BaudTick) state <= 4'b1000; / 開始位4'b1000

15、: if(BaudTick) state <= 4'b1001; / bit 04'b1001: if(BaudTick) state <= 4'b1010; / bit 14'b1010: if(BaudTick) state <= 4'b1011; / bit 24'b1011: if(BaudTick) state <= 4'b1100; / bit 34'b1100: if(BaudTick) state <= 4'b1101; / bit 44'b1101: if(BaudT

16、ick) state <= 4'b1110; / bit 54'b1110: if(BaudTick) state <= 4'b1111; / bit 64'b1111: if(BaudTick) state <= 4'b0001; / bit 74'b0001: if(BaudTick) state <= 4'b0010; / 停止位 14'b0010: if(BaudTick) state <= 4'b0000; / 停止位 2default: if(BaudTick) state <

17、;= 4'b0000;endcase注意看這個狀態機是怎樣實現當"TxD_start"有效就開始,但只在"BaudTick"有效的時候才轉換狀態的?,F在,我們只需要產生"TxD"輸出即可reg muxbit;always (state2:0)case(state2:0)0: muxbit <= TxD_data0;1: muxbit <= TxD_data1;2: muxbit <= TxD_data2;3: muxbit <= TxD_data3;4: muxbit <= TxD_data4;5

18、: muxbit <= TxD_data5;6: muxbit <= TxD_data6;7: muxbit <= TxD_data7;endcase /將開始位、數據以及停止位結合起來assign TxD = (state<4) | (state3 & muxbit);RS232接收模塊F面是我們想要實現的模塊*湘 liz erRbcAs>yrx* 1沁keiYiSir我們的設計目的是這樣的:1.當 RxD 線上有數據時,接收模塊負責識別 RxD 線上的數據2當收到一個字節的數據時,鎖存接收到的數據到"data"總線,并使"

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

20、里我們使用 8倍的采樣時鐘。當波特率為 115200時,采樣時鐘為 921600Hz 。假設我們已經有了一個 8倍于波特率的時鐘信號"Baud8Tick" ,其頻率為 92 1 600Hz 。具體設計首先, 接受到的 "RxD" 信號與我們的時鐘沒有任何關系, 所以采用兩個 D 觸發器對其進行過 采樣,并且使之我我們的時鐘同步。reg 1:0 RxD_sync;always (posedge clk) if(Baud8Tick) RxD_sync <= RxD_sync0, RxD;首先我們對接收到的數據進行濾波,這樣可以防止毛刺信號被誤認為是開始

21、信號。reg 1:0 RxD_cnt;reg RxD_bit;always (posedge clk) if(Baud8Tick) beginif(RxD_sync1 && RxD_cnt!=2'b11) RxD_cnt <= RxD_cnt + 1;elseif(RxD_sync1 && RxD_cnt!=2'b00) RxD_cnt <= RxD_cnt - 1;if(RxD_cnt=2'b00) RxD_bit <= 0;elseif(RxD_cnt=2'b11) RxD_bit <= 1;end一旦

22、檢測到 "開始位 ",使用如下的狀態機可以檢測出接收到每一位數據。reg 3:0 state;always (posedge clk)if(Baud8Tick)case(state)4'b0000: if(RxD_bit) state <= 4'b1000; / start bit found?4'b1000: if(next_bit) state <= 4'b1001; / bit 04'b1001: if(next_bit) state <= 4'b1010; / bit 14'b1010: if

23、(next_bit) state <= 4'b1011; / bit 24'b1011: if(next_bit) state <= 4'b1100; / bit 34'b1100: if(next_bit) state <= 4'b1101; / bit 44'b1101: if(next_bit) state <= 4'b1110; / bit 54'b1110: if(next_bit) state <= 4'b1111; / bit 64'b1111: if(next_bit)

24、 state <= 4'b0001; / bit 74'b0001: if(next_bit) state <= 4'b0000; / stop bit default: state <= 4'b0000;endcase注意,我們使用了 "next_bit" 來遍歷所有數據位。reg 2:0 bit_spacing;always (posedge clk) if(state=0) bit_spacing <= 0;else if(Baud8Tick)bit_spacing <= bit_spacing + 1;wire next_bit = (bit_spacing=7);最后我們使用一個移位存放器來存儲接受到的數據。reg 7:0 RxD_data;a

溫馨提示

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

評論

0/150

提交評論