研究生FPGA实验题目串口通信Word文件下载.docx

上传人:b****2 文档编号:4983547 上传时间:2023-05-04 格式:DOCX 页数:30 大小:327.24KB
下载 相关 举报
研究生FPGA实验题目串口通信Word文件下载.docx_第1页
第1页 / 共30页
研究生FPGA实验题目串口通信Word文件下载.docx_第2页
第2页 / 共30页
研究生FPGA实验题目串口通信Word文件下载.docx_第3页
第3页 / 共30页
研究生FPGA实验题目串口通信Word文件下载.docx_第4页
第4页 / 共30页
研究生FPGA实验题目串口通信Word文件下载.docx_第5页
第5页 / 共30页
研究生FPGA实验题目串口通信Word文件下载.docx_第6页
第6页 / 共30页
研究生FPGA实验题目串口通信Word文件下载.docx_第7页
第7页 / 共30页
研究生FPGA实验题目串口通信Word文件下载.docx_第8页
第8页 / 共30页
研究生FPGA实验题目串口通信Word文件下载.docx_第9页
第9页 / 共30页
研究生FPGA实验题目串口通信Word文件下载.docx_第10页
第10页 / 共30页
研究生FPGA实验题目串口通信Word文件下载.docx_第11页
第11页 / 共30页
研究生FPGA实验题目串口通信Word文件下载.docx_第12页
第12页 / 共30页
研究生FPGA实验题目串口通信Word文件下载.docx_第13页
第13页 / 共30页
研究生FPGA实验题目串口通信Word文件下载.docx_第14页
第14页 / 共30页
研究生FPGA实验题目串口通信Word文件下载.docx_第15页
第15页 / 共30页
研究生FPGA实验题目串口通信Word文件下载.docx_第16页
第16页 / 共30页
研究生FPGA实验题目串口通信Word文件下载.docx_第17页
第17页 / 共30页
研究生FPGA实验题目串口通信Word文件下载.docx_第18页
第18页 / 共30页
研究生FPGA实验题目串口通信Word文件下载.docx_第19页
第19页 / 共30页
研究生FPGA实验题目串口通信Word文件下载.docx_第20页
第20页 / 共30页
亲,该文档总共30页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

研究生FPGA实验题目串口通信Word文件下载.docx

《研究生FPGA实验题目串口通信Word文件下载.docx》由会员分享,可在线阅读,更多相关《研究生FPGA实验题目串口通信Word文件下载.docx(30页珍藏版)》请在冰点文库上搜索。

研究生FPGA实验题目串口通信Word文件下载.docx

START

D0

D1

D2

D3

D4

D5

D6

D7

P

STOP

起始位

数据位

校验位

停止位

FPGAUART系统组成:

如下图所示,FPGAUART由三个子模块组成:

波特率发生器;

接收模块;

发送模块;

2、模块设计:

系统由四部部分组成:

顶层模块;

UART接收器;

UART发送器

1)顶层模块

异步收发器的顶层模块由波特率发生器、UART接收器和UART发送器构成。

UART发送器的用途是将准备输出的并行数据按照基本UART帧格式转为TXD信号串行输出。

UART接收器接收RXD串行信号,并将其转化为并行数据。

波特率发生器就是专门产生一个远远高于波特率的本地时钟信号对输入RXD不断采样,使接收器与发送器保持同步。

2)波特率发生器

波特率发生器实际上就是一个分频器。

可以根据给定的系统时钟频率(晶振时钟)和要求的波特率算出波特率分频因子,算出的波特率分频因子作为分频器的分频数。

波特率分频因子可以根据不同的应用需要更改。

3)UART接收器

由于串行数据帧和接收时钟是异步的,由逻辑1转为逻辑0可以被视为一个数据帧的起始位。

然而,为了避免毛刺影响,能够得到正确的起始位信号,必须要求接收到的起始位在波特率时钟采样的过程中至少有一半都是属于逻辑0才可认定接收到的是起始位。

由于内部采样时钟bclk周期(由波特率发生器产生)是发送或接收波特率时钟频率的16倍,所以起始位需要至少8个连续bclk周期的逻辑0被接收到,才认为起始位接收到,接着数据位和奇偶校验位将每隔16个bclk周期被采样一次(即每一个波特率时钟被采样一次)。

如果起始位的确是16个bclk周期长,那么接下来的数据将在每个位的中点处被采样。

UART接收器的接收状态机

接收状态机一共有5个状态:

R_START(等待起始位);

R_CENTER(求中点);

R_WAIT(等待采样);

R_SAMPLE(采样);

