UART控制器设计.doc

上传人:韩长文 文档编号:6290977 上传时间:2020-10-18 格式:DOC 页数:24 大小:1.75MB
返回 下载 相关 举报
UART控制器设计.doc_第1页
第1页 / 共24页
UART控制器设计.doc_第2页
第2页 / 共24页
UART控制器设计.doc_第3页
第3页 / 共24页
UART控制器设计.doc_第4页
第4页 / 共24页
UART控制器设计.doc_第5页
第5页 / 共24页
点击查看更多>>
资源描述

《UART控制器设计.doc》由会员分享,可在线阅读,更多相关《UART控制器设计.doc(24页珍藏版)》请在三一文库上搜索。

1、.西安电子科技大学可编程逻辑器件原理、应用与实验 课程实验报告实验名称UART控制器设计及验证成 绩 研究生院 学院 代培生 班姓名 学号 同作者 实验日期 2017 年 4 月 23 日指导教师评语: 指导教师: 年 月 日实验报告内容基本要求及参考格式一、实验目的二、实验所用仪器(或实验环境)三、实验基本原理及步骤(或方案设计及理论计算)四、实验数据记录(或仿真及软件设计)五、实验结果分析及回答问题(或测试环境及测试结果)精品.目录一 任务简介11.1 实验目的11.2 开发工具平台1二 模块设计22.1输入模块设计22.1.1机械按键消抖22.1.2矩阵键盘扫描32.1.3参量输入及显示

2、输入52.2 显示模块62.3三态门控制模块82.4 UART通信协议帧格式及波特率设置92.5 UART通信模块10 2.5.1串口数据发送模块11 2.5.2串口数据接收模块12三 系统介绍133.1系统结构介绍133.2系统子模块介绍153.3 开发板实验结果17四 总结20精品.一 任务简介1.1 实验目的 本次任务的目标为设计一个基于FPGA的串口通信控制器,具体技术要求如下: (1) 实现与PC的双向通信; (2) 可以通过输入模块在开发板上定义向PC发送的数据; (3) 数据帧长度可调(6/7/8位);(4) 通信波特率可调;(5) 在数码管上实现波特率、输入数据、接收数据的显示

3、。(6) 按键A用于接收模式和输入模式的选择,按键B用于选择输入模式为波特率设置 还是发送数据设置,按键C为发送确认键,按键D用于选择数据帧长度,矩阵键盘 (09)用于输入波特率因子和发送数据(十六进制显示);各种模式均有数码管显示相 应内容,其中数据帧长度由四个LED灯表示。 (7) 操作流程: 1. 通信参数设置:在开发板上选择数据帧长度、设置波特率、输入发送数据帧; 在PC端的串口通信助手中设置波特率和数据帧长度; 2. 数据发送:按下C键向PC发送数据,在PC端确认接收的数据; 3. 数据接收:由PC端向开发板发送数据,在开发板上选择数据接收模式即可显示; 4. 默认设置:UART控制

4、器默认波特率为9600,默认发送数据为8h18;(8) 以上内容均需在开发板上验证;实验截图在本文第三部分给出。1.2 开发工具平台(1) 基于CycloneII EP2C5Q208C8核心的MAGIC3200_EP2C5开发板,具有四位扫描式数码管,RS232串口等外设,时钟CLK为50MHz;(2) 开发软件为Quartus II 13sp;(3) 串口通信助手;(4) 基于LP2303的USB-UART转接线,用于与笔记本电脑进行串口通信。 MAGIC3200_EP2C5开发板 USB-UART转接线精品. RS232串口 串口通信助手图1.1 开发平台设备二 模块设计2.1 输入模块设

5、计输入模块采用了矩阵键盘和独立按键,独立按键用于模式选择和发送确认,矩阵键盘用于数据的输入。关于消抖部分,对于矩阵键盘来说只要设置合适的扫描频率就可以实现消抖的功能,而对于独立按键来说就必须设计相应的消抖模块。2.2.1 机械按键消抖模块简介 机械按键按下时的机械抖动会产生很多个下降沿,而在逻辑上希望机械按键按下一次只产生一个下降沿,因此要进行按键消抖。按键防抖动其实是通过延时判断来做的,因为这种毛刺持续时间都在ms级,当检测到按键状态有变化时,经过一定延时后再次进行确认。消抖模块如图2.1所示,din为机械按键输入,dout为消抖后的输出。图2.1 消抖模块图关键程序 图2.2为键盘消抖的状

