基于FPGA的UART串口接收模块设计.doc
- 格式:doc
- 大小:314.00 KB
- 文档页数:6
通用异步接收发送器UART (Universal Asyn2chronousReceiver and Transmitter )能够在串行方式下发送和接收数据,数据传送方式只需要一对线路就能实现远距离数据通信。
其以资源简单、传输距离远、易于实现等特点成为各种处理器的标准集成外设之一。
在实际的应用设计中,经常要用到UART 的多个主要功能,常用的标准通信波特率有9600bps 、15200bps 等。
本文使用Verilog HDL 语言将UART 器件的核心功能描述成一个异步串行数字收发模块,并且在Modelsim 上实现了其功能仿真。
1UART 原理及设计简介UART 的全称是通用异步收发器(Universal Asynchronous Receiver /Transmitter ),是实现设备之间低速数据通信的标准协议。
“异步”指不需要额外的时钟线进行数据的同步传输,是一种串行总线接口,只需占用2根线就可以完成数据的收发(1根接收数据,1根发送数据)。
UART 一帧由起始位、数据位、校验位和停止位组成。
数据逐位传输,示意图如图1所示。
异步通信要求发送的每一帧数据都必须按照图1给定的UART 格式进行格式化。
一帧数据由4部分组成,首先是起始位“0”;接着是发送的数据(这里采用8位);然后是可选的检验位来判断接收数据有无错误(这里选用奇检验);最后是停止位“1”(停止位可以为1位、1.5位和2位)。
若线路上没有传输的数据,则线路始终保持为“1”,即空闲。
接收端不断检测线路状态,非接收状态下如果检测到线路由“1”变为“0”(“0”至少保持8个内部时钟周期),则认为有发送数据需接收,接收器进入接收阶段。
UART 模块总结构如图2所示。
首先,发送时按照UART 帧格式,由发送写信号启动发送波特率发生器,先发送一位起始位,然后由发送波特率发生器时钟启动发送移位寄存器,将发送数据存入发送移位寄存器,并将发送一位寄存器中的数据发送,同时由发送波特率发生器时钟启动发送数据计数器,当计数器计数到第10位时,产生奇偶校验位,此时发送奇偶校验位,计数到第11位时,发送停止位,同时产生发送完成指示信号。
基于FPGA的UART设计毕业设计此文档为word格式,下载后可随意编辑摘要通用串口是远程通信接口,在数字系统使用很普遍,是一个很重要的部件。
本论文使用Verilog HDL 语言描述硬件功能,利用QuartusII 5.0在 FPGA 芯片上的综合描述,采用模块化设计方法设计UART(通用异步收发器)的各个模块。
其中包括波特发生器,程序控制器,UART数据接收器和UART数据发送器,本文采用的外部时钟为48MHZ,波特率为9600。
在QuartusII 5.0和Modelsim6.0环境下进行设计、编译和仿真。
最后的程序编译仿真表明系统数据完全正确。
关键词:VerilogHDL; UART;帧格式;FPGA;AbstractAbstractIn this paper, the use of hardware description languages Verilog VHDL function, the use of Altera's FPGA chips, the design of modular design method of UART (Universal Asynchronous Receiver Transmitter) of each module, including Porter, generators, process controllers, UART receiver data and the UART transmitter data. QuartusII 5.0 and Modelsim6.0 in environment design, compilation, simulation and downloading. Finally, simulation results show that the procedures for compiling data entirely correct.Key words: VerilogHDL; UART; frame format; FPGA目录第一章绪论 (1)1.1引言 (1)1.2 什么是Verilog HDL? (1)1.3 历史 (2)1.4 主要能力 (2)1.5 模块 (4)1.6 数据流描述方式 (5)第二章片上系统SOC与FPGA的现状 (6)2.1 片上系统SOC介绍 (6)2.2 FPGA技术介绍 (6)2.3 FPGA 核心设计流程 (7)2.3.1 设计流程图 (7)2.3.2关键步骤的实现 (8)2.3.2.1 功能仿真 (8)2.3.2.2 逻辑综合 (9)2.3.2.3 前仿真 (9)2.3.2.4 布局布线 (150)2.3.2.5 后仿真(时序仿真) (161)第三章UART设计 (172)3.1 UART的帧格式 (172)3.2 UART模块 (183)3.2.1主要引脚功能介绍 (183)3.2.2UART主体程序 (194)3.3UART发送模块 (205)3.3.1UART的数据发送服务 (205)3.3.2UART的数据发送操作 (16)3.3.3UART的数据发送模块程序 (17)3.3.4UART的数据发送模块程序仿真图 (250)3.4UART接收模块 (261)3.4.1UART数据接收服务 (261)3.4.2UART数据接收操作 (272)3.4.3UART的数据接收模块程序 (272)3.4.4UART的数据接收模块程序功能仿真图 (305)3.5UART控制器 (26)3.5.1UART控制器服务 (26)3.5.2UART控制器模块程序 (3126)3.5.3UART控制器模块程序仿真图 (28)3.6UART波特发生器 (29)3.6.1UART波特发生器服务 (29)3.6.2UART波特发生器模块程序 (29)3.6.13UART波特发生器程序仿真图 (350)结论 (361)参考文献 (372)致谢 (383)附录 (394)外文资料原文 (405)译文 (483)绪论绪论1.1引言21世纪,电子技术迅猛发展,高新技术日新月异。
基于FPGA 的UART 模块的设计杨宗国,李艳萍(太原理工大学信息工程学院 山西太原 030024)摘 要:为了实现计算机与基于F PGA 图像处理系统的数据通信,这里用FP GA 设计了一款简易通用异步收发器(U A RT )模块。
U A RT 的主要功能是实现数据处理模块与RS 232串行数据接口之间的数据转换,即将送过来的并行数据转换为输出的串行数据流,由数据处理模块传送给计算机,还可以将串行数据转换为并行数据,供数据处理模块使用。
为了简化电路设计,减少电路面积,这里省略了U A RT 系统中的奇偶检验模块。
关键词:F PG A;V HDL ;串/并转换;并/串转换;U AR T中图分类号:T N971 文献标识码:B 文章编号:1004-373X(2009)02-019-04Design of UART Module Based on FPGAYA N G Zo ng guo,L I Yanping(Colleg e o f Info rmat i o n Engine ering,Ta i y uan U niversity of T echnolo gy ,T aiyuan,030024,Chi na)Abstract :To realize data communication between computer and FPGA -based imag e processing system,a simple U niversal Asyn -chronous Receiver Transmitter (U ART )is designed by F PGA.T he main function of UA RT is to realize data conversion between data disposal module and RS 232serial port,that is to say,parallel data trinsmitted by data disposal module is converted into serial data flow,then it is transmitted into computer,the serial data is converted into par allel data for the usage o f data disposal module.For pred-i g esting circuit design and reducing electrocircuit proportio n,par ity check module is not needed.Keywords :FP GA ;V H DL ;S/P conversion;P/S conversio n;U A RT收稿日期:2008-05-300 引 言在计算机的数据通信中,外设一般不能与计算机直接相连,它们之间的信息交换主要存在以下问题:(1)速度不匹配。
编号基于FPGA的UART模块设计与实现Design and Realization of UART based onFPGA学生姓名周大勇专业控制科学与工程学号S*********指导教师杨晓慧学院电子信息工程学院二〇一三年六月摘要UART因其可靠性高,传输距离远,线路简单,同时UART作为RS232协议的控制接口,从而成为比较广泛的串行数据通信电路,而现在大部分集成电路通信用的UART芯片,存在成本高,电路复杂,移植性较差等缺点,本文提出了一种将UART的功能集成在FPGA芯片中,可使整个系统更为灵活、紧凑,减小整个电路的体积,提高系统的可靠性和稳定性。
本模块功能全部基于verilogHDL硬件描述语言。
关键词:FPGA, UART ,verilogHDL ,RS232ABSTRACTUART, because of its high reliability, long transmission distance and the simple line, moreover mainly used in communication between device with RS232 interface. Thus it is becoming more extensive serial data communication circuit. But now most of the integrated UART chips used in communications, have faults of high cost and poor portability. The circuit of the chip is complex. This paper presents a method that UART function will be integrated in FPGA chip, It can makesystem more compact, flexible, reliable and stable. All functions of module are based on verilogHDL hardware description language.Keywords:FPGA, UART, verilogHDL, RS232目录摘要 (I)ABSTRACT .................................................................................................................................. I I 目录...................................................................................................................................... I II 第一章绪论. (1)第二章UART 简介 (2)第三章UART功能设计 (3)3.1 波特率发生模块 (3)3.2 波特率接收模块 (5)3.3 UART发送模块 (8)第四章顶层电路及实验数据 (11)第五章结论 (12)致谢 (13)参考文献 (14)第一章绪论通用异步收发器(universal asynchronous receiver transmitter, UART)尽管自20世纪70年代就已出现,但因其简单可靠,目前仍是一种使用广泛的串行通信接口。
基于FPGA 的UART 设计与实现在光栅尺信号采集电路中,使用了FPGA 完成对光栅尺脉冲的滤波、细分、辩向及计数,计数值最终由串行通信接口传送至上位机。
如果使用专用UART 芯片或利用单片机的串行通信接口实现数据传输,一是会造成成本增加,二是会造成电路面积和功耗更大。
在FPGA 中实现UART 模块,完成串口通信的功能,能够克服使用专用芯片或单片机完成数据通信的缺点,使整个系统更加灵活,使系统能够根据需要进行串口功能的升级、扩充和裁剪。
根据光栅尺信号采集电路的要求,串口主要需要实现数据的接收和发送,其主要过程为,当串口接收到上位机发送的一个字符‘s ’时,将24位的计数值通过串口分3次发送至上位机。
因此,本文所设计的UART 模块主要包括三个部分:波特率发生器模块、接收模块、发送模块。
通用异步接收发送器(UART )是广泛使用的串行数据传输协议。
基本的UART 通信只需要两条信号线(RXD ,TXD )就可以完成数据的互相通信,接收与发送是全双工形式,TXD 是发送端,RXD 是接收端。
UART 数据传输的格式如图1所示,本文是根据图1所示的数据帧格式进行UART 模块的设计。
起始位1位停止位D1D3D2D4D5D6D7D08 图1. UART 数据帧格式1. 16倍波特率发生器模块16倍波特率发生器模块主要产生UART 通信时所需要的时钟(16倍的波特率)。
16倍波特率发生器模块主要使用计数器实现分频,计数器由系统时钟驱动,当计数值等于某固定数值(cnter )的一半时,16倍波特率发生器输出高电平,当计数值小于cnter 且大于cnter/2时,16倍波特率发生器输出低电平,当计数值大于cnter 时,将计数器清零。
光栅尺信号采集电路所提供的系统时钟频率为20MHz ,因此,cnter=20MHz/(9600Bps ×16)=136。
16倍波特率发生器模块主要代码如下:module m16btl(clk, clk16x);input clk;output clk16x;reg clk16x;reg [11:0] cnter;always @(posedge clk)beginif (cnter >= 136)cnter <= 0;elsebeginif (cnter <= 68)clk16x <= 1;elseclk16x <= 0;cnter <= cnter + 1;endendendmodule其中clk为系统时钟输入端,clk16x为16倍波特率信号输出端。
一、题目基于FPGA的UART设计二、设计要求1)支持数据格式:起始位(1bit)+数据(8bit)+奇偶校验位(1bit)+终止位(1bit)2)奇/偶校验可配置3)可配置支持115200以下的常见波特率4)支持115200以下的波特率自适应,自适应过程如下:a.复位后,UART首先接收输入,不断自动调整波特率,直到以一定波特率正确连续接收到3个bytes的0x55b.接着UART以此波特率连续发送3个bytes 0xaac.之后两端以此波特率进行通信d.波特率自适应只在电路复位后进行一次,如欲再次自适应波特率应对电路再次复位e.波特率自适应过程中不能对UART的波特率作任何设置,自适应完成后可以对波特率作设置5)自动计算校验位用于发送数据;对接收到的校验位和数据进行校验,发现错误应设置错误标志,并丢弃数据6)对接收不正常数据(如无终止位、无校验位、数据位数不正确等)应能自动识别并设置错误标志、丢弃三、UART 的工作原理异步通信时,UART发送/接收数据的传输格式如图1所示,一个字符单位由开始位、数据位、停止位组成。
异步通信的一帧传输经历以下步骤:(1)无传输。
发送方连续发送信号,处于信息“1”状态。
(2)起始传输。
发送方在任何时刻将传号变成空号,即“1”跳变到“0”,并持续1位时间表明发送方开始传输数据。
而同时,接收方收到空号后,开始与发送方同步,并期望收到随后的数据。
(3)奇偶传输。
数据传输之后是可供选择的奇偶位发送或接收。
(4)停止传输。
最后是发送或接收的停止位,其状态恒为“1”。
发送或接收一个完整的字节信息,首先是一个作为起始位的逻辑“0”位,接着是8个数据位,然后是停止位逻辑“1”位,数据线空闲时为高或“1”状态。
起始位和停止位的作用是使接收器能把局部时钟与每个新开始接收的字符再同步。
异步通信没有可参照的时钟信号,发送器可以随时发送数据,任何时刻串行数据到来时,接收器必须准确地发现起始位下降沿的出现时间,从而正确采样数据。
UART串口接收模块设计实验目标:实现FPGA接收其他设备通过UART协议发送过来的数据知识点:1、U RAT通信协议工业环境下数据接收实现。
2、I n system sources and probes editor ISSP)调试工具的使用。
UART发送端发送一个字节数据时序图:采集中间时刻时的数据即可,如下图所示但是在工业应用中,往往有非常强的电磁干扰,只采样一次就作为该数据的电平判定,是不保险的,有可能恰好采集到被干扰的信号而导致结果出错,因此需要使用多次采样求概率的方式进行。
以下为改进型的单bit数据接收方式示意图:BI + 1 - 1丨丨「i |丨11 口「「「i「11 丨im i [1 2 3 4 5 6 7 8 9 10 11 12 1314 1516在这张图中,将每一位数据又平均分成了16小段,对于Bit_x这一位数据,考虑到数据在刚刚发生变化和即将发生变化的这一时期,数据极有可能不稳定的(用红色标出的两段),在这两个时间段采集数据,很有可能得到错误的结果,因此这两段时间的电平无效,采集时直接忽略。
而中间这一时间段(用绿色标出),数据本身是比较稳定的,一般都代表了正确的结果。
但是也不排除该段数据受强 电磁干扰而出现错误的电平脉冲, 因此对这一段电平,进行多次采样,并求高低 电平发生的概率,6次采集结果中,取出现次数多的电平作为采样结果。
例如, 采样6次的结果分别为1/1/1/1/0/1/,贝U 取电平结果为1,若为0/0/1/0/0/0,,贝U 取 电平结果为0,当6次采样结果中1和0各占一半(各3次),则可判断当前通 信线路环境非常恶劣,数据不具有可靠性。
串口发送模块包含两个主要组件:1、 起始位检测进程(低电平,下降沿)2、 波特率产生模块3、 数据接收模块串口接收模块整体结构图:Data_Byte[7:0] Rx_Done=Rst n波特率时钟计算:---------------- ►Baud_Set[2:0] ----- -------- ►ClkModelsim 仿真图:• 在testbench 文件中我们为设计输入了假定的信号, 在仿真图中我们可以看到 data_byte_r 在Rx_done 标志位产生的时候成功的将仿真数据 data_byte_t 接收到其中。
一基于FPGA的UART通信模块设计1. UART简介(1)UART(Universal Asynchronous Receiver Transmitter通用异步收发器)是一种应用广泛的短距离串行传输接口。
常常用于短距离、低速、低成本的通讯中。
8250、8251、NS16450等芯片都是常见的UART器件。
(2)基本的UART通信只需要两条信号线(RXD、TXD)就可以完成数据的相互通信,接收与发送是全双工形式。
TXD是UART发送端,为输出;RXD是UART接收端,为输入。
2. UART的基本特点是:(1) 在信号线上共有两种状态,可分别用逻辑1(高电平)和逻辑0(低电平)来区分。
在发送器空闲时,数据线应该保持在逻辑高电平状态。
(2) 起始位(Start Bit):发送器是通过发送起始位而开始一个字符传送,起始位使数据线处于逻辑0状态,提示接受器数据传输即将开始。
(3) 数据位(Data Bits):起始位之后就是传送数据位。
数据位一般为8位一个字节的数据(也有6位、7位的情况),低位(LSB)在前,高位(MSB)在后。
(4) 校验位(parity Bit):可以认为是一个特殊的数据位。
校验位一般用来判断接收的数据位有无错误,一般是奇偶校验。
在使用中,该位常常取消。
(5) 停止位:停止位在最后,用以标志一个字符传送的结束,它对应于逻辑1状态。
(6) 位时间:即每个位的时间宽度。
起始位、数据位、校验位的位宽度是一致的,停止位有0.5位、1位、1.5位格式,一般为1位。
(7) 帧:从起始位开始到停止位结束的时间间隔称之为一帧。
(8) 波特率:UART的传送速率,用于说明数据传送的快慢。
在串行通信中,数据是按位进行传送的,因此传送速率用每秒钟传送数据位的数目来表示,称之为波特率。
如波特率9600=9600bps(位/秒)。
3. FPGA UART系统组成FPGA UART由三个子模块组成:波特率发生器;接收模块;发送模块;包含四个模块:顶层模块,波特率发生器,UART接收器,UART发送器(1)顶层模块(1)异步收发器的顶层模块由波特率发生器、UART接收器和UART发送器构成。
FPGA的UART完整设计FPGA(现场可编程门阵列)是一种可编程逻辑设备,可以用于实现各种数字系统。
其中一个常见的应用是实现串行通信接口,如UART(通用异步收发器)。
UART是一种用于串行数据传输的通信协议,常用于连接计算机和外部设备(如传感器、显示器等)。
UART通信有两个关键部分:发送和接收。
在FPGA中,我们可以使用电平转换器、计数器和状态机等模块来设计和实现UART。
首先,我们需要设计发送模块。
发送模块的任务是将数据从FPGA发送到外部设备。
以下是发送模块的设计步骤:1.配置串行通信参数:确定波特率、校验位和停止位等参数。
2.设计数据缓冲区:创建一个FIFO(先进先出)缓冲区,用于存储要发送的数据。
3.生成波特率时钟:使用计数器和时钟分频器来生成适当速率的时钟信号。
4.串行化数据:将数据从缓冲区读取,并将其转换为串行比特流。
5.加入校验位和停止位:根据配置的参数,在数据的末尾添加校验位和停止位。
6.发送数据:将串行的比特流发送到外部设备。
接下来,我们需要设计接收模块。
接收模块的任务是从外部设备接收数据并传输到FPGA。
以下是接收模块的设计步骤:1.配置串行通信参数:确定波特率、校验位和停止位等参数,与发送模块保持一致。
2.生成波特率时钟:使用计数器和时钟分频器来生成适当速率的时钟信号。
3.接收数据:从外部设备接收串行比特流。
4.分析校验位和停止位:验证接收到的数据的校验位和停止位是否正确。
5.并行化数据:将串行比特流转换为并行数据,并存储到接收缓冲区中。
6.处理接收到的数据:根据串行通信协议,处理接收到的数据。
在设计中,需要考虑以下事项:1.时钟同步:确保发送端和接收端使用相同的时钟源,并进行合适的时序调整,以保持数据的稳定性和正确性。
2.缓冲区管理:使用FIFO缓冲区来处理发送和接收的数据,以防止数据丢失和冲突。
3.错误处理:根据串行通信协议,实现适当的错误检测和纠正机制,以确保数据的完整性和正确性。
基于FPGA的UART接口模块设计
UART(UniversalAnynchronousReceiverTransmitter,通用异步接收发送器)是广泛应用的串行数据传输协议之一,其应用范围遍及计算机外设、工控自动化等场合。
虽然USB传输协议比UART协议有更高的性能,但电路复杂开发难度大,并且大多数的微处理器只集成了UART,因此UART仍然是目前数字系统之间进行串行通信的主要协议。
随着FPGA的广泛应用,经常需要FPGA与其他数字系统进行串行通信,专用的UART集成电路如8250,8251等是比较复杂的,因为专用的UART集成电路既要考虑异步的收发功能,又要兼容RS232接口设计,在实际应用中,往往只需要用到UART的基本功能,使用专用芯片会造成资源浪费和成本提高。
可以将所需要的UART功能集成到FPGA内部,实现FPGA 与其他数字系统的直接通信,从而简化了整个系统电路,提高了可靠性、稳定性和灵活性。
1 UART简介
基本的UART通信只需要两条信号线(RXD,TXD)就可以完成数据的相互通信,接收与发送是全双工形式,其中TXD是UART发送端,RXD。
基于FPGA的UART通信接口电路设计张蕾【摘要】随着煤矿设备自动化程度的不断提高,对信号的传输也提出了越来越高的要求.本文设计了一种基于现场可编程门阵列(field programmable gate array,FPGA)的RS232接口电路.首先,分析了FPGA在设计通用串行收发器(universal asynchronous receiver and transmitter,UART)接口电路中的优势.该接口电路主要分为UART接收子模块、波特率发生器、先进先出(first in first out,FIFO)模块、UART发送子模块、通信校验模块等.然后,基于Xilinx公司的FPGA平台,使用Verilog HDL语言编写并实现了整个系统,给出了完整的电路结构框图及实验结果.实验结果验证了所设计RS232接口电路的有效性.【期刊名称】《山西焦煤科技》【年(卷),期】2011(035)008【总页数】3页(P18-20)【关键词】通用串行收发器(UART);可编程门阵列(FPGA);过采样;先进先出(FIFO)【作者】张蕾【作者单位】山西煤炭进出口集团有限公司,山西太原 030006【正文语种】中文【中图分类】TD65目前,我国的煤矿设备自动化程度不断提高,井下作业对信号传输的要求也愈趋严格。
本文研究的通用串行收发器(universal asynchronous receiver and transmitter,UART)可通过串行线传输并行数据,其本质功能是作为控制器和串行设备间的编码转换装置,在基于RS232、RS485等标准协议的通信系统中广泛应用[1-3],非常适合矿井通信系统。
常用的单片机、DSP控制器等一般都集成有专用的UART外设,极大地方便了基于RS232等协议的通信系统设计。
但这类预先固化好的系统也存在一定的不足,如工作模式不够灵活,数据位数固定、通信的波特率一般限制在几个固定的数值,可扩展性较小。
FPGA实现UART接收与发送//************************************************************* **//Uart_top mode: This module is to recieve data , then transfer data recieved , baud rate 9600//Author: LBQ// HIstory//Nov/24/2014: Inital release//************************************************************* **module uart_top(clk,n_rst,rxd,txd);input clk;input n_rst;input rxd;output txd;///////////////////inner wire and reg ////////////wire tra_en;wire [7:0] rxd_data;uart_rec my_uart_rec( .clk(clk),.n_rst(n_rst),.rxd(rxd),.rxd_data(rxd_data),.tra_en(tra_en));uart_tra my_uart_tra( .clk(clk),.n_rst(n_rst),.txd_data(rxd_data),.tra_en(tra_en),.txd(txd));endmodule//************************************************************* **//Uart_rec mode: This module is to recieve data , baud rate 9600//Author: LBQ// HIstory//Nov/24/2014: Inital release//************************************************************* **module uart_rec(clk,n_rst,rxd,rxd_data,tra_en);input clk,n_rst;// input clock and low resetinput rxd; //UART receiveroutput[7:0] rxd_data;//output recstart1;//output recstart2;output tra_en;reg tra_en;////////////////////innerreg///////////////////////////////////////////////////////////reg[15:0] div_reg_baud8;////counter for division , 8 baund ratereg[7:0] state_tras;//reg[7:0] state_rec;//reg clkbaud8x;// 8 baund rate clockreg recstart1;reg recstart2;reg tra_star;reg rxd_reg1;//reg rxd_reg2;//reg recstart;//reg rxd_buf_data_vaild;reg txd_reg;//reg[7:0] rxd_buf;//reg[7:0] txd_buf;//reg count_delay_tra_en;/////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////===parameter=====//////////// ////////////////////////parameter div_reg_baud8_par=16'h001; // *************** lbq for simulation//parameter div_reg_baud_par=16'h008; // *************** lbq for simulationparameter div_reg_baud8_par=16'h145;//////9600*8 (CLK 50M)//parameter div_reg_baud_par=16'ha2C;//////9600 (CLK 50M)///////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// ////////assign txd=txd_reg;assign rxd_data=rxd_buf;/////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// //////////always@(posedge clk)//get 8 baund rate clockbeginif(!n_rst)begindiv_reg_baud8<=0;clkbaud8x<=0;endelsebeginif(div_reg_baud8==div_reg_baud8_par-1)begindiv_reg_baud8<=0;clkbaud8x<=~clkbaud8x;endelsediv_reg_baud8<=div_reg_baud8+1;endend/////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////always@(posedge clkbaud8x or negedge n_rst)//receive data from rxdbeginif(!n_rst) beginrxd_reg1<=0;rxd_reg2<=0;rxd_buf<=0;state_rec<=0;recstart<=0;tra_en<=0;count_delay_tra_en<=0;endelse beginrxd_reg1<=rxd;rxd_reg2<=rxd_reg1;recstart1<=recstart;recstart2<=recstart1;//*******tra_en拉高保持2个clkbaud8x 时钟周期,以保证tra_en脉冲的高电平在 uart_tra模块中可以被正确采样到if(!recstart1&&recstart2)//checked negative edge , data to be receivedtra_en<=1;else beginif(tra_en) beginif(count_delay_tra_en>=1)tra_en<=0;elsecount_delay_tra_en<=count_delay_tra_en+1;endelse begintra_en<=0;count_delay_tra_en<=0;endend//************************************************************* **************************************if(!recstart) beginif(!rxd_reg1&&rxd_reg2) //checked negative edge recstart<=1;//latency =2elserecstart<=0;endelse begin// start to receive datastate_rec<=state_rec+1;case(state_rec)8'd8: begin rxd_buf[0]<=rxd_reg2;end8'd16: begin rxd_buf[1]<=rxd_reg2;end8'd24: begin rxd_buf[2]<=rxd_reg2;end8'd32: begin rxd_buf[3]<=rxd_reg2;end8'd40: begin rxd_buf[4]<=rxd_reg2;end8'd48: begin rxd_buf[5]<=rxd_reg2;end8'd56: begin rxd_buf[6]<=rxd_reg2;end8'd64: begin rxd_buf[7]<=rxd_reg2;end8'd72: beginif(rxd_reg2)// checked stop bitrxd_buf_data_vaild<=1;elserxd_buf_data_vaild<=0;state_rec<=0;recstart<=0;endendcaseendendendendmodule//************************************************************* **//Uart_tra mode: This module is to trasfer data, baud rate 9600//Author: LBQ// HIstory//Nov/24/2014: Inital release//************************************************************* **module uart_tra(clk,n_rst,txd_data,tra_en,txd);input clk,n_rst;// input clock and low resetinput[7:0] txd_data;//input recstart1;//input recstart2;input tra_en;output txd; //UART transmitter////////////////////innerreg///////////////////////////////////////////////////////////reg[15:0] div_reg_baud8;////counter for division , 8 baund ratereg[7:0] state_tras;//reg clkbaud8x;// 8 baund rate clockreg tra_star;reg rxd_buf_data_vaild;reg txd_reg;//reg[7:0] txd_buf;///////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////===parameter=====//////////// ////////////////////////parameter div_reg_baud8_par=16'h001; // *************** lbq for simulation//parameter div_reg_baud_par=16'h008; // *************** lbq for simulationparameter div_reg_baud8_par=16'h145;//////9600*8 (CLK 50M)//parameter div_reg_baud_par=16'ha2C;//////9600 (CLK 50M)/////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////assign txd=txd_reg;/////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// //////////always@(posedge clk)//get 8 baud rate clockbeginif(!n_rst)begindiv_reg_baud8<=0;clkbaud8x<=0;endelsebeginif(div_reg_baud8==div_reg_baud8_par-1)begindiv_reg_baud8<=0;clkbaud8x<=~clkbaud8x;endelsediv_reg_baud8<=div_reg_baud8+1;endend/////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// /////////always@(posedge clkbaud8x or negedge n_rst)beginif(!n_rst)begintxd_reg<=1;txd_buf<=0;tra_star<=0;state_tras<=0;endelse beginif(!tra_star)beginif(tra_en)begin //transfer eable , uart recieved a new data,may transfertra_star<=1;txd_buf<=txd_data;endelsetra_star<=0;endelse beginstate_tras<=state_tras+1;case(state_tras)8'd0: begin //txd_reg<=0;//state_tras<=state_tras+1;end8'd8: begin //txd_reg<=txd_buf[0];//state_tras<=state_tras+1;end8'd16: begin //txd_reg<=txd_buf[1];//txd_buf[6:0]<=txd_buf[7:1]; //state_tras<=state_tras+1;end8'd24: begin //txd_reg<=txd_buf[2];//txd_buf[6:0]<=txd_buf[7:1]; //state_tras<=state_tras+1;end8'd32: begin //txd_reg<=txd_buf[3];//txd_buf[6:0]<=txd_buf[7:1]; //state_tras<=state_tras+1;end8'd40: begin //txd_reg<=txd_buf[4];//txd_buf[6:0]<=txd_buf[7:1]; //state_tras<=state_tras+1;end8'd48: begin //txd_reg<=txd_buf[5];//txd_buf[6:0]<=txd_buf[7:1]; //state_tras<=state_tras+1;end8'd56: begin //txd_reg<=txd_buf[6];//txd_buf[6:0]<=txd_buf[7:1]; //state_tras<=state_tras+1;end8'd64: begin //txd_reg<=txd_buf[7];//txd_buf[6:0]<=txd_buf[7:1]; //state_tras<=state_tras+1;end8'd72: begin // sent stop bittxd_reg<=1;//txd_buf<=8'h55;////state_tras<=state_tras+1;end8'd75: begintra_star<=0;state_tras<=0;enddefault: begin//txd_buf<=8'h55;//state_tras<=state_tras+1; endendcaseendendendendmodule。
module rxduan(rx,clk16x,rst,dout);input rx,clk16x,rst;output[7:0] dout;reg clk_en;reg[2:0] count;reg[7:0] sr;reg[7:0] br;reg[3:0] state;reg clk96;reg[2:0] m;assign dout=br;always @(posedge clk16x or posedge rst)begin if(rst) count<=0;else beginif((~rx)&&(state==0)) count<=count+1;else count<=0;endend//在状态为0时检查起始位的低电平的个数,每检测到一个count的值就加一。
用来确定起始位是真的到来还是因为毛刺的影响使程序误运行。
always @(negedge clk16x or posedge rst)begin if(rst) begin clk_en<=0;endelse if(count==7) clk_en<=1;else if(state==10) clk_en<=0;end//当rst为低电平时,如果检测到起始位有8个低电平,则clk_en置1,当state为10时clk_en 置0always @(posedge clk16x)begin if(rst) begin m<=0;clk96<=0;endelse if(clk_en) begin m<=m+1;if(m==7) clk96<=~clk96;endend//生成clk96时钟信号,为clk16x时钟的16分频。
always @(negedge clk96 or posedge rst)begin if(rst) begin sr<=0;br<=0;endelse begin if((state>=1)&&(state<=8))begin sr[7]<=rx;sr[6:0]<=sr[7:1];endelse if(state==9)begin if(rx==1) br<=sr;endendend//移位串并转换。
UART串口接收模块设计
实验目标:实现FPGA接收其他设备通过UART协议发送过来的数据。
知识点:
1、URAT通信协议工业环境下数据接收实现。
2、In system sources and probes editor(ISSP)调试工具的使用。
UART发送端发送一个字节数据时序图:
对于其中的每一位进行采样,一般情况下每一位数据的中间点是最稳定的,因此一般应用中,
:
采集中间时刻时的数据即可,如下图所示
但是在工业应用中,往往有非常强的电磁干扰,只采样一次就作为该数据的电平判定,是不保险的,有可能恰好采集到被干扰的信号而导致结果出错,因此需要使用多次采样求概率的方式进行。
以下为改进型的单bit数据接收方式示意图:
12345678910111213141516
在这张图中,将每一位数据又平均分成了16小段,对于Bit_x这一位数据,考虑到数据在刚刚发生变化和即将发生变化的这一时期,数据极有可能不稳定的(用红色标出的两段),在这两个时间段采集数据,很有可能得到错误的结果,因此这两段时间的电平无效,采集时直接忽略。
而中间这一时间段(用绿色标出),
数据本身是比较稳定的,一般都代表了正确的结果。
但是也不排除该段数据受强电磁干扰而出现错误的电平脉冲,因此对这一段电平,进行多次采样,并求高低电平发生的概率,6次采集结果中,取出现次数多的电平作为采样结果。
例如,采样6次的结果分别为1/1/1/1/0/1/,则取电平结果为1,若为0/0/1/0/0/0,,则取电平结果为0,当6次采样结果中1和0各占一半(各3次),则可判断当前通信线路环境非常恶劣,数据不具有可靠性。
串口发送模块包含两个主要组件:
1、起始位检测进程(低电平,下降沿)
2、波特率产生模块
3、数据接收模块
串口接收模块整体结构图:
波特率时钟计算:
Modelsim仿真图:
·在testbench文件中我们为设计输入了假定的信号,在仿真图中我们可以看到data_byte_r 在Rx_done标志位产生的时候成功的将仿真数据data_byte_t接收到其中。
实现了串口接收数据的功能,其余各状态表现正常。
Rtl功能图
附录:源程序:
一,顶层功能代码
module uart_rx_top(Clk,Rst_n,Rs232_Rx);
input Clk;
input Rst_n;
input Rs232_Rx;
reg [7:0]data_rx_r;
wire [7:0]data_rx;
wire Rx_Done;
uart_byte_rx uart_byte_rx(
.Clk(Clk),
.Rst_n(Rst_n),
.baud_set(3'd0),
.Rs232_Rx(Rs232_Rx),
.data_byte(data_rx),
.Rx_Done(Rx_Done)
);
issp issp(
.probe(data_rx_r),
.source()
);
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
data_rx_r <= 8'd0;
else if(Rx_Done)
data_rx_r <= data_rx;
else
data_rx_r <= data_rx_r; endmodule
二testbench仿真文件
`timescale 1ns/1ns
`define clk_period 20
module uart_byte_rx_tb;
reg Clk;
reg Rst_n;
reg Rs232_Rx;
wire [7:0]data_byte_r;
wire Rx_Done;
reg [7:0]data_byte_t;
reg send_en;
reg [2:0]baud_set;
wire Rs232_Tx;
wire Tx_Done;
wire uart_state;
uart_byte_rx uart_byte_rx(
.Clk(Clk),
.Rst_n(Rst_n),
.baud_set(baud_set),
.Rs232_Rx(Rs232_Tx),
.data_byte(data_byte_r),
.Rx_Done(Rx_Done)
);
uart_byte_tx uart_byte_tx(
.Clk(Clk),
.Rst_n(Rst_n),
.data_byte(data_byte_t),
.send_en(send_en),
.baud_set(baud_set),
.Rs232_Tx(Rs232_Tx),
.Tx_Done(Tx_Done),
.uart_state(uart_state)
);
initial Clk = 1;
always#(`clk_period/2)Clk = ~Clk;
initial begin
Rst_n = 1'b0;
data_byte_t = 8'd0;
send_en = 1'd0;
baud_set = 3'd4;
#(`clk_period*20 + 1 );
Rst_n = 1'b1;
#(`clk_period*50);
data_byte_t = 8'haa;
send_en = 1'd1;
#`clk_period;
send_en = 1'd0;
@(posedge Tx_Done)
#(`clk_period*5000);
data_byte_t = 8'h55;
send_en = 1'd1;
#`clk_period;
send_en = 1'd0;
@(posedge Tx_Done)
#(`clk_period*5000);
$stop;
end
endmodule。