基于FPGA的异步收发器程序设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
毕业设计
设计题目基于FPGA的异步收发器设计
学院:物理科学与工程技术学院
专业:电子信息工程
年级:10级
姓名:陈淑珍
指导教师:王永祥
职称:副教授
(2013年 6月)
宜春学院教务处制
宜春学院物理科学与工程技术学院电子信息工程李扬
指导老师:王永祥
摘要:文章简要介绍了UART的基本功能,采用Verilog HDL语言作为硬件功能的描述,运用模块化设计方法设计了通用异步收发器的发送模块、接收模块和波特率发生器。
实现了基于FPGA的UART基本功能设计,并给出了UART的软件编程实例.
关键字:Verilog HDL;FPGA;UART
Based on SCM ultrasonic ranging system Design
( YiChun University Physical science and engineering institute of technology Li Yang)
Abstract: this paper briefly introduces the basic function of UART, the Verilog HDL language as a description of the hardware function, using modular design method to design the general asynchronous transceiver module, receive send the module and baud rate generator. Realized the basic function of UART which based on FPGA , and gives the UART software programming
examples. Key word: Verilog HDL; FPGA; UART; A
引言 (2)
1 . UART简介 (2)
1.1 UART结构 (2)
1.2 UART的帧格式 (2)
1.3 UART的基本原理 (2)
2 UART的设计与实现 (3)
2.1 UART发送器 (3)
2.2 UART接收器 (4)
2.3数码管动态显示 (5)
2.4 波特率发生器 (6)
2.5 UART设计总模块 (6)
3.FPGA UART系统组成 (7)
4.模块设计 (8)
4.1. 顶层模块 (8)
4.2波特率发生器 (10)
4.3 UART发送器 (11)
4.4 UART接收器 (15)
5.结语 (17)
6..参考文献 (18)
1
引言
由于微电子学和计算机科学的迅速发展,给EDA(电子设计自动化)行业带来了巨大的变化。
特别是进入20世纪90年代后,电子系统已经从电路板级系统集成发展成为包括ASIC、FPGA/CPLD和嵌入系统的多种模式。
可以说EDA产业已经成为电子信息类产品的支柱产业。
EDA之所以能蓬勃发展的关键因素之一就是采用了硬件描述语言(HDL)描述电路系统。
就FPGA和CPLD开发而言,比较流行的HDL主要有Verilog HDL、VHDL、ABEL-HDL和 AHDL 等,其中VHDL和Verilog HDL因适合标准化的发展方向而最终成为IEEE标准。
下面的设计就是用VHDL来完成实现的。
1 . UART简介
UART(即Universal Asynchronous Receiver Transmitter 通用异步收发器)是一种应用广泛的短距离串行传输接口。
UART允许在串行链路上进行全双工的通信。
UART主要有由数据总线接口、控制逻辑、波特率发生器、发送部分和接收部分等组成。
功能较为简单,但使用方便、占用资源少,可以灵活地嵌入到各种设计之中。
串行外设用到的RS232-C异步串行接口,一般采用专用的集成电路即UART实现。
使用VHDL将UART的核心功能集成,从而使整个设计更加紧凑、稳定且可靠。
1.1 UART结构
UART主要有由数据总线接口、控制逻辑、波特率发生器、发送部分和接收部分等组成。
1.2 UART的帧格式
UART是异步通信方式,发送方和接收方分别有各自独立的时钟,传输的速度由双方约定,使用起止式异步协议。
起止式异步协议的特点是以每一个字符为单位进行传输,字符之间没有固定的时
数据位停止位
校验位
起始位
图一基本UART帧格式
1.3 UART的基本原理
基本的UART通信只需要两条信号线:RXD和TXD,TXD是UART的发送端,RXD是UART的接收端,接收与发送是全双工工作的。
通过在串行端口上使用调制解调器,串行数据可以通过电话线进行长距离的收发(图二)。
用于收发串行数据的串行通信接口通常称为UART(通用异步收发机)。
UART串行数据传输的示意图如图二所示:
2
RxD
图二串行数据传输
发送数据过程:空闲状态,线路处于高电位,当收到发送数据指令后,拉低线路一个数据位的时间T,接着数据按低位到高位依次发送,数据发送完毕后,接着发送奇偶校验位和停止位(停止位为高电位),一帧数据发送结束。
接收数据过程:空闲状态,线路处于高电位,当检测到线路的下降沿(线路电位由高电位变为低电位)说明线路有数据传输,按照约定的波特率从低位到高位接收数据,数据接收完毕后,接着接收并比较奇偶校验位是否正确,如果正确则通知后续设备准备接收数据或存入缓存。
2 UART的设计与实现
2.1 UART发送器
串行发送数据时每秒钟发送的比特个数称之为波特率,常用串行口波特率有9600、19200、115200等多种。
UART的数据帧的形式分组发送数据,以8
位数据位、1位起始位和1位停止位的帧格式为例,每一个数据帧由10位数据构成,首先是一个低电平起始位来标志帧开始,随后由低至高发送8位数据,最后是1位高电平的停止位。
在逻辑结构上,每秒9600次的发送节拍由波特率发生器产生,它是一个参数化、分频比的整数分频器。
这里使用边沿逻辑,对于分频时钟的占空比并没有要求,所以直接用模n 计算器进行分频。
9600Hz的时钟信号驱动10bit的一位计数器,将数据总线上载入的8bit 数据加上起始位和停止位后由低到高依次移除。
发送逻辑的结构框图如图三所示:
图三发送结构框图
3
4
UART 发送器的发送流程图如图四所示:
图四
UART 发送器的发送流程图
2.2 UART 接收器
UART 是异步传输接口,没有时钟信号同步。
所以接收端需要进行过采样来保证数据的接收,RS232标准规定的过采样率是以发送波特率的16倍时钟对数据进行检测。
UART 接收逻辑通过检测TxD 上起始位的下降沿作为帧同步标准,这样就相当于把每个位分成了16份,为了避免干扰取16份中位于中部的6、7、8三个采样进行判别,以它们中两个或两个以上相同的值作为采样结果。
接收器结构框图如图五所示:
图五 接收结构框图
接收器的接收原理流程图如图六所示:
c、b、
个选通
个选通
图七共阳数码管及其电路
4位数码扫描电路的示意图如图八所示:
5
6
a
g
图八 4位数码扫描电路
2.4 波特率发生器
UART 的接收和发送是按照相同的波特率进行收发的。
波特率发生器产生的时钟频率不是波特率时钟频率,而是波特率时钟频率的16倍,目的是为在接收时进行精确地采样,以提出异步的串行数据。
2.5 UART 设计总模块
将发送器和接收器模块组装起来,就能较容易地实现通用异步收发器总模块,而且硬件实现不需要很多资源,尤其能较灵活地嵌入到FPGA/CPLD 的开发中。
UART 设计流程图如图九所示:
以超声波作为检测手段,必须产生超声波和接收超声波。
完成这种功能的装置就是超声波传感器,习惯上称为超声换能器,或者超声探头。
超声波探头主要由压电晶片组成,既可以发射超声波,也可以接收超声波。
小功率超声探头多作探测作用。
它有许多不同的结构,可分直探头(纵波)、斜探头(横波)、表面波探头(表面波)、兰姆波探头(兰姆波)、双探头(一个探头反射、一个探头接收)等。
7
初始化分频进程响铃进程按键检测进程加一按键
减一按键
发送按键加1
减1发送数据
接收数据
译码输出响铃引脚绑定引脚测试结束
N
Y
Y
N
Y
N
接收按键
3.FPGA UART 系统组成
FPGA UART 由三个子模块组成:
(1)波特率发生器;
(2)接收模块;
(3)发送模块
4.模块设计
4.1. 顶层模块
异步收发器的顶层模块由波特率发生器、UART接收器和UART发送器构成。
UART发送器的用途是将准备输出的并行数据按照基本UART帧格式转为TXD信号串行输出。
UART接收器接收RXD串行信号,并将其转化为并行数据。
波特率发生器就是专门产生一个远远高于波特率的本地时钟信号对输入RXD不断采样,使接收器与发送器保持同步
4.1.1顶层模块的电路图
4.1.2顶层模块仿真程序
--文件名:top.vhd。
8
⏹--功能:顶层映射。
⏹library IEEE;
⏹use IEEE.STD_LOGIC_1164.ALL;
⏹use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
⏹entity top is
⏹Port (clk32mhz,reset,rxd,xmit_cmd_p_in:in std
⏹--总的输入输出信号的定义
⏹ rec_ready,txd_out,txd_done_out:out std_logic;
⏹txdbuf_in:in std_logic_vector(7 downto 0); --待发送数据输入⏹rec_buf:out std_logic_vector(7 downto 0)); --接收数据缓冲⏹end top;
⏹architecture Behavioral of top is
⏹component reciever
⏹ Port (bclkr,resetr,rxdr:in std_logic;
⏹ r_ready:out std_logic;
⏹ rbuf:out std_logic_vector(7 downto 0));
⏹end component;
⏹component transfer
⏹ Port (bclkt,resett,xmit_cmd_p:in std_logic;
⏹ txdbuf:in std_logic_vector(7 downto 0);
⏹ txd:out std_logic;
⏹ txd_done:out std_logic);
⏹end component;
⏹component baud
⏹ Port (clk,resetb:in std_logic;
⏹ bclk:out std_logic);
⏹end component;
⏹signal b:std_logic;
⏹begin
9
⏹u1:baud port map(clk=>clk32mhz,resetb=>reset,bclk=>b); --顶层映射
⏹u2:reciever
⏹port map(bclkr=>b,resetr=>reset,rxdr=>rxd,r_ready=>rec_ready,
⏹ rbuf=>rec_buf);
⏹u3:transfer
⏹port map(bclkt=>b,resett=>reset,xmit_cmd_p=>xmit_cmd_p_in,
⏹ txdbuf=>txdbuf_in,txd=>txd_out,txd_done=>txd_done_out); end Behavioral
4.1.3顶层程序的仿真
4.2波特率发生器
波特率发生器实际上就是一个分频器。
可以根据给定的系统时钟频率(晶振时钟)和要求的波特率算出波特率分频因子,算出的波特率分频因子作为分频器的分频数。
波特率分频因子可以根据不同的应用需要更改。
4.2.1波特率发生率程序
--文件名:baud.vhd.
--功能:将外部输入的32MHz的信号分成频率为153600Hz的信号。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
10
entity baud is
Port (clk,resetb:in std_logic;
bclk:out std_logic);
end baud;
architecture Behavioral of baud is
begin
process(clk,resetb)
variable cnt:integer;
begin
if resetb='1' then cnt:=0; bclk<='0'; --复位
elsif rising_edge(clk) then
if cnt>=208 then cnt:=0; bclk<='1'; --设置分频系数 else cnt:=cnt+1; bclk<='0';
end if;
end if;
end process;
end Behavioral;
4.2.2波特率发生器的仿真图
4.3 UART发送器
由于串行数据帧和接收时钟是异步的,由逻辑1转为逻辑0可以被视为一个数据帧的起始位。
然而,为了避免毛刺影响,能够得到正确的起始位信号,必须要求接收到的起始位在波特率时钟采样的过程中至少有一半都是属于逻辑0才可认定接收到的是起始位。
由于内部采样时钟bclk周期(由波特率发生器产生)是发送或接收波特率时钟频率的16倍,所以起始位需要至少8个连续bclk周期的逻辑0被接收到,才认为起始位接收到,接着数据位和奇偶校验位将每隔16个bclk周期被采样一次(即每一个波特率时钟被采样一次)。
如果起始位的确是16个bclk周期长,那么接下来的数据将在每个位的中点处被采样。
4.3.1发送状态机的状态图
11
发送状态机一共有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状态
12
⏹同UART接收状态机中的R_WAIT状态类似。
X_SHIFT状态
⏹当状态机处于这一状态时,实现待发数据的并串转换。
转换完成立即回到X_WAIT
状态。
X_STOP
⏹停止位发送状态,当数据帧发送完毕,状态机转入该状态,并发送16个bclk周期
的逻辑1信号,即1位停止位。
⏹状态机送完停止位后回到X_IDLE状态,并等待另一个数据帧的发送命令。
4.3.2 UART发收器程序设计
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity transfer is
generic(framlent:integer:=8);
Port (bclkt,resett,xmit_cmd_p:in std_logic; --定义输入输出信号txdbuf:in std_logic_vector(7 downto 0);
txd:out std_logic;
txd_done:out std_logic);
end transfer;
architecture Behavioral of transfer is
type states is (x_idle, x_start, x_wait, x_shift, x_stop); --定义个子状态
signal state:states:=x_idle;
signal tcnt:integer:=0;
begin
process(bclkt,resett,xmit_cmd_p,txdbuf) --主控时序、组合进程variable xcnt16:std_logic_vector(4 downto 0):="00000"; --定义中间变量
variable xbitcnt:integer:=0;
variable txds:std_logic;
begin
if resett='1' then state<=x_idle; txd_done<='0'; txds:='1'; --复位
elsif rising_edge(bclkt) then
case state is
when x_idle=> --状态1,等待数据帧发送命令
13
if xmit_cmd_p='1' then state<=x_start; txd_done<='0';
else state<=x_idle;
end if;
when x_start=> --状态2,发送信号至起始位if xcnt16>="01111" then state<=x_wait; xcnt16:="00000";
else xcnt16:=xcnt16+1; txds:='0'; state<=x_start;
end if;
when x_wait=> --状态3,等待状态if xcnt16>="01110" then
if xbitcnt=framlent then state<=x_stop;xbitcnt:=0;xcnt16:="00000";
else state<=x_shift;
end if;
else xcnt16:=xcnt16+1; state<=x_wait;
end if;
when x_shift=>txds:=txdbuf(xbitcnt); xbitcnt:=xbitcnt+1; state<=x_wait;
--状态4,将待发数据进行并串转换
when x_stop=> --状态5,停止位发送状态if xcnt16>="01111" then
if xmit_cmd_p='0' then state<=x_idle; xcnt16:="00000";
else xcnt16:=xcnt16; state<=x_stop;
end if; txd_done<='1';
else xcnt16:=xcnt16+1; txds:='1'; state<=x_stop;
end if;
when others=>state<=x_idle;
end case;
end if;
txd<=txds;
end process;
end Behavioral;
4.3.3 UART发送器程序仿真
14
15
4.4 UART 接收器
只要每隔16个bclk 周期输出1个数据即可,次序遵循第1位是起始位,第8位是停止位。
在本设计中没有校验位,但只要改变Generic 参数FrameLen ,也可以加入校验位,停止位是固定的1位格式。
4.4.1 UART 接收器的接收状态图
4.4.2 UART 接收器程序设计
--文件名:reciever.vhd 。
--功能:UART
接受器。
--说明:系统由五个状态(r_start,r_center,r_wait,r_sample,r_stop )和两个进
--程构成
--最后修改日期:2004.3.24。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity reciever is
generic(framlenr:integer:=8);
Port (bclkr,resetr,rxdr:in std_logic; --定义输入输出信号r_ready:out std_logic;
rbuf:out std_logic_vector(7 downto 0));
end reciever;
architecture Behavioral of reciever is
type states is (r_start,r_center,r_wait,r_sample,r_stop); --定义各子状态
signal state:states:=r_start;
signal rxd_sync:std_logic;
begin
pro1:process(rxdr)
begin
if rxdr='0' then rxd_sync<='0';
else rxd_sync<='1';
end if;
end process;
pro2:process(bclkr,resetr,rxd_sync) --主控时序、组合进程variable count:std_logic_vector(3 downto 0); --定义中间变量variable rcnt:integer:=0;
variable rbufs:std_logic_vector(7 downto 0);
begin
if resetr='1' then 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_ready<='0'; rcnt:=0;
else state<=r_start; r_ready<='0';
end if;
when r_center=> --状态2,求出每位的中点if rxd_sync='0' then
if count="0100" then state<=r_wait; count:="0000";
16
else count:=count+1; state<=r_center;
end if;
else state<=r_start;
end if;
when r_wait=> --状态3,等待状态if count>="1110" then count:="0000";
if rcnt=framlenr then state<=r_stop;
else state<=r_sample;
end if;
else count:=count+1; state<=r_wait;
end if;
when r_sample=>rbufs(rcnt):=rxd_sync; rcnt:=rcnt+1;
state<=r_wait; --状态4,数据位采样检测when r_stop=>r_ready<='1'; rbuf<=rbufs;
state<=r_start; --状态4,输出帧接收完毕信号when others=>state<=r_start;
end case;
end if;
end process;
end Behavioral;
4.42 UART接收器仿真图形
5.结语
UATR是广泛使用的串行数据通信电路,因其要求的传输线少,可靠性高,传输距离远,所以系统间互联常采用异步串行通信接口方式。
本文用Verilog HDL语言,结合有限状
17
态机的设计方法实现了UART的功能,将其核心功能集成到FPGA上,使整体设计紧凑、小巧,实现的UART功能稳定、可靠。
通过本次课程设计,系统学习了应用EDA的VHDL语言设计、仿真与实现硬件的方法。
在本次的设计中通过对波特率发生器、发送器和接收器模块的设计与仿真,能实现通用异步收发器总模块。
也非常感谢王老师的指导和同学的帮助,让我受益匪浅,也明白动手能力的重要性,当然也要学好理论知识。
6..参考文献
[1] 1].郑亚民,董晓舟.VHDL与VerilogHDL比较学习及建模指导【M】.北京:国防工业出版社,2008.6
[2] 潘松,黄继业. EDA技术实验教程(第二版)【M】.北京:科学出版社,2005
[3] 江国强. 数字系统的VHDL设计【M】.北京:机械工业出版社,2008.10
[4] 李莉,路而红. 电子设计自动化(EDA)课程设计与项目实例【M】.北京:中国电力出版
社。
[5] 付家才.EDA原理与应用(第二版)【M】.北京:化学工业出版社,2005
[6].潘松.黄继业.EDA技术与VHDL.【M】.北京:清华大学出版社,2005.
[7].单片机软件UART(通用异步接收/发送装置)的设计资料.电子电路网[引用日期2012-05-31]
[8]杨跃.FPGA应用开发实战技巧精粹[M].北京:人民邮电出版社,2009.
18
宜春学院物理科学与工程技术学院毕业设计
19
19。