R_STOP(停止位接收)。

R_START状态

当UART接收器复位后,接收状态机将处于这一个状态。

在此状态,状态机一直在等待RXD的电平跳转,从逻辑1变为逻辑0,即起始位,这意味着新的一帧UART数据帧的开始,一旦起始位被确定,状态机将转入R_CENTER状态。

状态图中的RXD_SYNC信号是RXD的同步信号,因为在进行逻辑1或逻辑0判断时,不希望检测的信号是不稳定的,所以不直接检测RXD信号,而是检测经过同步后的RXD_SYNC信号。

R_CENTER状态

对于异步串行信号,为了使每一次都检测到正确的位信号,而且在较后的数据位检测时累计误差较小,显然在每位的中点检测是最为理想的。

在本状态,就是由起始位求出每位的中点,通过对bclk的个数进行计数(RCNT16),但计数值不是想当然的“1000”,要考虑经过一个状态,也即经过了一个bclk周期,所希望得到的是在采样时1/2位。

另外,可能在R_START状态检测到的起始位不是真正的起始位,可能是一个偶然出现的干扰尖脉冲(负脉冲)。

这种干扰脉冲的周期是很短的,所以可以认为保持逻辑0超过1/4个位时间的信号一定是起始位。

R_WAIT状态

当状态机处于这一状态,等待计满15个bclk,在第16个bclk是进入R_SAMPLE状态进行数据位的采样检测,同时也判断是否采集的数据位长度已达到数据帧的长度(FRAMELEN),如果到来,就说明停止位来临了。

FRAMELEN在设计时是可更改的(使用了Generic),在本设计中默认为8,即对应的UART工作在8位数据位、无校验位格式。

R_SAMPLE状态

即数据位采样检测,完成后无条件状态机转入R_WAIT状态,等待下次数据位的到来。

R_STOP状态

无论停止位是1还是1.5位,或是2位,状态机在R_STOP不具体检测RXD,只是输出帧接收完毕信号(REC_DONE<

=‘1’),停止位后状态机转回到R_START状态,等待下一个帧的起始位。

4)UART发送器

发送器只要每隔16个bclk周期输出1个数据即可,次序遵循第1位是起始位,第8位是停止位。

在本设计中没有校验位,但只要改变Generic参数FrameLen,也可以加入校验位,停止位是固定的1位格式。

发送状态机的状态图

发送状态机一共有5个状态:

X_IDLE(空闲);

X_START(起始位);

X_WAIT(移位等待);

X_SHIFT(移位);

X_STOP(停止位)。

X_IDLE状态:

当UART被复位信号复位后,状态机将立刻进入这一状态。

在这个状态下,UART的发送器一直在等待一个数据帧发送命令XMIT_CMD。

XMIT_CMD_P信号是对XMIT_CMD的处理,XMIT_CMD_P是一个短脉冲信号。

这时由于XMIT_CMD是一个外加信号,在FPGA之外,不可能对XMIT_CMD的脉冲宽度进行限制,如果XMIT_CMD有效在UART发完一个数据帧后仍然有效,那么就会错误地被认为,一个新的数据发送命令又到来了,UART发送器就会再次启动UART帧的发送,显然该帧的发送是错误的。

在此对XMIT_CMD进行了脉冲宽度的限定,XMIT_CMD_P就是一个处理后的信号。

当XMIT_CMD_P=‘1’,状态机转入X_START,准备发送起始位。

X_START状态:

在这个状态下,UART的发送器一个位时间宽度的逻辑0信号至TXD,即起始位。

紧接着状态机转入X_WAIT状态。

XCNT16是bclk的计数器

X_WAIT状态

同UART接收状态机中的R_WAIT状态类似。

X_SHIFT状态

当状态机处于这一状态时,实现待发数据的并串转换。

转换完成立即回到X_WAIT状态。

X_STOP

停止位发送状态,当数据帧发送完毕,状态机转入该状态,并发送16个bclk周期的逻辑1信号,即1位停止位。

状态机送完停止位后回到X_IDLE状态,并等待另一个数据帧的发送命令。

实验步骤:

1、创建工程文件

按照Quartus软件新建工程向导建立工程,工程名设为:

uart_test(可自行命名)。

2、子模块电路设计(包括各个模块的功能仿真)

1)波特率发生器

程序编写:

在“文件”菜单下选择“New”,在弹出的窗口点击“VHDLFile”点击“OK”打开vhdl编辑窗口。

编辑输入波特率发生器程序,编辑完毕后保存,文件名保存为“baud”

(注:

文件名必须与程序中实体名一致)

