FPGA 入门 23:UART 回环——帧格式、波特率与收发状态机
更新时间:2026-09-12。本文是
fpga/入门层第 25 篇。波特率节拍用 计数器与分频,收发是典型 状态机,防丢字节见进阶 FIFO 设计。
本文要回答的问题
- 没有时钟线,UART 收发双方靠什么保持同步?一帧 8N1 在时间轴上具体长什么样?
- 波特率怎么换算成时钟周期数?分频取整会带来多大误差,误差累加到第几位会开始采错?
- 接收端为什么要先等半个位周期、在每位「中点」采样?16 倍过采样多数表决又好在哪里?
- 发送状态机和接收状态机各有哪些状态、需要哪些计数器,移位寄存器按什么顺序装入和移出?
- 回环实验为什么要加 FIFO?电脑连续发送时,没有缓冲会在什么时刻丢字节?
- UART 的 TTL 电平、RS232 电平、USB 转串口芯片之间是什么关系,接错会有什么后果?
- 串口乱码、收不到、偶发出错分别该按什么顺序排查?怎样用 Testbench 和串口助手闭环验证?
一、UART 帧(8N1)
空闲 起始 D0 D1 D2 ... D7 停止 空闲
‾‾‾\__/__/‾‾\__/ ... __/‾‾‾
<-1 bit-> (LSB 先发, 每位等宽)一帧 = 1 起始(低)+ 8 数据(LSB 先)+ 1 停止(高),共 10 bit。无时钟线,双方按约定波特率定时。
二、波特率定时
| 波特率 | 每 bit 时间 | 50MHz 下周期数 |
|---|---|---|
| 9600 | 104.2 µs | 5208 |
| 115200 | 8.68 µs | 434 |
用计数器产生 tick;接收在每位中点采样(起始位后先等半 bit)。
三、发送 TX(并转串)
module uart_tx #(parameter CLKS=434)(
input wire clk, rst_n, tx_start,
input wire [7:0] tx_data,
output reg tx, output reg tx_done
);
reg [9:0] shift; reg [3:0] bit_cnt; reg [15:0] c; reg busy;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin tx<=1; busy<=0; tx_done<=0; end
else if (!busy && tx_start) begin
shift <= {1'b1, tx_data, 1'b0}; // 停止位+数据+起始位
bit_cnt<=0; c<=0; busy<=1; tx_done<=0;
end else if (busy) begin
if (c==CLKS-1) begin c<=0;
tx <= shift[0]; shift <= {1'b1, shift[9:1]}; // 移出 LSB
bit_cnt <= bit_cnt+1;
if (bit_cnt==9) begin busy<=0; tx_done<=1; tx<=1; end
end else c<=c+1;
end
end
endmodule四、接收 RX(串转并,中点采样)骨架
// 检测到下降沿(起始位) -> 等半个 bit 确认 -> 每隔 CLKS 拍在数据位中点采样
// 采满 8 位 -> {rx_data, rx_valid=1 拍}
// 状态: IDLE(等下降沿) -> START(半 bit 后确认仍低) -> DATA(8 次中点采样) -> STOP回环 top:rx_valid/rx_data → 小 FIFO → tx_start/tx_data,TX 空闲就发。
五、帧格式逐位拆解与空闲/断帧识别
UART 只有一根数据线,双方必须事先约定帧格式,线上的高低电平才能被解释成字节。8N1 是最常见配置:8 个数据位、无校验、1 个停止位。空闲时总线被上拉为高电平;发送方通过一个高到低的跳变(起始位,持续整整一个位周期)通知接收方「帧开始」;随后按最低位先发的顺序输出 D0 到 D7;停止位把线拉回高电平至少一个位周期,然后才能开始下一帧或保持空闲。接收端把一次完整接收看成十个等宽时隙:1 个起始位、8 个数据位、1 个停止位,每个时隙按同一个波特率定宽。
起始位是整套机制的关键:它既是「有数据」的事件信号,又给了接收端一个对齐基准。接收端检测到下降沿后,以这个沿为时间原点重建本地位时序,而不需要连续时钟。停止位除了表示帧结束,还保证两帧之间总线回到高电平,使下一帧的下降沿一定能被识别。若停止位采到低电平,说明波特率不匹配、噪声或帧不同步,接收端可报告帧错误(framing error)。没有数据时线恒为高,长时间拉低则常被解释为 break 条件,可用于复位或唤醒。理解了「下降沿对齐、等宽时隙、停止位归位」这三点,帧格式就不用死记。
六、波特率分频与误差预算
每个位周期对应的系统时钟拍数为 N,等于系统时钟频率除以波特率。50MHz、115200 波特时 N 约为 434.03,取整 434;9600 波特时约 5208。取整误差本身很小,真正要算的是误差在一帧内如何累积。接收端从起始位下降沿开始定时,越往后采的位,本地采样点相对理想位中心的偏移越大。若本地波特率相对对端偏差为 δ,到第 k 位中心的累积偏移约为 k 乘 δ 个位周期;为了不越到位边界,通常要求这个偏移始终小于约半个位周期,再留噪声裕量,工程上把双方误差控制在约 2%~3% 以内。
常见误差来源有三类:其一是系统时钟频率算错,例如把 100MHz 当 50MHz,误差达到百分之百必然乱码;其二是分频常数取整粗糙或波特率本身不能被晶振整除,可以选更合适的时钟频率或用 PLL 得到可整除的频率(时钟生成见 PLL 时钟向导);其三是对端 USB 转串口芯片的波特率误差,通常很小但在非标准波特率下要核对。设计时建议把分频常数参数化,并在注释里写明「目标波特率、时钟频率、实际位周期、百分比误差」。降低波特率会放宽时序裕量,所以联调第一遍常用 9600 或 115200 这类标准值确认通路,再考虑提速。
七、接收:从下降沿到中点采样
接收比发送复杂,因为时序要从异步跳变里恢复出来。一个健壮的接收状态机通常包含这些状态:
- IDLE:线为高时等待;用两级触发器先同步异步输入(防亚稳态,见 按键消抖的同步原理 与进阶 CDC),再检测下降沿。
- START:检测到下降沿后启动位定时器,先等待半个位周期,在起始位中央再确认一次仍为低;若已经回弹为高,说明那只是毛刺,放弃接收回到 IDLE。
- DATA:此后每过一个完整位周期采一次,正好落在 D0~D7 的中央;每采一位移入接收寄存器(注意顺序,先发的是 LSB)。
- STOP:第八位采完后再等一个位周期检查停止位是否为高,决定是否置帧错误标志;随后给出一个周期的接收有效脉冲 rx_valid 和并行字节,回到 IDLE。
为什么是中点而不是边沿?起始沿本身可能有抖动、双方时钟也有偏差,位中央是离两个跳变边界都最远的位置,采样裕量最大。先等半位再确认起始位还能滤掉线上窄毛刺。位定时器不要用「数满 N 拍就复位」的自由计数器直接驱动,而应由接收状态机在起始沿清零、按状态决定下一次采样时刻,这样时序原点始终锚定在每一帧的起始沿上。
八、16 倍过采样与抗噪
中点采样假设输入在位周期内干净,工业上更稳的做法是过采样:用 16 倍(或 8 倍、16 倍)于波特率的采样时钟,每个位周期内有 16 个样本。检测到下降沿后,用 3~4 个连续样本确认起始位;数据位在该位窗口的中部取 3 个样本做多数表决(三选二),单个毛刺无法翻结果;位中点通过在过采样计数器走到 7、23、39 这样的位置采样来定位。过采样把「一次采样定生死」变成「多次采样再表决」,显著提高噪声和轻微波特率偏差下的容错能力,代价是多用一些计数器和小逻辑,对 FPGA 毫无压力。
入门实现可以先做「一次中点采样」,理解时间原点和位定时;当需要和长线、工业模块、非理想时钟源通信时,再升级为过采样加多数表决。无论哪种,关键参数都参数化:采样倍率、每拍位周期数、数据位数、是否有校验位,这样同一套状态机可以适配 8N1、7E1 等多种帧格式。校验位(奇偶校验)是在数据位后附加一位使总 1 的个数为奇或偶,接收端重新计数比对,能发现单比特翻转;现代链路更多依赖上层协议校验,但理解它有助于读懂带校验的设备手册。
九、发送:并转串移位与状态机
发送方掌握时间主动权,状态机相对简单:IDLE 时 tx 保持高电平、busy 为 0;检测到发送请求 tx_start 且当前不忙,就锁存待发字节、置 busy、装入移位寄存器并开始一帧。一种清晰的装法是把「起始位 0、8 个数据位、停止位 1」拼成 10 位或 11 位移位寄存器,复位后 tx 直接输出最低位,每数满一个位周期就右移一次并把高位补 1;移满 10 位后保证线上为停止位高电平,拉低 busy 并产生一个周期的 tx_done 脉冲。位计数器记录已发送位数,波特率计数器在每帧开始时清零。
要注意三个细节。第一,发送请求最好转化为「启动脉冲」而不是电平,否则按住 start 不松会在一帧结束后立刻重发;第二,busy 期间到来的新请求不能直接覆盖正在发送的数据,要么忽略并报错,要么交给 FIFO 排队;第三,tx 的默认值和复位值必须是高电平(空闲态),否则上电瞬间线为低会被对端当成虚假起始位。发送器输出的是并行到串行的转换,接收器做串行到并行的逆过程,二者共用同一个波特率定时参数,这正是 计数器时钟使能 与 三段式状态机 的综合练习。
十、回环控制与 FIFO:为什么会丢字节
最简单的回环是把 rx_valid 和 rx_data 直接接到 TX 的启动端口,但它只能在「发送器恰好空闲」时工作。算一下时间就知道风险:115200 波特下一帧 10 位约需 87 微秒,电脑若连续发送两个字节,第二个字节可能在第一个还没发完时到达;接收器没有地方存放新字节,就会覆盖尚未取走的数据而丢帧。即使电脑看起来是「敲一个字符等回显」,USB 转串口和操作系统也可能批量投递,不能假设发送间隔。
解决方法是在收、发之间插入缓冲:
- 一位握手寄存器:接收完成把字节放入保持寄存器并置标志,TX 空闲时取走并清标志;能缓解偶发间隔但容量只有一帧,仍可能丢。
- FIFO 队列:接收侧每完成一帧写入 FIFO,发送侧在 TX 空闲且 FIFO 非空时读出一帧发送,空满标志提供反压。深度按最坏突发长度选,入门几十深度足够(FIFO 原理与实现见进阶 FIFO 设计,也可直接调 FIFO IP)。
- 流控:真正不能丢的协议用硬件 RTS/CTS 或软件 XON/XOFF 通知对端暂停,属于带流控的异步串口。
回环顶层因此分成四个清晰模块:波特率定时(或在收发器内各自计数)、RX、FIFO、TX,再加一个简单控制 FSM 做「非空就请求发送、完成后读下一个」。这也是多数通信控制器的标准骨架:物理层收发、缓冲、控制解耦。
十一、电平、接线与硬件接口
UART 调试最常见的失败其实不在逻辑而在物理层,必须分清三套电平:
- FPGA 引脚通常是 3.3V LVCMOS 逻辑电平:高电平约 3.3V 表示 1,低电平 0V 表示 0,俗称 TTL 串口;
- 传统 RS232 用正负电压(例如正负 3 到 15V)表示逻辑,绝不能把这种信号直接接 FPGA,必须经 MAX232 一类收发器转换;
- 现代电脑几乎没有原生串口,通常用板载或外接的 USB 转 TTL 芯片(CH340、CP2102、FT232 等),电脑侧是 USB,板侧输出 3.3V 或可配置 TTL 串口,直接和 FPGA 的 TX/RX 相连即可。
接线三条铁律:一是 TX 与 RX 交叉,即 FPGA 的发送接转换芯片的接收、FPGA 的接收接芯片发送,接反表现为完全收不到;二是必须共地,没有共同参考电平,高低电平无法正确判断;三是核对 IO 电平,5V TTL 直连 3.3V FPGA 可能损坏引脚,必要时加分压或电平转换。连接完成后在电脑上打开串口助手,设置与 FPGA 完全一致的波特率、8 数据位、无校验、1 停止位;端口号在设备管理器里确认,驱动缺失时端口根本不会出现。
十二、仿真与上板闭环验证
UART 特别适合用 Testbench 做收发闭环,因为可以在测试平台里行为级建模一个对端。建议分三步验证。先测发送器:用很小的分频参数(例如 CLKS=8)缩短仿真时间,给 tx_start 和数据,检查 tx 上是否依次出现起始位、D0~D7、停止位,用游标量每位宽度。再测接收器:在 TB 里用任务按位驱动 rx(起始低、串行数据、停止高),任务参数化位宽,检查 rx_data 与 rx_valid。最后做回环:TB 端先行为级发送一串字节给 DUT 的 RX,等待并从 DUT 的 TX 采样拼回字节,与发送序列逐一比较,连续突发用来暴露无 FIFO 时的丢帧(仿真方法见 Testbench、看波形)。
上板排查按「通路、电平、参数、协议、缓冲」的顺序最快:
- 端口能否打开、驱动是否正常;
- TX/RX 是否交叉、是否共地、电平是否匹配;
- 双方波特率是否完全一致、时钟频率常数是否正确;
- 帧格式(数据位、校验、停止位)是否一致;
- 现象是全乱码(多为波特率/时钟错误)、能收到但内容错位(多为位顺序或采样点错误)、还是高速连发才丢(多为缺 FIFO)。
用 ILA 同时抓同步后的 rx、接收状态、rx_valid 和 TX 忙标志,可以看到字节在状态机里的完整流动(ILA 见 第一次用);电脑侧可以发送 0x55(二进制 01010101,高低交替)这种规律字节,在波形上极易核对位顺序和位宽。
十三、设计清单与能力边界
交付一个 UART 模块前,按下面清单检查:
- 帧参数全部参数化:时钟频率、波特率、数据位数、校验、停止位、过采样倍率;
- 异步输入先两级同步,起始位有半位确认或多次表决,能拒绝窄毛刺;
- 采样点位于数据位中央,位定时在每帧起始沿重新对齐;
- 发送空闲与复位输出高电平,启动信号为单周期脉冲,忙时请求有明确处理;
- 收发之间有 FIFO 或握手,最坏突发下不丢字节,空满标志正确;
- 能报告帧错误、(若实现)校验错误、溢出错误,而不是静默出错;
- 时钟/波特率误差经计算在允许范围,Testbench 覆盖单帧、突发、错误起始位、停止位异常。
也要清楚 UART 的边界:它没有时钟线、靠双方时钟精度和起始沿对齐,因此速率有限(常用不超过约 1~2Mbps)、点对点、没有寻址、没有内置可靠传输;需要更高速度、多设备、时钟内嵌或标准化流接口时,应转向 SPI、I2C、AXI4-Stream 等接口(接口对比见进阶 UART/SPI/I2C)。但正因为简单,UART 是学习「异步定时恢复、串行并行转换、收发状态机、缓冲解耦、物理电平」最完整的一个实验,把它做扎实,后面所有串行协议都是在这个框架上增加时钟、寻址或成组传输。
十四、常用波特率速查与吞吐直觉
把常用波特率换算成「每位时间、每字节日历时间、50MHz 下分频常数」,调波特率时就不用每次重算:
| 波特率 | 每位时间 | 一字节(10bit) | 50MHz 下 N |
|---|---|---|---|
| 9600 | 约 104.2µs | 约 1.04ms | 5208 |
| 19200 | 约 52.1µs | 约 0.52ms | 2604 |
| 38400 | 约 26.0µs | 约 0.26ms | 1302 |
| 57600 | 约 17.4µs | 约 0.174ms | 868 |
| 115200 | 约 8.68µs | 约 86.8µs | 434 |
| 230400 | 约 4.34µs | 约 43.4µs | 217 |
| 921600 | 约 1.085µs | 约 10.85µs | 54 |
注意实际有效吞吐要按 10 位每字节(8N1)折算,而不是波特率除以 8:115200 波特每秒最多约 11520 个字节,理论约 11.25KB/s,再扣除帧间隔和软件开销更低。设计 FIFO 深度和上层协议超时时,要用这个真实字节速率估算:例如在 115200 下连续接收 64 字节约需 5.6ms,若你的处理循环响应慢于这个节奏就必须加深 FIFO 或降速。分频常数位宽要装得下最大 N,50MHz、9600 时 N=5208 需要 13 位,写死成 8 位会静默截断导致波特率完全错误——这和 计数器篇 讲的位宽陷阱是同一个。
把分频常数和位宽都用 parameter 加自动位宽推导表达,例化时只传系统时钟频率和目标波特率,能从语言层面消除这类错误。需要支持运行中切换波特率时,把分频常数做成由波特率选择寄存器驱动的一组常量,切换时等当前帧发送完毕(TX 空闲)再改,避免一帧内位宽突变。
十五、在回环之上加协议:从字节到报文
裸回环只验证物理链路,真实应用通常要在字节流之上定义简单协议,这也是从「会收发」到「会通信」的一步。一个最小组帧约定可以是:固定起始标志(如 0xAA、0x55 两字节,便于示波器辨认和同步)、长度字段、命令字、若干数据字节、校验(所有字节异或或求和取低 8 位)。接收侧用一个小状态机管理「等帧头、收长度、收负载、校验、执行或应答」,收到错误校验就丢弃整帧并回到找帧头状态,避免一个坏字节后所有后续报文错位。这和 FSM 篇 的「找起始、计数、判定」是同一套路,UART 只是把每个状态的输入换成字节而非电平。
工程上还有几个实用细节:其一是命令处理往往比接收慢,FIFO 不仅要放在 RX/TX 之间,命令队列本身也可能要缓冲;其二是回显不等于应答,真正的控制器应在执行完命令后回一个状态字(成功/错误码),电脑侧据此重试;其三是调试期可让 FPGA 把内部状态、寄存器值周期地通过串口打印出来,充当「软件版 ILA」,但要注意打印本身占用带宽、不能阻塞实时逻辑(调试手段对比见 ILA 第一次用)。当数据率或确定性要求超过 UART 能力(例如要传 ADC 连续采样流),就应换成带时钟的 SPI/I2C 或并行/AXI 接口,UART 保留作低速配置与日志通道——这种「高速数据走专用接口、低速控制走串口」的分工在真实系统里极为常见。
十六、推荐的四步动手路径
- 纯仿真 TX:CLKS 参数取 8,写发送状态机,TB 抓 tx 波形逐位拼回字节,先不碰硬件;
- 纯仿真 RX + 回环:TB 行为级造帧喂给 RX,再接 TX 自收自发,覆盖单帧、连发、错误起始位;
- 上板单口回环:接 USB 转 TTL,串口助手敲字符看回显,先用 9600 确认通路,再升到 115200 量乱码边界;
- 加 FIFO 与简单报文:连发压力测试不丢字节,再实现帧头、长度、校验的小协议和一个真实命令(如按键值上报、LED 控制)。
每一步都打印/抓取状态机当前状态和关键计数器,遇到问题先判断是「定时(波特率/采样点)、成帧(位序/停止位)、缓冲(FIFO/握手)、物理(接线/电平)」中的哪一层,再深入。完成这条路径后,你不仅得到一个可用的调试串口,也完整走了一遍通信控制器从物理层到协议层的设计过程。
十七、波特率误差从哪来:分频与采样的量化分析
串口能不能稳定通信,最终取决于接收端采样的时刻准不准,而这个"准"是可以定量算出来的,值得建立量化直觉。UART 没有独立时钟线,收发双方各自用本地波特率分频出节拍,两边的实际位速率必然有偏差,来源有三类:一是系统时钟分频取整误差——用 50MHz 整数分频 115200 时,理想分频比约 434.03,只能取 434 或 435,单个比特就有约万分之几的周期偏差;二是晶振本身的频率误差,普通板载晶振常见 ±50ppm(百万分之五十),廉价器件可能更差,温度变化还会带来漂移;三是接收端为了避开边沿、通常在每位的中间采样,累积偏差只要不把采样点推出比特边界就能容忍。经典结论是:在没有独立校验、一帧 10 位(起始位+8 数据+停止位)的情况下,采样点的总漂移控制在约 ±2%~±3% 以内通常可可靠工作,越界就会出现误码、整帧错位。
由此得到几条可操作的纪律。优先选能被系统时钟较好整除的波特率,或用频率可配的 PLL 产生一个让分频比接近整数的时钟,从源头减小取整误差;不要让一个波特率分频参数在多处硬编码,而应统一由 parameter 算出,评审时把"实际波特率/目标波特率/误差百分比"列成表逐项核对。接收端不要在检测到起始位边沿后立刻按整数倍位宽死采,规范做法是用 8 倍或 16 倍过采样时钟:先在起始位内多次确认它确实拉低(滤掉毛刺、防误触发),再把后续采样点对到每个比特的中央,给两侧漂移留出最大余量。若通信距离长、电磁环境差或温差大,还要给晶振精度和线缆畸变留额外裕量,并善用帧错误(停止位不为高)、校验错误等指示统计误码率。把"误差从哪来、容忍多少、如何过采样留余量"算清楚,你就从"波特率填个数字"进阶到了能预判和定位通信可靠性问题的层次,这套量化方法在 SPI、CAN、各类异步采样系统里同样适用。
十八、从 loopback 到真实多机:流控、组帧与可靠性
自收发 loopback 只是证明了比特级收发通路能工作,它把现实通信里最难的几个问题都回避掉了;一旦进入 FPGA 与 PC、MCU、多个模块之间的真实链路,就要面对"发得快、收得慢"和"数据边界在哪里"这两类挑战。第一类是流控与缓冲。loopback 时收到一个字节立刻原样发回,永远不会积压;真实接收方可能要花时间处理、或下游暂时繁忙,如果发送端不管不顾地连续发,接收寄存器/缓冲来不及取走,新数据就会覆盖旧数据,发生溢出丢字节。标准解法是加 FIFO:接收侧把字节先推进先入先出队列,处理逻辑按自己的节奏弹出;进一步用硬件握手信号 RTS/CTS 告诉对方"我还能不能收",或者在更高层协议里用 XON/XOFF 软件流控。判断系统是否需要 FIFO,只需问一句"接收速率是否可能瞬时超过消费速率",只要可能,就必须有缓冲或反压。
第二类是组帧与定界。串口字节流本身没有"一条消息从哪开始、到哪结束"的标记,loopback 单字节看不出来,传命令和数据包时就必须自己定规则,常见三种:用特殊起始/结束分隔符(并对载荷里出现的分隔符做转义)、固定长度帧头加长度字段、或者用空闲总线时间(如 LIN 总线)区分帧间间隔。帧内通常再配校验和或 CRC,接收端按"找帧头→按长度收齐→校验→交付/丢弃"的小状态机处理,并对非法长度、校验失败、缓冲溢出计数,必要时回送 ACK/NAK 或超时重传。第三类是多机与电气层:板内短距离用 TTL/LVTTL 电平直连即可,跨设备要经 RS-232、RS-485 等收发器转换电平;RS-485 是半双工差分总线,需要用使能信号在发送/接收之间切换方向,方向切早切晚都会丢字节,切换时机控制是其特有难点。把 loopback 当作"第零步",再依次加入 FIFO 缓冲、握手流控、帧格式、校验重传和方向控制,你就完整走过了从"能传一个字节"到"能可靠传一批结构化数据"的工程链路,而其中的 FIFO、状态机、握手思想正是后续 SPI/I2C、AXI-Stream 等所有数据通信协议的共同内核。
常见坑对照
| 坑 | 后果 | 正确做法 |
|---|---|---|
| 波特率/时钟频率算错 | 乱码 | N=时钟/波特率,按实钟频率 |
| TX/RX 没交叉或没共地 | 收不到 | 板 TX↔USB RX,共 GND |
| 数据位按 MSB 先发 | 字节错位 | UART 是 LSB 先发 |
| 不在中点采样 | 边沿抖动出错 | 起始后半 bit、逐位中点 |
| 连发不缓冲 | 丢字节 | RX/TX 间加 FIFO |
| 直连 RS232 ±12V | 烧引脚 | 经 TTL/RS232 电平转换 |
| 3.3V 接 5V 串口 | 电平不匹配 | 确认电平/加转换 |
相关与延伸
节拍/状态机:计数器与分频、状态机入门。 深入:进阶 低速接口 UART/SPI/I2C、FIFO 设计(防丢字节)、AXI4-Stream(更规范的流式接口)。
一句话总结
UART 是无时钟线的异步串口:空闲高,一帧 8N1 = 1 个低起始位 + 8 个数据位(LSB 先发)+ 1 个高停止位,收发双方只靠约定的波特率各自定时。波特率换算成时钟节拍 N=系统时钟/波特率(50MHz、115200 时 N≈434);发送是并转串的状态机按 N 拍逐位移出,接收靠检测起始位下降沿、在每位中点采样(先等半 bit)抗抖动,串转并凑满 8 位给一个 valid 脉冲。回环实验把 RX 收到的字节交 TX 发回,中间最好加 FIFO 防连发丢字节;电脑串口助手设 115200/8N1、TX/RX 交叉共地验证。乱码多因波特率/时钟频率算错或不在中点采样,收不到多因接线没交叉/没共地/电平不匹配(3.3V TTL 需经转换,不能直连 RS232 ±12V)。
上一篇:25 数码管与 LED 阵列(动态扫描) | 下一篇:27 仿真看波形(Testbench/读波形) | FPGA 系列目录