6、态转移图,按键信号din按下时为低电平,平时为高电平。 (1) 状态S0:输入din信号产生跳变后,进入状态S0。如果din为0,进入S1状态。否则循环检测。(2) 状态S1:如果再次检测到输入信号为逻辑0信号,则表明有按键按下,dout为0。状态机结束。状态机激励时钟周期为0.1s,以此实现延时,即按键按下后0.1s检测按键信号,若按键信号为低电平,则输出低电平完成消抖。精品.图2.2 消抖状态机消抖程序如下:always (posedge keyclk) /状态机激励beginif(RESET=0) pre_s=s0;else pre_s=next_s; endalways (pre_s,

7、next_s,din) /检查按键begin case(pre_s) s0: begin dout=1; if(din=0) next_s=s1; else next_s=s0; end s1: begin dout=1; if(din=0) dout=0; else next_s=s0; end default: next_s=s0; endcaseend2.2.2 矩阵键盘扫描简介及原理图 键盘扫描最大的优点就是能节约I/O口。如果使用普通的方法,那么16个按键就需要16个I/O口,但通过扫描的方式来完成,却只需要8个,按键越多它所显现的优势也就越明显。矩阵键盘原理电路如图2.3。键盘扫描

8、将使用行扫描法实现,即逐行扫描查询法。具体操作为:行线的初始状态输出都为0,只要有高电平出现,表明有按键被按下。在确认有按键被按下的情况下,需要确定具体哪个按键被按下。以一定的扫描频率依次将行线(key_out)电平拉高,并检测列线的输入(key_in),确定具体哪个按键被按下。 图2.3 矩阵键盘原理电路 图2.4 键盘扫描模块图精品.图2.5 键盘扫描模块原理图键盘扫描模块如如图2.4所示,输入为reset信号,clk信号(50MHz时钟),模式切换开关swith,列扫描信号key_in;输出为行扫描信号key_out,波特率因子bote,键盘输入值输出Data0Data4,Data1、D

9、ata2、Data3、Data4为输入模块向显示模块的输出,它们分别对应四位数码管千位、百位、十位、个位显示的内容。send_data为发送数据帧寄存器,图中给出的是8位模式下的键盘扫描模块,所以send_data位宽为8位,在7位和6位模式下扫描模块send_data的位宽分别为7位和6位,其余部分与8位模式下的键盘扫描模块基本一致。speaker为蜂鸣器信号,因为开发板设计上的一些问题,若不定义开发板的蜂鸣器管脚,蜂鸣器有时会响。关键程序其中扫描频率由键盘扫描模块内置的分频模块实现:always (posedge clk or negedge reset)beginif(reset=0)

10、time10ms=0; /最初设计扫描时钟周期为10ms,后来有改动else if(timecnt=1200000) /扫描频率为20Hz(20ms)begin time10ms=time10ms; timecnt=0; endelse timecnt=timecnt+1;end行轮扫的主要程序如下:key_out=scanvalue; /输出行扫描值cpy_scanvalue=scanvalue; /备份扫描值,用于进行列扫描case(scanvalue) /行轮扫4b0001:scanvalue=4b0010;4b0010:scanvalue=4b0100;4b0100:scanvalue

11、=4b1000;4b1000:scanvalue=4b0001;default: scanvalue=4b0001;endcase将键盘扫描与数据输入关联的程序如下: case(key_in,cpy_scanvalue) 8b00010001:begin Data0=1;counter=counter+1; end /对应键盘“1” 8b00100001:begin Data0=2;counter=counter+1; end /对应键盘“2” 8b01000001:begin Data0=3;counter=counter+1; end /对应键盘“3” 8b10000001:begin D

12、ata0=4;counter=counter+1; end/未使用 8b00010010:begin Data0=4;counter=counter+1; end /对应键盘“4” 8b00100010:begin Data0=5;counter=counter+1; end /对应键盘“5” 8b01000010:begin Data0=6;counter=counter+1; end /对应键盘“6”精品. 8b10000010:begin Data0=4;counter=counter+1; end /未使用 8b00010100:begin Data0=7;counter=counte