选中“Addfiletocurrentproject”选项,添加当前文件到项目。

--文件名:

baud.vhd.

--功能:

本实验想要实现的波特率为:

9600,EDA实验箱上晶振频率为:

4MHZ,

--波特率发生器的分频数计算如下式:

--4000000/(16*9600)=26

libraryIEEE;

useIEEE.STD_LOGIC_1164.ALL;

useIEEE.STD_LOGIC_ARITH.ALL;

useIEEE.STD_LOGIC_UNSIGNED.ALL;

entitybaudis

generic(framlenr:

integer:

=26);

Port(clk,resetb:

instd_logic;

bclk:

outstd_logic);

endbaud;

architectureBehavioralofbaudis

begin

process(clk,resetb)

variablecnt:

integer;

ifresetb='

1'

thencnt:

=0;

bclk<

='

0'

;

--复位

elsifrising_edge(clk)then

ifcnt>

=framlenrthencnt:

--设置分频系数

elsecnt:

=cnt+1;

endif;

endprocess;

endBehavioral;

文件编译:

保存文件后,选择“Project”菜单,点击“SetasTop-LevelEntity”项,把当前文件设置为顶层实体。

Quartus环境下所有操作(综合、编译、仿真、下载等)都只对顶层实体进行,所以编译任何程序前,必须先设置该选项,把当前要编译的文件设置为顶层实体后,才能对该文件进行编译等操作)

打开“Processing”菜单,点击“StartCompilation”执行完全编译

状态窗口显示编译过程进度信息

编译结束,系统会弹出编译结束窗口,报告错误与警告数,点击“确定”。

编译报告给出所有编译结果信息,包括硬件信息、资源占用率等。

错误修改:

如果程序中有错误,需要根据“Messages”消息栏给出的错误提示修改程序,保存后须再次编译,直至所有错误均改正后,方可执行下一步操作。

警告信息可以忽略。

波形仿真:

1.建立波形图文件

关闭编译报告窗口,在“文件”菜单下选择“New”,选中“otherfiles”标签页,在弹出的窗口点击“VectorWaveformFile”点击“OK”打开波形编辑窗口。

波形图编辑窗口

2.定义仿真观测的输入输出节点

在波形编辑窗口左侧栏内单击鼠标右键,出现浮动菜单,选择“InsertNoteorBus…”出现“InsertNoteorBus…”对话框,点击“NodeFinder…”按键,出现“NodeFinder”对话框,如下图所示。

在图中“Filter:

”选项下选择管脚类型为“Pins:

all”,然后单击List按钮,可在左下侧区域看到设计项目中的输入输出信号,单击按钮“=〉”,将这些信号选择到“SelectedNodes”区,表示对这些信号进行观测,单击OK

此时的波形编辑窗口如下图所示。

保存波形文件,文件名为uart_test.vwf(注:

扩展名默认不填,文件名与项目名同名)

3.为输入信号赋值

波形编辑器窗口左侧为信号赋值工具条,根据实际要求点选工具按钮对输入信号赋值。

1)为时钟信号clk赋值:

单击clk,使其呈蓝色即选中了clk,单击为时钟信号赋值工具按钮

,弹出Clock对话框,在Period框中输入合适的时钟周期数,其它值按默认即可,点击OK。

2)为复位信号resetb赋值:

选中resetb,单击赋值0工具条按钮,为期赋值为逻辑0。

3)设置仿真时间

选择Edit菜单下的EndTime…选项,打开EndTime对话框,在time框内入输100单位为us。

再次保存波形文件,窗口如下

4.时序仿真

选择Processing菜单下的BeginSimulation选项,即开始波形仿真。

状态窗口会显示出仿真进程,

仿真结束后可以看到仿真结果波形,如下图所示。

观察波形可用工具条上的放大缩小按钮放大缩小波形图,下图即为已经缩小了很多倍后的波形图。

结果分析:

图上可以观察到输出端bckl等间隔的有脉冲信号输出,通过标尺可以计算出它的脉冲输出频率及其与clk输入信号的关系。

该程序实现的是波特率发生器,输出频率为时钟输入频率的1/26。

生成符号文件:

通过波形仿真可以确定程序功能是否正确后,就可以把该程序生成符号文件,以便在后面的程序中调用。

具体操作是:

打开File文件菜单,选择Creat/Updata菜单项,右侧弹出子菜单再选择CreatSymbolfilesforCurrentfile把当前文件创建成符号文件。

状态窗口有进度信息显示。

生成的符号文件可以通过打开原理图窗口调入,进行验证。

下图为生成的波特率模块。

