久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    UART通信接口設計

     lixinhecom 2016-06-06
    1、UART通信協議

    UART:Universal Asynchronous Receiver/Transmitter,通用異步接收/發送裝置,所謂異步,就是說發送和接受不能同時進行,是單工的。對于UART的verilog設計,簡單的說就是需要“波特率發生器”與“數據傳輸時序”兩個模塊,如下:

    (1)波特率

    在UART通信協議中很重要的一個定義,就是“波特率”,即傳輸數據時的速率。波特率一般有以下這些:

    clip_image002

    (2)數據傳輸時序

    對于UART數據傳輸的協議,如下所示。其中奇偶校驗位與停止位不是必須的。而“起始位、資料位、停止位”則是必須的。一般資料位為8 bits。

    定義

    起始位

    先發出一個邏輯”0”的信號,表示傳輸字符的開始。

    資料位

    緊接著起始位之后。資料位的個數可以是4、5、6、7、8等,構成一個字符。通常采用ASCII碼。從最低位開始傳送,靠時鐘定位。

    奇偶校驗位

    資料位加上這一位后,使得“1”的位數應為偶數(偶校驗)或奇數(奇校驗),以此來校驗資料傳送的正確性。

    停止位

    它是一個字符數據的結束標志。可以是1位、1.5位、2位的高電平。

    空閑位

    處于邏輯“1”狀態,表示當前線路上沒有資料傳送。

    具體的時序圖如下所示。A-b為起始位,b-c為資料位,c-d為停止位。

    clip_image004


    2、UART硬件設計

    UART是計算機中串行通信端口的關鍵部分。在計算機中,UART相連于產生兼容RS232規范信號的電路。RS232標準定義邏輯“1”信號相對于地為-3到-15伏,而邏輯“0”相對于地為3到15伏。所以,當一個微控制器中的UART相連于PC時,它需要一個RS232驅動器來轉換電平。

    如下圖所示,UART硬件電路灰常的簡單,只需要一塊電平轉換芯片即可。電平轉換芯片一般用Max3232、Max232,SP3232等,其中Maxim公司的電平轉換芯片比較常用。跟PC和處理器相連接的,只要相應的TXD、RXD兩根信號線即可。

    clip_image006


    3、UART Verilog設計

    基于FPGA的UART設計,其實在單片機中沒有這么一說。單片機中早已有了UART的IP,我們只要調用函數即可,但FPGA中,純硬件設計電路上,我們想要使用串口來調試,那我們就必須了解徹底UART通信協議,必須自己動手寫UART的硬核。利用硬件描述語言,相當的方便。

    UART驅動代碼的編寫,算是比較簡單的設計了。Bingo當年用VHDL編寫串口通信,后來學了Verilog,重新來過,最后修改串口,改善得到穩定的版本,經過多次測試,上萬數據傳輸未出現過錯誤,已應用于多個項目中,在此獻丑,希望對你有用。

    以下是相關的下載信息:

    (1)串口調試助手

    http://www./lib/detail.aspx?id=86809

    (2)uart_io_test工程

    http://www./lib/detail.aspx?id=86812

    (3)uart_fifo_design工程

    http://www./lib/detail.aspx?id=86813

    對于基于FPGA的Verilog設計UART通信接口的代碼分析,如下所示:

    (1)波特率發生器

    如果您看過前面章節,那您是否還記得“第九章 為所欲為——教你什么才是真正的任意分頻”?此處我們為了達到標準的頻率,最大極限的不想出現任何誤差,Bingo利用自己設計的“相位控制分頻原理”,來完成此模塊的設計。具體的分頻原理請看第九章,此處不再做累贅的闡述,謝謝。

    關于本模塊的主要代碼,如下:

    /*************************************************

    * Module Name : clk_generator.v

    * Engineer : Crazy Bingo

    * Target Device : EP2C8Q208C8

    * Tool versions : Quartus II 11.0

    * Create Date : 2011/01/27

    * Revision : v1.0

    * Description :

    **************************************************/

    module clk_generator

    (

    input clk,

    input rst_n,

    output clk_bps,

    output clk_smp

    );

    //------------------------------------------

    /************clk_smp = 16*clk_bps************

    Freq_Word1 <= 32'd25770; Freq_Word1 <= 32'd412317; //300 bps

    Freq_Word1 <= 32'd51540; Freq_Word2 <= 32'd824634; //600 bps

    Freq_Word1 <= 32'd103079; Freq_Word2 <= 32'd1649267; //1200 bps

    Freq_Word1 <= 32'd206158; Freq_Word2 <= 32'd3298535; //2400 bps

    Freq_Word1 <= 32'd412317; Freq_Word2 <= 32'd6597070; //4800 bps

    Freq_Word1 <= 32'd824634; Freq_Word2 <= 32'd13194140; //9600 bps

    Freq_Word1 <= 32'd1649267; Freq_Word2 <= 32'd26388279; //19200 bps

    Freq_Word1 <= 32'd3298535; Freq_Word2 <= 32'd52776558; //38400 bps

    Freq_Word1 <= 32'd3693672; Freq_Word2 <= 32'd59098750; //43000 bps

    Freq_Word1 <= 32'd4810363; Freq_Word2 <= 32'd76965814; //56000 bps

    Freq_Word1 <= 32'd4947802; Freq_Word2 <= 32'd79164837; //57600 bps

    Freq_Word1 <= 32'd9895605; Freq_Word2 <= 32'd158329674; //115200bps

    Freq_Word1 <= 32'd10995116; Freq_Word2 <= 32'd175921860; //128000bps

    Freq_Word1 <= 32'd21990233; Freq_Word2 <= 32'd351843721; //256000bps

    *****************************************************/

    //only want to generate beautiful clk for bsp and sample

    reg [31:0] bps_cnt1;

    reg [31:0] bps_cnt2;

    always@(posedge clk or negedge rst_n)

    begin

    if(!rst_n)

    begin

    bps_cnt1 <= 0;

    bps_cnt2 <= 0;

    end

    else

    begin

    bps_cnt1 <= bps_cnt1 + 32'd9895605;

    //Bps=115200bps

    bps_cnt2 <= bps_cnt2 + 32'd158329674;

    //Bps=115200bps*16

    end

    end

    //------------------------------------------

    //clk_bps sync bps generater

    reg clk_bps_r0,clk_bps_r1,clk_bps_r2;

    always@(posedge clk or negedge rst_n)

    begin

    if(!rst_n)

    begin

    clk_bps_r0 <= 0;

    clk_bps_r1 <= 0;

    clk_bps_r2 <= 0;

    end

    else

    begin

    if(bps_cnt1 < 32'h7FFF_FFFF)

    clk_bps_r0 <= 0;

    else

    clk_bps_r0 <= 1;

    clk_bps_r1 <= clk_bps_r0;

    clk_bps_r2 <= clk_bps_r1;

    end

    end

    assign clk_bps = ~clk_bps_r2 & clk_bps_r1;

    //------------------------------------------

    //clk_smp sync receive bps generator

    reg clk_smp_r0,clk_smp_r1,clk_smp_r2;

    always@(posedge clk or negedge rst_n)

    begin

    if(!rst_n)

    begin

    clk_smp_r0 <= 0;

    clk_smp_r1 <= 0;

    clk_smp_r2 <= 0;

    end

    else

    begin

    if(bps_cnt2 < 32'h7FFF_FFFF)

    clk_smp_r0 <= 0;

    else

    clk_smp_r0 <= 1;

    clk_smp_r1 <= clk_smp_r0;

    clk_smp_r2 <= clk_smp_r1;

    end

    end

    assign clk_smp = ~clk_smp_r2 & clk_smp_r1;

    endmodule

    代碼中Bingo設置了多個選項的bps,根據您的需要,可以直接修改代碼,來達到自己的要求。本模塊的功能主要功能是生成兩個時鐘:

    a) clk_bps : UART TXD信號線數據發送的波特率

    b) clk_smp: UART RXD信號線數據接受的采樣速率,以對已波特率的16倍速度采樣,捕獲數據的中點,在數據最穩態讀取數據,達到最大限制的穩定。

    (2)TXD發送模塊

    這部分代碼比較簡單,因為FPGA是主控,只要根據固定的時序給數據即可。Bingo設計了一個狀態機來完成時序,狀態機代碼如下:

    always@(posedge clk or negedge rst_n)

    begin

    if(!rst_n)

    begin

    txd_state <= T_IDLE;

    txd_flag_r <= 0;

    txd <= 1'b1;

    end

    else

    begin

    case(txd_state)

    T_IDLE:

    begin

    txd <= 1;

    txd_flag_r <= 0;

    if(txd_en == 1)

    txd_state <= T_SEND;

    else

    txd_state <= T_IDLE;

    end

    T_SEND:

    begin

    if(clk_bps == 1)

    begin

    if(txd_cnt < 4'd9)

    txd_cnt <= txd_cnt + 1'b1;

    else

    begin

    txd_cnt <= 0;

    txd_state <= T_IDLE;

    txd_flag_r <= 1;

    end

    case(txd_cnt)

    4'd0: txd <= 0;

    4'd1: txd <= txd_data[0];

    4'd2: txd <= txd_data[1];

    4'd3: txd <= txd_data[2];

    4'd4: txd <= txd_data[3];

    4'd5: txd <= txd_data[4];

    4'd6: txd <= txd_data[5];

    4'd7: txd <= txd_data[6];

    4'd8: txd <= txd_data[7];

    4'd9: txd <= 1;

    endcase

    end

    end

    endcase

    end

    End

    數據發送的狀態機設計如下:

    image

    同時,為了軟件調試,數據識別等的方便,Bingo在此模塊設置了數據發送標志位。此部分主要參考了Bingo“第七章 你想干嘛——邊沿檢測技術”的方法,此處不再做累贅闡述,若有不懂請看上文。此部分代碼如下:

    //-------------------------------------

    //Capture the falling of data transfer over

    reg txd_flag_r0,txd_flag_r1;

    always@(posedge clk or negedge rst_n)

    begin

    if(!rst_n)

    begin

    txd_flag_r0 <= 0;

    txd_flag_r1 <= 0;

    end

    else

    begin

    txd_flag_r0 <= txd_flag_r;

    txd_flag_r1 <= txd_flag_r0;

    end

    end

    assign txd_flag = txd_flag_r1 & ~txd_flag_r0;

    (3)RXD發送模塊

    由于接收數據的時候,主控是PC,從機是FPGA,因此FPGA需要采樣數據。以上波特率發生器中講到過,采樣時鐘clk_bps = 16*clk_bps。FPGA硬件描述,通過計數,當采樣到RXD數據起始位信號有效時,0-7-15開始計數,,其中7為數據的中點,最穩定的時刻。因此在此時采樣數據,能夠達到最穩定的效果。Bingo設計代碼如下:

    always@(posedge clk or negedge rst_n)

    begin

    if(!rst_n)

    begin

    smp_cnt <= 0;

    rxd_cnt <= 0;

    rxd_data <= 0;

    rxd_state <= R_IDLE;

    end

    else if(clk_smp == 1)

    begin

    case(rxd_state)

    R_IDLE:

    begin

    rxd_cnt <= 0;

    if(rxd_sync == 1'b0)

    begin

    smp_cnt <= smp_cnt + 1'b1;

    if(smp_cnt == 4'd7) //8 clk_smp enable

    rxd_state <= R_SAMPLE;

    end

    else

    smp_cnt <= 0;

    end

    R_SAMPLE:

    begin

    smp_cnt <= smp_cnt +1'b1;

    if(smp_cnt == 4'd7)

    begin

    rxd_cnt <= rxd_cnt +1'b1;

    if(rxd_cnt == 4'd7)

    rxd_state <= R_IDLE;

    case(rxd_cnt)

    3'd0: rxd_data[0] <= rxd_sync;

    3'd1: rxd_data[1] <= rxd_sync;

    3'd2: rxd_data[2] <= rxd_sync;

    3'd3: rxd_data[3] <= rxd_sync;

    3'd4: rxd_data[4] <= rxd_sync;

    3'd5: rxd_data[5] <= rxd_sync;

    3'd6: rxd_data[6] <= rxd_sync;

    3'd7: rxd_data[7] <= rxd_sync;

    endcase

    end

    end

    endcase

    end

    end

    同樣,發送部分狀態機如下如下所示:

     

    image

      本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發現有害或侵權內容,請點擊一鍵舉報。
      轉藏 分享 獻花(0

      0條評論

      發表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 99久久久精品免费观看国产| 国产精品久久国产精麻豆99网站| 精品久久香蕉国产线看观看亚洲| 国产真实乱子伦精品视频| 天天做天天爱夜夜爽导航| 又大又粗欧美成人网站| 久久亚洲精品情侣| 久久久久久久久久久免费精品| 99久久99久久加热有精品| 亚洲国产精品久久久天堂麻豆宅男| 青草青草久热精品视频在线观看| 欧美牲交a欧美牲交aⅴ图片| 国产MD视频一区二区三区| 精品无码成人片一区二区| 亚洲最大的熟女水蜜桃AV网站| 男人狂桶女人出白浆免费视频| 强开少妇嫩苞又嫩又紧九色| 99久久无码私人网站| 亚洲AV永久无码精品秋霞电影影院| 精品国产中文字幕av| 精品久久久久久中文字幕大豆网 | 久久天天躁狠狠躁夜夜婷| 国产精品 视频一区 二区三区| 亚洲欧美人成网站在线观看看| 国产精品久久国产精品99| 99精品热在线在线观看视| 波多野结衣乳巨码无在线观看 | 2020国产欧洲精品网站| 伊人无码一区二区三区| 又大又爽又硬的曰皮视频| 亚洲精品日韩久久精品| 国精无码欧精品亚洲一区| 奇米777四色成人影视| 精品九九人人做人人爱| 欧美成人精品高清在线观看| 十八禁午夜福利免费网站| 国产资源精品中文字幕| 夜夜高潮夜夜爽国产伦精品| 天天影视网色香欲综合网| 免费无码一区无码东京热| 精品无码人妻一区二区三区|