【以太网通信】RS232 串口转以太网

这篇具有很好参考价值的文章主要介绍了【以太网通信】RS232 串口转以太网。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最近和 RK 研发同事在调试通信接口,排查与定位 RK3399 接收数据出错的问题。FPGA 与 RK3399 之间使用一路 RS232 串口进行通信,由于串口数据没有分包,不方便排查问题,想到可以开发一个 RS232 串口转以太网的工具,将串口接收到的数据封装为 UDP 数据报文,并通过网线传输到电脑,再进行后续问题的定位。

以下是串口转以太网工具,调试的效果图。

【以太网通信】RS232 串口转以太网,FPGA 以太网通信,计算机网络,fpga开发,串口通信

目录

1 模块设计

1.1 串口接收模块

1.2 以太网发送模块

2 上板调试


1 模块设计

1.1 串口接收模块

【以太网通信】RS232 串口转以太网,FPGA 以太网通信,计算机网络,fpga开发,串口通信

        串口接收模块电路需要实现的功能包括:

(1)串口数据接收;

(2)串口数据缓存。

        uart_rx_slice 是串口底层模块,负责接收单个 byte 数据。规定串口每帧传输的数据长度不超过 2048,需要例化一个深度为 4096,位宽为 8bit 的 Block RAM,并实现串口数据的乒乓缓存。

【以太网通信】RS232 串口转以太网,FPGA 以太网通信,计算机网络,fpga开发,串口通信

top_uart 模块代码:

