VHDL电子钟实验报告.docx
- 文档编号:17830622
- 上传时间:2023-08-04
- 格式:DOCX
- 页数:19
- 大小:671.15KB
VHDL电子钟实验报告.docx
《VHDL电子钟实验报告.docx》由会员分享,可在线阅读,更多相关《VHDL电子钟实验报告.docx(19页珍藏版)》请在冰点文库上搜索。
VHDL电子钟实验报告
期末大作业课程设计实验报告
设计题目:
基于VHDL电子钟的设计
一、概述…………………………………………………………3
1.1目的……………………………………………………………3
1.2课程设计的要求和功能………………………………………3
二、总结…………………………………………………………..3
2.1课程设计进行过程及步骤……………………………………3
2.2所遇到的问题,如何解决问题……………………………….15
2.3体会收获以及建议…………………………………………….15
3.4参考资料(书,网络资料)………………………………….15
三、教师评语………………………………………………………16
四、成绩……………………………………………………………16
一、概述
1.1目的
1.基于CPLD系统模块板,设计一个电子钟。
来熟悉CPLD的工作原理以及对VHDL的使用。
2.通过设计出一个电子钟具有校时功能,来巩固分频,键盘扫描,计数,动态扫描等知识内容。
1.2课程设计的要求和功能
设计一个电子钟,能进行正常的时分秒计时功能,分别有六个数码管显示24小时,60分钟,60秒的计数器显示。
利用实验箱系统上的按键实现“校时”、“校分”功能:
(1)按下“SA”键时,计时器快速递增,按24小时循环,进行时校正;
(2)按下“SB”键时,计分器快速递增,按60分循环,进行分校正
(3)按下“SC”键时,秒清零,进行秒校正;
二、总结
2.1课程设计进行及步骤
1.设计提示
系统框图见下
2.系统结构设计描述
(1)系统顶层文件
1.顶层原理图见下
2.各个模块的解释
(1)五个输入量clk50MHz,SA,SB,SC,reset:
其中clk50MHz为总体系统提供时钟,并且经过分频来分别对电子钟模块提供时钟,产生一秒一秒的进位信号,对显示模块的计数器提供时钟实现显示模块的扫描功能,对按键去抖动提供时钟,实现键盘扫描的功能。
SA,SB,SC用来控制按键,实现按键控制,SA是实现“时”加一,SB是实现“分”加一,SC是实现“秒”清零。
Reset是来控制按键功能的使能。
(2)按键功能模块
三个输入chos,date0,date1的功能是:
chos接受来自按键的信号,若按键按下,则将date0的内容,也就是通过按键产生的脉冲来控制电子钟进行加一,若按键没有按下,则将“秒”分频信号接入电子钟的clk计数输入端,通过时钟脉冲来控制电子钟。
(3)电子钟计数模块
有5个输入ci,nreset,load,clk,d[7..0],作用分别是ci是使能端,直接接高电位,nreset是复位,load和d[7..0]是用来置数的,clk提供计数时钟,也就是一秒一个脉冲。
输出端有三个,co是进位功能,只有“秒”和“分”模块有效,qh[3..0],ql[3..0]是分位的数字输出端,一个是十位,一个是个位。
(4)显示模块
输入端有qcnt接受来自计数器的计数实现显示扫描,d0h,d1h,d0m,d1m,d0s,d1s分别是接收的来自“秒”“分”“时”个位十位的数据,seg输出LCD的段扫描结果,SCAN输出LCD位扫描结果。
(2)系统各个模块的VHDL程序
1.显示模块
Libraryieee;
Useieee.std_logic_1164.all;
Useieee.std_logic_unsigned.all;
Useieee.std_logic_arith.all;
entitydisplayis
port(
qcnt:
INintegerrange0to7;--计数值输入
d0h,d1h,d0m,d1m,d0s,d1s:
INintegerrange0to9;
--分位得到的十位数和个位数
seg:
OUTstd_logic_vector(6downto0);--7位段码输出
scan:
OUTstd_logic_vector(7downto0)--8为位码输出
);
enddisplay;
architectureaofdisplayis
signaldata:
integerrange0to10;
begin
process(qcnt,d0h,d1h,d0m,d1m,d0s,d1s)
begin
caseqcntis
when0=>scan<="11111110";data<=d0h;
when1=>scan<="11111101";data<=d1h;
when2=>scan<="11111011";data<=10;
when3=>scan<="11110111";data<=d0m;
when4=>scan<="11101111";data<=d1m;
when5=>scan<="11011111";data<=10;
when6=>scan<="10111111";data<=d0s;
whenothers=>scan<="01111111";data<=d1s;
endcase;
endprocess;
process(data)
begin
casedatais
when0=>seg<="0111111";--0
when1=>seg<="0000110";--1
when2=>seg<="1011011";--2
when3=>seg<="1001111";--3
when4=>seg<="1100110";--4
when5=>seg<="1101101";--5
when6=>seg<="1111101";--6
when7=>seg<="0000111";--7
when8=>seg<="1111111";--8
when9=>seg<="1100111";--9
when10=>seg<="1000000";--
whenothers=>seg<="0000000";
endcase;
endprocess;
enda;
动态显示计数器部分:
LIBRARYieee;
USEieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
--EntityDeclaration
ENTITYqcnt_displayIS
--{{ALTERA_IO_BEGIN}}DONOTREMOVETHISLINE!
PORT
(
clk:
INSTD_LOGIC;
qcnt:
bufferSTD_LOGIC_VECTOR(2downto0)
);
--{{ALTERA_IO_END}}DONOTREMOVETHISLINE!
ENDqcnt_display;
--ArchitectureBody
ARCHITECTUREcnt_architectureOFqcnt_displayIS
BEGIN
PROCESS(clk)
BEGIN
IF(clk'EVENTANDclk='1')THEN
qcnt<=qcnt+1;
ENDIF;
ENDPROCESS;
ENDcnt_architecture;
2.分位计数模块
“秒”,“分”部分:
LIBRARYieee;
USEieee.std_logic_1164.all;
USEieee.std_logic_unsigned.all;
--EntityDeclaration
ENTITYcounter60IS
--{{ALTERA_IO_BEGIN}}DONOTREMOVETHISLINE!
PORT
(
ci:
instd_logic;
nreset:
INSTD_LOGIC:
='1';
load:
INSTD_LOGIC;
clk:
INSTD_LOGIC;
d:
instd_logic_vector(7downto0);
co:
outstd_logic;
qh:
bufferstd_logic_vector(3downto0);
ql:
bufferstd_logic_vector(3downto0)
);
--{{ALTERA_IO_END}}DONOTREMOVETHISLINE!
ENDcounter60;
--ArchitectureBody
ARCHITECTUREcounter_architectureOFcounter60IS
BEGIN
co<='1'when(qh="0101"andql="1001"andci='1')else'0';
process(clk,nreset)
begin
if(nreset='0')then
qh<="0000";
ql<="0000";
elsifrising_edge(clk)then
if(load='1')then
qh<=d(7downto4);
ql<=d(3downto0);
elsif(ci='1')then
if(ql=9)then
ql<="0000";
if(qh=5)then
qh<="0000";
else
qh<=qh+1;
endif;
else
ql<=ql+1;
endif;
endif;
endif;
endprocess;
ENDcounter_architecture;
“时”部分:
LIBRARYieee;
USEieee.std_logic_1164.all;
USEieee.std_logic_unsigned.all;
--EntityDeclaration
ENTITYcounter24IS
--{{ALTERA_IO_BEGIN}}DONOTREMOVETHISLINE!
PORT
(
ci:
instd_logic;
nreset:
INSTD_LOGIC:
='1';
load:
INSTD_LOGIC;
clk:
INSTD_LOGIC;
d:
instd_logic_vector(7downto0);
co:
outstd_logic:
='0';
qh:
bufferstd_logic_vector(3downto0);
ql:
bufferstd_logic_vector(3downto0)
);
--{{ALTERA_IO_END}}DONOTREMOVETHISLINE!
ENDcounter24;
--ArchitectureBody
ARCHITECTUREcounter_architectureOFcounter24IS
BEGIN
--co<='1'when(qh="0010"andql="0011"andci='1')else'0';
process(clk,nreset)
begin
--if(nreset='0')then
--qh<="0000";
--ql<="0000";
ifrising_edge(clk)then
if(load='1')then
qh<=d(7downto4);
ql<=d(3downto0);
elsif(ci='1')then
if(qh=0orqh=1)then
if(ql=9)then
ql<="0000";
if(qh=2)then
qh<="0000";
else
qh<=qh+1;
endif;
else
ql<=ql+1;
endif;
else
if(ql=3)then
ql<="0000";
if(qh=2)then
qh<="0000";
else
qh<=qh+1;
endif;
else
ql<=ql+1;
endif;
endif;
endif;
endif;
endprocess;
ENDcounter_architecture;
3.分频模块
Libraryieee;
Useieee.std_logic_1164.all;
Useieee.std_logic_unsigned.all;
Useieee.std_logic_arith.all;
Entityfdiv_duois
port(
clkin:
INstd_logic;
clkout_200HZ:
bufferstd_logic;--键盘去抖动
clkout_1KHZ:
bufferstd_logic;--显示模块计数器
clkout_10HZ:
bufferstd_logic;--按键选择
clkout_1HZ:
bufferstd_logic--计数器模块
);
Endfdiv_duo;
Architectureaoffdiv_duois
signalcnt_1HZ:
naturalrange0to24999999;
signalcnt_10HZ:
naturalrange0to249999999;
signalcnt_1KHZ:
naturalrange0to24999;
signalcnt_200HZ:
naturalrange0to124999;
Begin
process(clkin)
begin
if(clkin'eventandclkin='1')then
ifcnt_1HZ=24999999then
cnt_1HZ<=0;
clkout_1HZ<=notclkout_1HZ;
else
cnt_1HZ<=cnt_1HZ+1;
endif;
ifcnt_10HZ=249999999then
cnt_10HZ<=0;
clkout_10HZ<=notclkout_10HZ;
else
cnt_10HZ<=cnt_10HZ+1;
endif;
ifcnt_1KHZ=24999then
cnt_1KHZ<=0;
clkout_1KHZ<=notclkout_1KHZ;
else
cnt_1KHZ<=cnt_1KHZ+1;
endif;
ifcnt_200HZ=124999then
cnt_200HZ<=0;
clkout_200HZ<=notclkout_200HZ;
else
cnt_200HZ<=cnt_200HZ+1;
endif;
endif;
endprocess;
Enda;
4.键盘控制模块
时钟和分钟的键盘去抖动和“增益”,“清零”控制部分:
Libraryieee;
Useieee.std_logic_1164.all;
Useieee.std_logic_unsigned.all;
Useieee.std_logic_arith.all;
Entitydebounceis
port(
clk200hz,reset:
INstd_logic;--200HZ时钟
din:
INstd_logic;
dout:
OUTstd_logic);
Enddebounce;
architectureaofdebounceis
typestateis(S0,S1,S2);--定义状态机类型
signalcurrent:
state;
begin
process(clk200hz,reset,din)
begin
if(reset='1')then--状态机复位dout输出信号复位
current<=S0;
dout<='1';
elsif(clk200hz'eventandclk200hz='1')then
casecurrentis
whenS0=>
dout<='1';
if(din='0')then
current<=S1;
else
current<=S0;
endif;
whenS1=>
dout<='1';
if(din='0')then
current<=S2;
else
current<=S0;
endif;
whenS2=>
dout<='0';
if(din='0')then
current<=S2;
else
current<=S0;
endif;
whenothers=>
dout<='1';
current<=S0;
endcase;
endif;
endprocess;
enda;
作用解释:
当检测到按键被按下时,将按键的输出直接给计数模块的时钟控制通过按键控制计数时钟从而实现“增益”功能,如果没有检测到有效按键,“时”和“分”计数模块就受进位信号的控制。
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitychooseis
port
(chos:
instd_logic;
date0,date1:
instd_logic;
dout:
outstd_logic);
endchoose;
architecturebehaveofchooseis
begin
withchosselect
dout<=date0when'0',
date1whenothers;
endbehave;
“清零”功能的实现利用按键信号去控制“秒”模块的“复位”。
(3)实验效果图
22-01-27时按下秒钟清零
继续按分钟增益按钮,使分钟从1加到9
然后按时钟增益,使时钟从22加到下一轮的9时
2.2所遇到的问题,如何解决问题
(1)在分频时,如果键盘去抖动频率设计不合适会造成按键不灵敏,如果显示部分频率设置不好也会造成显示时音频率过快数字不清楚。
解决办法:
虽然实现分频的程序很多,但是有些程序的分频效果并不是很好,我这里用的是偶数分频器的第二种方法(取反或加一
(2)在设计时分秒的模模块时,因为我采用的是BCD计数器,所以在实现“分秒”的60进位比较容易,但是在实现“24小时”要注意,不然很容易出现时位为“1,2,3,11,12,13”的变化。
解决办法:
设计一个进位清零判断,是个位到了9需要清零还是到了3需要清零,取决于十位0和1还是2.
2.3体会收获以及建议
通过设计电子钟,重温了动态显示的设计、模计数器的设计以及按键去抖动设计,这里面主要的部分在于对电子钟按键控制,通过设计一个模块来判断按键是否有效后利用进位变量去触发计数器实现增益功能,或者利用判断按键是否有效将模计数器结果清零来实现置零功能。
在设计中,有很多细节问题会决定实验效果,所以一定要认真,多思考,并且要善于和同学交流讨论,可能自己在设计时会遇到盲区,需要别的同学的指点,比如我在设计按键功能判断时就向夏良飞同学请教了他的设计思路,然后再根据自己的理解设计出来选择器来实现按键控制功能。
3.4参考资料(书,网络资料)
《现在电子系统设计》
三、教师评语
四、成绩
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VHDL 电子钟 实验 报告
![提示](https://static.bingdoc.com/images/bang_tan.gif)