UART控制器设计说明_第1页
UART控制器设计说明_第2页
UART控制器设计说明_第3页
UART控制器设计说明_第4页
UART控制器设计说明_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

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

文档简介

./电子科技大学可编程逻辑器件原理、应用与实验课程实验报告实验名称UART控制器设计及验证成绩研究生院学院代培生班成绩学号同作者实验日期2017年4月23日指导教师评语:指导教师:年月日实验报告容基本要求及参考格式一、实验目的二、实验所用仪器〔或实验环境三、实验基本原理及步骤〔或方案设计及理论计算四、实验数据记录〔或仿真及软件设计五、实验结果分析及回答问题〔或测试环境及测试结果.目录TOC\o"1-3"\h\u一任务简介 11.1实验目的11.2开发工具平台 1二模块设计 22.1输入模块设计 22.1.1机械按键消抖 22.1.2矩阵键盘扫描 32.1.3参量输入及显示输入 52.2显示模块 62.3三态门控制模块 82.4UART通信协议帧格式及波特率设置 92.5UART通信模块 102.5.1串口数据发送模块 112.5.2串口数据接收模块 12三系统介绍 133.1系统结构介绍 133.2系统子模块介绍 153.3开发板实验结果 17四总结 20.一任务简介1.1实验目的本次任务的目标为设计一个基于FPGA的串口通信控制器,具体技术要求如下:<1>实现与PC的双向通信;<2>可以通过输入模块在开发板上定义向PC发送的数据;<3>数据帧长度可调<6/7/8位>;<4>通信波特率可调;<5>在数码管上实现波特率、输入数据、接收数据的显示。<6>按键A用于接收模式和输入模式的选择,按键B用于选择输入模式为波特率设置还是发送数据设置,按键C为发送确认键,按键D用于选择数据帧长度,矩阵键盘<0~9>用于输入波特率因子和发送数据<十六进制显示>;各种模式均有数码管显示相应容,其中数据帧长度由四个LED灯表示。<7>操作流程:1.通信参数设置:在开发板上选择数据帧长度、设置波特率、输入发送数据帧;在PC端的串口通信助手中设置波特率和数据帧长度;2.数据发送:按下C键向PC发送数据,在PC端确认接收的数据;3.数据接收:由PC端向开发板发送数据,在开发板上选择数据接收模式即可显示;4.默认设置:UART控制器默认波特率为9600,默认发送数据为8’h18;<8>以上容均需在开发板上验证;实验截图在本文第三部分给出。1.2开发工具平台基于CycloneIIEP2C5Q208C8核心的MAGIC3200_EP2C5开发板,具有四位扫描式数码管,RS232串口等外设,时钟CLK为50MHz;开发软件为QuartusII13sp;串口通信助手;基于LP2303的USB-UART转接线,用于与笔记本电脑进行串口通信。MAGIC3200_EP2C5开发板USB-UART转接线RS232串口串口通信助手图1.1开发平台设备二模块设计2.1输入模块设计输入模块采用了矩阵键盘和独立按键,独立按键用于模式选择和发送确认,矩阵键盘用于数据的输入。关于消抖部分,对于矩阵键盘来说只要设置合适的扫描频率就可以实现消抖的功能,而对于独立按键来说就必须设计相应的消抖模块。2.2.1机械按键消抖模块简介机械按键按下时的机械抖动会产生很多个下降沿,而在逻辑上希望机械按键按下一次只产生一个下降沿,因此要进行按键消抖。按键防抖动其实是通过延时判断来做的,因为这种毛刺持续时间都在ms级,当检测到按键状态有变化时,经过一定延时后再次进行确认。消抖模块如图2.1所示,din为机械按键输入,dout为消抖后的输出。图2.1消抖模块图关键程序图2.2为键盘消抖的状态转移图,按键信号din按下时为低电平,平时为高电平。<1>状态S0:输入din信号产生跳变后,进入状态S0。如果din为0,进入S1状态。否则循环检测。<2>状态S1:如果再次检测到输入信号为逻辑0信号,则表明有按键按下,dout为0。状态机结束。状态机激励时钟周期为0.1s,以此实现延时,即按键按下后0.1s检测按键信号,若按键信号为低电平,则输出低电平完成消抖。图2.2消抖状态机消抖程序如下:always<posedgekeyclk>//状态机激励begin if<RESET==0>pre_s=s0; elsepre_s=next_s;endalways<pre_s,next_s,din>//检查按键begin case<pre_s>s0:begindout=1;if<din==0>next_s=s1;elsenext_s=s0;end s1:begindout=1;if<din==0>dout=0;elsenext_s=s0;end default:next_s=s0; endcaseend2.2.2矩阵键盘扫描简介及原理图键盘扫描最大的优点就是能节约I/O口。如果使用普通的方法,那么16个按键就需要16个I/O口,但通过扫描的方式来完成,却只需要8个,按键越多它所显现的优势也就越明显。矩阵键盘原理电路如图2.3。键盘扫描将使用行扫描法实现,即逐行扫描查询法。具体操作为:行线的初始状态输出都为0,只要有高电平出现,表明有按键被按下。在确认有按键被按下的情况下,需要确定具体哪个按键被按下。以一定的扫描频率依次将行线<key_out>电平拉高,并检测列线的输入<key_in>,确定具体哪个按键被按下。图2.3矩阵键盘原理电路图2.4键盘扫描模块图图2.5键盘扫描模块原理图键盘扫描模块如如图2.4所示,输入为reset信号,clk信号<50MHz时钟>,模式切换开关swith,列扫描信号key_in;输出为行扫描信号key_out,波特率因子bote,键盘输入值输出Data0~Data4,Data1、Data2、Data3、Data4为输入模块向显示模块的输出,它们分别对应四位数码管千位、百位、十位、个位显示的容。send_data为发送数据帧寄存器,图中给出的是8位模式下的键盘扫描模块,所以send_data位宽为8位,在7位和6位模式下扫描模块send_data的位宽分别为7位和6位,其余部分与8位模式下的键盘扫描模块基本一致。speaker为蜂鸣器信号,因为开发板设计上的一些问题,若不定义开发板的蜂鸣器管脚,蜂鸣器有时会响。关键程序其中扫描频率由键盘扫描模块置的分频模块实现:always<posedgeclkornegedgereset>begin if<reset==0>time10ms<=0;//最初设计扫描时钟周期为10ms,后来有改动 elseif<timecnt==1200000>//扫描频率为20Hz<20ms> begintime10ms<=~time10ms;timecnt<=0;end elsetimecnt<=timecnt+1;end行轮扫的主要程序如下: key_out<=scanvalue; //输出行扫描值 cpy_scanvalue<=scanvalue;//备份扫描值,用于进行列扫描 case<scanvalue>//行轮扫 4'b0001:scanvalue<=4'b0010; 4'b0010:scanvalue<=4'b0100; 4'b0100:scanvalue<=4'b1000; 4'b1000:scanvalue<=4'b0001; default:scanvalue<=4'b0001; endcase将键盘扫描与数据输入关联的程序如下: case<{key_in,cpy_scanvalue}> 8'b00010001:beginData0<=1;counter<=counter+1;end//对应键盘"1" 8'b00100001:beginData0<=2;counter<=counter+1;end//对应键盘"2" 8'b01000001:beginData0<=3;counter<=counter+1;end//对应键盘"3" 8'b10000001:beginData0<=4;counter<=counter+1;end//未使用 8'b00010010:beginData0<=4;counter<=counter+1;end//对应键盘"4" 8'b00100010:beginData0<=5;counter<=counter+1;end//对应键盘"5" 8'b01000010:beginData0<=6;counter<=counter+1;end//对应键盘"6" 8'b10000010:beginData0<=4;counter<=counter+1;end//未使用 8'b00010100:beginData0<=7;counter<=counter+1;end//对应键盘"7" 8'b00100100:beginData0<=8;counter<=counter+1;end//对应键盘"8" 8'b01000100:beginData0<=9;counter<=counter+1;end//对应键盘"9" 8'b10000100:beginData0<=4;counter<=counter+1;end//未使用 8'b00011000:beginData0<=0;counter<=counter+1;end//对应键盘"0" 8'b00101000:beginData0<=2;counter<=counter+1;end//未使用 8'b01001000:beginData0<=3;counter<=counter+1;end//未使用 8'b10001000:beginData0<=4;counter<=counter+1;end//未使用 default: ;//无键盘按下 endcase如以上程序所示,每当按下键盘对应按键后,将有对应数值写入寄存器Data0中,寄存器counter为当前输入对应的位数。2.2.3参量输入及显示输入键盘输入数值的存储程序如下:switch1==0<控制信号下文将详细介绍>时进入波特率设置模式,输入的数值为波特率因子bote,bote为一个四位数,此模式下可以通过矩阵键盘从千位到个位依次写数,将每次输入的值依次写入四位寄存器Data1、Data2、Data3、Data4中,最终组成一个完整的十进制四位数,其中counter为位数标志位。Data1、Data2、Data3、Data4为输入模块向显示模块的输出,它们分别对应四位数码管千位、百位、十位、个位显示的容。if<switch1==0>begin bote<=Data1*1000+Data2*100+Data3*10+Data4; case<counter> 4'b0001:Data1<=Data0; 4'b0010:Data2<=Data0; 4'b0011:Data3<=Data0; 4'b0100:Data4<=Data0; default:beginData1<=5;Data2<=2;Data3<=0;Data4<=8;end endcase if<counter==5>counter<=0; endswitch==1时进入发送数据设置模式,最终把键盘输入值写入send_data,发送寄存器send_data为一个6~8位<可设置>的二进制数,用于存储将要发送的数据帧。因为四个Data寄存器位宽为4位,所以send_data的容只需要由两个寄存器的数据构成。令Data1、Data2为10,意思为关闭千位、百位的数码管,这在显示模块部分将会详细介绍。elsebeginsend_data<={Data3,Data4}; Data1<=10; Data2<=10; case<counter> 4'b0001:Data3<=Data0; 4'b0010:Data4<=Data0; default:beginData3<=8;Data4<=8;end endcase if<counter>2>counter<=0;end 仿真结果:图2.6键盘扫描模块仿真为了方便观察结果,仿真中加快了时钟和一些分频的频率。从仿真图像可以看出,行线扫描信号key_out以一定频率扫描,当列扫描信号key_in有所输入时,输入寄存器Data0、Data1、Data2、Data3、Data4都有相应的变化。而且当切换开关switch按下时,输出信号bote和send_data都发生了相应变化,这说明波特率设置模式和发送数据写入模式的切换功能正常运行。仿真表明输入模块在功能上是可行的。2.2显示模块模块简介及原理图显示模块用于驱动开发板上的四位数码管显示串口数据,每个数码管有八个控制位和一个片选位,还有一个用于显示‘:’控制位。由于开发板只给出了13个引脚用于控制四个数码管,因此必须采用数码管扫描的形式来进行显示。因为人眼有视觉暂留的特性.一般说来,当1秒钟刷新24次以上,人眼就无法区分而认为四个数码管是一起亮的。扫描具有节约引脚的优点,如果并行驱动四位数码管,那么至少需要33个引脚,而扫描法只需要13个引脚就可以实现。使用的是共阳数码管,引脚电平为低时点亮。图2.7显示模块显示模块如图2.6所示,输入为reset信号,50Mhz时钟信号clk,前文提到的Data1、Data2、Data3、Data4显示容输入,分别对应四位数码管千位、百位、十位、个位的显示容。输出信号中的LED_A~LED_G、LED_Point、LED_PointTime均为显示控制信号;LED_VCC1~LED_VCC4为LED片选信号,高电平有效,LED_EN1为使能信号。关键程序以下为数码管扫描的关键程序:always<posedgeclk>begin if<reset=='b0> count<=0; elseif<count==6000> //设置数码管扫描频率 begin count<=0; if<scancnt>3>scancnt<=0; elsescancnt<=scancnt+1; end elsecount<=count+1;end以上程序主要作用是,使变量scancnt扫描频率在0~3累加循环,scancnt有0123共四个状态,通过scancnt控制数码管片选信号,分别在四个数码管上显示容。译码部分见附录。仿真结果图2.8显示模块仿真结果可以看出随着Data1和Data1的变化,LED控制信号和LED片选信号同时变化,说明显示模块功能正常。2.3三态门控制模块模块简介及原理图在本任务顶层的设计中有些部分需要使用多输入三态门来控制数据的传输,本部分将以任务中的一个多输入三态门来介绍该模块。模块的原理图和模块图如图2.9所示图2.9三态门模块如图所示,data1~data4为输入数据,D1~D4为输出,若en=1则D1~D4输出data1~data4的数据,若en=0则D1~D4输出高阻。关键程序if<en==1> beginD1<=data1;D2<=data2;D3<=data3;D4<=data4;end else beginD1<=4'bzzzz;D2<=4'bzzzz;D3<=4'bzzzz;D4<=4'bzzzz;end仿真结果图2.10三态门仿真从仿真结果中可以看出,当en为低电平时输出为高阻,en为高电平时输出等于输入。这说明三态门模块功能正确。2.4UART通信协议帧格式及波特率设置模块简介及原理图基本的UART帧格式如图所示。图2.11URAT帧格式基本的UART帧格式包括起始位、数据位、校验位和停止位四部分。一个字符帧数据由四部分组成:一个起始位〔逻辑为0,紧接着一个5位到8位可变的数据位D0-D7,一个奇偶校验位〔可选择,最后是停止位〔逻辑1。在没有数据被传输时,串行数据线上一直是逻辑高电平。本次任务未设置奇偶校验。帧格式设置本次所设计的UART控制器支持长度6、7、8位的帧格式,实现方式将在下文系统介绍中叙述,各个模块间相互的切换由一个控制模块实现,模块图形由下图所示:图2.12控制模块图如图所示,模块输入为50MHz时钟CLK、RESET复位信号,机械按键D对应DDD信号,输出信号为数据帧长度控制信号c[2..0],led[3..0]为数据帧长度指示信号用于控制开发板上的四个led灯。功能说明:每按下机械D,数据帧长度会以8-7-6-8顺序改变一档,而开发板上从左到右的四个led灯会以相应的顺序发光表示目前数据帧的长度;0111表示8位,1000表示7位,1001表示6位,系统默认8位模式;0表示亮,1表示灭。关键程序数据帧长度控制模块由下列代码实现:key5key5_1<CLK,RESET,DDD,DD>;//例化消抖模块对机械按键DDD消抖always<negedgeDD>//每按下机械按键D一次,状态指示寄存器counter加1beginif<counter>2>counter<=0;//counter大于2时清零elsecounter<=counter+1;endalways<posedgeDD>beginif<counter==0>beginc<=3'b001;led<=4'b0111;end//8位模式elseif<counter==1>beginc<=3'b010;led<=4'b1000;end//7位模式elseif<counter==2>beginc<=3'b100;led<=4'b1001;end//6位模式elsebeginc<=3'b001;led<=4'b0000;end//默认8位模式End仿真结果图2.13控制模块仿真输出随输入规律变化,可以看出模块功能正常。波特率设置:波特率发生器为传输提供了串行移位时钟。波特率表示数据的传送速率,即每秒传输二进制的位数。波特率控制模块实际上是一个分频器,产生相应的符合RS232的波特率同步时钟。因为开发板自带时钟为50MHz,因此:波特率=50M/bote;可见其中波特率是由波特率因子bote决定,若bote=5208,则波特率为9600。关键程序always<posedgeCLKornegedgeRESET>begin if<ClockCount==bote>beginClock9600<=1;ClockCount<=0;end else beginClock9600<=0;ClockCount<=ClockCount+1;endend波特率发生器本质为一个分频器,bote为之前键盘输入模块送来的设定值。仿真结果该模块的仿真验证将于下文中UART通信模块的仿真中一并验证。2.5UART通信模块模块介绍及原理图基本的UART仅有RXD和TXD两条信号线,接收和发送之间相互不存在干扰,即全双工。由于UART是异步通信,要求RXD接口和TXD发送端制定相应的规则,对数据进行同步,以使接收、发送之间协调一致。UART的工作原理是将传输数据的每一个字符一位接一位地传输,以字符为单位从低位到高位逐位传输,一个字符表示一帧信息。如图2.14所示,串口数据发送模块和串口数据接收模块以及相关分频模块都集成于同一个UART模块中。输入:CLK:50MHz时钟;RESET:复位信号;UART0_RX:接收数据引脚;KEYA:对应机械按键C,为发送确认键;bote[14..0]:由输入模块送来的波特率因子,用于设置波特率;SEND_DATA[7..0]:数据帧,在6位模式中位宽为6,在7位模式中位宽为7。输出:UART0_TX:发送数据引脚;Data01[0..3]~Data04[0..3]:用于向显示模块传递接收的数据。图2.14UART模块2.5.1串口数据发送模块关键程序Clock9600为前文介绍的波特率发生器产生的波特率时钟;always<posedgeClock9600orposedgeSend_en>beginif<Send_en==1>beginsend_count<=0;UART0_TX<=1;send_over<=1;end//串口清零elseif<Send_count==9>beginUART0_TX<=Send_data[9];send_over<=0;end//发送完成elsebeginUART0_TX<=Send_data[Send_count];//逐位由发送寄存器向串口写数据Send_count<=Send_count+1;endalways<posedgedoutornegedgeRESET>//发送数据begin if<RESET==0>beginsend_en<=1;Send_data<=10'b1000000000;end else begin Send_en<=0; Send_data<={last,SEND_DATA,start};//写入起始位和终止位 if<Send_over==0>Send_en<=1; endend2.5.2串口数据接收模块首先介绍采样时钟Clock3,它是波特率的16倍,即串口上一个数据位长度会有16个Clock3周期,如果在每个数据位的第8个Clock3周期上采样,即在每个数据位的中间进行取样,这样可以使采样值更加准确可靠。此原理如图2.15所示。图2.15采样原理关键程序接收采样时钟分频模块:always<posedgeCLKornegedgeRESET>begin if<ClockCount_UART0_RX==bote/16>//采样频率为波特率的16倍beginClock3<=1;ClockCount_UART0_RX<=0;end elsebeginClock3<=0;ClockCount_UART0_RX<=ClockCount_UART0_RX+1;endend检测到UART0_RX出现下降沿时,令UART0_RX_Hold=1,启动接收进程; case<m> //8位数据帧采样 24: beginUART0_RX_Data[0]<=UART0_RX;m<=m+1;end 40: beginUART0_RX_Data[1]<=UART0_RX;m<=m+1;end 56: beginUART0_RX_Data[2]<=UART0_RX;m<=m+1;end 72: beginUART0_RX_Data[3]<=UART0_RX;m<=m+1;end 88: beginUART0_RX_Data[4]<=UART0_RX;m<=m+1;end 104:beginUART0_RX_Data[5]<=UART0_RX;m<=m+1;end 120:beginUART0_RX_Data[6]<=UART0_RX;m<=m+1;end 136:beginUART0_RX_Data[7]<=UART0_RX;m<=m+1;end 152:beginUART0_RX_Valid<=1;m<=m+1;end//标志串口数据接收完成 168:beginm<=0;UART0_RX_Valid<=0;end default:m<=m+1; endcase接收数据输出部分:<8位模式>Data01<={UART0_RX_Data[3],UART0_RX_Data[2],UART0_RX_Data[1],UART0_RX_Data[0]};Data02<={UART0_RX_Data[7],UART0_RX_Data[6],UART0_RX_Data[5],UART0_RX_Data[4]};如果系统处于7位模式,那么Data01<={UART0_RX_Data[3],UART0_RX_Data[2],UART0_RX_Data[1],UART0_RX_Data[0]};Data02<={start,UART0_RX_Data[6],UART0_RX_Data[5],UART0_RX_Data[4]};如果系统处于6位模式,那么Data01<={UART0_RX_Data[3],UART0_RX_Data[2],UART0_RX_Data[1],UART0_RX_Data[0]};Data02<={start,start,UART0_RX_Data[5],UART0_RX_Data[4]};其中start=0。仿真结果图2.16UART模块仿真从仿真结果可以看出,波特率时钟clock9600、采样时钟clock3均正常,UART0_TX有正确数据输出,Data01和Data02正确反映了UART0_RX送来的数据,因此UART通信模块功能正确。三系统介绍3.1系统结构介绍整个系统的结构可以用以下框图描述:图3.1系统框图从图3.1中可以看出整个系统的功能即为实现帧格式、波特率可调的全双工串口通信,并显示相关数据信息。具体的操作流程如图3.2所示。图3.2操作流程顶层图如下:图3.3顶层图图中部分1为数据位宽6位的通信子系统,部分2为数据位宽8位的通信子系统,部分3为数据位宽8位的通信子系统,部分4为数据帧长度控制模块,用于选择哪一个系统运作。端口说明输入:clk:50MHz时钟;reset:复位信号;switch:用于控制波特率输入模式和发送数据输入模式间的切换;key_in[3..0]:键盘列扫描信号;UART0_RX:接收数据引脚;B:机械按键,发送确认键;s1:机械按键,按下后显示接收的数据,再按下退出;DDD:机械按键,切换数据位宽。输出:led[3..0]:数据位宽指示灯;key_out[3..0]:键盘行扫描信号;speaker:蜂鸣器控制信号;LED_A~LED_G:显示控制信号;LED_Point,LED_PointTime:均为显示控制信号;LED_VCC1~LED_VCC4:LED片选信号;LED_EN1:使能信号;UART0_TX:发送数据引脚。3.2系统子模块介绍因为三个通信子系统基本相似,所以本文仅介绍数据位宽6位的通信子系统。图3.4子系统图3.4的子系统中左边和右边的模块都是多输入三态门,其使能信号由数据帧长度控制模块控制,从而决定了在任何一时刻三个子系统只有一个系统处于工作状态。该图中间的模块即为实现6位串口通信的功能模块,其结构如图3.5所示。图3.56位串口通信的功能模块如图3.5所示,串口通信模块主要分为6个子模块,各个子模块在前文中都有介绍;模块说明:模块1:UART通信模块,用于数据的接收和传送,将接收到的数据经过三态门<模块传送到显示模块;模块2:输入模块,用于输入波特率、发送数据,将用户输入的数据经过三态门<模块发送到显示模块;模块3,模块4:三态门模块,用于保证任何时刻只有一组显示数据输入显示模块进行显示;模块5:显示模块,用于驱动数码管;模块6:三态门控制模块;用于选择数码管显示的容。端口说明输如:clk:50MHz时钟;reset:复位信号;switch:用于控制波特率输入模式和发送数据输入模式间的切换;key_in[3..0]:键盘列扫描信号;UART0_RX:接收数据引脚;B:机械按键,发送确认键;s1:机械按键,按下后显示接收的数据,再按下退出;输出:key_out[3..0]:键盘行扫描信号;speaker:蜂鸣器控制信号;LED_A~LED_G:显示控制信号;LED_Point,LED_PointTime:均为显示控制信号;LED_VCC1~LED_VCC4:LED片选信号;LED_EN1:使能信号;UART0_TX:发送数据引脚。3.3开发板实验结果实验条件:数据位宽:6位;波特率/波特率因子:38400/1304;发送数据:2’h18;接收数据:2’h32;图

温馨提示

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

评论

0/150

提交评论