基于FPGA 的UART 串口技术研究

作者: 尹军茹

基于FPGA 的UART 串口技术研究0

摘要:针对传统UART集成电路芯片设计复杂、可移植性差、成本较高等诸多缺点,文章提出一种基于DSP+FPGA架构的UART串口设计方案。该方案利用FPGA资源实现高性能、低成本的通用化UART驱动,具有高可配置性、可扩容性和良好的可移植性。文章详细论述了系统架构设计、FPGA软件设计和DSP软件设计,采用差错重传机制和奇偶校验,提高了数据传输的可靠性和正确性。实验结果验证了该方案实现了可靠的全双工串口通信,并具有良好的工程实用性和复用价值。关键词:UART;FPGA;DSP;FIFO;串口接收;串口发送

中图分类号:TP311.52 文献标识码:A

文章编号:1009-3044(2025)04-0076-09 开放科学(资源服务) 标识码(OSID) :

0 引言

UART以其传输线少、可靠性高、波特率可调等优点,广泛应用于短距离、低速率、低成本的通信系统,如无线通信和雷达系统[1]。DSP芯片与UART接口的数据交互是实际应用中的常见需求,但现有的几种实现方式各有不足(详见表1) ,因此研究UART串口设计在工程实际中的简洁高效实现方式成为亟须解决的问题。本文提出一种基于DSP+FPGA 架构的UART 串口设计方案,利用FPGA资源实现高性能、低成本的通用化UART驱动。该方案具有高可配置性、可扩容性和良好的可移植性,能够实现可靠的全双工串口通信。

1 系统架构设计

本文采用DSP+FPGA结构设计,通过FPGA芯片实现UART 接收发送驱动,DSP 与FPGA 之间通过EMIF接口进行数据交互, DSP负责实现接收发送控制。其功能框图如图1所示。

如图2 所示,所有外部接口均由DSP 软件配合FPGA完成控制,DSP通过FPGA完成与外部接口之间的串口通信。利用DSP+FPGA结构设计的可移植性,系统可同时实现多个串口通路,与多个设备交联互不干扰。

2 FPGA 软件设计

FPGA作为一种半定制电路,具有开发周期短、功能强大、现场可编程等优点,适用于实现UART功能。当前大多数UART芯片设计复杂、移植性差,而FPGA 的灵活性使其能够根据项目需求定制UART功能,去除不必要的模块,从而提高系统的效率和稳定性。此外,FPGA支持硬件描述语言(如VHDL、Verilog) 进行编程,便于实现复杂的逻辑功能。从资源需求、接口类型/数量、功耗、成本等方面综合评估后,本文采用深圳市国微电子有限公司的国产芯片SMQ7K325TFFG900,速度等级为-2,封装形式为FFG900,FPGA 芯片工作频率为100 MHz。FPGA软件采用VHDL语言编写,开发环境为Vivado2018.3,主要实现UART接收发送驱动,同时完成与DSP的EMIF总线通信,并实现与外部其他交联设备的互联功能。该设计具有高可配置性、可扩容性、可移植性、低硬件成本以及低开发成本等优点。

2.1 波特率设计

为提高该设计对不同场合应用需求的兼容性,本设计开放了波特率、数据位、停止位、奇偶校验选择等配置参数。通过更改baud_rate_cnt实现波特率配置灵活,可适应不同场合的时钟频率;通过更改data_bits_num、parity_style、stop_bit_len可实现数据位(5-8) 、校验位(奇、偶、无) 和停止位(0.5、1、1.5、2) 的灵活配置。波特率计算公式为:

baud_rate = F / baud_rate_cnt (1)

式中:F为系统时钟频率,baud_rate_cnt为波特率计数(1bit所占的时钟数) 。

利用上述波特率计算公式,得出几种常用波特率与波特率计数对照表,如表2所示。

波特率越高,传输速度越快,但误码率也会增加,同时会增加硬件成本和复杂度。例如,若应用需要传输大量数据,选择较高的波特率(如115 200) 更合适;反之,若数据量不大或实时性要求不高,较低波特率(如9 600) 即可满足需求。在信号质量较差或干扰较多的环境中,较低的波特率可以提供更可靠的通信;在电池供电的设备中,较低的波特率可降低功耗和硬件成本。因此,需要根据具体的应用场景和需求选择合适的波特率,以平衡传输速度、误码率、硬件成本和能耗等因素。

2.2 UART_RX 驱动设计

