<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 手機與無(wú)線(xiàn)通信 > 牛人業(yè)話(huà) > 小梅哥和你一起深入學(xué)習FPGA之串口調試(一)(上)

小梅哥和你一起深入學(xué)習FPGA之串口調試(一)(上)

作者: 時(shí)間:2015-11-19 來(lái)源:網(wǎng)絡(luò ) 收藏

  大家好,這幾天在各個(gè)論壇上,經(jīng)常就有人在向我咨詢(xún)基于的串口通信代碼,大部分都是在網(wǎng)上下載一個(gè)現成的代碼,但是在使用中就遇到了各種問(wèn)題,于是就發(fā)到了論壇上來(lái)求助。在閱讀了他們的代碼之后,我發(fā)現幾乎出自同一個(gè)版本(目前確定為特權同學(xué)的基于EPM240入門(mén)實(shí)驗的代碼)。他們在調試這個(gè)代碼的時(shí)候,經(jīng)常存在這樣幾個(gè)問(wèn)題:1、部分人對該串口通訊模塊完全不理解,對每句話(huà),甚至每個(gè)模塊的功能都不理解;2、部分人采用最原始的畫(huà)波形的方式來(lái)對該模塊進(jìn)行仿真,結果無(wú)法得到仿真結果;3、部分人不會(huì )使用modelsim對該設計進(jìn)行仿真;4、絕大部分人不會(huì )編寫(xiě)testbench;5、下板測試無(wú)法進(jìn)行正確的字符串收發(fā)。在公司內部,我將這種現象和幾位老師交流之后,夏宇聞老師建議我專(zhuān)門(mén)針對該代碼寫(xiě)一個(gè)由原理到代碼,由仿真到板級的調試筆記。爭取用最通俗,也是最笨的辦法,手把手的教會(huì )大家來(lái)調試這個(gè)代碼。

