FPGA通信——实现串口通信(Uart)

FPGA通信——实现串口通信(Uart)

一、串口通信介绍

1.1、核心概念

并行通信 (Parallel):像高速公路,8车道同时跑8辆车。速度快,但占用引脚多,且在长距离传输时容易出现“时钟偏差(Skew)”导致数据错位。

串行通信 (Serial):像单行道,车必须一辆接一辆地排队走。引脚少,成本低,且现代高速串行技术(如PCIE, SATA)通过差分信号解决了速度问题。

我们常说的“串口”通常特指 UART (Universal Asynchronous Receiver/Transmitter,通用异步收发传输器)

1.2、逻辑层面

UART 是一种异步通信协议。

  • 异步 (Asynchronous):发送方和接收方之间没有公共的时钟线(不像 SPI 或 I2C 有 CLK 线)。
  • 约定:双方必须提前约定好相同的波特率 (Baud Rate),否则就像两个人语速不同,无法交流。

数据帧格式 (Frame Format)

FPGA 的状态机就是根据这个时序图来写的:

  1. 空闲位 (Idle):默认高电平(1)。
  2. 起始位 (Start Bit):拉低 1 个周期。告诉接收方:“注意,我要开始说话了!”(这是我们在 Verilog 里检测下降沿的原因)。
  3. 数据位 (Data Bits):通常是 8 位(1 Byte),LSB (低位) 先发
  4. 校验位 (Parity):可选(奇/偶/无)。用于简单的检错,但在工业应用中常被 CRC 取代。
  5. 停止位 (Stop Bit):拉高 1 或 2 个周期。表示一帧结束,并为空闲状态做准备。

1.3、物理层

        FPGA 产生的信号只是逻辑上的 0 和 1(TTL电平),要传输出去,需要穿上不同的“外衣”(电气标准),也就是PCB版上的芯片。

标准传输方式电平特征典型距离拓扑典型应用
TTL单端0~5V<30cm点对点芯片间通信
RS232单端±5~±12V<15m点对点老式PC,工控机
RS485差分A-B电压差<1200m多点/总线PLC、电表
RS422差分4线全双工<1200m点对多较少见,类485

注意:

  • RS-232 是负逻辑(-12V是逻辑1),但 MAX3232 芯片会自动帮你翻转,你在 FPGA 里只需按正逻辑写。
  • RS-485 是抗干扰之王,因为它看的是两根线的压差,外界的共模噪声会被抵消。

1.4、FPGA 实现

在设计代码是应特别关注以下影响设计稳定性的细节:

A. 采样策略 (Sampling)

  • 做法:在波特率计数的中间点读取一次 rx_pin
  • 进阶做法 (过采样):为提高抗噪能力,例如使用 16 倍波特率的时钟去采样,在中间连续采 3 次,取众数(多数表决)。

B. 跨时钟域 (CDC)

  • 外部进来的 rx 信号是异步的,与 FPGA 的 sys_clk 无关。
  • 必须使用“打两拍”处理,否则状态机会因为亚稳态而跑飞。

C. 波特率误差

  • 公式:DIV_CNT = CLK_FREQ / BAUD_RATE
  • 如果系统时钟是 50MHz,波特率 115200:
    • 50,000,000 / 115200 ≈ 434.02
    • 取整 434,误差非常小,可以忽略。
  • 但如果时钟频率很奇葩,导致除不尽,累积误差可能会导致这一帧的最后一位采样偏移出界。一般来说,累积误差控制在 5% 以内都能正常通信。

二、Verilog代码

为了保证代码的鲁棒性,我们将设计分为三个部分:

  • UART_RX (接收模块):关键在于跨时钟域处理(打两拍)和中心对齐采样或者过采样,防止亚稳态和噪声干扰。
  • UART_TX (发送模块):相对简单,主要是状态机控制时序。
  • Top_Loopback (顶层回环):用于板级验证,接收什么就发送什么。

