串口通信实现-串口发送(vivado&verilog版)

这篇具有很好参考价值的文章主要介绍了串口通信实现-串口发送(vivado&verilog版)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

串口系列知识分享:
(1)串口通信实现-串口发送
(2)串口通信发送多字节数据
(3)串口通信实现-串口接收
(4)UART 通信-使用VIO进行板级验证
(5)串口接收-控制LED闪烁
(6)使用串口发送实现ACX720开发板时钟显示
(7)串口发送+RAM+VGA传图


前言

此文介绍uart串口协议(串口发送)的verilog实现和testbench的编写,仿真环境为vivado 2018.3。


提示:以下是本篇文章正文内容,下面案例可供参考

一、串口通信协议(uart)

串口作为常用的三大低速总线(UART、SPI、IIC)之一,在设计众多通信接口和调试时占有重要地位。串口(UART)全称通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),主要用于数据间的串行传递,是一种全双工传输模式。它在发送数据时将并行数据转换成串行数据来传输,在接收数据时将接收到的串行数据转换成并行数据。(具体应用可自行百度)

二、串口发送的时序图

UART 在发送或接收过程中的一帧数据由4部分组成,起始位、数据位、奇偶校验位和停止位,如上图所示。其中,起始位标志着一帧数据的开始,停止位标志着一帧数据的结束,数据位是一帧数据中的有效数据。

    起始位:起始位标志。低有效。

    数据位:一帧数据中的有效数据。注意,串口协议规定了数据位长度只能位 6 7 8 位。要想发多位数据,只能将其切分为多个过程发送。

    奇偶校验位:是用来验证数据的正确性。奇偶校验一般不使用,如果 使用,则既可以做奇校验(Odd)也可以做偶校验(Even)。其实就是发的时候如果奇校验位为1,表面数据中1的个数为奇数个,再看接受端的奇校验位是否依旧为1。如果是的话,校验成功。在一定概率上保证了传输的正确性。当然,只是概率上的传输正确。此次试验不同奇偶校验。

    停止位:停止位标志着一帧数据的结束,高有效。

    空闲时,传输 1 。

    波特率设置 : 由于是异步通信,所以没有一个统一的时钟,需要双方约定传输传输速率。常见的波特率有:300, 1200, 2400, 9600, 19200, 115200 等.即一秒发送多少位数据。

    所以我们需要实现下面的时序图。当使能信号到来时,发送起始位,数据位,停止位,一帧数据发送结束。

串口时序图,FPGA代码分享,fpga开发

三、uart_byte_tx模块

