基于FPGA的UART设计
2012-01-15谢谢
谢谢
(陕西烽火电子股份有限公司 陕西 宝鸡721006)
通 用 异 步 收 发 器 (Universal Asynchronous Receiver/Transmitter,UART)可以和各种标准串行接口,如RS232和RS485等进行全双工异步通信,具有传输距离远、成本低、可靠性高等优点。一般UART由专用芯片来实现,但专用芯片引脚都较多,内含许多辅助功能,在实际使用时往往只需要用到UART的基本功能,使用专用芯片会造成资源浪费和成本提高。当我们不需要用到完整的的UART功能和一些辅助功能时,就可以将需要的UART功能集成用FPGA来实现,然而,FPGA内部并不拥有CPU控制单元,无法处理由UART控制器产生的中断,所以FPGA不能利用现成的UART控制器构成异步串行接口,必须将UART控制器的功能集成到FPGA内部。从而可以大大的减少了体积、简化了电路,也提高了系统的灵活性。
1 UART的工作原理
UART是一种串行数据总线,用于异步通信,并且双向通信,可实现全双工发送和接收。基本的UART只需要两条信号线(TXD、RXD)和一条地线就可以完成数据的互相通信,接收和发送互不干扰,这样就大大节省了传输费用。由于UART是异步通信,所以需要对数据进行同步。UART发送/接收数据的传输格式如图1所示,一个字符单位由开始位、数据位、校验位、停止位组成(其中校验位可供选)。
图1 异步串口传输格式Fig.1 Asynchronous serial transmission format
发送或接收一个完整的字节信息,首先是一个作为起始位的逻辑“0”位,接着是8个数据位,然后是停止位逻辑“1”位,数据线空闲时为高或“1”状态。在字符的8位数据部分,先发送数据的最低位,最后发送最高位。每位持续时间是固定的,由发送器本地时钟控制,每秒发送的数据位个数,即为“波特率”。起始位和停止位起着很重要的作用。显然,它们标志每个字符的开始和结束,但更重要的是他们使接收器能把他的局部时钟与每个新开始接收的字符再同步。异步通信没有可参照的时钟信号,发送器随时都可能发送数据,任何时刻串行数据到来时,接收器必须准确地发现起始位下降沿的出现时间,从而正确地采样紧接着的10或者11位(包括开始位、数据位和停止位),接收器的时钟和发送器的时钟不是同一个,因此,接收器所确定的采样点的间隔和发送器所确定的位间隔时间不同,这点要特别注意。
2 UART功能设计
异步通信的一帧传输经历以下步骤:1)空闲状态。发送方连续发送信号,处于信息“1”状态。2)开始传输。发送方在任何时刻将传号变成空号,即“1”跳变到“0”,并持续 1位时间表明发送方开始传输数据。而同时,接收方收到空号后,开始与发送方同步,并期望收到随后的数据。3)奇偶传输。数据传输之后是可供选择的奇偶位发送或接收。4)停止传输。最后是发送或接收的停止位,其状态恒为“1”。
设计的基本原则是保留最主要的功能,基于FPGA的UART系统由波特率时钟发生器、接收器和发送器3个子模块组成,如图2所示。
图2 UART功能框图Fig.2 UART functional block diagram
2.1 波特率发生器设计
波特率发生器实质是设计一个分频器,用于产生和RS232通信同步的时钟。在系统中用一个计数器来完成这个功能,分频系数N决定了波特率的数值。该计数器一般工作在一个频率较高的系统时钟下,当计数到N/2时将输出置为高电平,再计数到N/2的数值后将输出置为低电平,如此反复即可得到占空比50%的波特率时钟,具体的波特率依赖于所使用的系统时钟频率和N的大小。如系统时钟频率是6.4 MHz,要求波特率是9 600,则16倍波特率时钟的周期约等于42个系统时钟周期,则计数器取42/2=21时,当计数溢出时输出电平取反就可以得到16倍约定波特率的时钟。
使用VHDL来描述波特率发生器的完整代码如下:Process(rst,clk6_4M)
if rst=‘0’then --0复位
count<=0;
bclkr<= ‘0’;
elsif rising_edge(clk6_4M) then
if(count=20)
count<=0;
bclkr<=not bclkr; ‘--生成16倍于波特率的clock,6.4 MHz晶振。
else
count<=count+1;
end if;
end if;
end process;
2.2 发送器设计
UART发送器的设计较容易,只要每隔一个发送周期按照数据帧格式及要求的速率输出数据即可。没有数据要发送时,发送数据寄存器为空,发送器处于空闲状态;当检测到发送数据寄存器满信号后,发送器及发送起始位,同时8个数据位被并行装入发送移位寄存器,停止位紧接着数据位指示一帧数据结束。只有发送数据寄存器为空时,RAM中的待发数据才能被装入。程序中使用计数器要保证各位周期定时正确。
2.3 接收器设计
接收器的工作过程如下,串行数据帧和接收时钟是异步的,发送来的数据由逻辑1变为逻辑0可以视为一个数据帧的开始。接收器先要捕捉起始位,然而,通信线上的噪音也极有可能使传号“1”跳变到空号“0”。所以接收器以16倍的波特率对这种跳变进行检测,确定rxd输入由1到0,逻辑0要8个bclkr(16倍的波特率时钟)周期,才是正常的起始位,而不是噪音引起的,其中若有一次采样得到的为高电平则认为起始信号无效,返回初始状态重新等待起始信号的到来。
采到正确的起始位后,就开始接收数据,最可靠的接收应该是接收时钟的出现时刻正好对着数据位的中央。由于在起始位检测时,已使时钟对准了位中央,用16倍波特率的时钟作为接收时钟,就是为了确保在位宽的中心时间对接收的位序列进行可靠采样,当采样计数器计数结束后所有数据位都已经输入完成。最后对停止位的高电平进行检测,若正确检测到高电平,说明本帧的各位正确接收完毕,否则出错。最后将正确的数据转存到数据寄存器中,输出数据。还要输出一个数据接收标志信号标志数据接收完。
利用有限状态机实现,完整代码如下:
process(bclkr,reset,rxd_sync)
variable count :std_logic_vector(3 downto 0); --定义中间变量
variable rcnt :integer:=0;
variable rbufs :std_logic_vector(7 downto 0);
begin
if reset='0'then --0复位
state<=r_start;
count:="0000";
elsif rising_edge(bclkr) then
case state is
when r_start=> --状态1,等待起始位
if rxd_sync='0'then
state<=r_center; --检测到起始位,进入下一个状态(r_center状态)
r_ready<=‘0’;
rcnt:=0;
else
state<=r_start; --没 检 测 到 起 始位,仍处于r_start状态
r_ready<=‘0’;
end if;
when r_center=> --状态2,求出每位的中点
if rxd_sync='0'then
if count>="0100"then--保持逻辑0超过1/4个位时间的信号一定是起始位
state<=r_wait;
count:="0000";
else
count:=count+1;
state<=r_center;
end if;
else
state<=r_start;
end if;
when r_wait=> --状态3,等待状态
if count>=“1110”then --等待 15个 clkb周期
count:=“0000”;
if rcnt=framlenr then--已经采集8 bit数据
state<=r_stop;
else
state<=r_sample;
end if;
else--等待,一直等到15个bclkr周期
count:=count+1;
state<=r_wait;
end if;
when r_sample=>
rbufs (rcnt):=rxd_sync; --数据时低位在前,高位在后,先转换低位数据
rcnt:=rcnt+1;
state<=r_wait; --状态 4,数据位采样检测,检测是否已经收到8 bit数据
when r_stop=> --并没有处理停止位。所以输出数据不加停止位
r_ready<=‘1;; --输出帧接收完毕信号
rbuf<=rbufs;
state<=r_start; --状态4,输出帧接收完毕信号
when others=>
state<=r_start;
end case;
end if;
end process;
3 仿 真
本设计在Altera Cyclone系列的EPlC3T100I7芯片上进行了验证,对发送模块和接收模块的仿真结果分别如图3、图4所示。发送的数据能严格按照串行通信协议进行传输;接收的数据也完全正确。仿真无误后,使用QuarltusⅡ软件将编译好的.pof格式文件载到配置芯片EPCS1中。结果通信数据完全正确,电路工作稳定、可靠。
用FPGA设计UART,可以用片上很少的逻辑单元实现UART的基本功能。与传统设计相比,能有效减少系统的PCB面积,降低系统的功耗,提高设计的稳定性和可靠性,充分利用FPGA的剩余资源。并可方便地进行系统升级和移植。
图3 发送模块仿真Fig.3 Receiver simulation
图4 接收模块仿真Fig.4 Transmitter simulation
4 结 论
该设计具有很大的灵活性,通过调整波特率发生器的分频参数,就可以使其工作在不同的频率。采用16倍波特率的采样时钟,可以实时有效监测数据的起始位,并对数据位进行中央采样,从而保证了所采样数据的正确性。该模块可以作为一个完整的IP核,灵活地移植进各种型号FPGA中,在实际应用时也可嵌入到其他系统中,有很好的借鉴和参考价值。
[1]黄智伟.FPGA系统设计与实践[M].北京:电子工业出版社,2005.
[2]赵鑫,蒋亮.VHDL与数字电路设计[M].北京:机械工业出版社,2005.
[3]姜宁,范多旺.基于FPGA/CPLD的通用异步通信接口UART的设计[J].信息技术与信息化,2006(1):86-88.JIANG Ning,FAN Duo-wang.The design of UART based on FPGA/CPLD[J].Information Technology and Information,2006(1):86-88.
[4]于宏毅,王大鸣,顾雪琳.简化UART功能的FPGA实现[J].现代电子技术,2004,4(171):64-66.YU Hong-yi,WANG Da-ming,GU Xue-lin.Implementation of UART on FPGA[J].Modern Electronic Technology,2004,4(171):64-66.
[5]聂涛,许世宏.基于FPGA的UART设计[J].现代电子技术,2006,2(217):127-129.NIE Tao,XU Shi-hong.Design of UART Based on FPGA[J].Modern Electronic Technology,2006,2(217):127-129.
[6]何勇.基于FPGA的UART设计与实现[J].现代电子技术,2010(11):95-99.HE Yong.Design and implementation of UART based on FPGA[J].Modern Electronic Technology,2010(11):95-99.