串行口数据传输的仿真及硬件实现.docx
《串行口数据传输的仿真及硬件实现.docx》由会员分享,可在线阅读,更多相关《串行口数据传输的仿真及硬件实现.docx(25页珍藏版)》请在冰豆网上搜索。
串行口数据传输的仿真及硬件实现
串行口数据传输的仿真
及硬件实现
第*组
班级:
**********
姓名:
******
指导老师:
***
一、实验目的:
串行口数据传输是数字系统中常用的一种数据传输方式。
本次课程设计要求学生综合数字逻辑电路和串行口通信的有关知识,用硬件独立设计完成一个简单的串行口数据传输系统,并用FPGA可编程逻辑器件进行仿真。
二、实验仪器
1双踪示波器1台
2直流稳压电源1台
3频率计1台
4数字万用表1台
5面包板1台
三、实验内容与设计:
1、实验内容:
一个简单的串行口数据传输系统的系统框图如下:
同步字符
结束字符发生器
信息码
由图可见,系统分为发送端,接收端两部分。
发送端主要是同步字符、结束字符、时钟电路和信息码发生器。
接收端包括串/并转换电路、字符检测电路、控制电路、锁存接收和显示电路。
2、各部分功能的端口设置:
(1)时钟电路:
晶振的时钟输入信号、通过分频后提供系统使用的输出信号。
(2)信号发生电路:
时钟电路发出的时钟信号输入端、生成的序列输出端。
(3)串并转换电路:
时钟信号输入、串行序列输入端、并行序列输出端。
(4)字符检测电路:
若采用并行检测,有并行数据输入端、检测信号输出端;
若采用串行检测,有串行数据接入端、时钟信号输入端、
检测信号输出端。
(5)控制电路:
时钟信号输如端、检测信号输入端、控制信号输出端。
(6)锁存电路:
控制信号输入端、并行数据输入端、并行数据输出端。
(7)显示电路:
并行数据输入端。
3、各部分的逻辑设计:
(1)时钟电路设计:
由于晶振产生的时钟频率为1MHz,而为了显示稳定,需要的时钟频率为2Hz以下,所以需要分频。
本次设计采用的是同步计数器来进行分频,输出端为Qa~Qd,分频系数为2N(N为端口数)。
每个74LS163最多为24=16分频,而需要的分频系数:
106÷2=5×105≈219。
所以需要5块74LS163芯片用作分频。
具体电路图如下:
所得的输出频率约为2Hz.
(2)序列信号发生器设计:
本次实验需要产生的序列为15位循环码“111100010011010”,通过检验可知,此序列产生的15个4位序列不互相重复,因此可以用4个D触发器来构造序列发生器。
此序列信号发生器的反馈电路可以通过“与”、“或”、“非”逻辑门或数据选择器实现。
本次实验中,我们使用了数据选择器。
状态表及卡诺图如下所示:
Q4
Q3
Q2
Q1
Q4Q3
Q2Q1
00
01
11
10
00
φ
1
0
1
01
0
1
0
1
11
0
1
0
1
10
0
1
0
1
D
1
1
1
1
0
1
1
1
0
0
1
1
0
0
0
1
0
0
0
1
0
0
0
1
0
0
0
1
0
0
0
1
0
0
1
1
0
0
1
1
0
0
1
1
0
0
1
1
0
1
1
1
0
1
0
1
0
1
0
1
0
1
0
1
1
1
0
1
1
1
0
1
1
1
1
为使系统能够自启动,令φ=1。
使用Q4Q3作为数据选择器的输入,有
C0=
,C1=1,C2=1,C3=0
故序列信号发生器的电路图设计如下所
(3)串并转换电路的设计
因为系统需要7位并行输出,所以串并转换电路可由两块移位寄存器74LS194级联构成。
电路图如下:
(4)串行字符检测电路的设计:
串行字符检测实际就是依次对字符进行检测,符合同步码的输出1,否则输出0。
但若对7位同步码都进行检测,需要的触发器较多,电路将非常复杂。
通过观察发现同步码后4位1000在整个序列中是唯一的,因此实验中通过检测1000来达到检测同步码的效果。
检测电路可通过状态机来实现。
状态转移图如下所示:
1/0
0/0
A
B
1/0
0/11/01/00/0
C
D
0/0
对A、B、C、D进行编码:
A00,B01,C11,D10
X=0
Z
X=0
X=1
00
0
0
01
0
0
11
0
0
10
1
0
X=1
00
00
01
01
11
01
11
10
01
10
00
01
卡诺图如下:
Q2Q1
D
00
01
11
Q2Q1
D
00
01
11
10
0
0
1
0
0
1
1
1
1
1
Q1n+1
10
0
0
1
1
0
1
0
0
0
0
Q2n+1
Q2Q1
D
00
01
11
10
0
0
0
0
1
1
0
0
0
0
Z
由卡诺图可得:
D2=Q2n+1=Q1
D1=Q1n+1=
Q1+D
Z=Q2·
·
可用D触发器实现,电路图如下所示:
(5)并行字符检测电路的设计:
并行字符检测,即将原序列经串并转换电路后产生的并行信号与同步码1111000相比较,当与同步码相同时,即产生一个高电平。
此检测电路可通过两个比较器实现,比较时应由低位到高位依次进行。
本实验采用了两个数据比较器74LS85级联的方式。
电路图如下所示:
(6)控制电路的设计:
字符检测电路若检测到同步码就会对控制电路输出一个信号,控制电路对此信号做出反应,以此来控制锁存电路的开关。
检测信号通过控制电路使锁存器开启,此后检测信号对锁存器的影响就不存在了。
电路图如下所示:
(7)锁存电路的设计:
锁存电路比较简单,只需要一块74LS273锁存芯片就可以。
只要把7个数据输入端分别连接到串并转换电路的并行输出端,再将控制电路的输出端接到锁存器的时钟输入端即可。
电路如下所示:
(8)显示电路的设计:
将锁存器的7个输出端接到数码显示管的7个管脚即可实现显示电路。
要注意的是,数码管的abcdefg七个管脚分别对应数据的高位到低位。
3、总电路图:
(1)串行:
(2)并行:
四、波形仿真结果
1、
串并转换输出
原序列信号
检测信号
串行:
2、
检测信号
串并转换输出
原序列信号
锁存器输出
锁存器输入
控制信号
并行:
控制信号
锁存器输出
锁存器输入
手绘示波器波形见坐标纸
五、VHDL程序代码及注释
1、串行代码:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitycxingis--定义实体名为cxing
port(
clk_in:
instd_logic;
clk_out:
bufferstd_logic;
c_out:
outstd_logic_vector(6downto0));
endcxing;
architectureaofcxingis--定义结构体名为a
signaltmp1:
integerrange0to999999;
signaltmp2:
integerrange0to14;
signalclk,f,q_out,q,cp_control,control:
std_logic;
typestate_typeis(s0,s1,s2,s3,s4);
signalcurrent_state,next_state:
state_type;
signaltmp:
std_logic_vector(6downto0);
begin
p1:
process(clk_in)--分频器1MHz分为2Hz
begin
ifclk_in'eventandclk_in='1'then
iftmp1=999999then
tmp1<=0;
else
tmp1<=tmp1+1;
endif;
iftmp1=500000then
clk<='1';
else
clk<='0';
endif;
endif;
endprocessp1;
clk_out<=clk;
p2:
process(clk)--函数信号发生器111100*********
begin
ifclk'eventandclk='1'then
iftmp2=14then
tmp2<=0;
else
tmp2<=tmp2+1;
endif;
endif;
endprocessp2;
p3:
process(tmp2)
begin
casetmp2is
when4|5|6|8|9|12|14=>q_out<='0';
whenothers=>q_out<='1';
endcase;
endprocessp3;
p4:
process(current_state,q_out)--串行检测
begin
casecurrent_stateis
whens0=>if(q_out='1')thennext_state<=s1;
elsenext_state<=s0;endif;
whens1=>if(q_out='1')thennext_state<=s2;
elsenext_state<=s1;endif;
whens2=>if(q_out='0')thennext_state<=s3;
elsenext_state<=s1;endif;
whens3=>if(q_out='0')thennext_state<=s4;
elsenext_state<=s1;endif;
whens4=>if(q_out='0')thennext_state<=s0;
elsenext_state<=s1;endif;
endcase;
endprocess;
p5:
process(clk)
begin
if(clk'eventandclk='1')then
current_state<=next_state;
endif;
endprocess;
p6:
process(current_state)
begin
casecurrent_stateis
whens0=>f<='0';
whens1=>f<='0';
whens2=>f<='0';
whens3=>f<='0';
whens4=>f<='1';
endcase;
endprocess;
cp_control<=clkorq;
p7:
process--控制信号
begin
waituntilcp_control='1';
q<=f;
endprocess;
control<=qandclk;
p8:
process(clk)--串并转换
begin
ifclk'eventandclk='1'then
tmp(6)<=tmp(5);
tmp(5)<=tmp(4);
tmp(4)<=tmp(3);
tmp(3)<=tmp
(2);
tmp
(2)<=tmp
(1);
tmp
(1)<=tmp(0);
tmp(0)<=q_out;
endif;
endprocess;
p9:
process(control)--锁存器输出
begin
ifcontrol'eventandcontrol='1'then
c_out(6)<=nottmp(6);
c_out(5)<=nottmp(5);
c_out(4)<=nottmp(4);
c_out(3)<=nottmp(3);
c_out
(2)<=nottmp
(2);
c_out
(1)<=nottmp
(1);
c_out(0)<=nottmp(0);
endif;
endprocess;
enda;
2、并行代码
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitybxingis--定义实体名为bxing
port(
clk_in:
instd_logic;
clk_out:
bufferstd_logic;
c_out:
outstd_logic_vector(6downto0));
endbxing;
architecturebofbxingis--定义结构体名为b
signaltmp1:
integerrange0to999999;
signaltmp2:
integerrange0to14;
signalclk,f,q_out,q,cp_control,control,a,b,c,d:
std_logic;
signaltmp:
std_logic_vector(7downto0);
begin
p1:
process(clk_in)--分频器1MHz分为2Hz
begin
ifclk_in'eventandclk_in='1'then
iftmp1=999999then
tmp1<=0;
else
tmp1<=tmp1+1;
endif;
iftmp1=500000then
clk<='1';
else
clk<='0';
endif;
endif;
endprocessp1;
clk_out<=clk;
p2:
process(clk)--函数信号发生器111100*********
begin
ifclk'eventandclk='1'then
iftmp2=14then
tmp2<=0;
else
tmp2<=tmp2+1;
endif;
endif;
endprocessp2;
p3:
process(tmp2)
begin
casetmp2is
when4|5|6|8|9|12|14=>q_out<='0';
whenothers=>q_out<='1';
endcase;
endprocessp3;
p4:
process(clk)--串并转换
begin
ifclk'eventandclk='1'then
tmp(7)<=tmp(6);
tmp(6)<=tmp(5);
tmp(5)<=tmp(4);
tmp(4)<=tmp(3);
tmp(3)<=tmp
(2);
tmp
(2)<=tmp
(1);
tmp
(1)<=tmp(0);
tmp(0)<=q_out;
endif;
endprocess;
p5:
process(tmp(0),tmp
(1),tmp
(2),tmp(3))--并行检测
begin
if(tmp(0)='0')then
a<='1';
elsea<='0';
endif;
if(tmp
(1)='0')then
b<='1';
elseb<='0';
endif;
if(tmp
(2)='0')then
c<='1';
elsec<='0';
endif;
if(tmp(3)='1')then
d<='1';
elsed<='0';
endif;
endprocess;
f<=aandbandcandd;
cp_control<=clkorq;
p6:
process--控制信号
begin
waituntilcp_control='1';
q<=f;
endprocess;
control<=qandclk;
p7:
process(control)--锁存器输出
begin
ifcontrol'eventandcontrol='0'then
c_out(6)<=nottmp(7);
c_out(5)<=nottmp(6);
c_out(4)<=nottmp(5);
c_out(3)<=nottmp(4);
c_out
(2)<=nottmp(3);
c_out
(1)<=nottmp
(2);
c_out(0)<=nottmp
(1);
endif;
endprocess;
endb;
串并行的仿真图一样,皆如下:
六、选做部分:
纠错电路的设计与实现
错码发生器,即序列信号发生器,我们的错码序列为“111100*********”,若使用触发器,则至少需要6个,因此我们可以通过一个74LS163计数器和由74LS153级联构成的16选1数据选择器构成序列信号发生器。
纠错电路设计的另一个关键在于,如何定位错误的码。
与之前同步检测的原理类似,我们要找到以错码为结尾并且始终没有重复的码形作为检测的目标。
本次实验我们的错码为“111100*********”,因此,以“0011”作为检测码,通过时序电路实现。
状态机的设计如下。
1/0
B
A
1/0
0/0
0/00/0
1/1
C
D
1/0
0/0
对状态机的四个状态进行编码,A00,B01,C11,D10
Q2nQ1n
X=0
X=1
Q2n+1Q1n+1
Z
Q2n+1Q1n+1
Z
00
01
0
00
0
01
11
0
00
0
11
11
0
10
0
10
01
0
00
1
由状态表可绘出卡诺图如下所示:
Q2nQ1n
X
00
01
11
10
0
0
1
1
0
1
0
0
1
0
Q2n+1
Q2nQ1n
X
00
01
11
10
0
1
1
1
1
1
0
0
0
0
Q1n+1
Q2nQ1n
X
00
01
11
10
0
0
0
0
0
1
0
0
0
1
Z
由卡诺图可得,
Q2n+1=Q1n
+Q2nQ1n
Q1n+1=
Z=Q2n
X
在数字逻辑电路课上我们知道,任何数跟1异或可以得到与之相反的数,因此检测到错码后检测电路输出1,此1跟原序列该位置的码相异或,得到正确码。
综上所述,错码发生电路如下所示:
控制信号
错误码
同步检测信号
正确码
波形仿真:
正确码锁存输出
错码锁存输出
七、实验分析及总结
1、本次实验综合性较强,既考查了数字电路知识,也锻炼了动手操作能力,我们从中获益良多。
通过对序列信号发生器、串并转换电路、检测电路等电路的设计,我们“温故而知新”,对计数器、移位寄存器、数据选择器、比较器等中规模集成电路的实际应用有了更深刻的理解。
另外,由于此次实验电路较为繁琐、芯片数量较大,我们在连接电路上花费了较多的精力,也遇到过重重困难,但我们将这些问题各个击破,并在这个过程中学到了许多东西。
2、本次实验遇到的问题较多,在此总结如下:
(1)串行电路刚刚完成时,接通电源之后数码显示管的预热阶段总是不能显示完整的“8”字,并且也不是每一次都是从“倒c”开始循环显示。
后来才发现是电源线与板子接触不良,有的插孔较为稳定,有的插孔则不是。
我们最后找到了一个能够使电源与板子接触良好的插孔,使得数码显示管预热阶段显示完整的“8”,并且码形从“倒c”开始。
(2)在并行电路的连接中,我们发现锁存器的输出与串行时相比延迟了一个脉冲,这是由并行检测电路中使用的两个74LS85比较器级联而产生的。
我们解决的方法是,将串并转换电路的输出全部向高位平移一位再接入锁存器,从而抵消了检测电路的延时。
(3)在纠错电路中,很关键的一点就是正确码与错误码的同步。
我们对两个信号采用了相同的串并转换电路、同步检测电路和控制电路,但在测试时发现正确码所对应的数码管总是会发生间歇的全部熄灭,经过仔细检查后才发现,锁存器74LS273的清零端没有接高电平。
经过修改后,我们实现了正确码与错误码的同步显示。
(4)连接电路的过程中有时会遇到跨线的问题,这就容易产生干扰。
因此,在以后的实验学习中,我们会更加合理的安排芯片的布局与绕线,尽量减免这种干扰。
3、此次实验让我们对数字电路与逻辑设计的知识,尤其是序列信号发生器以及状态机的设计,有了更进一步的了解。
并且,这个实验过程也让我们认识到坚持不懈的精神、严谨求实的态度在科学工作中的重要性。
我们应该继续以良好的态度,在以后的实验学习中,不断培养自己提出问题、分析问题、解决问题的能力,真正去领会科学知识中的精髓。