FPGA自学笔记--串口通信发送多字节数据(verilog版)

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

1.需求分析

        关于uart协议实现这部分大家可以参考我上一篇的博客。《FPGA自学笔记--串口通信实现(vivado&verilog版)》。在上一篇博客中,主要实现了将单字节的数据,我们其实就是用上一篇博客的模块来实现多字节数据的发送。

        在真实的数据传输过程中,我们不只是发送 6 7 8 位数据,也有可能发送12 16 20位的数据,所以我们需要调用多次串口发送模块来发送多字节数据。通过状态机实现,假设我们这次发送一个40位,5字节的数据,所以朴素的来讲,我们可以有6个状态,0状态是整个模块等待状态,1,2,3,4,5状态分别为5个字节数据的发送状态。

2.总体模块和状态转移图。

        上一篇博客中,单字节的串口发送模块为uart_tx。实现的具体功能为,当send_go为高电平时,将data里的并行数据以串行数据发出,发送完成时 tx_done 产生一个单脉冲。我们需要在上层模块中调用这个模块。上层模块的框图如昨图。需要调用的uart_tx模块如右图所示。

        FPGA自学笔记--串口通信发送多字节数据(verilog版)FPGA自学笔记--串口通信发送多字节数据(verilog版)

所以,需要trans_go启动状态机,状态机内部产身send_go信号,传输一字节数据。发送完成后,uart_tx模块会产生tx_done信号,tx_done信号用来激活状态机的下一个状态,开始发送下一个数据,再次产生一个send_go脉冲,送入data数据,依次送完5字节数据,当最后一个字节发送完成成,最后一个状态5在tx_done下返回第一个状态,并产生五字节发送完成信号,trans_down.回到第一个状态后,等待发送下一个四十位,五字节数据的trans_go。

状态转移图如下。

FPGA自学笔记--串口通信发送多字节数据(verilog版)

当然,这个状态转移图也可以简化,由于我目前也是小白状态,只能写出这种比较好理解,简单的写法,大家以后也可以尝试比较高级的写法。即只用两个状态机实现,或者讲后面五个状态总结为一个大状态,

3.设计文件和testbench文件

        在top文件中例化uart_byte_tx模块,这部分具体代码请参考上一个博客。代码参考了B站小梅哥的视频。新手强烈推荐。

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/04/30 20:20:59
// Design Name: 
// Module Name: uart_tx_5byte
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//
// 使用串口发送5个字节(40 bit)的数据到电脑

module uart_tx_5byte(
    clk,
    reset,
    data40,
    trans_go,
    uart_tx,
    trans_done
    );
    
    input clk;
    input reset;
    input trans_go;
    input [39:0]data40;
    output uart_tx;
    output reg trans_done;
    reg [7:0]data;
    reg send_go;
    //reg tx_done;
    
uart_byte_tx uart_byte_tx(
        .clk(clk),
        .reset(reset),
        .send_go(send_go),
        .data(data),
        .baud_set(4),
        .uart_tx(uart_tx),
        .tx_done(tx_done)
    );

    reg [2:0]state;
   
    always@(posedge clk or negedge reset)
        if(!reset)begin
            state <= 0;
            send_go <= 0;
            data <= 0;
            trans_done <= 0;
        end
        else if(state == 0)begin
            trans_done <= 0;
            //if(tx_done)begin             // 当发完的时候  发新的
            if(trans_go)begin             //  由trans_go 点燃第一个状态  启动状态  用tx_done 是无法启动状态机的  tx_done 是 0状态结束标志
                data <= data40[7:0];
                send_go <= 1;
                state <= 1;
            end
            else begin
                data <= data;
                send_go <= 0;
                state   <= 0;
            end        
        end
        else if(state == 1)begin
            if(tx_done)begin
                data <= data40[15:8];
                send_go <= 1;
                state <= 2;
            end
            else begin
                data <= data;
                send_go <= 0;
                state   <= 1;
            end        
        end
        else if(state == 2)begin
            if(tx_done)begin
                data <= data40[23:16];
                send_go <= 1;
                state <= 3;
            end
            else begin
                data <= data;
                send_go <= 0;
                state   <= 2;
            end        
        end
        else if(state == 3)begin
            if(tx_done)begin
                data <= data40[31:24];
                send_go <= 1;
                state <= 4;
            end
            else begin
                data <= data;
                send_go <= 0;
                state   <= 3;
            end        
        end
        else if(state == 4)begin
            if(tx_done)begin
                data <= data40[39:32];
                send_go <= 1;
                state <= 5;
            end
            else begin
                data <= data;
                send_go <= 0;
                state   <= 4;
            end        
        end
        else if(state == 5)begin
            if(tx_done)begin               // 当发完的时候 回到初始状态
                send_go <= 0;
                state <= 0;
                trans_done <= 1;
            end
            else begin                    // 当没发完的时候 等他发完
                data <= data;
                send_go <= 0;
                state   <= 5;
            end        
        end
endmodule

对应的testbench文件

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2022/04/30 21:51:02
// Design Name: 
// Module Name: uart_tx_5byte_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module uart_tx_5byte_tb(
    );
    reg clk;
    reg reset;
    reg [39:0]data40;
    reg trans_go;
    wire trans_done;
    wire uart_tx;
   
    