13、r+1; end /对应键盘“7” 8b00100100:begin Data0=8;counter=counter+1; end /对应键盘“8” 8b01000100:begin Data0=9;counter=counter+1; end /对应键盘“9” 8b10000100:begin Data0=4;counter=counter+1; end /未使用 8b00011000:begin Data0=0;counter=counter+1; end /对应键盘“0” 8b00101000:begin Data0=2;counter=counter+1; end /未使用 8b010

14、01000:begin Data0=3;counter=counter+1; end /未使用 8b10001000:begin Data0=4;counter=counter+1; end /未使用 default:; /无键盘按下 endcase如以上程序所示,每当按下键盘对应按键后,将有对应数值写入寄存器Data0中,寄存器counter为当前输入对应的位数。2.2.3 参量输入及显示输入键盘输入数值的存储程序如下:switch1=0(控制信号下文将详细介绍)时进入波特率设置模式,输入的数值为波特率因子bote,bote为一个四位数,此模式下可以通过矩阵键盘从千位到个位依次写数,将每次输

15、入的值依次写入四位寄存器Data1、Data2、Data3、Data4中,最终组成一个完整的十进制四位数,其中counter为位数标志位。Data1、Data2、Data3、Data4为输入模块向显示模块的输出,它们分别对应四位数码管千位、百位、十位、个位显示的内容。 if(switch1=0) begin bote=Data1*1000+Data2*100+Data3*10+Data4; case(counter) 4b0001:Data1=Data0; 4b0010:Data2=Data0; 4b0011:Data3=Data0; 4b0100:Data4=Data0; default:b

16、egin Data1=5;Data2=2;Data3=0;Data4=8; end endcase if(counter=5) counter=0; endswitch=1时进入发送数据设置模式,最终把键盘输入值写入send_data,发送寄存器send_data为一个68位(可设置)的二进制数,用于存储将要发送的数据帧。因为四个Data寄存器位宽为4位,所以send_data的内容只需要由两个寄存器的数据构成。令Data1、Data2为10,意思为关闭千位、百位的数码管,这在显示模块部分将会详细介绍。 else begin send_data=Data3,Data4; Data1=10;精品

17、. Data2=10; case(counter) 4b0001:Data3=Data0; 4b0010:Data4=Data0; default:begin Data3=8;Data42) counter=0; end 仿真结果:图2.6 键盘扫描模块仿真为了方便观察结果,仿真中加快了时钟和一些分频的频率。从仿真图像可以看出,行线扫描信号key_out以一定频率扫描,当列扫描信号key_in有所输入时,输入寄存器Data0、Data1、Data2、Data3、Data4都有相应的变化。而且当切换开关switch按下时,输出信号bote和send_data都发生了相应变化,这说明波特率设置模式

18、和发送数据写入模式的切换功能正常运行。仿真表明输入模块在功能上是可行的。2.2 显示模块模块简介及原理图显示模块用于驱动开发板上的四位数码管显示串口数据,每个数码管有八个控制位和一个片选位,还有一个用于显示:控制位。由于开发板只给出了13个引脚用于控制四个数码管,因此必须采用数码管扫描的形式来进行显示。因为人眼有视觉暂留的特性.一般说来,当1秒钟刷新24次以上,人眼就无法区分而认为四个数码管是一起亮的。扫描具有节约引脚的优点,如果并行驱动四位数码管,那么至少需要33个引脚,而扫描法只需要13个引脚就可以实现。使用的是共阳数码管,引脚电平为低时点亮。精品. 图2.7 显示模块显示模块如图2.6所

19、示,输入为reset信号,50Mhz时钟信号clk,前文提到的Data1、Data2、Data3、Data4显示内容输入,分别对应四位数码管千位、百位、十位、个位的显示内容。输出信号中的LED_ALED_G、LED_Point、LED_PointTime均为显示控制信号;LED_VCC1LED_VCC4为LED片选信号,高电平有效,LED_EN1为使能信号。关键程序以下为数码管扫描的关键程序:always (posedge clk)beginif(reset=b0) count=0;else if(count=6000) /设置数码管扫描频率begincount3) scancnt=0;els