采用状态机设计以实现复杂的串行通信协议,负责接收串行数据,并将其转换为并行数据存储在接收FIFO缓冲中。该模块检测RX线上的串行数据,添加起始位、数据位、校验位(可选) ,并在接收到停止位后结束接收过程。

串口接收驱动主要程序实现如下:

entity UART_RX is

--波特率计数器位宽

generic(BAUD_COUNTER_WIDTH:integer:=16);

Port(clk:in STD_LOGIC;

--全局复位,高有效

rst:in STD_LOGIC;

--接收数据,数据长度不足8 位时,按最低位对齐

rx_data:out STD_LOGIC_VECTOR(7 downto 0);

--接收完成

rx_end:out STD_LOGIC;

--串行输入

serial_in:out STD_LOGIC;

--接收忙

rx_busy:out STD_LOGIC;

--发送参数设置

--数据位位数: data_bits_num + 1,范围:5~8

data_bits_num:in STD_LOGIC_VECTOR(2 downto 0);

--校验方式: "000"-无校验;"100"-0校验;"101"-1校验;"110"-偶校验;"111"-奇校验;

parity_style:in STD_LOGIC_VECTOR(2 downto 0);

--停止位长度: "00"-0.5位;"01"-1位;"10"-1.5 位;"11"-2位;

stop_bit_len:in STD_LOGIC_VECTOR(1 downto 0);

--波特率计数 (1bit所占的时钟数) = 时钟频率 / 波特率

baud_rate_cnt:in STD_LOGIC_VECTOR(BAUD_COUNTER_WIDTH -1 downto 0);

end UART_RX

接收状态机流程图如图3所示。

接收状态机主要程序实现如下:

--采样状态

When RX_BITS=>

--波特率控制

if(rx_baud_cnt < baud_rate_cnt-1)thenrx_baud_cnt <= rx_baud_cnt+1;

else

rx_baud_cnt <= (others=>‘0’);

end if;

if(rx_baud_cnt = baud_rate_cnt-1)then

--当前bit的最大似然判断and移位and校验位计算的预处理

if(sample_0_cnt > CONV_INTEGER(baud_rate_cnt)/2)then

rx_shift_reg(9 downto 0) <= ‘0’& rx_shift_reg(9downto 1);

rx_shift_cnt <= rx_shift_cnt+1;

--起始位应为0

elsif(sample_1_cnt>CONV_INTEGER(baud_rate_cnt)/2)

and(rx_shift_cnt>0)then

rx_shift_reg(9 downto 0) <= ‘1’& rx_shift_reg(9downto 1);

rx_shift_cnt <= rx_shift_cnt+1;

--将所有数据位按位异或进行校验位计算的预处理

if(rx_shift_cnt < (CONV_INTEGER(data_bits_num)+2))then

--异或计算算法,当前输入bit位‘1’,将结果取反;当前输入bit位‘0’,对结果无影响;

calc_partity <= not calc_parity

end if;

else --起始位不为0 or中间位不为0或1

rx_state <= RX_IDLE;

end if;

--下一bit的第一采样点

if(serial_in_dly(2) =‘ 0’)then

sample_0_cnt <=((0)=>’1’,others=>’0’);

sample_1_cnt <=(others=>’0’);

elsif(serial_in_dly(2) =‘ 1’)then

sample_0_cnt <=(others=>’0’);

sample_1_cnt <=((0)=>’1’,others=>’0’);

else

sample_0_cnt <=(others=>’0’);

sample_1_cnt <=(others=>’0’);

endif

if(rx_shift_cnt = rx_bit_num-1)thenrx_state <= RX_STOP;

endif;

else

--当前bit采样

if(serial_in_dly(2) =‘ 0’)then

sample_0_cnt <= sample_0_cnt + 1;

elsif(serial_in_dly(2) =‘ 1’)then

sample_1_cnt <= sample_1_cnt + 1;

endif;

endif;

2.3 UART 发送模块设计

采用状态机设计以实现复杂的串行通信协议,负责发送串行数据,确保每个比特的发送时间准确无误。该模块从发送FIFO缓冲中读取数据,添加起始位、校验位和停止位,形成完整的UART帧格式,并将并行数据转换为串行数据通过TX线发送。串口发送驱动主要程序实现如下:

entity UART_TX is

--波特率计数器位宽

generic(BAUD_COUNTER_WIDTH:integer:=16);

Port(clk:in STD_LOGIC;

--全局复位,高有效

rst:in STD_LOGIC;

--发送数据,数据长度不足8 位时,按最低位对齐

经典小说推荐

杂志订阅