module uart_byte_tx(
    Clk,
    Reset_n,
    Data,
    Send_Go,    // 改成单脉冲启动信号  启动一个内部 send_en 信号
    Baud_set,
    uart_tx,
    Tx_done
);
    input Clk;
    input Reset_n;
    input [7:0]Data;
    input Send_Go;
    input [2:0]Baud_set;
    output reg uart_tx;
    output reg Tx_done;
    
    //Baud_set = 0   就让波特率 = 9600;
    //Baud_set = 1   就让波特率 = 19200
    //Baud_set = 2   就让波特率 = 38400;
    //Baud_set = 3   就让波特率 = 57600;   
    //Baud_set = 4   就让波特率 = 115200; 

    reg [17:0]bps_DR;
    always@(*)
        case(Baud_set)
            0:bps_DR = 1000000000/9600/20;
            1:bps_DR = 1000000000/19200/20;
            2:bps_DR = 1000000000/38400/20;
            3:bps_DR = 1000000000/57600/20;
            4:bps_DR = 1000000000/115200/20;
            default:bps_DR = 1000000000/9600/20;
         endcase

    reg Send_en;
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)       
        Send_en <= 0;
    else if(Send_Go)
        Send_en <= 1;
    else if(Tx_done)
        Send_en <= 0;
        
    reg [7:0]r_Data;
    always@(posedge Clk)     //进行数据寄存,防止当Send_Go脉冲出现时,Data数据发生偏差
    if(Send_Go)
        r_Data <= Data;
    else
        r_Data <= r_Data;     

    wire bps_clk;
    assign bps_clk = (div_cnt == 1);
    
    reg [17:0]div_cnt;
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        div_cnt <= 0;
    else if(Send_en)begin
        if(div_cnt == bps_DR - 1)
            div_cnt <= 0;
        else 
            div_cnt <= div_cnt + 1'b1;
    end
    else
        div_cnt <= 0;

    reg [3:0]bps_cnt;
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        bps_cnt <= 0;
    else if(Send_en)begin
        if(bps_clk)begin
            if(bps_cnt == 11)
                bps_cnt <= 0;
            else
                bps_cnt <= bps_cnt + 1'b1;
        end
    end
    else
        bps_cnt <= 0;
    
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n) begin
        uart_tx <= 1'b1;
    end
    else begin
        case(bps_cnt)
            1:uart_tx <= 0;
            2:uart_tx <= r_Data[0];
            3:uart_tx <= r_Data[1];
            4:uart_tx <= r_Data[2];
            5:uart_tx <= r_Data[3];
            6:uart_tx <= r_Data[4];
            7:uart_tx <= r_Data[5];
            8:uart_tx <= r_Data[6];
            9:uart_tx <= r_Data[7]; 
            10:uart_tx <= 1;
            11:begin uart_tx <= 1;end
            default:uart_tx <= 1;
        endcase
     end
     
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n) 
        Tx_done <= 0;
    else if((bps_clk == 1)  && (bps_cnt == 10))
        Tx_done <= 1;
    else
        Tx_done <= 0;

endmodule

四、uart_tx_test模块

此模块用于对uart_byte_tx模块进行测试,将uart_byte_tx模块中的Data输入设为每次发送加1。即第一次发送8’d0,第二次发送8’d1,依次加1发送。

module uart_tx_test(
    Clk,
    Reset_n,
    uart_tx,
);
    input Clk;
    input Reset_n;
    output uart_tx;
    
    reg Send_Go;
    reg [7:0]Data;
    
    uart_byte_tx uart_byte_tx(
        .Clk(Clk),
        .Reset_n(Reset_n),
        .Data(Data),
        .Send_Go(Send_Go),
        .Baud_set(3'd4),
        .uart_tx(uart_tx),
        .Tx_done(Tx_done)
    );
    
    reg [24:0]counter;
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        counter <= 0;
    else if(counter == 4999999)        //每10ms发送一次数据
        counter <= 0;
    else
        counter <= counter + 1;
        
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)       
        Send_Go <= 0;
    else if(counter == 1)
        Send_Go <= 1;
    else
        Send_Go <= 0;

    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)        
        Data <= 0;
    else if(Tx_done)
        Data <= Data + 1'b1;   
    
endmodule

五、TB文件