`timescale 1ns / 1ps

module top_uart #(
   parameter       FREQ_SYS_CLK    = 32'd200_000_000,
   parameter       BAUD_RATE       = 32'd256_000     
)(
   // System level
   input           sys_rst         ,
   input           sys_clk         ,

   // Uart received data flow
   output [7:0]    uart_rcv_data   ,
   output          uart_rcv_valid  ,

   // Uart Interface
   input           uart_rxd        ,
   output          uart_txd        
);

wire               frame_ss        ;
wire [7:0]         rcv_data        ;
wire               rcv_valid       ;

reg                frame_ss_r1     ;
reg                frame_ss_r2     ;
reg  [7:0]         blk_mem_wdata   ;
reg  [11:0]        blk_mem_waddr   ;
reg  [11:0]        blk_mem_waddr_r ;
reg  [0:0]         blk_mem_wren    ;
reg                blk_mem_rd_busy ;
reg  [11:0]        blk_mem_raddr   ;
wire [7:0]         blk_mem_rdata   ;
reg                blk_mem_rdvld   ;

// uart_rx_slice: Uart receive module
uart_rx_slice uart_rx_slice_inst (
   .sys_rst        (sys_rst       ), // input
   .sys_clk        (sys_clk       ), // input
   .frame_ss       (frame_ss      ), // output
   .rcv_data       (rcv_data      ), // output
   .rcv_valid      (rcv_valid     ), // output
   .uart_rxd       (uart_rxd      )  // input
);

defparam uart_rx_slice_inst.FREQ_SYS_CLK = FREQ_SYS_CLK;
defparam uart_rx_slice_inst.BAUD_RATE    = BAUD_RATE;
// End of uart_rx_slice instantiation

// blk_mem_4096x8b: Block Memory generator
blk_mem_4096x8b blk_mem_4096x8b_inst (
   .clka          (sys_clk        ), // input
   .ena           (1'b1           ), // input
   .wea           (blk_mem_wren   ), // input
   .addra         (blk_mem_waddr  ), // input
   .dina          (blk_mem_wdata  ), // input
   .clkb          (sys_clk        ), // input
   .rstb          (sys_rst        ), // input
   .enb           (1'b1           ), // input
   .addrb         (blk_mem_raddr  ), // input
   .doutb         (blk_mem_rdata  ), // output
   .rsta_busy     (               ), // output
   .rstb_busy     (               )  // output
);
// End of blk_mem_4096x8b_inst instantiation

always @(posedge sys_rst or posedge sys_clk) begin
   if (sys_rst == 1'b1) begin
      frame_ss_r1 <= 1'b0;
      frame_ss_r2 <= 1'b0;
   end
   else begin
      frame_ss_r1 <= frame_ss;
      frame_ss_r2 <= frame_ss_r1;
   end
end

always @(posedge sys_rst or posedge sys_clk) begin
   if (sys_rst == 1'b1) begin
      blk_mem_waddr <= 12'd0;
      blk_mem_wdata <= 8'd0;
      blk_mem_wren  <= 1'b0;
   end
   else begin
      blk_mem_wdata <= rcv_data;
      blk_mem_wren[0] <= rcv_valid;

      if (frame_ss_r2 == 1'b1 && frame_ss_r1 == 1'b0) begin
         blk_mem_waddr[11] <= ~blk_mem_waddr[11];
         blk_mem_waddr[10:0] <= {11{1'b0}};
      end
      else if (blk_mem_wren[0] == 1'b1) begin
         blk_mem_waddr[11] <= blk_mem_waddr[11];
         blk_mem_waddr[10:0] <= blk_mem_waddr[10:0] + 1'b1;
      end
   end
end

always @(posedge sys_rst or posedge sys_clk) begin
   if (sys_rst == 1'b1) begin
      blk_mem_waddr_r <= 12'd0;
      blk_mem_raddr   <= 12'd0;
      blk_mem_rd_busy <= 1'b0;
      blk_mem_rdvld   <= 1'b0;
   end
   else begin
      if (blk_mem_rd_busy == 1'b0 && frame_ss_r2 == 1'b1 && frame_ss_r1 == 1'b0) begin
         blk_mem_waddr_r <= blk_mem_waddr - 1'b1;
         blk_mem_rd_busy <= 1'b1;
      end
      else if (blk_mem_rd_busy == 1'b1) begin
         if (blk_mem_raddr == blk_mem_waddr_r) begin
            blk_mem_raddr[11] <= ~blk_mem_raddr[11];
            blk_mem_raddr[10:0] <= {11{1'b0}};
            blk_mem_rd_busy <= 1'b0;
         end
         else begin
            blk_mem_raddr[11] <= blk_mem_raddr[11];
            blk_mem_raddr[10:0] <= blk_mem_raddr[10:0] + 1'b1;
         end
      end
      blk_mem_rdvld <= blk_mem_rd_busy;
   end
end

assign uart_rcv_data  = blk_mem_rdata;
assign uart_rcv_valid = blk_mem_rdvld;

endmodule

1.2 以太网发送模块

【以太网通信】RS232 串口转以太网,FPGA 以太网通信,计算机网络,fpga开发,串口通信

        以太网网络层使用 IPv4 协议,传输层使用 UDP 协议。

以太网发送模块电路需要实现的功能包括:

(1)IPv4 与 UDP 协议校验;

(2)以太网帧组帧(包括 CRC 校验);

(3)GMII 与 RGMII 桥接。

        同样例化一个深度为 4096,位宽为 8bit 的 Block RAM,实现以太网帧数据的乒乓缓存,在初始化文件中写入以太网帧头,MAC 地址等信息。

使用 Python 代码生成 coe 文件,代码如下:

# 以太网帧头数据
f = b'\x55\x55\x55\x55\x55\x55\x55\xd5\xd4\x5d\x64\xad\x16\x47\x11\x22\x33\x44\x55\x66\x08\x00\x45\x00\x00\x00\x00\x00\x40\x00\x40\x11\xff\xff\xc0\xa8\x01\x08\xc0\xa8\x01\x09\x1f\x90\x1f\x90\x00\x00\x00\x00'
raw_data = list(map(lambda e: "{:02X}".format(e), f))

while len(raw_data) < 2048:
   raw_data.append('00')

# 写入coe文件
with open('blk_mem_4096x8b_MAC.coe', 'w') as f:
   f.write('memory_initialization_radix = 16;\n')
   f.write('memory_initialization_vector = \n')
   for i,e in enumerate(raw_data*2):
      if i != len(raw_data*2)-1:
         f.write("{:s},\n".format(e))
      else:
         f.write("{:s};".format(e))

在 IP 核配置界面,选择 coe 初始化文件,点击 Edit 查看数据。

【以太网通信】RS232 串口转以太网,FPGA 以太网通信,计算机网络,fpga开发,串口通信

top_ethernet 模块代码:

`timescale 1ns / 1ps