按照生成波特率模块的步骤完成以下其它模块的程序编写,并进行仿真波形、功能验证,仿真通过后生成各自的符号文件。

这里只给出仿真得到的波形图。

2)UART发送器

UART发送器程序:

transfer.vhd

UART发送器

--说明:

系统由五个状态(x_idle,x_start,x_wait,x_shift,x_stop)和一个进程构成。

entitytransferis

generic(framlent:

=8);

--类属说明

Port(bclkt,resett,xmit_cmd_p:

--定义输入输出信号

txdbuf:

instd_logic_vector(7downto0);

txd,txd_done:

endtransfer;

architectureBehavioraloftransferis

typestatesis(x_idle,x_start,x_wait,x_shift,x_stop);

--定义5个子状态

signalstate:

states:

=x_idle;

signaltcnt:

process(bclkt,resett,xmit_cmd_p,txdbuf)--主控时序进程

variablexcnt16:

std_logic_vector(4downto0):

="

00000"

--定义中间变量

variablexbitcnt:

variabletxds:

std_logic;

begin

ifresett='

thenstate<

--复位,txd输出保持1

txd_done<

txds:

elsifrising_edge(bclkt)then

casestateis

whenx_idle=>

--状态1,等待数据帧发送命令

ifxmit_cmd_p='

=x_start;

txd_done<

elsestate<

whenx_start=>

--状态2,发送信号至起始位

ifxcnt16="

01111"

=x_shift;

xcnt16:

elsexcnt16:

=xcnt16+1;

txds:

state<

--输出开始位,'

whenx_wait=>

--状态3,等待状态

ifxcnt16>

01110"

then

ifxbitcnt=framlentthenstate<

=x_stop;

xbitcnt:

elsestate<

=x_wait;

whenx_shift=>

--状态4,将待发数据进行并串转换

=txdbuf(xbitcnt);

=xbitcnt+1;

whenx_stop=>

--状态5,停止位发送状态

--高电平保持时间应低于一个帧发送的时间

xcnt16:

elsexcnt16:

=xcnt16;

endif;

txd_done<

whenothers=>

state<

endcase;

endif;

txd<

=txds;

endprocess;

生成的模块如下图所示:

仿真波形:

说明:

1)resett:

为复位信号,高电平复位,初始时刻需要手动设置一段时间的高电平

2)Bclkt为波特率发生信号,用时钟信号定义,周期设为10ns。

3)为了得到完整的仿真结果,仿真时间要设的长一些(100us)

4)xmit_cmd_p:

为发送控制信号,开始时刻设置一段高电平

5)txdbuf:

为要发送的八位数据,点击“+”后,可对每一个位信号分别赋值,

本波形设置为txdbuf[7]、[5]、[3]、[1]位置“1”,[6]、[4]、[2]、[0]位置“0”

6)txd:

为发送器发出的串行信号

7)txd_done:

为发送结束信号,高电平有效

3)UART接收器

UART接收器程序:

reciever.vhd.

--功能:

UART接受器。

--系统由五个状态(r_start,r_center,r_wait,r_sample,r_stop)和两个进程构成

entityrecieveris

--传送的数据位为8位

Port(bclkr,resetr,rxdr:

r_ready:

outstd_logic;

rbuf:

outstd_logic_vector(7downto0));

endreciever;

architectureBehavioralofrecieveris

typestatesis(r_start,r_center,r_wait,r_sample,r_stop);

--定义各子状态

signalstate:

=r_start;

signalrxd_sync:

--rxd_sync内部信号,接受rxd输入

begin

pro1:

process(rxdr)

ifrxdr='

thenrxd_sync<

elserxd_sync<

pro2:

process(bclkr,resetr,rxd_sync)--主控时序、组合进程

variablecount:

std_logic_vector(3downto0);

variablercnt:

--rcnt为接收的数据位数计数

variablerbufs:

std_logic_vector(7downto0);

ifresetr='

count:

0000"

elsifrising_edge(bclkr)then--波特率信号的上升沿

--状态机

casestateis

whenr_start=>

--状态1,等待起始位

ifrxd_sync='

=r_center;

r_ready<

rcnt:

elsestate<

r_ready<

endif;

whenr_center=>

--状态2,求出每位的中点

then--每个数据位被分为16等分,中点为8

ifcount="

0100"

=r_wait;

elsecount:

=count+1;

whenr_wait=>

ifcount>

1110"

then

ifrcnt=framlenrthenstate<

=r_stop;

--rcnt=framlenr表示数据接收够8位

=r_sample;

endIf;

count:

elsecount:

wh

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

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2