20、e scancnt=scancnt+1;endelse count=count+1;end以上程序主要作用是,使变量scancnt扫描频率在03内累加循环,scancnt有0123共四个状态,通过scancnt控制数码管片选信号,分别在四个数码管上显示内容。译码部分见附录。仿真结果图2.8 显示模块仿真结果 可以看出随着Data1和Data1的变化,LED控制信号和LED片选信号同时变化,说明显示模块功能正常。精品.2.3 三态门控制模块模块简介及原理图在本任务顶层的设计中有些部分需要使用多输入三态门来控制数据的传输,本部分将以任务中的一个多输入三态门来介绍该模块。模块的原理图和模块图如图2.

21、9所示 图2.9 三态门模块如图所示,data1data4为输入数据,D1D4为输出,若en=1则D1D4输出data1data4的数据,若en=0则D1D4输出高阻。关键程序 if(en=1) begin D1=data1;D2=data2;D3=data3;D4=data4; endelse begin D1=4bzzzz; D2=4bzzzz;D3=4bzzzz;D42) counter=0; / counter大于2时清零else counter= counter+1;endalways(posedge DD)beginif(counter=0) begin c=3b001; led=

22、4b0111; end / 8位模式else if(counter=1) begin c=3b010; led=4b1000; end / 7位模式精品.else if(counter=2) begin c=3b100; led=4b1001; end / 6位模式else begin c=3b001; led=4b0000; end / 默认8位模式End仿真结果图2.13 控制模块仿真 输出随输入规律变化,可以看出模块功能正常。波特率设置:波特率发生器为传输提供了串行移位时钟。波特率表示数据的传送速率,即每秒传输二进制的位数。波特率控制模块实际上是一个分频器,产生相应的符合RS232的波特

23、率同步时钟。 因为开发板自带时钟为50MHz,因此:波特率=50M/bote;可见其中波特率是由波特率因子bote决定,若bote=5208,则波特率为9600。关键程序always (posedge CLK or negedge RESET) beginif(ClockCount=bote) begin Clock9600=1; ClockCount=0; endelsebegin Clock9600=0; ClockCount=ClockCount+1; end end波特率发生器本质为一个分频器,bote为之前键盘输入模块送来的设定值。仿真结果该模块的仿真验证将于下文中UART通信模块的

24、仿真中一并验证。2.5 UART通信模块模块介绍及原理图基本的UART仅有RXD和TXD两条信号线,接收和发送之间相互不存在干扰,即全双工。由于UART是异步通信,要求RXD接口和TXD发送端制定相应的规则,对数据进行同步,以使接收、发送之间协调一致。UART的工作原理是将传输数据的每一个字符一位接一位地传输,以字符为单位从低位到高位逐位传输,一个字符表示一帧信息。精品.如图2.14所示,串口数据发送模块和串口数据接收模块以及相关分频模块都集成于同一个UART模块中。 输入:CLK:50MHz时钟;RESET:复位信号;UART0_RX:接收数据引脚;KEYA:对应机械按键C,为发送确认键;b

25、ote14.0:由输入模块送来的波特率因子,用于设置波特率;SEND_DATA7.0:数据帧,在6位模式中位宽为6,在7位模式中位宽为7。输出:UART0_TX:发送数据引脚;Data010.3Data040.3:用于向显示模块传递接收的数据。图2.14 UART模块2.5.1 串口数据发送模块 关键程序Clock9600为前文介绍的波特率发生器产生的波特率时钟;always (posedge Clock9600 or posedge Send_en)begin if(Send_en=1) begin send_count=0; UART0_TX=1; send_over=1; end /串口

26、清零 else if(Send_count=9) begin UART0_TX=Send_data9; send_over=0; end/发送完成 else begin UART0_TX=Send_dataSend_count; /逐位由发送寄存器向串口写数据 Send_count=Send_count+1; endalways (posedge dout or negedge RESET) /发送数据beginif(RESET=0) begin send_en=1;Send_data=10b1000000000; endelse begin Send_en=0; Send_data=last