`timescale 1ns / 1ps

module uart_tx_test_tb();
    reg Clk;
    reg Reset_n;
    wire uart_tx;
    
     uart_tx_test uart_tx_test(
        .Clk(Clk),
        .Reset_n(Reset_n),
        .uart_tx(uart_tx)
    );
    
    initial Clk = 1;
    always#10 Clk = ~Clk;
    
    initial begin
        Reset_n = 0;
        #201;
        Reset_n = 1;
        #50000000;    
    end

endmodule

六、仿真波形展示

串口时序图,FPGA代码分享,fpga开发
【附件:】链接:https://pan.baidu.com/s/1KNI2lWvdekhcJ-VJukWNeg?pwd=78h6
提取码:78h6文章来源地址https://www.toymoban.com/news/detail-621468.html

到了这里,关于串口通信实现-串口发送(vivado&verilog版)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【FPGA协议篇】UART通信及其verilog实现(代码采用传参实现模块通用性,适用于快速开发)

    ​ 即通用异步收发器(Universal Asynchronous Receiver/Transmitter),是一种 串行、异步、全双工 的通信协议。特点是通信线路简单,适用于远距离通信,但传输速度慢。 数据传输速率:波特率(单位:baud,波特) 常见波特率有:1200、2400、4800、19200、38400、57600等,最常用的是9600和11520

    2024年02月05日
    浏览(36)
  • FPGA——用vivado实现串口通讯协议

    串口通信是一种通过串行传输数据的通信方式。它使用单个数据线将数据位逐个传输,而不是同时传输多个数据位。串口通信常用于连接计算机与外部设备,如打印机、调制解调器、传感器等。 串口通信一般使用的是异步传输方式,即发送方和接收方的时钟不同步。数据传输

    2024年02月06日
    浏览(30)
  • 基于FPGA实现串口多字节发送

    module UART_tx #( parameter UART_BPS = \\\'d9600, //波特率9600 parameter CLK_FREQ = \\\'d50_000_000, //时钟频率50Mhz parameter BYTES = \\\'d8, //需要发送数据的字节数 ) ( input wire clk, input wire rst_n, input wire [(BYTES * 8 -1):0] pi_data, input wire pi_flag, ); localparam BAUD_CNT_MAX = CLK_FREQ/UART_BPS ; //1S钟传输9600bit数据,时钟1S有

    2024年02月16日
    浏览(30)
  • FPGA用verilog HDL实现串口通讯协议

    串口通信是一种通过串行传输数据的通信方式。它使用单个数据线将数据位逐个传输,而不是同时传输多个数据位。串口通信常用于连接计算机与外部设备,如打印机、调制解调器、传感器等。 串口通信一般使用的是异步传输方式,即发送方和接收方的时钟不同步。数据传输

    2024年02月05日
    浏览(46)
  • 【Python】串口通信-与FPGA、蓝牙模块实现串口通信(Python+FPGA)

    🎉欢迎来到Python专栏~与FPGA、蓝牙模块实现串口通信 ☆* o(≧▽≦)o *☆ 嗨 ~我是 小夏与酒 🍹 ✨ 博客主页: 小夏与酒的博客 🎈该系列 文章专栏: Python学习专栏 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏 📜 欢迎大家关注! ❤️ Python与FPGA串口通信

    2024年02月15日
    浏览(34)
  • fpga verilog rs232 发送模块实现

    RS-232是一种串行通信协议,用于在计算机和其他外部设备之间进行数据传输。RS-232定义了电气特性、信号级别、机械特性和传输速率等规范,为串行通信提供了一种标准化的接口。 RS-232通常使用DB9连接器,用于传输和接收数据、控制信号以及地线连接。 但除了235脚其它基本

    2024年02月03日
    浏览(39)
  • P27[9-3]STM32:串口通信(串口发送)(内含:1.接线图+2.实物图+3.代码部分+4.解决串口发送数据,数据是汉字,结果发送结果为乱码的现象)

    1.接线图如下: 跳线帽接在4~5引脚,2,3引脚连接PA9和PA10引脚。下图也可得出USART接PA9和PA10引脚。 TX和RX是交叉连接。PA9(黄线)是TX,接RXD。PA9(绿线)是RXD,接TX. 图中的串口模块和STINK都接电脑上,使之拥有独立供电。 2.实物图: 黄色为跳线帽,接4~5引脚。

    2024年02月09日
    浏览(32)
  • FPGA 串口通信(uart)初探篇(含源代码)

    一、UART 串口通信,说实话是日常生活中很常见的一种9针型的主机和显示屏之间的通信模式。本次博客,只为自己复盘相关知识,初学者,错误较多,请多指教。所以本文参考(一)FPGA之串口通信(UART)_fpga uart-CSDN博客 而编著的。 FPGA是一种可编程的逻辑器件,用于各种数字电

    2024年04月14日
    浏览(28)
  • FPGA时序分析与时序约束(Vivado)

    后缀L的这个单元中,会生成锁存器 查看布线 定位线路 时间分析,还要考虑数据变化的建立时间与保持时间 经过图上计算可得公式 : Tsu裕量 = (Tskew + 时钟周期 - Tsu) - (Tco + Tdelay) Thd裕量 = Tco + Tdelay - Thd 两个时间都大于0,才能保证系统不产生亚稳态。 建立时间裕量、组

    2024年01月19日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包