• 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
        
  • 相关阅读:
    .Net Core微服务——Ocelot(2):集成Consul 老马
    .NET 微服务——CI/CD(1):Jenkins+Gitee自动构建 老马
    .Net Core——用SignalR撸个游戏 老马
    JUC之线程间的通信
    SpringBoot文章合集
    JUC之线程间定制化通信
    JUC之集合中的线程安全问题
    JUC文章合集
    JUC之Lock接口以及Synchronized回顾
    JUC概述
  • 原文地址:https://www.cnblogs.com/bixiaopengblog/p/6048300.html
Copyright © 2020-2023  润新知