数码管扫描显示 数电实验综述.docx
《数码管扫描显示 数电实验综述.docx》由会员分享,可在线阅读,更多相关《数码管扫描显示 数电实验综述.docx(8页珍藏版)》请在冰豆网上搜索。
![数码管扫描显示 数电实验综述.docx](https://file1.bdocx.com/fileroot1/2023-1/26/5bbe6d80-feb4-47f1-b5d5-a2d867b2fa03/5bbe6d80-feb4-47f1-b5d5-a2d867b2fa031.gif)
数码管扫描显示数电实验综述
实验报告
2016年1月5日成绩:
姓名
陈孟春、程平安
学号
14051112、14051115
班级
14052311
专业
计算机科学与技术
课程名称
《数字电路课程设计》
任课老师
冯建文
指导老师
冯建文
机位号
实验序号
18
实验名称
数码管扫描显示
实验时间
2016.1.5
实验地点
1教233
实验设备号
一、实验程序源代码
(含实验程序源代码及模块设计说明、注释等)
/*
1.实验分工
本实验的代码主要由陈孟春同学完成,程平安同学做了后期的测试工作。
2.程序介绍
本程序分为4个模块,分别为主模块(shiyan18)、显示模块(Display)、分频模块(Timer)、十进制计数器模块(DecAdder)。
主模块(shiyan18)主要负责连接其他模块以及连接各个管脚。
显示模块(Display)的功能是把4位8421码转换为数码管所需的位选信号和段选信号。
分频模块(Timer)的功能是把100M的时钟转换成其他频率的时钟。
比如显示模块每位数字的刷新时间大约为2.6ms,那就用了分频模块输出的第19、18位作为位选的时钟。
数码管的计数需要较慢的速度,所以选择了第24位作为它的时钟,如果需要更快的增加速度,也可以选择23或者22位。
十进制计数器模块(DecAdder)的功能是对时钟的脉冲个数进行计数,当来了一个时钟上升沿时就可以加一。
由于本实验的数码管是4位的,所以在主模块中创建了4个十进制计数器模块的实例,通过级联来实现4位的十进制计数器。
*/
`timescale1ns/1ps
moduleshiyan18(
inputStartStop,
inputclk,
input_clr,
output[3:
0]AN,
output[7:
0]seg
);
wire[24:
0]delay;
wirec0,c1,c2,c3;
wire[15:
0]data;
Timertimer(clk,delay);
Displaydisplay(data,delay[19:
18],AN,seg);
DecAdderda0(_clr,StartStop,delay[24],data[3:
0],c0),
da1(_clr,StartStop,c0,data[7:
4],c1),
da2(_clr,StartStop,c1,data[11:
8],c2),
da3(_clr,StartStop,c2,data[15:
12],c3);
endmodule
moduleTimer(
inputCP,
outputreg[24:
0]delay={24{1'b0}}
);
always@(posedgeCP)
begin
delay<=delay+1'b1;
end
endmodule
moduleDisplay(
input[15:
0]Data,
input[1:
0]Bit_Sel,
outputreg[3:
0]AN,
outputreg[7:
0]Seg
);
reg[7:
0]memory[0:
15]={8'b00000011,
8'b10011111,
8'b00100101,
8'b00001101,
8'b10011001,
8'b01001001,
8'b01000001,
8'b00011111,
8'b00000001,
8'b00001001,
8'b00010001,
8'b11000001,
8'b01100011,
8'b10000101,
8'b01100001,
8'b01110001
};
always@(Bit_Sel)
begin
case(Bit_Sel)
0:
begin
AN<=4'b0111;
Seg<=memory[Data[15:
12]];
end
1:
begin
AN<=4'b1011;
Seg<=memory[Data[11:
8]];
end
2:
begin
AN<=4'b1101;
Seg<=memory[Data[7:
4]];
end
3:
begin
AN<=4'b1110;
Seg<=memory[Data[3:
0]];
end
default:
begin
AN<=4'b1111;
Seg<={8{1'b1}};
end
endcase
end
endmodule
moduleDecAdder(
input_MR,
inputEN,
inputCLK,
outputreg[3:
0]Q,
outputregC1
);
always@(negedge_MRorposedgeCLK)
begin
if(_MR==0)
{C1,Q}<=5'b00000;
elseif(EN)
begin
if(Q==4'b1001)
begin
Q<=4'b0000;
C1<=1'b1;
end
else
begin
Q<=Q+1'b1;
C1<=1'b0;
end
end
end
endmodule
二、仿真波形
三、电路图
四、引脚配置(约束文件)
NET"AN[0]"LOC=N16;
NET"AN[1]"LOC=N15;
NET"AN[2]"LOC=P18;
NET"AN[3]"LOC=P17;
NET"seg[7]"LOC=T17;
NET"seg[6]"LOC=T18;
NET"seg[5]"LOC=U17;
NET"seg[4]"LOC=U18;
NET"seg[3]"LOC=M14;
NET"seg[2]"LOC=N14;
NET"seg[1]"LOC=L14;
NET"seg[0]"LOC=M13;
NET"clk"LOC=V10;
NET"StartStop"LOC=T10;
NET"_clr"LOC=T9;
五、思考与探索
(1)在实验中,你碰到了哪些问题,又是如何解决的?
如果感觉数字闪烁,分析是什么原因?
如何解决?
答:
写完程序后,第一次上板子测试的时候除了有个数字显示错了,其他基本没有问题。
但在后来仿真的时候,代码报错,似乎是不能直接给寄存器数组初始化,于是改了一下原来的代码,最后显示出了仿真波形。
如果数字闪烁可能是刷屏的频率不够高,可以把分频模块的输出时钟频率调的高一点。
(2)板级实验时,当你置开关Start/Stop=0时,观察数码管显示状态:
停止计数了吗?
数码管是某个点亮还是4个均点亮?
当你Start/Stop=1时,计数从0000开始,还是从刚才停止的数据开始?
假如要求停止计数时,数码管稳定显示停止时的4位计数值,再次启动计数时,又从刚才中断的计数值继续开始计数,请你修改你的程序,达到上述效果。
答:
停止计数了。
4个均点亮。
从刚才的数据开始。
我的程序已经实现了上述效果。
(3)考虑设计一个通用的4位数码管显示模块,输入端口为16位的数据Data[15:
0],每4位用一个数码管显示,输入端口即为数码管位选AN[3:
0]和段选Seg[7:
0]。
答:
代码如下:
moduleDisplay(
input[15:
0]Data,
input[1:
0]Bit_Sel,
outputreg[3:
0]AN,
outputreg[7:
0]Seg
);
reg[7:
0]memory[0:
15]={8'b00000011,
8'b10011111,
8'b00100101,
8'b00001101,
8'b10011001,
8'b01001001,
8'b01000001,
8'b00011111,
8'b00000001,
8'b00001001,
8'b00010001,
8'b11000001,
8'b01100011,
8'b10000101,
8'b01100001,
8'b01110001
};
always@(Bit_Sel)
begin
case(Bit_Sel)
0:
begin
AN<=4'b0111;
Seg<=memory[Data[15:
12]];
end
1:
begin
AN<=4'b1011;
Seg<=memory[Data[11:
8]];
end
2:
begin
AN<=4'b1101;
Seg<=memory[Data[7:
4]];
end
3:
begin
AN<=4'b1110;
Seg<=memory[Data[3:
0]];
end
default:
begin
AN<=4'b1111;
Seg<={8{1'b1}};
end
endcase
end
endmodule