2.1、接收模块(uart_rx)

核心设计:加入了输入两级寄存器同步(消除亚稳态)和比特中心采样逻辑。

module uart_rx #( parameter CLK_FREQ = 50_000_000, // 系统时钟频率 parameter BAUD_RATE = 115200 // 目标波特率 )( input wire clk, input wire rst_n, input wire rx_pin, // 异步串口输入 output reg [7:0] rx_data, // 接收到的数据 output reg rx_done // 接收完成脉冲 ); // 计算分频计数最大值 localparam CNT_MAX = CLK_FREQ / BAUD_RATE; localparam CNT_MID = CNT_MAX / 2; // 采样点(波特率中心) // 状态定义 localparam IDLE = 0; localparam START = 1; localparam DATA = 2; localparam STOP = 3; reg [1:0] state; reg [31:0] clk_cnt; reg [2:0] bit_cnt; // 消除亚稳态:对异步信号 rx_pin 打两拍 reg rx_d1, rx_d2; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin rx_d1 <= 1'b1; rx_d2 <= 1'b1; end else begin rx_d1 <= rx_pin; rx_d2 <= rx_d1; end end // 下降沿检测(用于检测起始位) wire rx_negedge = rx_d2 & (~rx_d1); always @(posedge clk or negedge rst_n) begin if (!rst_n) begin state <= IDLE; clk_cnt <= 0; bit_cnt <= 0; rx_data <= 0; rx_done <= 0; end else begin rx_done <= 0; // 默认拉低 case (state) IDLE: begin if (rx_negedge) begin // 检测到起始位下降沿 state <= START; clk_cnt <= 0; end end START: begin if (clk_cnt == CNT_MID) begin // 在起始位中间再次确认电平 if (rx_d2 == 1'b0) begin clk_cnt <= 0; state <= DATA; end else begin state <= IDLE; // 误触发,或者是毛刺 end end else begin clk_cnt <= clk_cnt + 1; end end DATA: begin if (clk_cnt == CNT_MAX - 1) begin clk_cnt <= 0; rx_data[bit_cnt] <= rx_d2; // 移位接收 if (bit_cnt == 7) begin bit_cnt <= 0; state <= STOP; end else begin bit_cnt <= bit_cnt + 1; end end else begin clk_cnt <= clk_cnt + 1; end end STOP: begin if (clk_cnt == CNT_MAX - 1) begin state <= IDLE; clk_cnt <= 0; rx_done <= 1'b1; // 接收完成,产生一个脉冲 end else begin clk_cnt <= clk_cnt + 1; end end default: state <= IDLE; endcase end end endmodule

2.2、发送模块(uart_tx)

核心设计:加入了输入两级寄存器同步(消除亚稳态)和比特中心采样逻辑。

module uart_tx #( parameter CLK_FREQ = 50_000_000, parameter BAUD_RATE = 115200 )( input wire clk, input wire rst_n, input wire tx_start, // 发送使能信号 input wire [7:0] tx_data, // 待发送数据 output reg tx_pin, // 串口发送引脚 output reg tx_busy // 忙信号 ); localparam CNT_MAX = CLK_FREQ / BAUD_RATE; localparam IDLE = 0; localparam START = 1; localparam DATA = 2; localparam STOP = 3; reg [1:0] state; reg [31:0] clk_cnt; reg [2:0] bit_cnt; reg [7:0] data_reg; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin state <= IDLE; tx_pin <= 1'b1; // 空闲时为高 tx_busy <= 1'b0; clk_cnt <= 0; bit_cnt <= 0; data_reg <= 0; end else begin case (state) IDLE: begin tx_pin <= 1'b1; if (tx_start) begin state <= START; data_reg <= tx_data; tx_busy <= 1'b1; clk_cnt <= 0; end else begin tx_busy <= 1'b0; end end START: begin // 发送起始位 0 tx_pin <= 1'b0; if (clk_cnt == CNT_MAX - 1) begin clk_cnt <= 0; state <= DATA; end else begin clk_cnt <= clk_cnt + 1; end end DATA: begin // 发送8位数据(LSB first) tx_pin <= data_reg[bit_cnt]; if (clk_cnt == CNT_MAX - 1) begin clk_cnt <= 0; if (bit_cnt == 7) begin bit_cnt <= 0; state <= STOP; end else begin bit_cnt <= bit_cnt + 1; end end else begin clk_cnt <= clk_cnt + 1; end end STOP: begin // 发送停止位 1 tx_pin <= 1'b1; if (clk_cnt == CNT_MAX - 1) begin clk_cnt <= 0; state <= IDLE; tx_busy <= 1'b0; // 释放忙信号 end else begin clk_cnt <= clk_cnt + 1; end end default: state <= IDLE; endcase end end endmodule