27、,SEND_DATA,start; /写入起始位和终止位精品.if(Send_over=0) Send_en=1;endend 2.5.2 串口数据接收模块 首先介绍采样时钟Clock3,它是波特率的16倍,即串口上一个数据位长度会有16个Clock3周期,如果在每个数据位的第8个Clock3周期上采样,即在每个数据位的中间进行取样,这样可以使采样值更加准确可靠。此原理如图2.15所示。图2.15 采样原理关键程序接收采样时钟分频模块:always (posedge CLK or negedge RESET)beginif(ClockCount_UART0_RX=bote/16) / 采样频率

28、为波特率的16倍 begin Clock3=1; ClockCount_UART0_RX=0; endelse begin Clock3=0; ClockCount_UART0_RX=ClockCount_UART0_RX+1; endend检测到UART0_RX出现下降沿时,令UART0_RX_Hold=1,启动接收进程;case(m)/ 8位数据帧采样24 :begin UART0_RX_Data0=UART0_RX;m=m+1;end40 :begin UART0_RX_Data1=UART0_RX;m=m+1;end56 :begin UART0_RX_Data2=UART0_RX;m

29、=m+1;end72 :begin UART0_RX_Data3=UART0_RX;m=m+1;end88 :begin UART0_RX_Data4=UART0_RX;m=m+1;end104 :begin UART0_RX_Data5=UART0_RX;m=m+1;end120 :begin UART0_RX_Data6=UART0_RX;m=m+1;end136 :begin UART0_RX_Data7=UART0_RX;m=m+1;end152 :begin UART0_RX_Valid=1;m=m+1;end /标志串口数据接收完成168 : begin m=0;UART0_RX_

30、Valid=0;enddefault:m=m+1;endcase精品.接收数据输出部分:(8位模式)Data01=UART0_RX_Data3,UART0_RX_Data2,UART0_RX_Data1,UART0_RX_Data0;Data02=UART0_RX_Data7,UART0_RX_Data6,UART0_RX_Data5,UART0_RX_Data4;如果系统处于7位模式,那么Data01=UART0_RX_Data3,UART0_RX_Data2,UART0_RX_Data1,UART0_RX_Data0;Data02=start,UART0_RX_Data6,UART0_RX

31、_Data5,UART0_RX_Data4;如果系统处于6位模式,那么Data01=UART0_RX_Data3,UART0_RX_Data2,UART0_RX_Data1,UART0_RX_Data0;Data02=start,start,UART0_RX_Data5,UART0_RX_Data4;其中start=0。仿真结果图2.16 UART模块仿真 从仿真结果可以看出,波特率时钟clock9600、采样时钟clock3均正常,UART0_TX有正确数据输出,Data01和Data02正确反映了UART0_RX送来的数据,因此UART通信模块功能正确。三 系统介绍3.1 系统结构介绍整个

32、系统的结构可以用以下框图描述:图3.1 系统框图 从图3.1中可以看出整个系统的功能即为实现帧格式、波特率可调的全双工串口通信,并显示相关数据信息。具体的操作流程如图3.2所示。精品.图3.2 操作流程 顶层图如下:图3.3 顶层图图中部分1为数据位宽6位的通信子系统,部分2为数据位宽8位的通信子系统,部分3为数据位宽8位的通信子系统,部分4为数据帧长度控制模块,用于选择哪一个系统运作。端口说明输入:clk:50MHz时钟;reset:复位信号;switch:用于控制波特率输入模式和发送数据输入模式间的切换;key_in3.0:键盘列扫描信号;UART0_RX:接收数据引脚;B:机械按键,发送

33、确认键;s1:机械按键,按下后显示接收的数据,再按下退出;DDD:机械按键,切换数据位宽。输出:led3.0:数据位宽指示灯;key_out3.0:键盘行扫描信号;speaker:蜂鸣器控制信号;LED_ALED_G:显示控制信号;LED_Point,LED_PointTime:均为显示控制信号;LED_VCC1LED_VCC4:LED片选信号;LED_EN1:使能信号;UART0_TX:发送数据引脚。3.2 系统子模块介绍 因为三个通信子系统基本相似,所以本文仅介绍数据位宽6位的通信子系统。精品.图3.4 子系统图3.4的子系统中左边和右边的模块都是多输入三态门,其使能信号由数据帧长度控制模

