UART(Universal Asynchronous Receiver/Transmitter)作为最古老的通信协议之一,至今仍在嵌入式系统和工业控制领域广泛应用。其核心价值在于简单可靠的传输机制——仅需两根信号线(TX和RX)即可实现全双工通信。这种简洁性使得UART成为设备调试、传感器数据采集等场景的首选方案。
在Xilinx K7系列FPGA平台上实现UART通信,需要深入理解其物理层和协议层的双重特性。物理层涉及电平标准转换,常见的有TTL(3.3V)和RS-232(±12V)两种规格。MK7160FA开发板采用CP2102 USB转串口芯片,实现了USB接口到TTL电平UART的转换,其原理图设计显示FPGA通过Pmod接口的IO_L12P_T1_MRCC_35(RX)和IO_L12N_T1_MRCC_35(TX)引脚与转换芯片连接。
协议层的关键参数包括:
关键细节:在TTL电平规范中,逻辑高电平(1)为3.3V,逻辑低电平(0)为0V。这与RS-232的负逻辑(+3V~+15V为0,-3V~-15V为1)形成鲜明对比,实际工程中必须注意电平转换芯片的选用。
波特率精度直接决定通信可靠性。以100MHz系统时钟生成115200bps为例,其分频系数计算过程如下:
在Verilog实现中,需要构建16倍过采样的波特率发生器(工业标准做法),对应代码结构如下:
verilog复制parameter CLK_FREQ = 100_000000;
parameter BAUD_RATE = 115200;
localparam BAUD_DIV = CLK_FREQ/(BAUD_RATE*16);
reg [15:0] baud_cnt;
wire baud_tick = (baud_cnt == BAUD_DIV);
always @(posedge clk) begin
if(baud_tick)
baud_cnt <= 0;
else
baud_cnt <= baud_cnt + 1;
end
常见波特率误差容忍度:
| 波特率 | 允许误差 | 100MHz分频系数 |
|---|---|---|
| 9600 | ±2% | 10416 |
| 115200 | ±1% | 868 |
| 460800 | ±0.5% | 217 |
工程经验:实际设计中建议在PLL输出端生成专用波特率时钟(如184.32MHz),这样可以通过整数分频得到精确的常用波特率时钟,避免累计误差。
UART接收状态机是设计核心,需要处理三个关键问题:
采用三采样点表决机制消除毛刺:
verilog复制reg [2:0] rx_sync;
always @(posedge clk) rx_sync <= {rx_sync[1:0], UART_RX};
wire start_detected = (rx_sync[2:1]==2'b10); // 下降沿检测
在数据位中点采样保证稳定性:
verilog复制localparam SAMPLE_POINT = BAUD_DIV/2;
reg [3:0] bit_cnt;
reg [7:0] rx_data;
always @(posedge clk) begin
if(baud_tick) begin
if(sample_cnt == SAMPLE_POINT) begin
rx_data[bit_cnt] <= rx_sync[2]; // 中点采样
bit_cnt <= bit_cnt + 1;
end
sample_cnt <= sample_cnt + 1;
end
end
完整的状态机应包括:
避坑指南:实际测试中发现,在电磁环境复杂的场景中,建议增加数字滤波模块,对每个bit进行3次采样表决,可显著提高抗干扰能力。同时,接收缓冲区应设计为双缓冲结构,避免数据覆盖。
发送时序控制需要注意两个关键点:
采用状态机精确控制每个bit的发送时长:
verilog复制reg [3:0] tx_state;
reg [7:0] tx_shift;
always @(posedge clk) begin
case(tx_state)
0: if(tx_start) begin // 起始位
UART_TX <= 0;
tx_shift <= tx_data;
tx_state <= 1;
bit_cnt <= 0;
end
1-8: if(baud_tick) begin // 数据位
UART_TX <= tx_shift[0];
tx_shift <= {1'b0, tx_shift[7:1]};
tx_state <= tx_state + 1;
end
9: if(baud_tick) begin // 停止位
UART_TX <= 1;
tx_state <= 0;
end
endcase
end
通过CTS/RTS信号实现硬件流控:
性能优化:对于高速UART(≥1Mbps),建议采用DMA传输机制,将数据从内存直接搬运到UART发送缓冲区,减轻CPU负担。在FPGA中可通过AXI-Stream接口实现类似功能。
验证收发功能的黄金标准:
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 接收数据乱码 | 波特率不匹配 | 核对双方波特率设置 |
| 只能接收部分数据 | 停止位配置错误 | 统一设置为1位停止位 |
| 长时间通信后出错 | 时钟漂移累积误差 | 改用更精确的时钟源 |
| 高波特率时通信失败 | 信号完整性问题 | 添加终端电阻(通常120Ω) |
在MK7160FA开发板上进行实测时,发现当波特率超过3Mbps时,需要优化PCB布局布线:缩短信号走线长度、避免锐角转弯、增加地平面屏蔽。对于工业级应用,建议选用隔离型串口芯片(如ADI的ADM3251E),可承受1500V的隔离电压。