2.3、顶层模块(uart_top)

核心设计:将RX的 rx_done 直接作为 TX的 tx_start,实现“收到什么发回什么”的回环测试功能,这是验证串口最快的方法。

module uart_loopback_top( input wire clk, // 连接到 PL 时钟 ( 50MHz) input wire rst_n, // 复位信号 input wire uart_rx, output wire uart_tx ); // 参数定义 parameter CLK_FREQ = 50_000_000; parameter BAUD_RATE = 115200; wire [7:0] rx_data; wire rx_done; wire tx_busy; // 实例化 RX uart_rx #( .CLK_FREQ(CLK_FREQ), .BAUD_RATE(BAUD_RATE) ) u_rx ( .clk(clk), .rst_n(rst_n), .rx_pin(uart_rx), .rx_data(rx_data), .rx_done(rx_done) ); // 实例化 TX // 当接收完成(rx_done)且发送不忙时,启动发送 uart_tx #( .CLK_FREQ(CLK_FREQ), .BAUD_RATE(BAUD_RATE) ) u_tx ( .clk(clk), .rst_n(rst_n), .tx_start(rx_done), .tx_data(rx_data), .tx_pin(uart_tx), .tx_busy(tx_busy) ); endmodule

2.4、引脚约束(XDC)

create_clock -period 20.000 -name sys_clk [get_ports clk] set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports clk] set_property -dict {PACKAGE_PIN N16 IOSTANDARD LVCMOS33} [get_ports rst_n] set_property -dict {PACKAGE_PIN T19 IOSTANDARD LVCMOS33} [get_ports uart_rx] set_property -dict {PACKAGE_PIN J15 IOSTANDARD LVCMOS33} [get_ports uart_tx] set_property SLEW SLOW [get_ports uart_tx]

对时钟信号、复位信号、uart输入输出信号进行引脚及电平绑定,同时对时钟信号进行时序约束。Slew Rate是压摆率控制输出引脚电平变化的“陡峭程度”,通常默认就是SLOW,可用可不用。

三、上板验证

板卡:正点原子启明星ZYNQ7020
软件:Vivado2019.2
串口助手:XCOM

步骤与结果验证:

  1. 参数配置:启动串口调试终端,设置波特率为 115200,8 位数据位,1 位停止位,无校验模式,并打开串口。
  2. 数据收发:在发送缓冲区输入指令“ABCD”等回环测试数据并发送。
  3. 结果判定:接收缓冲区显示的数据与发送数据一致(参见上图)。此现象表明串口数据环回功能运行正常,链路通信可靠。

Read more

Submodular function次模函数 概念——AI学习

Submodular function次模函数 概念——AI学习

