基于FPGA的异步收发器程序方案设计书Word文件下载.docx
《基于FPGA的异步收发器程序方案设计书Word文件下载.docx》由会员分享,可在线阅读,更多相关《基于FPGA的异步收发器程序方案设计书Word文件下载.docx(19页珍藏版)》请在冰豆网上搜索。
A
引言
由于微电子学和计算机科学的迅速发展,给EDA(电子设计自动化)行业带来了巨大的变化。
特别是进入20世纪90年代后,电子系统已经从电路板级系统集成发展成为包括ASIC、FPGA/CPLD和嵌入系统的多种模式。
可以说EDA产业已经成为电子信息类产品的支柱产业。
EDA之所以能蓬勃发展的关键因素之一就是采用了硬件描述语言(HDL)描述电路系统。
就FPGA和CPLD开发而言,比较流行的HDL主要有VerilogHDL、VHDL、ABEL-HDL和AHDL等,其中VHDL和VerilogHDL因适合标准化的发展方向而最终成为IEEE标准。
下面的设计就是用VHDL来完成实现的。
1.UART简介
UART(即UniversalAsynchronousReceiverTransmitter通用异步收发器)是一种应用广泛的短距离串行传输接口。
UART允许在串行链路上进行全双工的通信。
UART主要有由数据总线接口、控制逻辑、波特率发生器、发送部分和接收部分等组成。
功能较为简单,但使用方便、占用资源少,可以灵活地嵌入到各种设计之中。
串行外设用到的RS232-C异步串行接口,一般采用专用的集成电路即UART实现。
使用VHDL将UART的核心功能集成,从而使整个设计更加紧凑、稳定且可靠。
1.1UART结构
UART主要有由数据总线接口、控制逻辑、波特率发生器、发送部分和接收部分等组成。
1.2UART的帧格式
UART是异步通信方式,发送方和接收方分别有各自独立的时钟,传输的速度由双方约定,使用起止式异步协议。
起止式异步协议的特点是以每一个字符为单位进行传输,字符之间没有固定的时间间隔要求,每个字符都以起始位开始,以停止位结束。
帧的格式如图一所示,每一个字符的前面都有一位起始位(低电平,逻辑值0),字符本身有5到8比特数据位组成,接着是一位校验位(也可以没有校验位),最后是一位(或一位半、二位)停止位,停止位后面是不定长度的空闲位。
停止位和空闲位都规定为高电平,这样就保证了起始位开始处一定有一个下降沿。
从图中可以看出,这种格式是靠起始位和停止位来实现字符的界定或同步的,故称为起止式协议。
UART的帧格式的示意图如图一所示:
图一基本UART帧格式
1.3UART的基本原理
基本的UART通信只需要两条信号线:
RXD和TXD,TXD是UART的发送端,RXD是UART的接收端,接收与发送是全双工工作的。
通过在串行端口上使用调制解调器,串行数据可以通过电话线进行长距离的收发(图二)。
用于收发串行数据的串行通信接口通常称为UART(通用异步收发机)。
UART串行数据传输的示意图如图二所示:
图二串行数据传输
发送数据过程:
空闲状态,线路处于高电位,当收到发送数据指令后,拉低线路一个数据位的时间T,接着数据按低位到高位依次发送,数据发送完毕后,接着发送奇偶校验位和停止位(停止位为高电位),一帧数据发送结束。
接收数据过程:
空闲状态,线路处于高电位,当检测到线路的下降沿(线路电位由高电位变为低电位)说明线路有数据传输,按照约定的波特率从低位到高位接收数据,数据接收完毕后,接着接收并比较奇偶校验位是否正确,如果正确则通知后续设备准备接收数据或存入缓存。
2UART的设计与实现
2.1UART发送器
串行发送数据时每秒钟发送的比特个数称之为波特率,常用串行口波特率有9600、19200、115200等多种。
UART的数据帧的形式分组发送数据,以8位数据位、1位起始位和1位停止位的帧格式为例,每一个数据帧由10位数据构成,首先是一个低电平起始位来标志帧开始,随后由低至高发送8位数据,最后是1位高电平的停止位。
在逻辑结构上,每秒9600次的发送节拍由波特率发生器产生,它是一个参数化、分频比的整数分频器。
这里使用边沿逻辑,对于分频时钟的占空比并没有要求,所以直接用模n计算器进行分频。
9600Hz的时钟信号驱动10bit的一位计数器,将数据总线上载入的8bit数据加上起始位和停止位后由低到高依次移除。
发送逻辑的结构框图如图三所示:
图三发送结构框图
UART发送器的发送流程图如图四所示:
图四UART发送器的发送流程图
2.2UART接收器
UART是异步传输接口,没有时钟信号同步。
所以接收端需要进行过采样来保证数据的接收,RS232标准规定的过采样率是以发送波特率的16倍时钟对数据进行检测。
UART接收逻辑通过检测TxD上起始位的下降沿作为帧同步标准,这样就相当于把每个位分成了16份,为了避免干扰取16份中位于中部的6、7、8三个采样进行判别,以它们中两个或两个以上相同的值作为采样结果。
接收器结构框图如图五所示:
图五接收结构框图
接收器的接收原理流程图如图六所示:
图六接收器的接收原理流程图
2.3数码管动态显示
图八所示的是共阳数码管及其电路,其中每个数码管的8个段:
h、g、f、e、d、c、b、a(h是小数点)都连在一起。
图九是4位数码扫描显示电路,4个数码管分别由4个选通信号k1~k4来选择。
被选通的数码管显示数据。
例如,在某一时刻,k3为低电平,其余选通信号为高电平,这时仅k3对应的数码管显示来自段信号端的数据,就必须使得4个选通信号k1~k4分别被单独选通,与此同时,在段信号输入口加上希望在该对应数码管上显示的数据,于是随着选通信号的扫变,就能实现扫描显示的目的。
共阳数码管及其电路示意图如图七所示:
图七共阳数码管及其电路
4位数码扫描电路的示意图如图八所示:
图八4位数码扫描电路
2.4波特率发生器
UART的接收和发送是按照相同的波特率进行收发的。
波特率发生器产生的时钟频率不是波特率时钟频率,而是波特率时钟频率的16倍,目的是为在接收时进行精确地采样,以提出异步的串行数据。
2.5UART设计总模块
将发送器和接收器模块组装起来,就能较容易地实现通用异步收发器总模块,而且硬件实现不需要很多资源,尤其能较灵活地嵌入到FPGA/CPLD的开发中。
UART设计流程图如图九所示:
以超声波作为检测手段,必须产生超声波和接收超声波。
完成这种功能的装置就是超声波传感器,习惯上称为超声换能器,或者超声探头。
超声波探头主要由压电晶片组成,既可以发射超声波,也可以接收超声波。
小功率超声探头多作探测作用。
它有许多不同的结构,可分直探头(纵波)、斜探头(横波)、表面波探头(表面波)、兰姆波探头(兰姆波)、双探头(一个探头反射、一个探头接收)等。
3.FPGAUART系统组成
FPGAUART由三个子模块组成:
(1)波特率发生器;
(2)接收模块;
(3)发送模块
4.模块设计
4.1.顶层模块
异步收发器的顶层模块由波特率发生器、UART接收器和UART发送器构成。
UART发送器的用途是将准备输出的并行数据按照基本UART帧格式转为TXD信号串行输出。
UART接收器接收RXD串行信号,并将其转化为并行数据。
波特率发生器就是专门产生一个远远高于波特率的本地时钟信号对输入RXD不断采样,使接收器与发送器保持同步
4.1.1顶层模块的电路图
4.1.2顶层模块仿真程序
⏹--文件名:
top.vhd。
⏹--功能:
顶层映射。
⏹libraryIEEE;
⏹useIEEE.STD_LOGIC_1164.ALL;
⏹useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
⏹entitytopis
⏹Port(clk32mhz,reset,rxd,xmit_cmd_p_in:
instd
⏹--总的输入输出信号的定义
⏹rec_ready,txd_out,txd_done_out:
outstd_logic;
⏹txdbuf_in:
instd_logic_vector(7downto0);
--待发送数据输入
⏹rec_buf:
outstd_logic_vector(7downto0));
--接收数据缓冲
⏹endtop;
⏹architectureBehavioraloftopis
⏹componentreciever
⏹Port(bclkr,resetr,rxdr:
instd_logic;
⏹r_ready:
⏹rbuf:
⏹endcomponent;
⏹
componenttransfer
⏹Port(bclkt,resett,xmit_cmd_p:
⏹txdbuf:
⏹txd:
⏹txd_done:
outstd_logic);
⏹componentbaud
⏹Port(clk,resetb:
⏹bclk:
⏹signalb:
std_logic;
⏹begin
⏹u1:
baudportmap(clk=>
clk32mhz,resetb=>
reset,bclk=>
b);
--顶层映射
⏹u2:
reciever
⏹portmap(bclkr=>
b,resetr=>
reset,rxdr=>
rxd,r_ready=>
rec_ready,
⏹rbuf=>
rec_buf);
⏹u3:
transfer
⏹portmap(bclkt=>
b,resett=>
reset,xmit_cmd_p=>
xmit_cmd_p_in,
⏹txdbuf=>
txdbuf_in,txd=>
txd_out,txd_done=>
txd_done_out);
endBehavioral
4.1.3顶层程序的仿真
4.2波特率发生器
波特率发生器实际上就是一个分频器。
可以根据给定的系统时钟频率(晶振时钟)和要求的波特率算出波特率分频因子,算出的波特率分频因子作为分频器的分频数。
波特率分频因子可以根据不同的应用需要更改。
4.2.1波特率发生率程序
--文件名:
baud.vhd.
--功能:
将外部输入的32MHz的信号分成频率为153600Hz的信号。
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
entitybaudis
Port(clk,resetb:
bclk:
endbaud;
architectureBehavioralofbaudis
begin
process(clk,resetb)
variablecnt:
integer;
ifresetb='
1'
thencnt:
=0;
bclk<
='
0'
;
--复位
elsifrising_edge(clk)then
ifcnt>
=208thencnt:
--设置分频系数
elsecnt:
=cnt+1;
endif;
endprocess;
endBehavioral;
4.2.2波特率发生器的仿真图
4.3UART发送器
由于串行数据帧和接收时钟是异步的,由逻辑1转为逻辑0可以被视为一个数据帧的起始位。
然而,为了避免毛刺影响,能够得到正确的起始位信号,必须要求接收到的起始位在波特率时钟采样的过程中至少有一半都是属于逻辑0才可认定接收到的是起始位。
由于内部采样时钟bclk周期(由波特率发生器产生)是发送或接收波特率时钟频率的16倍,所以起始位需要至少8个连续bclk周期的逻辑0被接收到,才认为起始位接收到,接着数据位和奇偶校验位将每隔16个bclk周期被采样一次(即每一个波特率时钟被采样一次)。
如果起始位的确是16个bclk周期长,那么接下来的数据将在每个位的中点处被采样。
4.3.1发送状态机的状态图
发送状态机一共有5个状态
⏹X_IDLE(空闲)
⏹X_START(起始位)
⏹X_WAIT(移位等待)
⏹X_SHIFT(移位)
⏹X_STOP(停止位)
X_IDLE状态
⏹当UART被复位信号复位后,状态机将立刻进入这一状态。
⏹在这个状态下,UART的发送器一直在等待一个数据帧发送命令XMIT_CMD。
⏹XMIT_CMD_P信号是对XMIT_CMD的处理,XMIT_CMD_P是一个短脉冲信号。
这时由于XMIT_CMD是一个外加信号,在FPGA之外,不可能对XMIT_CMD的脉冲宽度进行限制,如果XMIT_CMD有效在UART发完一个数据帧后仍然有效,那么就会错误地被认为,一个新的数据发送命令又到来了,UART发送器就会再次启动UART帧的发送,显然该帧的发送是错误的。
⏹在此对XMIT_CMD进行了脉冲宽度的限定,XMIT_CMD_P就是一个处理后的信号。
⏹当XMIT_CMD_P=‘1’,状态机转入X_START,准备发送起始位。
X_START状态:
⏹在这个状态下,UART的发送器一个位时间宽度的逻辑0信号至TXD,即起始位。
紧接着状态机转入X_WAIT状态。
⏹XCNT16是bclk的计数器
X_WAIT状态
⏹同UART接收状态机中的R_WAIT状态类似。
X_SHIFT状态
⏹当状态机处于这一状态时,实现待发数据的并串转换。
转换完成立即回到X_WAIT状态。
X_STOP
⏹停止位发送状态,当数据帧发送完毕,状态机转入该状态,并发送16个bclk周期的逻辑1信号,即1位停止位。
⏹状态机送完停止位后回到X_IDLE状态,并等待另一个数据帧的发送命令。
4.3.2UART发收器程序设计
entitytransferis
generic(framlent:
integer:
=8);
Port(bclkt,resett,xmit_cmd_p:
--定义输入输出信号
txdbuf:
txd:
txd_done:
endtransfer;
architectureBehavioraloftransferis
typestatesis(x_idle,x_start,x_wait,x_shift,x_stop);
--定义个子状态
signalstate:
states:
=x_idle;
signaltcnt:
process(bclkt,resett,xmit_cmd_p,txdbuf)--主控时序、组合进程
variablexcnt16:
std_logic_vector(4downto0):
="
00000"
--定义中间变量
variablexbitcnt:
variabletxds:
begin
ifresett='
thenstate<
txd_done<
txds:
elsifrising_edge(bclkt)then
casestateis
whenx_idle=>
--状态1,等待数据帧发送命令
ifxmit_cmd_p='
=x_start;
elsestate<
whenx_start=>
--状态2,发送信号至起始位
ifxcnt16>
01111"
=x_wait;
xcnt16:
elsexcnt16:
=xcnt16+1;
state<
whenx_wait=>
--状态3,等待状态
01110"
then
ifxbitcnt=framlentthenstate<
=x_stop;
xbitcnt:
xcnt16:
=x_shift;
whenx_shift=>
txds:
=txdbuf(xbitcnt);
xbitcnt:
=xbitcnt+1;
--状态4,将待发数据进行并串转换
whenx_stop=>
--状态5,停止位发送状态
=xcnt16;
whenothers=>
state<
endcase;
endif;
txd<
=txds;
4.3.3UART发送器程序仿真
4.4UART接收器
只要每隔16个bclk周期输出1个数据即可,次序遵循第1位是起始位,第8位是停止位。
在本设计中没有校验位,但只要改变Generic参数FrameLen,也可以加入校验位,停止位是固定的1位格式。
4.4.1UART接收器的接收状态图
4.4.2UART接收器程序设计
reciever.vhd。
UART接受器。
--说明:
系统由五个状态(r_start,r_center,r_wait,r_sample,r_stop)和两个进
--程构成
--最后修改日期:
2004.3.24。
entityrecieveris
generic(framlenr:
Port(bclkr,resetr,rxdr:
r_ready:
rbuf:
endreciever;
architectureBehavioralofrecieveris
typestatesis(r_start,r_center,r_wait,r_sample,r_stop);
--定义各子状态
=r_start;
signalrxd_sync:
pro1:
process(rxdr)
ifrxdr='
thenrxd_sync<
elserxd_sync<
pro2:
process(bclkr,resetr,rxd_sync)--主控时序、组合进程
variablecount:
std_logic_vector(3downto0);
variablercnt:
variablerbufs:
std_logic_vector(7downto0);
ifresetr='
count:
0000"
elsifrising_edge(bclkr)then
whenr_start=>
--状态1,等待起始位
ifrxd_sync='
=r_center;
r_ready<
rcnt:
r_