module top_ethernet #(
   parameter       local_ip_addr   = 32'hC0A80109,
   parameter       remote_ip_addr  = 32'hC0A8010A,
   parameter       local_udp_port  = 16'h1F90,
   parameter       remote_udp_port = 16'h1F90
)(
   // System level
   input           sys_rst         ,
   input           sys_clk         ,

   // RGMII Interface
   input           rgmii_rxc       ,
   input  [3:0]    rgmii_rxd       ,
   input           rgmii_rx_ctl    ,
   output          rgmii_txc       ,
   output [3:0]    rgmii_txd       ,
   output          rgmii_tx_ctl    ,

   // UDP data input ports
   input  [7:0]    eth_udp_txd     ,
   input           eth_udp_txen     
);

wire               gmii_tx_clk;
wire [7:0]         eth_mac_txd;
wire               eth_mac_txen;

// mac_tx_slice: MAC data pack and transmit module
mac_tx_slice mac_tx_slice_inst(
   .sys_rst        (sys_rst        ), // input
   .sys_clk        (sys_clk        ), // input
   .gmii_tx_clk    (gmii_tx_clk    ), // input
   .eth_udp_txd    (eth_udp_txd    ), // input
   .eth_udp_txen   (eth_udp_txen   ), // input
   .eth_mac_txd    (eth_mac_txd    ), // output
   .eth_mac_txen   (eth_mac_txen   )  // output
);

defparam mac_tx_slice_inst.local_ip_addr   = local_ip_addr;
defparam mac_tx_slice_inst.remote_ip_addr  = remote_ip_addr;
defparam mac_tx_slice_inst.local_udp_port  = local_udp_port;
defparam mac_tx_slice_inst.remote_udp_port = remote_udp_port;
// End of mac_tx_slice_inst instantiation

