• FPGA之旅设计99例之第四例-----多byte串口通信


    一. 简介

    这是FPGA之旅的第四个设计实例了,在上一例中,也就是第三例,串口通信,实现了单byte的传输。也就是每次只能传输一个btye的数据。在实际使用过程中,需要发送多byte的数据为一包数据,里面包含各种信息,例如最常见的包头和包尾。本例将在第三例的基础上,实现多byte的接收实例,以满足具体的需求。

    欢迎关注微信公众号 FPGA之旅 获取更多!

    二. 实现方法

    串口通信中数据一般为:1 bit的起始位 + 5,6,7,8bit的数据位 + 1 bit的停止位。最多为包数据为 10 bit。

    其实串口协议中,并没有规定数据位为5,6,7,8,理想情况下可以为任意位。例如,两块FPGA之间通过串口通信,就可以自定义。但是呢? 上位机软件支持位数只有这么几种。为了通用性,还是以上位机软件为标准。

    假如说我要一次性发送5 bytes的数据 或者 一次性接收 5 bytes的数据,然后交给FPGA进行处理,那么该怎么做呢?其实也是比较容易的。只需要再设计一个模块,重复调用 5 次串口发送模块,和串口接收模块接收了 5 bytes的数据后,再进行对应的处理,就可以了。

    基础的串口通信模块完成后,就只需要完成这个多bytes 的模块了。


    三. Verilog 代码实现

    1. 先来看一下发送的顶层模块,顶层模块,可以说和普通的串口发送模块一样,只是多出了一个参数,来控制发送字节的位宽,具体定义如下。MulTXNum通过这个参数可以在实例化这个模块的时候,自行确定每次测试字节的个数,非常灵活。

      module UART_MulTX #( 
          parameter MulTXNum = 3)   /*每次发送的字节数*/
      (
          input                           sys_clk,
          input                           rst_n,
          input                           uart_tx_req,   /*串口发送请求*/
          output                          uart_txs_done,  /*串口发送完成*/       
          input[MulTXNum*'d8 - 'd1:0]     idats,           /*发送的数据*/
          output                          uarttx         /*uart tx数据线*/
      );
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
    2. 在这个顶层模块中调用基本的串口发送模块。波特率也通过参数进行控制,在实例化的时候,方便修改波特率。

       UART_TX #(
          .UARTBaud(115200)   /*设置波特率*/
       )UART_TXHP
       (
          .sys_clk           (sys_clk),       /*系统时钟 50M*/
          .rst_n              (rst_n),         /*系统复位 低电平有效*/
      
          .uart_tx_req        (UART_TX_Reg),   /*串口发送请求*/
          .uart_tx_done       (uart_tx_done),  /*串口发送完成*/
      
          .idat               (txdata),          /*发送数据*/
          .uarttx             (uarttx)        /*uart tx数据线*/
      );
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
    3. 串口接收模块定义也一样,具体的实现过程可以看完整的过程项目,就不粘贴上来了。需要的可以自行获取,可以看一下模块框图。
      在这里插入图片描述
      在这里插入图片描述


    四. testbeach编写

    写完各个模块后,怎么能少得了仿真呢?也是调了几次才没有bug,嗐,直接上仿真。这里测试的是每次发送3个字节的数据,每次发送完成后,发送完成后,发送数据加上2323,然后继续发送,具体的可以看看仿真波形。

    `timescale 1ns/1ps
    
    module testbeach();
        reg     clk;
        reg     rst;
        reg     uart_tx_req;
        wire    uart_txs_done;
        reg[23:0]   idats;
        wire        uart;
        wire[23:0]  odats;
        wire        uart_rxs_done;
        
        always #50 clk = ~clk;
        initial begin
            clk = 1'b1;
            rst = 1'b1;
            idats = 'd12256;
            uart_tx_req = 1'b0;
            #100
            rst = 1'b0;  /*手动复位*/
            #100
            rst = 1'b1;
            #100
            uart_tx_req <= 1'b1;
        end
        always@(posedge clk)
            if(uart_txs_done == 1'b1)
                idats <= idats + 'd2323;
    
    UART_MulRX #(
        .MulRXNum (3)
    )UART_MulRXHP(
        .sys_clk                         (clk),         /*系统时钟 50M*/
        .rst_n                           (rst),          /*系统复位*/
      .uart_rxs_done                     (uart_rxs_done),    /*串口接收完成*/
      .odats                             (odats),           /*接收数据*/
      .uartrx                           (uart)         /*uart rx数据线*/
    );
    UART_MulTX #( 
        .MulTXNum(3))   /*每次发送的比特数*/
    UART_MulTXHP(
       .sys_clk                            (clk),         /*系统时钟 50M*/
       .rst_n                              (rst),          /*系统复位*/
       .uart_tx_req                        (uart_tx_req),   /*串口发送请求*/
       .uart_txs_done                      (uart_txs_done),  /*串口发送完成*/
       .idats                              (idats),           /*发送的数据*/
        .uarttx                             (uart)        /*uart tx数据线*/
    );
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    通过波形可以看到,程序编写正确!!!(已上板验证
    在这里插入图片描述
    需要完整代码的可以在公众号FPGA之旅中回复 :FPGA之旅设计99例之第四例

  • 相关阅读:
    飞瞳引擎™集装箱AI检测云服务,集装箱信息识别功能免费,全球顶尖AI高泛化性,正常集装箱识别率99.98%,全球2000企业用户
    免root修改手机imei的技术原理是什么?如何实现的?hook吗
    【LVGL(重要)】样式属性API函数及其参数
    Spring Boot 动态数据源
    ODI报错
    CentOS 7 离线安装nginx1.18
    高等教育学:教学理论
    多张图片转为pdf怎么弄?
    java stream中的peek()用法
    【漏洞复现-webmin-命令执行】vulfocus/webmin-cve_2019_15107
  • 原文地址:https://blog.csdn.net/weixin_44678052/article/details/126355088