论文名称:Submodularity In Machine Learning and Artificial Intelligence 一、综述论文 这篇文章是一篇 综述论文(survey)。 核心目标是: 介绍 Submodular functions(次模函数) 以及它们在 机器学习与人工智能中的应用。 作者想说明一个非常重要的观点: 很多机器学习问题其实是“离散优化问题”。 例如: * Feature Selection:属于数据预处理问题,旨在从原始特征中筛选出最相关、最有信息量的子集,以降低维度、提升模型性能与可解释性。 * Dataset Subset Selection:属于数据采样或核心集选择问题,旨在从大规模数据中选取一个具有代表性的子集,以降低计算和存储成本,同时保持模型性能。 * Active Learning:属于机器学习训练策略问题,通过让模型主动选择最有价值的数据进行标注,以最少的标注成本最大化模型性能。 * Clustering:属于无监督学习问题,旨在根据数据的内在相似性,将未标记的数据自动分组为不同的类别或簇。 * Data

爆火 OpenClaw「龙虾」从 0 到 1 保姆级全指南:安装→QQ 机器人→运维→卸载全流程,附全网高频报错解决方案

爆火 OpenClaw「龙虾」从 0 到 1 保姆级全指南:安装→QQ 机器人→运维→卸载全流程,附全网高频报错解决方案

引言:OpenClaw:一爪入魂,万事自动。 🔥 前言:为什么全网都在「养龙虾」? 最近 AI 圈顶流非 OpenClaw(昵称「龙虾」)莫属! 这个能住在你电脑里的 AI 智能体,不仅能读写本地文件、操控浏览器、自动化办公、一键搭建网站,甚至能接入 QQ 变身私人机器人,让你随时随地都能「养虾」调用。 但随之而来的是乱象丛生:网上出现数百元的上门安装服务,甚至深圳腾讯大厦门口曾出现千人排队免费安装的盛况。其实自己安装全程免费,30 分钟就能搞定,还能彻底规避他人操作电脑带来的数据泄露风险! 本文整合OpenClaw 官方权威文档+ 全网高频踩坑解决方案,带你从 0 到 1 零失败上手,从安装配置、QQ 机器人接入、日常运维到彻底卸载,保姆级一步到位,新手也能轻松玩转。 📋 前置准备与安全红线 1.

机器人远程控制终极指南:免费手机AR技术快速上手

机器人远程控制终极指南:免费手机AR技术快速上手 【免费下载链接】lerobot🤗 LeRobot: State-of-the-art Machine Learning for Real-World Robotics in Pytorch 项目地址: https://gitcode.com/GitHub_Trending/le/lerobot 还在为专业机器人控制器的高昂价格而烦恼吗?🤔 今天我要分享一个革命性的解决方案:用你的智能手机实现专业级机器人远程控制!通过LeRobot项目,任何人都能在30分钟内搭建完整的手机AR控制系统,无需任何额外硬件投入。 为什么选择手机AR控制机器人?✨ 传统机器人控制需要专用手柄、编程软件或复杂的控制面板,而手机AR控制技术彻底颠覆了这一模式: * 零成本投入:利用现有手机,无需购买额外设备 * 直观操作:AR界面让机器人控制像玩游戏一样简单 * 跨平台兼容:支持iOS和Android系统 * 专业精度:实现6自由度精准控制,满足工业级需求 快速入门:5步搭建手机控制环境 🚀 第一步:环境准备 确保你的设备满足

配置钉钉龙虾OpenClaw机器人调用OpenMetadata

配置钉钉龙虾OpenClaw机器人调用OpenMetadata

目录 * 一、前言 * 1️⃣钉钉(DingTalk) * 2️⃣OpenClaw * 3️⃣OpenMetadata * 4️⃣MCP(Model Context Protocol) * 二、安装OpenClaw * 三、配置OpenClaw钉钉机器人 * 四、调用OpenMetadata MCP 一、前言 先介绍下这四个工具/协议的定位与核心能力,本文将从零开始配置。 1️⃣钉钉(DingTalk) 阿里巴巴旗下的企业协作平台,2014年上线,是中国市场份额最大的企业即时通讯与办公套件之一。 核心能力包括:即时消息与视频会议、考勤打卡与审批流、企业通讯录、低代码应用搭建(宜搭)、以及近年来整合的 AI 助理功能。它更像一个"企业操作系统",把 HR、OA、协同文档、