摘要:UART是广泛使用的串行数据通信电路,因其要求的传输线少,可靠性高,传输距离远, 所以系统间互联常采用RS—232接口方式,一般说来,该接口由硬件(UART专用芯片)实现。 文章基于VerilogHDL语言,结合有限状态机的设计方法来实现UART,将其核心功能集成到 FPGA上,使整体设计紧凑、小巧,实现的UART功能稳定、可靠,为RS—232接口提供了一种 新的解决方案;同时,与其他设计方法相比较,利用有限状态机的方法具有结构模式直观简单, 设计流程短,程序层次分明,易综合,可靠性高等优点,必将在EDA技术中发挥重要作用。
关键词:VerilogHDL; UART; 帧格式; 状态机
引言
随着微机系统的广泛运用和微机网络的极大发展,UART(Universal Asynchronous Receive Transmitter)【1】在数据通信及控制系统中得到了广泛运用。8250、NS16450等芯片都是常见的UART器件[2],这类芯片已经相当复杂,有的含有许多辅助模块(如FIFO),但在实际中有时只需要使用UART的部分功能,因而会造成一定的资源浪费。FPGA在现代电子设计中的广泛运用,使我们可以充分利用其资源,在芯片上集成UART的功能模块,这样就无需外接专用UART芯片,从而简化了电路,缩小了体积,设计的灵活性更大。
文章通过分析UART的功能,利用有限状态机[4]来描述UART核心控制逻辑的方法,将其核心功能集成,从而使整个设计更加稳定、可靠。基本的UART通信只需要两条信号线就可以完成数据的相互通信。UART的结构如图1所示。
1 UART的帧格式
在UART中,数据位是以字符为传送单位,数据的前、后要有起始位、停止位,另外可以在停止位的前面加上一个比特(bit)的校验位。其帧格式如图2所示[4]。
其基本特点是:
① 在信号线上共有两种状态,可分别用逻辑1和逻辑0来区分。在发送器空闲时,数据线应该保持在逻辑高电平状态。
② 起始位:该位是一个逻辑0,总是加在每一帧的头部,提示接受器数据传输即将开始,在接收数据位过程中又被分离出去。
③ 数据位:在起始位之后就是数据位,一般为8位一个字节的数据,低位在前,高位在后。如字母C在ASCII表中是十进制67,二进制01000011,那么传输的将是11000010。
④ 校验位:该位一般用来判断接收的数据位有无错误,常用的校验方法是奇偶校验法。
⑤ 停止位:停止位总在每一帧的末尾,为逻辑1,用于标志一个字符传送的结束。
⑥ 帧:从起始位到停止位结束的时间间隙称为一帧。
2 UART的设计
2.1 UART接收器
串行数据帧和接收时钟是异步的,由逻辑1跳变为逻辑0可视为一个数据帧的开始,所以接收器首先要判断起始位。常用的方法有三倍速采样法,起始位中断捕捉、定时采样法[5]。文章采用的方法是中间时刻采样法。由于内部采样时钟clk__rev是发送或接收时钟频率的16倍,所以起始位至少有8个连续的clk__rev周期的逻辑0被检测到才认为起始位接收到了,接着数据位和奇偶校验位将每隔 个clk__rev周期被采样一次。如果起始位的确是 个clk__rev周期长,那么接下来将在每个位的中点处被采样。
UART接收器的状态转移图如图3所示。
图3 UART接收器的状态转移图
状态机一共有4个状态:state0(检测起始位),state1(对数据位进行采样,并串/并转换),state2(奇偶校验分析),state3(接收数据正确与否检测)。
① state0状态:当UART接收器复位以后,接收器将处于这一状态。在该状态,状态机一直等待rxd电平的跳变,即从逻辑1变为逻辑0,也就是等待起始位的到来。一旦检测到起始位,就对采样时钟clk__rev上跳沿计数,当计数为8时,也就是确保在起始位的中间点,然后转到state1状态。
② state1状态:该状态下,每间隔16位时钟采样一位串行数据,接收8位异步数据并进行串/并转换。即对clk__rev上跳沿计数,当为16时,就对数据采样,这样保证了数据位是在中点处被采样的,同时串/并转换,当探测已经收到8位数据以后,便进入了state2状态。
③ state2状态:该状态实现的功能是奇偶校验。本文采用的是偶校验。校验结束以后,转到state3状态。
④ state3状态:该状态是用来帧校验的,即在校验位以后,检测停止位是否为逻辑1。
如果是逻辑1,则输出state2中串/并转换后的8位数据,同时输出后级使能控制信号en__con为1,提醒后级可以接收该8位数据;如果是逻辑0,则说明帧错误,en__con输出为0,后级不能接收该8位数据。状态最终返回到state0。
接收器端口信号如图4所示。
图4 接收器端口信号图
clk__rev:内部采样时钟 parity_err:奇偶校验位
rst:复位信号 fra_err:桢错误信号
rxd:串行输入数据 en_con:后级使能控制
dout[7..0]:输出数据总线
UART接收器仿真结果如图5所示。
图5 UART接收器仿真结果
仿真结果说明:选择8位数据宽度,例如在rxd信号线上设置数据000001011,在输出数据总线dout[7..0]得到10100000,表明仿真结果正确。
2.2 UART发送器
发送器实现的功能是将输入的 8位并行数据 变为串行数据,同时在数据头部加起始位,在数据位尾部加奇偶校验位和停止位。
UART发送器的状态转移图如图6所示。
图6 UART发送器的状态转移图
①state0状态:当 UART被复位信号复位以后,状态机将立刻进入这一状态,在该状态下读8位并行数据,并转到state1。
② state1状态:输出起始位之前的一位逻辑1,然后转入到state2。
③ state2状态:输出起始位0。综合state1和state2可知,在第一位数据位之前,有一个从1到0的下跳变。
④ state3状态:根据8位数据,检验校验位为逻辑1还是逻辑0,校验位在state4状态输出。
⑤ state4状态:该状态机的功能在state3中已经讲过。
⑥ state5状态:输出停止位。
发送器端口信号如图7所示。
图7 发送器端口信号图
rst:复位信号 w__en:写锁存
clk__send:发送时钟 din[7..0]:输入数据
d__out:串行数据输出
UART发送器仿真结果如图8所示。
图8 UART发送器仿真结果
仿真结果说明:在写锁存w__en有效的情况下,当输入数据din[7..0]为11001100时,串行数据输出d__out为0011001101。倒数第2位是添加的奇偶校验位0,显然满足偶校验的方式;最后一位是停止位,为高电平1。
2.3 波特率发生器
波特率发生器实际上就是分频器,设计比较简单,文章用的是16分频。
3 结束语
利用VerilogHDL设计的灵活性,根据串行通信协议的要求,通过对波特率发生器、发送器和接收器的设计与仿真,能较容易地实现通用异步收发器总模块。对于收发的数据帧和波特率时钟频率能较灵活地改变,而且硬件实现不需要很多资源。
本文设计出的基于VerilogHDL异步串行通信电路,在实验室已经与计算机串口RS—232进行了通信实验,实验表明,0到255所有的数据都能被正确收、发。
参考文献:
[1] Wilfried Elmenreich,Martin Delvai。“Time—Triggered Communication with UARTS” [J] 4th IEEE International Workshop on Factory Communication Systems,Vasteras,Sweden,August 28—30,2002 .
[2] Martin S.Michael,“A Comparison of the INS8250,NS16450 and NS16550AF Series of UARTs” [J] National Seiniconductor Application Note 493,April 1989 .
[3] 潘松,王国栋.VHDL实用教程[M] .成都:电子科技大学出版社,2003 .
[4] 李群芳,黄建.单片微型计算机与接口技术[M].北京:电子工业出版社,2002 .
[5] http://www.goldenchip.com.cn/gdbbs/dispbbs.asp?ID=200433110139608&boardid=4.
11.5.3 UART分频器
假设数据的波特率为p,则所需时钟的频率为16*p。以波特率p为115200为例,系统时钟为50MHz,则分频系数为50000000/(16*115200) = 27.127,取整为27。分频器Verilog HDL语言代码如下:
保存文件为clkdiv.v,单击Files → Create/Update → Create Symbol Files for Current File命令,为clkdiv.v生成原理图模块。新建一个原理图文件,在原理图空白处双击,在弹出的Symbol对话框中选择Project → clkidv模块,单击OK按钮退出Symbol对话框。在原理图的适当位置放置clkdiv模块,并添加输入输出模块。保存原理图为uartrxtx.bdf。编译工程文件,编译无误后单击Processing → Generate Functional Simulation Netlist,产生功能仿真网表。新建波形仿真文件,加入输入输出信号,设置系统时钟信号clk的周期为20ns,保存波形文件为 uartrxtx.vwf,单击 按钮进行分频器的波形仿真,波形仿真报告如图11-41所示。
11.5.4 UART发送模块
UART发送模块的功能:接收到发送指令后,把数据按UART协议输出,先输出一个低电平的起始位,然后从低到高输出8个数据位,接着是可选的奇偶校验位,最后是高电平的停止位。Verilog HDL语言代码如下:
保存文件为uarttx.v,单击Files → Create/Update → Create Symbol Files for Current File命令,为uarttx.v生成原理图模块。为了测试UART发送模块的正确性,需要编写一个测试模块来测试UART发送模块,Verilog HDL语言代码如下:
保存文件为testuart.v,单击Files → Create/Update → Create Symbol Files for Current File命令,为testuart.v生成原理图模块。新建一个原理图文件,在原理图空白处双击,在弹出的Symbol对话框中选择Project → testuart模块和uarttx模块,单击OK按钮退出Symbol对话框。在原理图的适当位置放置testuart模块和uarttx模块,并添加输入输出模块。为了仿真方便,把原来分频模块的分频系数更改为4,各个模块的连接如图11-42所示。
保存原理图为uartrxtx.bdf。编译工程文件,编译无误后单击Processing → Generate Functional Simulation Netlist,产生功能仿真网表。新建波形仿真文件,加入输入输出信号,设置系统时钟信号clk的周期为20ns,保存波形文件为uartrxtx.vwf,单击 按钮进行UART数据发送的波形仿真,波形仿真报告如图11-43所示。
11.5.5 UART接收模块
UART接收模块的功能:时时检测线路,当线路产生下降沿时,即认为线路有数据传输,启动接收数据进程进行接收,按从低位到高位接收数据。UART接收模块的Verilog HDL语言代码如下:
保存文件为uartrx.v,单击Files → Create/Update → Create Symbol Files for Current File命令,为uartrx.v生成原理图模块。新建一个原理图文件,在原理图空白处双击,在弹出的Symbol对话框中选择Project → uartrx模块,单击OK按钮退出Symbol对话框。在原理图的适当位置放置uartrx模块,并添加输入输出模块,各个模块的连接如图11-44所示。
保存原理图为uartrxtx.bdf。编译工程文件,编译无误后单击Processing → Generate Functional Simulation Netlist,产生功能仿真网表。新建波形仿真文件,加入输入输出信号,设置系统时钟信号clk的周期为20ns,保存波形文件为 uartrxtx.vwf,单击 按钮进行UART数据接收的波形仿真,波形仿真报告如图11-45所示。
波形仿真报告说明:
对图11-45分析看出,UART接收模块接收到的数据与UART发送模块发送的数据相一至,每接收到一个数据都有一个读取数据指示rdisg,UART接收模块得到正确验证。