zoukankan      html  css  js  c++  java
  • 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
        
  • 相关阅读:
    UVA 408 (13.07.28)
    linux概念之用户,组及权限
    Java实现 蓝桥杯 历届试题 网络寻路
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 约数倍数选卡片
    Java实现 蓝桥杯 历届试题 九宫重排
    Java实现 蓝桥杯 历届试题 九宫重排
  • 原文地址:https://www.cnblogs.com/bixiaopengblog/p/6048300.html
Copyright © 2011-2022 走看看