全球最实用的IT互联网信息网站!

AI人工智能P2P分享&下载搜索网页发布信息网站地图

当前位置:诺佳网 > 电子/半导体 > 接口/总线/驱动 >

fpga串口通信的verilog驱动编程解析

时间:2023-04-21 11:18

人气:

作者:admin

标签: 并行接  串口通信  FPGA  Verilog 

导读:fpga串口通信的verilog驱动编程解析-串口的全程为串行接口,也称为串行通信接口,是采用串行通信方式的扩展接口。与串口对应的并行接口,例如高速AD和DA,...

串口的全程为串行接口,也称为串行通信接口,是采用串行通信方式的扩展接口。与串口对应的并行接口,例如高速AD和DA,

这些都是用的并行接口,而且在编程也简单一些。

串口有一下特点:

(1)通信线路简单,只要一对传输线就可以实现双向通信。

(2)布线简单,成本低。

(3)通信距离长,可以实现数米到数千米的通信距离。

(4)传输速率慢。

常见的串口速率如4800 , 9600 , 115200bps,代表每秒钟发送多少bit数据,例如9600bps就代表1秒内发送9600bit数据。 

50d3db3e-dff2-11ed-bfe3-dac502259ad0.png

串口协议 :协议比较简单,一般都是10位数据,1个起始位 低电平 ,然后八个数据位,低位在前,一个奇偶校验位,平时

一般不用,最后是一位停止位高电平,这样一帧数据发送结束。

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

50e5d762-dff2-11ed-bfe3-dac502259ad0.png

整体框架分为两个部分:一个是串口驱动部分 另一个是串口数据控制部分。串口驱动部分负责串口驱动和波特率的选择,串口数据控制模块

负责控制数据内容的控制和发送速度的控制。

51023a2e-dff2-11ed-bfe3-dac502259ad0.jpg

从上面时序图可以看出,每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
    

编辑:黄飞

 

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信