通用异步收发器UART设计实验报告2.doc_第1页
通用异步收发器UART设计实验报告2.doc_第2页
通用异步收发器UART设计实验报告2.doc_第3页
通用异步收发器UART设计实验报告2.doc_第4页
通用异步收发器UART设计实验报告2.doc_第5页
免费预览已结束,剩余16页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

摘 要 UART(即 Universal Asynchronous Receiver Transmitter通用异步收发器)是广泛使用的串行数据传输协议。UART允许在串行链路上进行全双工的通信。通过应用 EDA技术,基于 CPLD/ FPGA器件设计与实现 UART的波特率产生器、UART发送器和接收器及其整合电路,目的是熟练运用 Verilog HD语言,掌握 CPLD芯片的使用。波特率发生器、接收器和发送器是UART的三个核心功能模块,利用Verilog HDL语言对这三个功能模块进行描述并加以整合,通过MaxPlusII10.01仿真,用串口调试助手进行验证,其结果完全符合UART协议的要求和预期的结果。目 录1 课题概述11.1 课题背景11.2 课题目的与意义21.3设计要求、工具及分工明细21.3.1设计要求21.3.2设计工具21.3.3 分工明细32 相关理论与技术32.1 UART的实现32.2 UART协议介绍32.3波特率发生器(分频器)42.4发送模块的实现62.5接收模块的实现112.6总体调试162.7 结果及分析172.8设计中出现的主要问题及措施173 结论184 心得体会181 课题概述1.1 课题背景UART协议是数据通信及控制系统中广泛使用的一种全双工串行数据传输协议,在实际工业生产中有时并不使用UART的全部功能。只需将其核心功能集成即可。波特率发生器、接收器和发送器是UART的三个核心功能模块,利用Vefilog-HDL语言对这三个功能模块进行描述并加以整合UART(即Universal AsynchronousReceiver Transmitter 通用异步收发器)是广泛使用的串行数据传输协议。UART允许在串行链路上进行全双工的通信。串行外设用到RS232-C异步串行接口,一般采用专用的集成电路即UART实现。如8250、8251、NS16450等芯片都是常见的UART器件,这类芯片已经相当复杂,有的含有许多辅助的模块(如FIFO),有时我们不需要使用完整的UART的功能和这些辅助功能。或者设计上用到了FPGA/CPLD器件,那么我们就可以将所需要的UART功能集成到FPGA内部。使用VHDL或Veriolog -HDL将UART的核心功能集成,从而使整个设计更加紧凑、稳定且可靠。本文应用EDA技术,基于FPGA/CPLD器件设计与实现UART。1.2 课题目的与意义 实际应用上,有时我们不需要使用完整的UART的功能和这些辅助功能。使用Verilog-HDL将所需要的UART的核心功能集成到FPGACPLD内部,就可以实现紧凑、稳定且可靠的UART数据传输。这样,既可以满足实际的应用,实现所要求的简单的通信和控制,又能够去除更多不需要的繁杂复杂的功能实现。 1.3设计要求、工具及分工明细1.3.1设计要求1) 支持数据格式:起始位(1bit)数据(8bit)奇偶校验位(1bit)终止位(1bit)2) 奇/偶校验可配置3) 可配置支持115200以下的常见波特率4) 支持115200以下的波特率自适应,自适应过程如下:a. 复位后,UART首先接收输入,不断自动调整波特率,直到以一定波特率正确连续接收到3个bytes的0x55b.c. 接着UART以此波特率连续发送3个bytes 0xaad. 之后两端以此波特率进行通信e. 波特率自适应只在电路复位后进行一次,如欲再次自适应波特率应对电路再次复位f. 波特率自适应过程中不能对UART的波特率作任何设置,自适应完成后可以对波特率作设置5) 自动计算校验位用于发送数据;对接收到的校验位和数据进行校验,发现错误应设置错误标志,并丢弃数据6) 对接收不正常数据(如无终止位、无校验位、数据位数不正确等)应能自动识别并设置错误标志、丢弃1.3.2设计工具1)所有电路采用VerilogHDL或原理图方法进行设计2)在QuartusII下进行设计3)综合和仿真可以采用其他工具,如综合可以采用Synplify,仿真可以采用ModelSim4)目标器件采用与实验箱相同的器件(EPF10KLC84-4)1.3.3 分工明细 组员三人,分别负责硬件设计、程序烧写、综合仿真。其它细节的过程共同合作完成。2 相关理论与技术2.1 UART的实现 比较复杂的数字电子系统的设计往往采用自顶向下 ( Top2 Down)的方法 ,即首先把设计任务划分成几个模块 ,然后分模块进行设计。本文所介绍的 UART串行通讯模块由 3个子模块组成:波特率发生器、 接收模块和发送模块 ,如图 2所示。所以对 UART通讯模块的实现就是对组成UART的三个子模块 (即:波特率发生器、 接收模块及发送模块 )的实现。波特率发生器专门产生一个本地时钟信号来控制 UART的接收与发送; UART接收模块的用途是接收 RxD端的串行信号 ,并将其转化为并行数据; UART发送模块的用途是将准备输出的并行数据按照基本 UART帧格式转为串行数据从TxD端串行输出。2.2 UART协议介绍 基本的UART通信只需要两条信号线(RxD,TxD)就可以完成数据的全双工通信任务。TxD是UART发送端,为输出;RxD是UART接收端,为输人。UART的基本特点是:在信号线上共有两种状态,分别用逻辑1(高电平)和逻辑O(低电平)来区分。例如,在发送器空闲时,数据线保持在逻辑高电平状态,发送器是通过发送起始位来开始一个数据帧的传送,起始位使数据线处于逻辑O状态,提示接收器数据传输即将开始。接着发送数据位,数据位一般为8位一个字节的数据(也有5位、6位或7位的情况),低位(LSB)在前,高位(MSB)在后。然后发送校验位,校验位一般用来判断传输的数据位有无错误,一般是奇偶校验。在使用中,该位常取消。停止位在最后,用以标识数据传送的结束,它对应于逻辑1状态。UART的帧格式包括起始位(start bit,低电平)、58位数据位(data bits)、校验位(parity bit,可选)和停止位(stop bit,位数可为1、15、2位)。这种格式是由起始位和停止位来实现字符的同步H1,如图所示。2.3波特率发生器(分频器)波特率发生器实际上就是分频器 ,可以根据给定的系统时钟频率 (晶振时钟 ) 和要求的波特率算出波特率分频因子 ,把算出的波特率分频因子作为分频器的分频系数。假设数据的波特率为p,则所需时钟的频率为16*p。以波特率p为115200为例,系统时钟为50MHz,则分频系数为50000000/(16*115200) = 27.127,取整为27。流程图如下:分频器Verilog HDL语言代码如下: module clkdiv(clk, clkout); input clk; /系统时钟 output clkout; /采样时钟输出 reg clkout; reg 15:0 cnt; always (posedge clk) /分频进程 begin if(cnt = 16d12) begin clkout = 1b1; cnt = cnt + 16d1; end else if(cnt = 16d26) begin clkout = 1b0; cnt = 16d0; end else begin cnt = cnt + 16d1; end endendmodule20波形仿真如下:保存文件为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,单击按钮进行分频器的波形仿真。如右所示。2.4发送模块的实现发送模块实现的功能是将要发送的 8位并行数据变为串行数据 ,同时在数据头部加起始位 ,在数据位尾部加奇偶校验位和停止位。即 ,当 UART发送模块被复位信号复位以后 ,发送模块将立刻进入准备发送状态 ,在该状态下读 8位并行数据到寄存器 7: 0I NSend中 ,之后输出逻辑 0作为起始位 ,从起始位的下一位开始对 UART串行通讯所要求的波特率时钟D I V_CLK的上升沿计数,每计一次数从寄存器 7: 0INSend中按照由低位到高位的顺序取出一位数据送到 TxD端 ,当计数为 8时 ,也就是确保发送了所有的数据位 ,同时也将 8位并行数据转换为 8位串行数据。根据 8位数据位中逻辑 1的个数确定校验位 ,然后输出校验位 ,最后输出逻辑 1作为停止位。Verilog HDL语言代码如下:module uarttx(clk, datain, wrsig, idle, tx); input clk,wrsig; /UART时钟 input 7:0 datain; /需要发送的数据 input wrsig; /发送命令,上升沿有效 output idle; /线路状态指示,高为线路忙,低为线路空闲 output tx; /发送数据信号 reg idle, tx; reg send; reg wrsigbuf, wrsigrise; reg presult; reg7:0 cnt; /计数器 parameter paritymode = 1b0; /检测发送命令是否有效 always (posedge clk) begin wrsigbuf = wrsig; wrsigrise = (wrsigbuf) & wrsig; end always (posedge clk) begin if (wrsigrise & (idle) /当发送命令有效且线路为空闲时,启动新的数据发送进程 begin send = 1b1; end else if(cnt = 8d176) /一帧资料发送结束 begin send = 1b0; end end always (posedge clk) begin if(send = 1b1) begin case(cnt) /产生起始位 8d0: begin tx = 1b0; idle = 1b1; cnt = cnt + 8d1; end 8d16: begin tx = datain0; /发送数据0位 presult = datain0paritymode; idle = 1b1; cnt = cnt + 8d1; end 8d32: begin tx = datain1; /发送数据1位 presult = datain1presult; idle = 1b1; cnt = cnt + 8d1; end 8d48: begin tx = datain2; /发送数据2位 presult = datain2presult; idle = 1b1; cnt = cnt + 8d1; end 8d64: begin tx = datain3; /发送数据3位 presult = datain3presult; idle = 1b1; cnt = cnt + 8d1; end 8d80: begin tx = datain4; /发送数据4位 presult = datain4presult; idle = 1b1; cnt = cnt + 8d1; end 8d96: begin tx = datain5; /发送数据5位 presult = datain5presult; idle = 1b1; cnt = cnt + 8d1; end 8d112: begin tx = datain6; /发送数据6位 presult = datain6presult; idle = 1b1; cnt = cnt + 8d1; end 8d128: begin tx = datain7; /发送数据7位 presult = datain7presult; idle = 1b1; cnt = cnt + 8d1; end 8d144: begin tx = presult; /发送奇偶校验位 presult = datain0paritymode; idle = 1b1; cnt = cnt + 8d1; end 8d160: begin tx = 1b1; /发送停止位 idle = 1b1; cnt = cnt + 8d1; end 8d176: begin tx = 1b1; idle = 1b0; /一帧资料发送结束 cnt = cnt + 8d1; end default: begin cnt = cnt + 8d1; end endcase end else begin tx = 1b1; cnt = 8d0; idle = 1b0; end end endmodule保存文件为uarttx.v,单击Files Create/Update Create Symbol Files for Current File命令,为uarttx.v生成原理图模块。如右所示。为了测试UART发送模块的正确性,需要编写一个测试模块来测试UART发送模块,Verilog HDL语言代码如下。module testuart(clk, dataout, wrsig); input clk; output7:0 dataout; output wrsig; reg 7:0 dataout; reg wrsig; reg 7:0 cnt; always (posedge clk) begin if(cnt = 254) begin dataout = dataout + 8d1; /每次数据加“1” wrsig = 1b1; /产生发送命令 cnt = 8d0; end else begin wrsig = 1b0; cnt = cnt + 8d1; end end endmodule波形仿真如下:保存文件为testuart.v,单击Files Create/Update Create Symbol Files for Current File命令,为testuart.v生成原理图模块。新建一个原理图文件,如右所示在原理图空白处双击,在弹出的Symbol对话框中选择Project testuart模块和uarttx模块,单击OK按钮退出Symbol对话框。在原理图的适当位置放置testuart模块和uarttx模块,并添加输入输出模块。各个模块的连接如下所示。2.5接收模块的实现UART通讯模块是从 RxD端接收数据的 , RxD端由逻辑 1跳变为逻辑 0可视为一个数据帧的开始 ,所以接收模块首先要判断起始位。当 UART接收模块复位后,接收模块一直在等待 RxD的电平跳转。当RXD电平从逻辑 1变为逻辑 0,即起始位到来 ,意味着新的 UART数据帧的开始 ,一旦检测到起始位 ,就从起始位的下一位开始对 UART通讯所要求的波特率时钟 D I V _CLK的上升沿计数 ,每计一次数就对RXD进行一次采样 ,把每次采样获得的逻辑电平值按先后顺序存入寄存器 Q中 ,当计数为 8时 ,也就是确保接收了所有的数据位 , 8位串行数据也被转换为 8位并行数据。UART接收模块的Verilog HDL语言代码见下:module uartrx(clk, rx, dataout, rdsig, dataerror, frameerror); input clk; /采样时钟 input rx; /UART数据输入 output dataout; /接收数据输出 output rdsig; output dataerror; /资料出错指示 output frameerror; /帧出错指示 reg7:0 dataout; reg rdsig, dataerror; reg frameerror; reg 7:0 cnt; reg rxbuf, rxfall, receive; parameter paritymode = 1b0; reg presult, idle; always (posedge clk) /检测线路的下降沿 begin rxbuf = rx; rxfall = rxbuf & (rx); end always (posedge clk) begin if (rxfall & (idle) /检测到线路的下降沿并且原先线路为空闲,启动接收数据进程 begin receive = 1b1; end else if(cnt = 8d175) /接收数据完成 begin receive = 1b0; end end always (posedge clk) begin if(receive = 1b1) begin case (cnt) 8d0: begin idle = 1b1; cnt = cnt + 8d1; rdsig = 1b0; end 8d24: /接收第0位数据 begin idle = 1b1; dataout0 = rx; presult = paritymoderx; cnt = cnt + 8d1; rdsig = 1b0; end 8d40: /接收第1位数据 begin idle = 1b1; dataout1 = rx; presult = presultrx; cnt = cnt + 8d1; rdsig = 1b0; end 8d56: /接收第2位数据 begin idle = 1b1; dataout2 = rx; presult = presultrx; cnt = cnt + 8d1; rdsig = 1b0; end 8d72: /接收第3位数据 begin idle = 1b1; dataout3 = rx; presult = presultrx; cnt = cnt + 8d1; rdsig = 1b0; end 8d88: /接收第4位数据 begin idle = 1b1; dataout4 = rx; presult = presultrx; cnt = cnt + 8d1; rdsig = 1b0; end 8d104: /接收第5位数据 begin idle = 1b1; dataout5 = rx; presult = presultrx; cnt = cnt + 8d1; rdsig = 1b0; end 8d120: /接收第6位数据 begin idle = 1b1; dataout6 = rx; presult = presultrx; cnt = cnt + 8d1; rdsig = 1b0; end 8d136: /接收第7位数据 begin idle = 1b1; dataout7 = rx; presult = presultrx; cnt = cnt + 8d1; rdsig = 1b1; end 8d152: /接收奇偶校验位 begin idle = 1b1; if(presult = rx) dataerror = 1b0; else dataerror = 1b1; /如果奇偶校验位不对,表示数据出错 cnt = cnt + 8d1; rdsig = 1b1; end 8d168: begin idle = 1b1; if(1b1 = rx) frameerror = 1b0; else frameerror = 1b1; /如果没有接收到停止位,表示帧出错 cnt = cnt + 8d1; rdsig = 1b1; end default: begin cnt = cnt + 8d1; end endcase end else begin cnt = 8d0; idle = 1b0; rdsig = 1b0; end end endmodule波形仿真如下: 保存文件为uartrx.v,单击Files Create/Update Create Symbol Files for Current File命令,为uartrx.v生成原理图模块,如右所示。新建一个原理图文件,在原理图空白处双击,在弹出的Symbol对话框中选择Project uartrx模块,单击OK按钮退出Symbol对话框。在原理图的适当位置放置uartrx模块,并添加输入输出模块,各个模块的连接如下所示。2.6总体调试1)将以上各个模块连接好,进行编译,如下图所示。2)进行相应管脚设置,如下图所示3)选择下载方式,根据实验室设备选择USB下载。然后勾选Program/Configure下面的框。最后点击Start按钮,当Progress显示100%时表示下载完成。用9针串口线将试验箱和计算机连接。2.7 结果及分析1)结果如图所示:2) 分析:本设计采用原理图及Verilog DHL联合设计方法。前面的各个模块逐个验证后,在最后的整合采用原理图设计,清晰且直观。本设计能够实现固定波特率的通信,FPGA能够将受到的字符串回发给上位机。采用Verilog-HDL对异步通信接口UART的设计流程,对设计进了功能仿真、综合,以及静态时序分析和时序仿真,最后在ALTERA 公司生产的 FLEX10K系列的EPF10KLC84-4芯片上下载,完成了在CPLD上实现UART的全过程。2.8设计中出现的主要问题及措施问题 1:在仿真过程中经常遇到一些寄存器没有被初始化 ,导致仿真结果不正确 ,这是因为 if语句嵌套太复杂或循环语句使用不恰当使得寄存器初始化语句未能执行。措施:尽量减少 if语句的嵌套

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论