本文引用地址:http://dyxdggzs.com/article/283059.htm

  本調試筆記主要由五個(gè)部分組成:原始代碼分析;原始代碼驗證;對原始代碼進(jìn)行修改;對修改后的代碼進(jìn)行驗證;對修改后的設計進(jìn)行板級驗證。每個(gè)部分,小梅哥都會(huì )用圖文結合的方式,教大家一步一步的來(lái)進(jìn)行。

  原始代碼分析

  該代碼來(lái)自小梅哥最崇拜的大神,特權同學(xué)。當時(shí)小梅哥也是看著(zhù)特權同學(xué)的書(shū)和視頻教程一步一步走過(guò)來(lái)的。特權同學(xué)的代碼實(shí)現了單字節的收發(fā)測試,沒(méi)有對連續字節的收發(fā)進(jìn)行測試。特權同學(xué)當時(shí)也說(shuō)過(guò),這個(gè)只是一個(gè)簡(jiǎn)單的實(shí)驗,離實(shí)際工業(yè)應用還有一定的距離??紤]到論壇上很多小伙伴都希望能夠實(shí)現連續字節的收發(fā)功能,因此小梅哥就在特權同學(xué)的代碼上進(jìn)行了修改。修改后的代碼,輸入時(shí)鐘可以在一定范圍內選擇任意頻率,目前已經(jīng)支持5種波特率選擇(9600、19200、38400、57600、115200),實(shí)際小梅哥還做過(guò)更高波特率的測試,目前實(shí)測在115200波特率的速率下可以實(shí)現超過(guò)9999999次連續無(wú)間斷的收發(fā)。這里,小梅哥首先將特權同學(xué)設計架構在這里列出來(lái),以給讀者一個(gè)直觀(guān)的印象。

    

 

  由上圖可知,特權同學(xué)的UART串口設計主要包含了四個(gè)模塊:串口發(fā)送模塊(my_uart_tx)、串口接收模塊(my_uart_rx)、串口接收波特率發(fā)生器(speed_rx)和串口發(fā)送波特率發(fā)生器(speed_tx),其中,串口發(fā)送波特率發(fā)生器主要用來(lái)產(chǎn)生串口發(fā)送模塊發(fā)送數據時(shí)所需的波特率時(shí)鐘,串口接收波特率發(fā)生器主要用來(lái)產(chǎn)生串口接收模塊接收數據時(shí)的波特率時(shí)鐘,串口發(fā)送模塊主要負責在指定波特率的速率下將待發(fā)送字節發(fā)送出去,串口接收模塊則主要負責接收來(lái)自其他設備發(fā)送過(guò)來(lái)的串口數據。my_uart_top模塊即串口收發(fā)頂層模塊實(shí)現了各個(gè)模塊間的信號連接功能,通過(guò)該頂層模塊的連接,實(shí)現了將串口接收到的數據再發(fā)送出去的功能,即我們測試串口通信最常用的一種方式——回環(huán)測試。特權同學(xué)該實(shí)驗的各個(gè)端口和內部信號的意義如表1所示:

  該實(shí)驗的內容為,串口接收模塊在檢測到發(fā)送設備發(fā)送過(guò)來(lái)的數據起始位時(shí),接收中斷信號置1,該信號則作為啟動(dòng)串口接收波特率發(fā)送器的控制信號,然后在每個(gè)波特率時(shí)鐘上升沿到來(lái)時(shí)讀取串口接收端口(rs232_rx)上的數據。一幀(字節)數據接收完成后,接收中斷信號拉低,停止波特率發(fā)生器工作,接收完成,系統進(jìn)入等待狀態(tài),等待下一次的數據到來(lái)。

  同時(shí),接收中斷信號的下降沿也作為串口發(fā)送模塊的發(fā)送使能信號,因為一旦接收中斷信號的下降沿出現,就表明接收模塊完成了一次數據的接收,此時(shí),就開(kāi)始使能串口發(fā)送波特率發(fā)生器,串口發(fā)送模塊則在波特率時(shí)鐘的上升沿到來(lái)時(shí)依次將接收模塊接收到的數據的每一位(發(fā)送模塊自動(dòng)添加起始位和停止位)依次發(fā)送出去,當數據發(fā)送完成之后,停止串口發(fā)送波特率發(fā)生器的使能,模塊進(jìn)入等待狀態(tài),等待下一次接收中斷信號下降沿的到來(lái)。

  這里,我們首先對該設計的波特率發(fā)生器模塊進(jìn)行分析。該模塊相對簡(jiǎn)單,代碼如下所示:

  以下是代碼片段:

  1 module speed_select (

  2 clk, rst_n ,

  3 bps_start , clk_bps

  4 );

  5

  6 input clk; // 50MHz

  7 input rst_n ; //

  8 input bps_start ; //

  9 output clk_bps ; // clk_bps

  10

  11 /*

  12 parameter bps9600 = 5207, // 9600bps

  13 bps19200 = 2603, // 19200bps

  14 bps38400 = 1301, // 38400bps

  15 bps57600 = 867, // 57600bps

  16 bps115200 = 433; // 115200bps

  17

  18 parameter bps9600_2 = 2603,

  19 bps19200_2 = 1301,

  20 bps38400_2 = 650,

  21 bps57600_2 = 433,

  22 bps115200_2 = 216;

  23 */

  24

  25 //

  26 `define BPS_PARA 5207 // 9600

  27 `define BPS_PARA_2 2603 // 9600

  28

  29 reg[ 12 : 0] cnt ; //

  30 reg clk_bps_r ; //

  31

  32 //---------------------------------------------------------

  33 reg[ 2 : 0] uart_ctrl ; // uart

  34 //---------------------------------------------------------

  35

  36 always @ ( posedge clk or negedge rst_n )

  37 if(! rst_n ) cnt <= 13'd0 ;

  38 else if(( cnt == `BPS_PARA ) || ! bps_start ) cnt <= 13'd0 ;

  39 else cnt <= cnt+1'b1 ; //

  40

  41 always @ ( posedge clk or negedge rst_n )

  42 if(! rst_n ) clk_bps_r <= 1'b0 ;

  43 else if( cnt == `BPS_PARA_2 ) clk_bps_r <= 1'b1 ;

  //clk_bps_r ,

  44 else clk_bps_r <= 1'b0 ;

  45

  46 assign clk_bps = clk_bps_r ;

  47

  48 endmodule

  該代碼的12-22行用注釋的方式告訴了我們,獲得不同波特率時(shí)波特率分頻計數器的值應該為多少,以及波特率計數器計數到一半時(shí)的值為多少(該值作為對信號的采樣點(diǎn),因為一般情況下,一位數據,在該位數據保持時(shí)間的中間時(shí)刻是最穩定的)。26行和27行定義的兩個(gè)參數BPS_PARA和BPS_PARA_2分別就是波特率分頻計數器的最大值和中間值。實(shí)際使用時(shí),只需要根據你所需要的波特率,更改這兩個(gè)參數的值即可 。例如,選擇波特率為9600bps時(shí),設定BPS_PARA=5207,BPS_PARA_2=2603。關(guān)于這個(gè)值的計算,這里暫時(shí)不提,后文會(huì )有交代。

  36行至39行為波特率分頻計數器的計數進(jìn)程,即波特率發(fā)生模塊沒(méi)有被使能(! bps_start)或者計數器計數到BPS_PARA后則將計數器清零,其它情況下則每來(lái)一個(gè)時(shí)鐘上升沿計數器自加1。通過(guò)此進(jìn)程,則可得到相對精準的波特率定時(shí)。

  41行至44行為數據采樣時(shí)刻的生成,上面提到過(guò)“一般情況下,一位數據,在該位數據保持時(shí)間的中間時(shí)刻是最穩定的”,因此這里我們在計數器計數到一半時(shí),產(chǎn)生一個(gè)時(shí)鐘周期的高脈沖,此脈沖作為采樣數據的使能信號。

 


上一頁(yè) 1 2 3 下一頁(yè)

關(guān)鍵詞: FPGA 串口調試

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>