fpga串口通信的verilog驅動


  串口的全程為串行接口,也稱為串行通信接口,是采用串行通信方式的擴展接口。與串口對應的並行接口,例如高速AD和DA,

這些都是用的並行接口,而且在編程也簡單一些。

  串口有一下特點:

  (1)通信線路簡單,只要一對傳輸線就可以實現雙向通信。

  (2)布線簡單,成本低。

  (3)通信距離長,可以實現數米到數千米的通信距離。

  (4)傳輸速率慢。

  常見的串口速率如4800 , 9600 , 115200bps,代表每秒鍾發送多少bit數據,例如9600bps就代表1秒內發送9600bit數據。 

  串口協議 : 協議比較簡單,一般都是10位數據,1個起始位 低電平 ,然后八個數據位,低位在前,一個奇偶校驗位,平時

一般不用,最后是一位停止位高電平,這樣一幀數據發送結束。

  下面介紹一下我的程序框架:

    整體框架分為兩個部分:一個是串口驅動部分 另一個是串口數據控制部分。串口驅動部分負責串口驅動和波特率的選擇,串口數據控制模塊

  負責控制數據內容的控制和發送速度的控制。

從上面時序圖可以看出,每10ms發送一幀數據,這里data_en負責波特率驅動使能,uart_tx_end有兩個功能,一個是關閉data_en使能,另一個是給10ms計數器

清零。

/*-----------------------------------------------------------------------

Date                :        2017-09-03
Description            :        Design for uart_driver.

-----------------------------------------------------------------------*/

module uart_tx_driver
(
    //global clock
    input                    clk            ,        //system clock
    input                    rst_n        ,         //sync reset
    
    //uart interface
    output    reg                uart_tx        ,

    //user interface
    input            [1:0]    bps_select    ,        //波特率選擇
    input            [7:0]    uart_data    ,        
    input                    data_en        ,        //發送數據使能
    output    reg                uart_tx_end    
); 


//--------------------------------
//Funtion :    參數定義

parameter            BPS_4800    =    14'd10417    ,
                    BPS_9600    =    14'd5208    ,
                    BPS_115200    =    14'd434        ;

reg            [13:0]        cnt_bps_clk                ;
reg            [13:0]        bps                        ;
reg                        bps_clk_en                ;    //bps使能時鍾
reg            [3:0]        bps_cnt                    ;
wire        [13:0]        BPS_CLK_V = bps >> 1    ;
//--------------------------------
//Funtion :    波特率選擇          

always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        bps <= 1'd0;
    else if(bps_select == 2'd0)
        bps <= BPS_115200;
    else if(bps_select == 2'd1)
        bps <= BPS_9600;
    else
        bps <= BPS_4800;
end

//--------------------------------
//Funtion :    波特率計數

always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        cnt_bps_clk <= 1'd0;
    else if(cnt_bps_clk >= bps - 1 && data_en == 1'b0)
        cnt_bps_clk <= 1'd0;
    else
        cnt_bps_clk <= cnt_bps_clk + 1'd1;
end
 
//--------------------------------
//Funtion :    波特率使能時鍾

always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        bps_clk_en <= 1'd0;
    else if(cnt_bps_clk == BPS_CLK_V - 1)
        bps_clk_en <= 1'd1;
    else
        bps_clk_en <= 1'd0;
end

//--------------------------------
//Funtion :    波特率幀計數

always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        bps_cnt <= 1'd0;
    else if(bps_cnt == 11)
        bps_cnt <= 1'd0;
    else if(bps_clk_en)
        bps_cnt <= bps_cnt + 1'd1;
end

//--------------------------------
//Funtion :    uart_tx_end

always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        uart_tx_end <= 1'd0;
    else if(bps_cnt == 11)
        uart_tx_end <= 1'd1;
    else
        uart_tx_end <= 1'd0;
end


//--------------------------------
//Funtion :       發送數據

always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        uart_tx <= 1'd1;
    else case(bps_cnt)
        4'd0     : uart_tx <= 1'd1; 
        
        4'd1     : uart_tx <= 1'd0; //begin
        4'd2     : uart_tx <= uart_data[0];//data
        4'd3     : uart_tx <= uart_data[1];
        4'd4     : uart_tx <= uart_data[2];
        4'd5     : uart_tx <= uart_data[3];
        4'd6     : uart_tx <= uart_data[4];
        4'd7    : uart_tx <= uart_data[5];
        4'd8     : uart_tx <= uart_data[6];
        4'd9     : uart_tx <= uart_data[7];
        
        4'd10     : uart_tx <= 1; //stop
        default : uart_tx <= 1;    
    endcase
end




endmodule
    
/*-----------------------------------------------------------------------

Date                :        2017-XX-XX
Description            :        Design for .

-----------------------------------------------------------------------*/

module uart_tx_control
(
    //global clock
    input                    clk                ,            //system clock
    input                    rst_n            ,             //sync reset
    
    //user interface
    output    reg        [7:0]    uart_data        ,
    output    reg                data_en            ,
    input                    uart_tx_end
    
); 


//--------------------------------
//Funtion :  參數定義

parameter            DELAY_10MS        =        500_000                ;
reg        [31:0]        cnt_10ms            ;
wire                delay_10ms_done        ;             


//data    define
reg        [31:0]        cnt_1s;                        


//--------------------------------
//Funtion :  cnt_10ms

always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        cnt_10ms <= 1'd0;
    else if(cnt_10ms == DELAY_10MS - 1 && uart_tx_end == 1'd1)
        cnt_10ms <= 1'd0;
    else 
        cnt_10ms <= cnt_10ms + 1'd1;
end

assign        delay_10ms_done    =    (cnt_10ms == DELAY_10MS - 1) ? 1'd1 : 1'd0;



//--------------------------------
//Funtion :  data_en

always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        data_en <= 1'd0;
    else if(delay_10ms_done)
        data_en <= 1'd1;
    else if(uart_tx_end)
        data_en <= 1'd0;
end


///////////////////////數據測試/////////////////////////////
//--------------------------------
//Funtion :  cnt_1s

always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        cnt_1s <= 1'd0;
    else if(cnt_1s == 49_999_999)
        cnt_1s <= 1'd0;
    else    
        cnt_1s <= cnt_1s + 1'd1;
end

//--------------------------------
//Funtion : uart_data

always @(posedge clk or negedge rst_n)
begin
    if(!rst_n)
        uart_data <= 1'd0;
    else if(uart_data >= 10)
        uart_data <= 1'd0;
    else if(cnt_1s == 49_999_999)
        uart_data <= uart_data + 1'd1;
end




endmodule
    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM