基于LCD1602的简易秒表的设计与实现.docx

上传人:b****2 文档编号:145964 上传时间:2023-04-28 格式:DOCX 页数:52 大小:341.36KB
下载 相关 举报
基于LCD1602的简易秒表的设计与实现.docx_第1页
第1页 / 共52页
基于LCD1602的简易秒表的设计与实现.docx_第2页
第2页 / 共52页
基于LCD1602的简易秒表的设计与实现.docx_第3页
第3页 / 共52页
基于LCD1602的简易秒表的设计与实现.docx_第4页
第4页 / 共52页
基于LCD1602的简易秒表的设计与实现.docx_第5页
第5页 / 共52页
基于LCD1602的简易秒表的设计与实现.docx_第6页
第6页 / 共52页
基于LCD1602的简易秒表的设计与实现.docx_第7页
第7页 / 共52页
基于LCD1602的简易秒表的设计与实现.docx_第8页
第8页 / 共52页
基于LCD1602的简易秒表的设计与实现.docx_第9页
第9页 / 共52页
基于LCD1602的简易秒表的设计与实现.docx_第10页
第10页 / 共52页
基于LCD1602的简易秒表的设计与实现.docx_第11页
第11页 / 共52页
基于LCD1602的简易秒表的设计与实现.docx_第12页
第12页 / 共52页
基于LCD1602的简易秒表的设计与实现.docx_第13页
第13页 / 共52页
基于LCD1602的简易秒表的设计与实现.docx_第14页
第14页 / 共52页
基于LCD1602的简易秒表的设计与实现.docx_第15页
第15页 / 共52页
基于LCD1602的简易秒表的设计与实现.docx_第16页
第16页 / 共52页
基于LCD1602的简易秒表的设计与实现.docx_第17页
第17页 / 共52页
基于LCD1602的简易秒表的设计与实现.docx_第18页
第18页 / 共52页
基于LCD1602的简易秒表的设计与实现.docx_第19页
第19页 / 共52页
基于LCD1602的简易秒表的设计与实现.docx_第20页
第20页 / 共52页
亲,该文档总共52页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

基于LCD1602的简易秒表的设计与实现.docx

《基于LCD1602的简易秒表的设计与实现.docx》由会员分享,可在线阅读,更多相关《基于LCD1602的简易秒表的设计与实现.docx(52页珍藏版)》请在冰点文库上搜索。

基于LCD1602的简易秒表的设计与实现.docx

基于LCD1602的简易秒表的设计与实现

数字电路与逻辑设计

实验报告

学院:

电子工程学院

班级:

2014211212

姓名:

学号:

班内序号:

一、设计课题的任务要求

简易秒表的设计与实现

设计制作一个计时精度为百分之一秒的计时秒表

基本要求:

1.用LCD1602液晶屏显示计时;

2.秒表计时长度为23小时59分59.99秒;

3.用BTN0作为启动/停止开关;

4.用BTN1作为复位开关,在任何情况下,只要按下复位开关,秒表都要无条件执行清零操作。

提高要求:

1.增加定时器功能,可根据用户设定的时间进行倒计时,时间到0后蜂鸣器报警提示;

2.自拟其他功能。

二、系统设计(设计思路、总体框图、分块设计)

1.设计思路:

①分别设计6进制计数器、10进制计数器和24进制计数器用于秒表计时部分。

具体来说:

将两个10进制计数器级联分别作为秒表的十分秒位(最小单位为0.1秒)和百分秒位(最小单位为0.01秒);将一个10进制计数器和6进制计数器级联,分别作为秒表秒钟部分的个位(最小单位为1秒)和十位(最小单位为10秒);再将一个10进制计数器和6进制计数器级联,分别作为秒表分钟部分的个位(最小单位为1分钟)和十位(最小单位为10分钟);将24进制计数器作为秒表小时部分,其中低位输出作为秒表小时部分的个位(最小单位为1小时),高位输出作为秒表小时部分的十位(最小单位为10小时)。

最后把秒表百分秒、十分秒部分、秒钟部分、分钟部分、小时部分这四部分级联起来便构成了简易数字秒表的计时部分。

②将各个计数器部分的输出信号通过译码模块,变成LCD1602液晶屏能够读取并从而显示相关字符的8位二进制数据。

再定义一个存储器ram,存储各个计数器部分的输出信号经过译码部分之后得到的数据,然后将这个存储器ram代表的数据在LCD1602液晶屏上显示。

③考虑到秒表的最小计时长度为0.01秒(频率为100HZ),如果系统时钟设置为50MHZ,则需要500000分频;实验时发现LCD1602液晶屏的时钟在1KHZ时,显示效果较好,故需要在系统时钟为50MHZ的基础上进行50000分频。

④考虑到基本要求中需要用BTN0作为启动/停止开关,用BTN1作为复位开关,所以需要设计相应的按键防抖电路,这里我采用的是计数型防抖。

2.总体框图:

 

图1系统结构框图

3.分块设计:

系统共通过9个模块实现,分别是:

500000分频模块fpq

50000分频模块fpq1

6进制计数器模块cnt6

10进制计数器模块cnt10

24进制计数器模块cnt24

译码模块yima

LCD1602显示模块LCD1602

BTN0启动/停止开关消抖模块xiaodou

BTN1复位开关消抖模块fuweixiaodou

具体设计如下:

①500000分频模块fpq

输入端口:

clk:

instd_logic;

输出端口:

clkout:

outstd_logic;

生成符号:

设计思路:

利用计数法实现分频

主要代码:

(完整代码请见源程序)

signalclktmp:

std_logic;

signaltmp:

integerrange0to249999;

begin

process(clk)

begin

ifclk'eventandclk='1'then

iftmp=249999then--500000分频

tmp<=0;clktmp<=notclktmp;

else

tmp<=tmp+1;

endif;

endif;

endprocess;

clkout<=clktmp;

②50000分频模块fpq1:

输入端口:

clk:

instd_logic;

输出端口:

clkout:

outstd_logic;

生成符号:

设计思路:

利用计数法实现分频

主要代码:

(完整代码请见源程序)

signalclktmp:

std_logic;

signaltmp:

integerrange0to24999;

begin

process(clk)

begin

ifclk'eventandclk='1'then

iftmp=24999then--50000分频

tmp<=0;clktmp<=notclktmp;

else

tmp<=tmp+1;

endif;

endif;

endprocess;

clkout<=clktmp;

③6进制计数器模块cnt6:

输入端口:

reset,en,clk:

INSTD_LOGIC;

输出端口:

carry:

OUTSTD_LOGIC;

q:

OUTSTD_LOGIC_VECTOR(3DOWNTO0);

生成符号:

设计思路:

正常的计数状态是0->1->2->3->4->5->0->1……;

当计数到5时,进位信号变为‘1’;否则状态自增,进位信号保持在‘0’

主要代码:

(完整代码请见源程序)

SIGNALqs:

STD_LOGIC_VECTOR(3DOWNTO0);

SIGNALca:

STD_LOGIC;

BEGIN

PROCESS(clk)

begin

IF(reset='1')THENqs<="0000";

ELSIF(clk'EVENTANDclk='1')THEN

IF(en='0')THEN

IF(qs="0101")THEN--计数到5

qs<="0000";

ca<='1';

ELSE

qs<=qs+1;

ca<='0';

ENDIF;

ENDIF;

ENDIF;

ENDPROCESS;

PROCESS(ca,en)

BEGIN

q<=qs;

carry<=ca;

ENDPROCESS;

④10进制计数器模块cnt10:

输入端口:

reset,en,clk:

INSTD_LOGIC;

输出端口:

carry:

OUTSTD_LOGIC;

q:

OUTSTD_LOGIC_VECTOR(3DOWNTO0);

生成符号:

设计思路:

正常的计数状态是;

0->1->2->3->4->5->6->7->8->9->0->1……

当计数到9时,进位信号变为‘1’;否则状态自增,进位信号保持在‘0’

主要代码:

(完整代码请见源程序)

SIGNALqs:

STD_LOGIC_VECTOR(3DOWNTO0);

SIGNALca:

STD_LOGIC;

BEGIN

PROCESS(clk)

begin

IF(reset='1')THENqs<="0000";

ELSIF(clk'EVENTANDclk='1')THEN

IF(en='0')THEN

IF(qs="1001")THEN--计数到9

qs<="0000";

ca<='1';

ELSE

qs<=qs+1;

ca<='0';

ENDIF;

ENDIF;

ENDIF;

ENDPROCESS;

PROCESS(ca)

BEGIN

q<=qs;

carry<=ca;

ENDPROCESS;

⑤24进制计数器模块cnt24:

输入端口en,Reset,clk:

inSTD_LOGIC;

输出端口carry:

outSTD_LOGIC;

qa:

outSTD_LOGIC_VECTOR(3DOWNTO0);

qb:

outSTD_LOGIC_VECTOR(3DOWNTO0);

生成符号:

设计思路:

正常的计数状态是;

低位qa状态变化:

0->1->2->3->4->5->6->7->8->9->0->1……

高位qb状态变化:

0->1->2->0->1……

当低位qa计数到9时,qb自增,进位信号保持在‘0’

当低位qa为3且高位qb为2时,进位信号变为‘1’,

同时qa变为0、qb变为0

主要代码:

(完整代码请见源程序)

SIGNALca:

STD_LOGIC;

BEGIN

process(clk,Reset,en)

variabletma:

STD_LOGIC_VECTOR(3DOWNTO0);

variabletmb:

STD_LOGIC_VECTOR(3DOWNTO0);

begin

IfReset='1'thentma:

="0000";tmb:

="0000";else

ifclk'eventandclk='1'then

IF(en='0')THEN

--当BTN0键没有第一次按下时,正常计数

iftma="1001"thentma:

="0000";tmb:

=tmb+1;

elsiftmb="0010"andtma="0011"then

--计数到23

tma:

="0000";tmb:

="0000";

ca<='1';

elsetma:

=tma+1;

endif;

endif;

endif;

endif;

qa<=tma;qb<=tmb;

carry<=ca;

endprocess;

⑥译码模块yima:

输入端口:

carry:

inSTD_LOGIC;

data:

instd_logic_vector(3downto0);

输出端口:

dataout:

outstd_logic_vector(7downto0));

生成符号:

设计思路:

根据输入信号的不同,使用case语句进行不同的译码操作即可。

具体来说:

'0'(四位二进制)译为"30"(八位二进制)

'1'(四位二进制)译为"31"(八位二进制)

'2'(四位二进制)译为"32"(八位二进制)

'3'(四位二进制)译为"33"(八位二进制)

'4'(四位二进制)译为"34"(八位二进制)

'5'(四位二进制)译为"35"(八位二进制)

'6'(四位二进制)译为"36"(八位二进制)

'7'(四位二进制)译为"37"(八位二进制)

'8'(四位二进制)译为"38"(八位二进制)

'9'(四位二进制)译为"39"(八位二进制)

其他译为"20"(八位二进制)

主要代码:

(完整代码请见源程序)

signaldis:

std_logic_vector(7downto0);

begin

process(data)

begin

if(carry='1')then

dis<="11111111";

else

casedatais

when"0000"=>dis<="00110000";--'0'译为"30"

when"0001"=>dis<="00110001";--'1'译为"31"

when"0010"=>dis<="00110010";--'2'译为"32"

when"0011"=>dis<="00110011";--'3'译为"33"

when"0100"=>dis<="00110100";--'4'译为"34"

when"0101"=>dis<="00110101";--'5'译为"35"

when"0110"=>dis<="00110110";--'6'译为"36"

when"0111"=>dis<="00110111";--'7'译为"37"

when"1000"=>dis<="00111000";--'8'译为"38"

when"1001"=>dis<="00111001";--'9'译为"39"

whenothers=>dis<="00100000";--其他译为"20"

endcase;

endif;

endprocess;

dataout<=dis;

⑦LCD1602显示模块LCD1602:

输入端口:

YIMA_DATA1:

instd_logic_vector(7downto0);--译码数据信号1

YIMA_DATA2:

instd_logic_vector(7downto0);--译码数据信号2

YIMA_DATA3:

instd_logic_vector(7downto0);--译码数据信号3

YIMA_DATA4:

instd_logic_vector(7downto0);--译码数据信号4

YIMA_DATA5:

instd_logic_vector(7downto0);--译码数据信号5

YIMA_DATA6:

instd_logic_vector(7downto0);--译码数据信号6

YIMA_DATA7:

instd_logic_vector(7downto0);--译码数据信号7

YIMA_DATA8:

instd_logic_vector(7downto0);--译码数据信号8

LCD_Clk:

instd_logic;

--状态机时钟信号,同时也是液晶时钟信号,其周期应该满足液晶数据的建立时间

carry:

inSTD_LOGIC;

输出端口:

LCD_RS:

outstd_logic;--寄存器选择信号

LCD_RW:

outstd_logic;--液晶读写信号

LCD_EN:

outstd_logic;--液晶时钟信号

LCD_Data:

outstd_logic_vector(7downto0);--液晶数据信号

生成符号:

设计思路:

将各个计数器部分的输出信号通过译码模块,变成LCD1602液晶屏能够读取并从而显示相关字符的8位二进制数据。

再定义一个存储器ram,存储各个计数器部分的输出信号经过译码部分之后得到的数据,然后将这个存储器ram代表的数据在LCD1602液晶屏上显示。

主要代码:

(完整代码请见源程序)

typeramisarray(0to10)ofstd_logic_vector(7downto0);

signalram1:

ram;

begin

LCD_EN<=LCD_Clk;--液晶时钟信号

LCD_RW<='0';--液晶读写信号

ram1(0)<=YIMA_DATA8;--译码数据信号8,秒表小时部分十位

ram1

(1)<=YIMA_DATA7;--译码数据信号7,秒表小时部分个位

ram1

(2)<=x"3a";--显示冒号:

ram1(3)<=YIMA_DATA6;--译码数据信号6,秒表分钟部分十位

ram1(4)<=YIMA_DATA5;--译码数据信号5,秒表分钟部分个位

ram1(5)<=x"3a";--显示冒号:

ram1(6)<=YIMA_DATA4;--译码数据信号4,秒表秒钟部分十位

ram1(7)<=YIMA_DATA3;--译码数据信号3,秒表秒钟部分个位

ram1(8)<=x"2e";--显示小数点.

ram1(9)<=YIMA_DATA2;--译码数据信号2,秒表十分秒位

ram1(10)<=YIMA_DATA1;--译码数据信号1,秒表百分秒位

process(LCD_Clk)

variablecnt:

integerrange0to37;

begin

ifLCD_Clk'eventandLCD_Clk='1'then

ifcnt=37thencnt:

=0;

elsecnt:

=cnt+1;

endif;

endif;

casecntis

-----------------InitLCD1602初始化部分-------------

when0=>LCD_RS<='0';lcd_data<="00111000";--0x38

when1=>LCD_RS<='0';lcd_data<="00001100";--0x0C

when2=>LCD_RS<='0';lcd_data<="00000001";--0x01

when3=>LCD_RS<='0';lcd_data<="00000110";--0x06

-----------------------------------------------------

when4=>LCD_RS<='0';lcd_data<="10000000";--0x80

--display,0x00+0x80

-------------------datadisplay----------------------

when5=>LCD_RS<='1';lcd_data<="10100000";--空格

when6=>LCD_RS<='1';lcd_data<="10100000";--空格

when7=>LCD_RS<='1';lcd_data<="10100000";--空格

when8=>LCD_RS<='1';lcd_data<=ram1(0);--秒表小时部分十位

when9=>LCD_RS<='1';lcd_data<=ram1

(1);--秒表小时部分个位

when10=>LCD_RS<='1';lcd_data<=ram1

(2);--冒号:

when11=>LCD_RS<='1';lcd_data<=ram1(3);--秒表分钟部分十位

when12=>LCD_RS<='1';lcd_data<=ram1(4);--秒表分钟部分个位

when13=>LCD_RS<='1';lcd_data<=ram1(5);--冒号:

when14=>LCD_RS<='1';lcd_data<=ram1(6);--秒表秒钟部分十位

when15=>LCD_RS<='1';lcd_data<=ram1(7);--秒表秒钟部分个位

when16=>LCD_RS<='1';lcd_data<=ram1(8);--小数点.

when17=>LCD_RS<='1';lcd_data<=ram1(9);--秒表十分秒位

when18=>LCD_RS<='1';lcd_data<=ram1(10);--秒表百分秒位

when19=>LCD_RS<='1';lcd_data<="10100000";-空格

when20=>LCD_RS<='1';lcd_data<="10100000";-空格

-----------------------------------------------------

when21=>LCD_RS<='0';lcd_data<="11000000";

--设定显示的位置在40H+80H,

-----------------------------------------------------

when22=>LCD_RS<='1';lcd_data<="10100000";--空格

when23=>LCD_RS<='1';lcd_data<="10100000";--空格

when24=>LCD_RS<='1';lcd_data<="10100000";--空格

when25=>LCD_RS<='1';lcd_data<="10100000";--空格

when26=>LCD_RS<='1';lcd_data<="10100000";--空格

when27=>LCD_RS<='1';lcd_data<="10100000";--空格

when28=>LCD_RS<='1';lcd_data<="10100000";--空格

when29=>LCD_RS<='1';lcd_data<="10100000";--空格

when30=>LCD_RS<='1';lcd_data<="10100000";--空格

when31=>LCD_RS<='1';lcd_data<="10100000";--空格

when32=>LCD_RS<='1';lcd_data<="10100000";--空格

when33=>LCD_RS<='1';lcd_data<="10100000";--空格

when34=>LCD_RS<='1';lcd_data<="10100000";--空格

when35=>LCD_RS<='1';lcd_data<="10100000";--空格

when36=>LCD_RS<='1';lcd_data<="10100000";--空格

when37=>LCD_RS<='1';lcd_data<="10100000";--空格

endcase;

endprocess;

⑧BTN0启动/停止开关消抖模块xiaodou:

输入端口:

clk:

instd_logic;

key_en:

instd_logic;

输出端口:

en_out:

outstd_logic;

生成符号:

设计思路:

采用计数型防抖

当key_en第一次为'1'时,en_out延迟一段时间后变为'1',

并且en_out就此保持在高电平'1';

直到key_en第二次为'1'时,en_out延迟一段时间后变为'0'。

主要代码:

(完整代码请见源程序)

signalcnt:

integerrange0to3;--采用计数型防抖

signalen,en_tmp:

std_logic;

begin

p0:

process(clk)

begin

ifclk'eventandclk='1'then

ifkey_en='1'then

ifcnt=3thenen<='1';

elsecnt<=cnt+1;en<='0';

endif;

elsecnt<=0;en<='0';

endif;

endif;

endprocessp0;

p1:

process(en)

begin

ifen'eventanden='1'then

en_tmp<=noten_tmp;

endif;

en_out<=en_tmp;

endprocessp1;

⑨BTN1复位开关消抖模块fuweixiaodou:

输入端口:

clk:

instd_

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

当前位置:首页 > 人文社科

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

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