// gmii_rgmii_bright: GMII to RGMII bridge
util_gmii_to_rgmii util_gmii_to_rgmii (
   .reset          (sys_rst        ), // input
   .rgmii_td       (rgmii_txd      ), // output
   .rgmii_tx_ctl   (rgmii_tx_ctl   ), // output
   .rgmii_txc      (rgmii_txc      ), // output
   .rgmii_rd       (rgmii_rxd      ), // input
   .rgmii_rx_ctl   (rgmii_rx_ctl   ), // input
   .rgmii_rxc      (rgmii_rxc      ), // input
   .gmii_txd       (eth_mac_txd    ), // input
   .gmii_tx_en     (eth_mac_txen   ), // input
   .gmii_tx_er     (1'b0           ), // input
   .gmii_tx_clk    (gmii_tx_clk    ), // output
   .gmii_crs       (               ), // output
   .gmii_col       (               ), // output
   .gmii_rxd       (               ), // output
   .gmii_rx_dv     (               ), // output
   .gmii_rx_er     (               ), // output
   .gmii_rx_clk    (               ), // output
   .speed_selection(2'b10          ), // input
   .duplex_mode    (1'b1           )  // input
);
// End of util_gmii_to_rgmii_inst instantiation

endmodule

2 上板调试

        使用 ALINX AX7035 开发板,进行工程调试。接入网线和 USB 转串口线,使用电脑模拟发送串口数据,接收以太网数据。

【以太网通信】RS232 串口转以太网,FPGA 以太网通信,计算机网络,fpga开发,串口通信

         电脑端同时打开串口调试助手,和 wireshark 工具,开始抓包。

【以太网通信】RS232 串口转以太网,FPGA 以太网通信,计算机网络,fpga开发,串口通信

在串口调试助手中输入待发送数据,选择定时 1s 发送,观察 wireshark 界面是否间隔 1s 收到数据包。文章来源地址https://www.toymoban.com/news/detail-666698.html

到了这里,关于【以太网通信】RS232 串口转以太网的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • FPGA通过以太网与PC机通信的完整方案

    FPGA(可编程逻辑门阵列)是一种灵活且高度可定制的芯片,可以用于实现各种数字电路。在许多应用中,FPGA与PC机之间的通信是至关重要的。本文将提供一个完整的方案,介绍如何使用FPGA通过以太网与PC机进行通信,并附带相应的源代码。 硬件准备 首先,我们需要准备以下

    2024年04月14日
    浏览(80)
  • FPGA平台以太网学习:MAC与PHY间通信

    1、PHY(物理层):   MII/GMI/RMII/RGMII/SGMIII(介质独立接口子层),PLS/PCS(物理编码子层),PMA(物理介质连接子层),PMD(物理介质相关子层),AN(自动协商),MDI(媒介相关接口)。 2、PLS/PCS(物理编码子层):   (PLS)对 MAC 给的信息进行传递,只在IMb/s、10Mb/s 的应

    2024年02月04日
    浏览(55)
  • 基于FPGA的百兆以太网通信(一)——MDIO配置PHY芯片

     一、以太网简介   之前提了个引子,接下来我会分享一下基于FPGA的百兆以太网通信学习过程。第一部分是对于以太网PHY芯片的配置和状态读取。   一般来说,FPGA以太网通信是需要外接的PHY芯片的,目前的很多FPGA出厂的底板上已经焊好了PHY芯片,所以这一点是比较方便的。

    2024年04月10日
    浏览(57)
  • 【计算机网络】数据链路层——以太网

    前面我们学习了关于应用层——自定义协议、传输层——UDP、TCP协议、网络层——IP协议,今天我将为大家分享关于数据链路层——以太网方面的知识。 “以太网” 不是一种具体的网络,而是一种技术标准;既包含了数据链路层的内容,也包含了一些物理层的内容。例如:规

    2024年02月06日
    浏览(67)
  • 计算机网络【IP协议与以太网】

    ● 4位版本号(version):指定IP协议的版本,对于IPv4来说,就是4 ●4位头部长度(header length):IP头部的长度是多少个32bit,也就是 length * 4 的字节数。4bit表示最大的数字是15,因此IP头部最大长度是60字节 ●8位服务类型(Type Of Service):3位优先权字段(已经弃用),4位TO

    2024年02月02日
    浏览(58)
  • FPGA实现以太网(一)——以太网简介

    以太网(Ethernet)是当今现有局域网采用的最通用的通信协议标准, 该标准定义了在局域网中采用的电缆类型和信号处理方法。 以太网凭借其成本低、通信速率高、抗干扰性强等优点被广泛应用在网络远程监控、 交换机、工业自动化等对通信速率要求较高的场合。 以太网是一

    2024年02月03日
    浏览(53)
  • 【计算机网络】 IP协议格式以及以太网帧结构

    IP工作在网络层 IP头分为两部分,固定部分和可变部分,固定部分就是一定要带这些数据,正常存储应该是连续的,并不是像图中这样会换行,图中只是为了方便观察。 首先是一个版本号,也就是看是ipv4还是ipv6,然后是首部长度,就是我们ip头的首部长度,是为了能将首部和

    2024年02月09日
    浏览(59)
  • FPGA之以太网详解

    以太网(Ethernet)是当今局域网采用的最通用的局域网标准。它规定了包括物理层的连线,电子信号和介质访问协议的内容。它具有成本低,通信速率快,抗干扰性强的特点。 以太网主要分为: 标准以太网:10Mbit/s 快速以太网:100Mbit/s 千兆以太网:1000Mbit/s 以太网的接口主要

    2024年02月09日
    浏览(45)
  • 计算机网络:网络适配器(网关),IP,以太网 VMware 的详细讲解

    前言 有很多人对于网关,ip,以及VMware网络的概念以及配置不太了解,本篇就对于这几个进行介绍 ipconfig/all(win+R–cmd–ipconfig/all)最常用的就是显示自己主机的ip了,可以让我们了解自己的计算机是否成功的租用到一个IP地址。但是ipconfig显示的除了当前主机网络ip之外还有

    2024年02月09日
    浏览(76)
  • .NET串口通信 RS232 、RS485

    1.RS232是全双工的,RS485是半双工的,RS422是全双工的。 在信息传输通道中,携带数据信息的信号单元叫码元,每秒钟通过信道传输的码元数称为码元传输速率,简称波特率。波特率是传输通道频宽的指标。 波特率9600与波特率19200的区别就是:波特率19200传输快但传输距离近,波

    2024年02月12日
    浏览(55)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包