基于FPGA的通用异步收发器设计

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

基于FPGA的通用异步收发器设计作者:学号:指导教师摘要:文章简要介绍了UART的基本功能,采用VerilogHDL语言作为硬件功能的描述,运用模块化设计方法设计了通用异步收发器的发送模块、接收模块和波特率发生器。实现了基于FPGA的UART基本功能设计,并给出了UART的软件编程实例。关键字:VerilogHDL;FPGA;UART;Abstract:thispaperbrieflyintroducesthebasicfunctionofUART,theVerilogHDLlanguageasadescriptionofthehardwarefunction,usingmodulardesignmethodtodesignthegeneralasynchronoustransceivermodule,receivesendthemoduleandbaudrategenerator.RealizedthebasicfunctionofUARTwhichbasedonFPGA,andgivestheUARTsoftwareprogrammingexamples.Keyword:VerilogHDL;FPGA;UART;1.引言串行通信要求的传输线少,可靠性高,传输距离远,被广泛应用于计算机和外设的数据交换。通常都由通用异步收发器(UART)来实现串口通信的功能。在实际应用中,往往只需要UART的几个主要功能,专用的接口芯片会造成资源浪费和成本提高。随着FPGA/CPLD的飞速发展与其在现代电子设计中的广泛应用,FPGA/CPLD功能强大、开发过程投资小、周期短、可反复编程、保密性好等特点也越来越明显。因此可以充分利用其资源,在芯片上集成UART功能模块,从而简化了电路、缩小了体积、提高了可靠性,而且设计时的灵活性更大,周期更短。鉴于此本文提出了一种采用FPGA实现UART功能的方法,可以有效地解决上述问题。2.UART的工作原理UART(UniversalAsynchronousReceiverTransmitter,通用异步收发器)是广泛使用的异步串行数据传输协议。在串行通信中,数据以字节为单位的字节帧进行传送。发送端和接收端必须按照相同的字节帧格式和波特率进行通信。UART控制器所传输的一帧串行数据包括1位起始位(低电平)、5~8位数据位、1位校验位(可选)和停止位(可为1,1.5,2位)。起始位是字节帧的开始,使数据线处于逻辑0状态,用于向接收端表明开始发送数据帧,起到使发送和接收设备实现同步的功能。停止位是字节帧的终止,使数据线处于逻辑1状态。用于向接收端表明数据帧发送完毕。波特率采用标准速率9600b/s。数据在传输时,低位在前,高位在后。接收端检测并确认起始位后,接收数据位。停止位接收完毕后,向CPU发出中断信号,同时将数据发送到计算机的8位数据总线上;发送数据时,先由CPU设置波特率,然后将8位并行数据加上起始位和停止位发送给外设。停止位发送完毕后,向CPU发出中断信号。在数据发送和接收过程中,CPU可以通过控制信号来读取UART的工作状态,以便进行实时处理。图(1)为UART的传输结构图。图(1)3.UART的模块化设计3.1系统总体结构在大规模电路的设计中,广泛采用层次化、结构化的设计方法。它将一个完整的硬件设计任务从系统级开始,划分为若干个可操作的模块,编制出相应的模型并进行仿真验证,最后在系统级上进行组合。这样在提高设计效率的同时又提高了设计质量,是目前复杂数字系统实现的主要手段,也是本文设计思想的基础。按照系统功能进行划分,UART主要由波特率发生器、接收模块和发送模块三大部分组成。下面分别讨论发送模块、接收模块和波特率发生器模块的具体实现过程。moduleuart_test(clock,key,rdata,wen,sdata,seg,seg_dig);inputclock;//系统时钟(48MHz)input[2:0]key;//按键输入(KEY1~KEY3)input[7:0]rdata;//接收到的数据outputwen;//发送数据使能output[7:0]sdata;//要发送的数据output[7:0]seg;//数码管段码输出output[7:0]seg_dig;//数码管位码输出//I/O寄存器reg[7:0]sdata;reg[7:0]seg;reg[7:0]seg_dig;//内部寄存器reg[16:0]count;//时钟分频计数器reg[2:0]dout1,dout2,dout3,buff;//消抖寄存器reg[1:0]cnt;//数码管扫描计数器reg[3:0]disp_dat;//数码管扫描显存regdiv_clk;//分频时钟wire[2:0]key_edge;//按键消抖输出//时钟分频部分always@(posedgeclock)beginif(count17'd120000)begincount=count+1'b1;div_clk=1'b0;endelsebegincount=17'd0;div_clk=1'b1;endend//按键消抖部分always@(posedgeclock)beginif(div_clk)begindout1=key;dout2=dout1;dout3=dout2;endend//按键边沿检测部分always@(posedgeclock)beginbuff=dout1|dout2|dout3;endassignkey_edge=~(dout1|dout2|dout3)&buff;//2位16进制数输出部分always@(posedgeclock)//按键1beginif(key_edge[0])sdata[7:4]=sdata[7:4]+1'b1;endalways@(posedgeclock)//按键2beginif(key_edge[1])sdata[3:0]=sdata[3:0]+1'b1;endassignwen=key_edge[2];//按键3//数码管扫描显示部分always@(posedgeclock)//定义上升沿触发进程beginif(div_clk)cnt=cnt+1'b1;endalways@(posedgeclock)beginif(div_clk)begincase(cnt)//选择扫描显示数据2'd0:disp_dat=sdata[7:4];//第一个数码管2'd1:disp_dat=sdata[3:0];//第二个数码管2'd2:disp_dat=rdata[7:4];//第七个数码管2'd3:disp_dat=rdata[3:0];//第八个数码管endcasecase(cnt)//选择数码管显示位2'd0:seg_dig=8'b01111111;//选择第一个数码管显示2'd1:seg_dig=8'b10111111;//选择第二个数码管显示2'd2:seg_dig=8'b11111101;//选择第七个数码管显示2'd3:seg_dig=8'b11111110;//选择第八个数码管显示endcaseendendalways@(disp_dat)begincase(disp_dat)//七段译码4'h0:seg=8'hc0;//显示04'h1:seg=8'hf9;//显示14'h2:seg=8'ha4;//显示24'h3:seg=8'hb0;//显示34'h4:seg=8'h99;//显示44'h5:seg=8'h92;//显示54'h6:seg=8'h82;//显示64'h7:seg=8'hf8;//显示74'h8:seg=8'h80;//显示84'h9:seg=8'h90;//显示94'ha:seg=8'h88;//显示a4'hb:seg=8'h83;//显示b4'hc:seg=8'hc6;//显示c4'hd:seg=8'ha1;//显示d4'he:seg=8'h86;//显示e4'hf:seg=8'h8e;//显示fendcaseendendmodule3.2发送模块发送模块主要实现对并行数据的缓存、并串转换,并把串行数据按照既定数据帧格式进行输出。数据发送的思想是,当启动字节发送时,通过TxD先发起始位,然后发数据位和奇偶数效验位,最后再发停止位,发送过程由发送状态机控制,每次中断只发送1个位,经过若干个定时中断完成1个字节帧的发送。【1】发送模块的代码如下:modulesend(clk,clkout,Datain,TXD,TI,WR);inputWR;input[7:0]Datain;//发送的一字节数据inputclk;outputclkout;outputTXD,TI;//串行数据,发送中断reg[9:0]Datainbuf,Datainbuf2;//发送数据缓存regWR_ctr,TI,txd_reg;reg[3:0]bincnt;//发送数据计数器reg[15:0]cnt;wireclk_equ;parametercout=5000;/*************波特率发生进程****************************/always@(posedgeclk)beginif(clk_equ)cnt=16'd0;elsecnt=cnt+1'b1;endassignclk_equ=(cnt==cout);assignclkout=clk_equ;/*************读数据到缓存进程****************************/always@(posedgeclk)beginif(WR)beginDatainbuf={1'b1,Datain[7:0],1'b0};//读入数据,并把缓存组成一帧数据,10位WR_ctr=1'b1;//置开始标志位endelseif(TI==0)WR_ctr=1'b0;end/*************主程序进程****************************/always@(posedgeclk)beginif(clk_equ)beginif(WR_ctr==1||bincnt4'd10)//发送条件判断,保证发送数据的完整性beginif(bincnt4'd10)begintxd_reg=Datainbuf2[0];//从最低位开始发送Datainbuf2=Datainbufbincnt;//移位输出bincnt=bincnt+4'd1;//发送数据位计数TI=1'b0;endelsebincnt=4'd0;endelsebegin//发送完毕或者处于等待状态时TXD和TI为高txd_reg=1'b1;TI=1'b1;endendendassignTXD=txd_reg;//TXD连续输出endmodule由CPU送来的待发送的并行数据,首先写入发送缓冲器TBR[7..0]。发送缓冲区中有数据待发送时,数据自动装入移位寄存器TSR[7..0]并自动完成串行数据的发送。首先传送一位起始位0,然后根据帧结构中定义的数据长度,分别串行移出TSR[7..0]中的数据,数据的低位在前,高位在后。当没有数据发送的时候,SDO管脚保持高电平。二进制数11110000从引脚DIN[7..0]并行输入,当WRN为0时,启动发送程序,计数器开始计数,使发送器将并行数据锁存到发送缓冲器TBR[7..0],并通过发送移位寄存器TSR[7..0]逐位移位发送串行数据至串行数据输出端SDO。在数据发送过程中用输出信号TBRE,TSRE作为标志信号。当一帧数据由发送缓冲器TBR[7..0]送到发送移位寄存器TSR[7..0]时,TBRE信号为1。由发送数据缓冲器传给发送移位寄存器主要由信号TSRE控制。当TSRE为1时,表示发送移位寄存器TSR[7..0]串行发送完毕;为0时表示还没有发送完一帧数据。由仿真结果验证了发送模块的正确性。3.3数据接收模块3.3.1接收模块及其功能接收模块的作用是把收到的串行

1 / 16
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功