34、块控制,从而决定了在任何一时刻三个子系统只有一个系统处于工作状态。该图中间的模块即为实现6位串口通信的功能模块,其结构如图3.5所示。图3.5 6位串口通信的功能模块如图3.5所示,串口通信模块主要分为6个子模块,各个子模块在前文中都有介绍;模块说明:模块1:UART通信模块,用于数据的接收和传送,将接收到的数据经过三态门(模块 4) 传送到显示模块;模块2:输入模块,用于输入波特率、发送数据,将用户输入的数据经过三态门(模块 3) 发送到显示模块;模块3,模块4:三态门模块,用于保证任何时刻只有一组显示数据输入显示模块进行 显示;模块5:显示模块,用于驱动数码管;模块6:三态门控制模块;用于

35、选择数码管显示的内容。端口说明输如:精品.clk:50MHz时钟;reset:复位信号;switch:用于控制波特率输入模式和发送数据输入模式间的切换;key_in3.0:键盘列扫描信号;UART0_RX:接收数据引脚;B:机械按键,发送确认键;s1:机械按键,按下后显示接收的数据,再按下退出;输出:key_out3.0:键盘行扫描信号;speaker:蜂鸣器控制信号;LED_ALED_G:显示控制信号;LED_Point,LED_PointTime:均为显示控制信号;LED_VCC1LED_VCC4:LED片选信号;LED_EN1:使能信号;UART0_TX:发送数据引脚。3.3 开发板实验

36、结果(1) 实验条件: 数据位宽:6位; 波特率 / 波特率因子:38400 / 1304;精品. 发送数据:2h18;接收数据:2h32;图3.6 设置波特率因子(6位位宽) 图3.7 设置发送数据(6位位宽) 图3.8 显示接收数据(6位位宽)图3.9 PC端串口通信助手(绿字为开发板送来的数据黑字为向开发板发送的数据)(2) 实验条件:(按下按键D切换数据位宽) 数据位宽:7位; 波特率 / 波特率因子:19200 / 2604; 发送数据:2h31;接收数据:2h56;精品.图3.10 设置波特率因子(7位位宽) 图3.11 设置发送数据(7位位宽) 图3.12 显示接收数据(7位位宽

37、)图3.9 PC端串口通信助手(绿字为开发板送来的数据黑字为向开发板发送的数据)(3) 实验条件:(按下按键D切换数据位宽) 数据位宽:8位; 波特率 / 波特率因子:9600 / 5208; 发送数据:2h99;接收数据:2h66;精品.图3.13 设置波特率因子(8位位宽) 图3.14 设置发送数据(8位位宽) 图3.15 显示接收数据(8位位宽)图3.16 PC端串口通信助手(绿字为开发板送来的数据黑字为向开发板发送的数据)实验总结从实验结果可以看出,PC端串口助手上,设置的波特率和数据位宽,接收和发送的数据均与开发板上数码管和led等显示的数据相一致;在6位位宽的实验中波特率为3840

38、0;对应的波特率因子本应该为1302,而实际设置的波特率因子为1304,而串口通信依然正常进行,这说明本系统具有一定的容错能力。精品.综上所述,开发板实验验证了本次任务设计的系统功能都已在硬件上实现。五 总结在本次项目中我的体会主要由以下几点: 一、自身的编程水平和软件水平需要提高,在本项目的设计过程中我遇到了很多问题,比如刚开始编程时总会出现一些无法理解的语法问题,例如a=b/2这样的除法运算中要求a和b的数据位宽是一样的,否则运算难以成立。解决这些问题花费了我大量的时间,这反映出我对于verilog语言的语法的理解依然不够。在软件层面,quartus的很多功能我依然不能熟练使用,例如如何将modelsim与quartus的工程直接建立联系,编写testbench在modelsim进行仿真;又比如使用SignalTap抓取开发板运行时的一些信号,熟练使用SignalTap可以非常方便的验证自己项目的时序和排除故障;这些功能非常强大软件功能我还没有熟练的掌握,这说明我仍然需要更多的学习。 二、语言和软件只是工具,设计思想才是至关重要的核心。在学习和实际操作FPGA以前我一直认为只要熟练掌握开发语言和软件就可以胜任开发工作。然而我在实际的操作过程中却发现,大部分的逻辑功能都可以由简单的verilog语句实现,而怎么去用语言实现一个功能如果有正确的设计思想确实是可

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 科普知识


经营许可证编号:宁ICP备18001539号-1