uart_tx_5byte uart_tx_5byte(
    .clk(clk),
    .reset(reset),
    .data40(data40),
    .trans_go(trans_go),
    .uart_tx(uart_tx),
    .trans_done(trans_done)
    );
    
    initial clk = 1;
    always #10 clk = ~clk;
    
    initial begin
    reset = 0;
    data40 = 0;
    trans_go = 0;
    # 201;
    # 200;
    reset = 1;
    data40 = 40'h123456789a;
    trans_go = 1;
    # 20
    trans_go = 0;
    
    @(posedge trans_done);
    # 200000;
    data40 = 40'habc1234655;
    trans_go = 1;
    # 20
    trans_go = 0;
    @(posedge trans_done);
    # 200000;
    $stop;
    end 
endmodule

 4.仿真结果分析

FPGA自学笔记--串口通信发送多字节数据(verilog版)

显然,如图所示,一定要注意,多字节发送,每个字节还是存在起始位和终止位的,所以应该还是10位10位的发,看时序图的时候一定不要看错了,去除箭头所示的标志位后,对比数据,并行40位输入和串行输出,结果一致,从低位到高位,完全正确。有兴趣的同学可以直接下载我的vivado工程。文章来源地址https://www.toymoban.com/news/detail-416002.html

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

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

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

相关文章

  • FPGA入门学习笔记(十)Vivado设计状态机实现UART多字节数据发送

    使用串口发送5个字节数据到电脑 1、ADC采样的结果为12位,如何使用串口发送 2、16位数据,如何通过串口发送 3、多个字节的数据,如何通过串口发送 UART规定,发送的数据位只能有6、7、8位,若直接修改发送位数,接收模块将不适配。 两种情况: 1、没有开始发送(上一次的

    2024年02月12日
    浏览(50)
  • 【个人笔记】51单片机串口通信的字符串接收和发送,串口通信调节数码管显示时钟(串口通信,定时器,数码管)

           目的:利用PROTUES仿真软件、串口调试助手、虚拟串口,搭建单片机与PC通信仿真平台,熟悉单片机串口的配置及与PC机的通信方法;尝试制定通信协议,单片机根据通信协议解析接收到的内容,并根据接收的指令执行相应的操作。 基本功能: 1.时分秒的动态显示。

    2024年02月11日
    浏览(63)
  • FPGA串口(RS422)调试笔记:理解串口通信与调试记录

    探索FPGA串口(RS422)通信的调试过程与记录,包括串口通信概念解析、调试步骤、代码示例以及数据拼接方法。记录调试中遇到的问题与解决方案,展示对串口通信功能的实现与乐趣体验。

    2023年04月08日
    浏览(42)
  • 串口通信-发送和接收数据

    目录 通信方式 硬件电路 软件部分 USART外设(同步/异步收发器) 波特率 引脚复用 初始化基本流程 发送 接收 语言简述 常用的函数 使用的结构体 引脚模式 打印数据的三种方法 使用printf 在实际的串口中,只能发送二进制数,也就是十六进制的最直接数据。如果想发送字符,

    2024年02月12日
    浏览(61)
  • 【友善串口调试助手Serial Port Utility以ASCII形式发送字节数据显示0D的问题】

    在做DS18B20温度检测时自己想通过UART串口接收上位机发出的指令来进行相应的操作,但是第一次上板未能成功,所以回过头来逐步排查问题 自己考虑FPGA与DS18B20数据交互对DS18B20的控制可分为三类:复位、写操作与读操作,每种操作后面还需跟相应具体的指令,如SKIP ROM [CCh]、

    2024年04月28日
    浏览(48)
  • SpringBoot+jSerialComm实现Java串口通信 读取串口数据以及发送数据

    记录一下使用SpringBoot+jSerialComm实现Java串口通信,使用Java语言开发串口,对串口进行读写操作,在win和linux系统都是可以的,有一点好处是不需要导入额外的文件。 案例demo源码:SpringBoot+jSerialComm实现Java串口通信 读取串口数据以及发送数据 之前使用RXTXcomm实现Java串口通信,这

    2024年02月05日
    浏览(42)
  • SpringBoot+RXTXcomm实现Java串口通信 读取串口数据以及发送数据

    记录一下使用SpringBoot+RXTXcomm实现Java串口通信,使用Java语言开发串口,对串口进行读写操作。 案例源码:SpringBoot+RXTXcomm实现Java串口通信 读取串口数据以及发送数据 RXTXcomm.jar这个包支持的系统较多,但是更新太慢,在win系统下使用没有问题,但是在centos的工控机系统里使用

    2024年02月04日
    浏览(40)
  • 孩子都能学会的FPGA:第九课——多字节数据的发送和接收

    (原创声明:该文是 作者的原创 ,面向对象是 FPGA入门者 ,后续会有进阶的高级教程。宗旨是 让每个想做FPGA的人轻松入门 , 作者不光让大家知其然,还要让大家知其所以然 !每个工程作者都搭建了全自动化的仿真环境,只需要双击 top_tb.bat 文件就可以完成整个的仿真(前

    2024年02月04日
    浏览(61)
  • Unity串口通信、接受和发送数据、C#

    串行接口(串口)通常指COM接口,是采用串行通信方式的扩展接口。串口按位(bit)发送和接收字节。尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。特别适用于远距离通信。 查看串口:右键 我的电脑-管理-设备管理器

    2023年04月13日
    浏览(55)
  • ZYNQ 7020 之 FPGA知识点重塑笔记一——串口通信

    目录 一:串口通信简介 二:三种常见的数据通信方式—RS232串口通信 2.1 实验任务 2.2 串口接收模块的设计 2.2.1 代码设计 2.3 串口发送模块的设计 2.3.1 代码设计 2.4 顶层模块编写 2.4.1 代码设计 2.4.2 仿真验证代码 2.4.3 仿真结果 2.4.4 板上验证        通信方式一般分为 串行

    2024年02月03日
    浏览(50)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包