2016-1-15 07:13 上传
点击文件名下载附件
综合实验设计要求单片机及接口技术
1.标题:电子实时时钟/万年日历系统
二、功能要求:
1.基本要求:
(1) 北京时间(时、分、秒)显示准确,可采用24小时标准;
(2) 时间可以随时调整。
(3) 增加公历日期显示功能(年、月、日),年号只显示最后两位;
(4) 年、月、日可随时调整;
(5) 允许通过转换功能键转换显示时间或日期。
(6) 所有按钮都需要通过串口自发自收来调整各种功能。
三、考虑方案:
1.硬件方案:
⑴ 6位显示器LED时间或日期可分别显示数字管(可共阴或共阳);
⑵ 显示器的驱动采用动态扫描电路的形式,以达到简化电路的目的。但需要注意的是,驱动电流大于静态驱动,因此需要增加驱动电路。LS244或晶体管;
⑶ 键盘可采用4×3(12)键,也可采用一键多用方案减少按键数量。
⑷ 整体上要考虑:结构简单、布局美观、操作方便、成本低廉。
2. 参考电路图

请注意,上图为共阳LED但实验室提供的数字管LED数字管有两种:共阳和共阴。如果使用共阴,需要修改相应的驱动电路,不能复制。
以下是试验报告:
电子与信息学院
综合实验报告《单片机原理与应用》
电子实时钟/万年日历系统
专 业信 息 工 程
班 级06(3)
学生姓黄锐张鑫
学 号200630212136200630215366
一、系统概述: 1.基本要求:
(1) 北京时间(时、分、秒)显示准确,可采用24小时标准;
(2) 时间可以随时调整。
(3) 增加公历日期显示功能(年、月、日),年号只显示最后两位;
(4) 随时可以调校年、月、日;
(5) 允许通过转换功能键转换显示时间或日期。
(6) 所有按钮都需要通过串口自发自收来调整各种功能。
2.发挥部分
(1)增加秒表功能
(2)增加闹钟功能
(3)增加整点报时功能。
实验功能:
该系统以单片机为基础AT89S52制作的数字电子钟。除了完成实验所需的基本功能外,还扩展了几个功能。
硬件系统设计:
采用六位LED数字管,切换显示日期或时间和设置的闹钟时间;
调整日期、时间和闹钟时间;
具有设置闹钟的功能;
软件系统设计:
编程采用汇编语言,使自己更好地理解硬件语言及其工作原理。
时钟的基准时间由单片机内部的定时中断提供,用计数器计算定时中断的次数,可以实现秒定时,也可以分﹑“时”定时,以及“日”﹑“月”﹑年定期,并充分考虑闰年的日期差异
重用按键查询功能,简化程序设计
采用动态扫描法显示6位数字管
方案考虑:
1、硬件方案
(1)使用6位LED数字管显示日期或时间。
(2)、显示器的驱动可采用“静态显示驱动”(如7段译码/锁存/驱动芯片CD4511);也可采用动态扫描驱动,但后者大于前者所需的驱动电流。
(3)液晶也可示部分,但液晶成本较高。
(4)键盘按键数量较多时,最好采用行列矩阵结构。一键多用的构思和设计可以大大降低按键数量。
(5)整体设计应考虑其结构简单﹑操作简便﹑布局美观﹑成本低廉。
2、软件方案
(1)时钟的基准时间由单片机内部的定时中断提供,定时时间应为秒的整除数,长度合适。最长时间不得超过16位定时器;最短时间不得
可以少于中断服务程序的执行时间。一般来说,基准时间越短,时钟的运行精度就越好。
(2)用计数器计数定时中断的次数,可以实现秒定时,也可以分﹑时定时,日﹑“月”﹑定时年。
(3)、LED 数字管显示器采用动态扫描驱动时,需要注意的是,驱动信号的维护时间必须大于启动时间较短),驱动信号的间歇时间必须小于余辉时间(电流较长),但驱动电流由硬件电路能力和LED限制数码管极限功耗。
(4)更新显示内容时,动态扫描显示模式LED数字管余辉的存在可能会导致显示字符的模糊。在将新内容写入显示器之前,必须将所有内容都写入显示器LED数码管熄灭。
(5)关于自动识别月大﹑月小和平年﹑考虑润年问题
方案比较:
显示部分:
我们使用数字管显示,鉴于数字管也可以实现基本功能,液晶成本太贵,我们放弃使用翻译芯片,一方面进一步降低成本,另一方面减少部分电路,减少错误。
焊接部分:
印刷电路板的特点是布线紧凑,优点美观,跳线少,线路稳定。主要工作量在于前期原理图的绘制PCB板接线的缺点是腐蚀容易不均匀,断线;手工焊接万用板具有可变性高、自由度高的优点。主要工作量是原理图布线和跳线的概念和焊接,缺点是电路板焊接麻烦。
选择手工焊接万用板的原因:
1 原材料只提供万用板,根据主题要求考虑
2 万用板便于功能扩展,创新功能也留有大量空间。 按键部分
在按钮方面,主要使用矩阵键盘扫描和按钮查询。矩阵键盘扫描方法使用了更多的按钮,使操作复杂,资源无法充分利用。为了避免不必要的错误,采用按钮查询,一个功能,一个按钮的方式
单片机实物图:
二、组件清单:
IC 89S52 1
IC座 40脚 3
微型按钮 4脚 &nbs; 5
LED发光二极管 红色 1
电阻 4.7K 2
电阻 1k 6
电阻 3K 6
电阻 330 7
排阻 1k 1
电解电容 10UF 1
万能电路板 块 1
LED七段数码管 共阳BS 6
晶体三极管 PNP8550 6
蜂鸣器 1
三.按键使用
(1)。P0.7口按键具有切换显示模式的功能
(2)。P0.6口按键具有闪烁位移位的功能
(3)。P0.5 口按键具有对闪烁位加一的功能
(4)。P0.4口按键具有计秒的功能,即开始秒表/停止秒表/清楚秒表,同时还具有停止闹钟的功能。
(5)第9口具有复位的功能。即一按下去后恢复到初始化状态
(6)串口自收自发功能,当p3.0与p3.1连接起来后,按键有效,但当p3.0与p3.1断开后,按键无效。
系统使用调试说明:
按开关key1次数系统
状态
0(50)=00H,(51H)=00H,正常显示时间
1(50)=01H,(51H)=00H,正常显示日期
2(50)=02H,(51H)=00H,正常显示闹铃
3(50)=03H,(51H)=00H,正常显示秒表
4(50)=00H,(51H)=00H,正常显示时间
按键2:
按开关key2次数系统
状态
0(50)=00H,(51H)=00H,不闪烁
1(50)=00H,(51H)=01H,低两位闪烁
2(50)=00H,(51H)=02H,中两位闪烁
3(50)=00H,(51H)=03H,高两位闪烁
4(50)=00H,(51H)=00H,不闪烁
数码管显示代码表:
数码管管脚号Dpgfedcba数码管显示值编码数值
P1端口P1.7P1.6P1.5P1.4P1.3P1.2P1.1P1.0
端口电平110000000C0H
1111100110F9H
1010010020A4H
1011000030B0H
10010100199H
10010010592H
10000010682H
1111100070F8H
10000000880H
10010000990H
主程序流程图:
日历处理程序流程图:
附程序清单:
;;;;;;;;;;;;;;;;;;;
;预定义部分;;;;;;;;
;;;;;;;;;;;;;;;;;;;
;预定义用来显示小时、分钟、秒钟的存储单元
secL equ 30h;秒的十位
secH equ 31h;秒的个位
minL equ 32h;
minH equ 33h;
hourL equ 34h;
hourH equ 35h;
dayL equ 36h
dayH equ 37h
monL equ 38h
monH equ 39h
yearL equ 3ah
yearH equ 3bh
als_l equ 40h;
als_h equ 41h;
alm_l equ 42h;
alm_h equ 43h;
alh_l equ 44h;
alh_h equ 45h;
xsbz equ 50h;
shanshou equ 51h;
mao_sfw equ 5ah;秒的十分位
mao_bfw equ 5bh;秒的百分位
mao_sw equ 5ch;秒的十位
mao_gw equ 5dh; 秒的各位
mao_qw equ 5eh;qianwei
mao_bw equ 5fh;baiwei
org 0000h;复位入口
ljmp main
org 000bh;定时器T0入口
ljmp time0
org 0003h;外部中断0入口
reti;
org 0013h;外部中断1入口
reti
org 001bh;定时器T1入口
ljmp time1;
org 0023h;串行中断入口
reti
;;;;;;;;;;;;;;;;;;;;;;
;主程序入口;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;
main:
;放置初始值,H表示低地址,L表示高地址
mov secH,#0h
mov secL,#5h
mov minH,#9h
mov minL,#5h
mov hourH,#2h
mov hourL,#1h
mov yearH,#8h
mov yearL,#0h
mov monH,#1h
mov monL,#1h
mov dayH,#0h
mov dayL,#2h
mov als_l,#3h;
mov als_h,#1h;
mov alm_l,#3h;
mov alm_h,#0h;
mov alh_l,#1h;
mov alh_h,#2h;
mov mao_sfw ,#00h;秒的十分位
mov mao_bfw ,#00h;秒的百分位
mov mao_sw,#00h ;秒的十位
mov mao_gw,#00h ; 秒的各位
mov mao_qw,#00h;
mov mao_bw,#00h;
mov 50h,#00h;
mov 51h,#00h;
clr p3.2;
MOV SCON,#90H;串行口工作于方式2
;定时器T0,T1设置
mov TMOD,#11H;设置T0与T1为16位定时器
mov TL0,#0b0h;
mov TH0,#3ch;T0初值为3cb0h定时50ms
mov TL1,#0f0h;
mov TH1,#0d8h;T1初值为fc18h定时10ms
setb pt0;
setb EA;总中断允许
setb et0;
setb TR0;开启T0中断开始记时
mov r4,#20;定时次数,刚好1s
mov 60h,#0ah;定时器1定时次数10次
start:
lcall display;
jnb P0.7,k0;
jnb p0.6,k1;
jnb p0.5,k3;
jnb p0.4,k4;
lcall naoling1;
lcall zhengdi
jmp start;
k0: lcall chxianshi;
k1: lcall k2
k4: ljmp jimiao;
;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;闪烁位加一
;;;;;;;;;;;;;;;;;;;;;;;;;
k3: lcall dl30ms;
jb p0.5,outout;
set12: jnb p0.5,set12;
lcall chuan;
mov a,50h;
cjne a,#01h,sjiantz;
mov a,51h;
cjne a,#01h,zhwei;
mov r1,#dayH;
lcall add1;
mov a,r3;
cjne a,#32h,ftiao;分若小于则转退出
mov dayH,#01h;否则清0
mov dayL,#00h;
ftiao: ljmp outout;
zhwei: cjne a,#02h,gwei;
mov r1,#monH;
lcall add1;
mov a,r3;
cjne a,#13h,outout;
mov monH,#01h;
mov monL,#00h;
ljmp outout;
gwei: cjne a,#03h,outout;
mov r1,#yearH;
lcall add1;
mov a,r3;
cjne a,#99h,outout;
mov yearH,#00h;
mov yearL,#00h;
ljmp outout;
outout: ljmp start; 跳出
sjiantz:cjne a,#00h,naozhtz;转闹钟调整
mov a,51h;
cjne a,#01h,zhwei2;
mov r1,#secH;
lcall add1;
mov a,r3;
cjne a,#60h,ftiao2;分若小于则转退出
mov secH,#00h;否则清0
mov secL,#00h;
ftiao2: ljmp outout;
zhwei2: cjne a,#02h,gwei2;
mov r1,#minH;
lcall add1;
mov a,r3;
cjne a,#60h,outout;
mov minH,#00h;
mov minL,#00h;
ljmp outout;
gwei2: cjne a,#03h,outout;
mov r1,#hourH;
lcall add1;
mov a,r3;
cjne a,#24h,outout;
mov hourH,#00h;
mov hourL,#00h;
ljmp outout;
naozhtz:mov a,51h;
cjne a,#01h,zhwei3;
mov r1,#als_h;
lcall add1;
mov a,r3;
cjne a,#60h,ftiao3;分若小于则转退出
mov als_h,#00h;否则清0
mov als_l,#00h;
ftiao3: ljmp outout;
zhwei3: cjne a,#02h,gwei3;
mov r1,#alm_h;
lcall add1;
mov a,r3;
cjne a,#60h,outout;
mov alm_h,#00h;
mov alm_l,#00h;
ljmp outout;
gwei3: cjne a,#03h,outout;
mov r1,#alh_h;
lcall add1;
mov a,r3;
cjne a,#24h,outout;
mov alh_h,#00h;
mov alh_l,#00h;
ljmp outout;
;;;;;;;;;;;;;;;;;;;;;;;;
;;;;naoling
;;;;;;;;;;;;;;;;;;;;;;;;;
naoling1:push acc;
setb p0.1
mov a,31h;
cjne a,41h,out6;
mov a,30h;
cjne a,40h,out6;
mov a,33h;
cjne a,43h,out6;
mov a,32h;
cjne a,42h,out6;
mov a,35h;
cjne a,45h,out6;
mov a,34h;
cjne a,44h,out6;
nao: clr P0.1
lcall display
jnb P0.4,stopnao
sjmp nao
stopnao: lcall dl30ms
mov P0,#0ffH
out6: pop acc;
lcall display;
ret;
;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;整点报时;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;
zhengdi: push acc;
mov a,31h;
cjne a,#00h,out7;
mov a,30h;
cjne a,#00h,out7;
mov a,33h;
cjne a,#00h,out7;
mov a,32h;
cjne a,#00h,out7;
mov a,#0ah;
clr p0.1;
clr p0.3
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
lcall display;
setb p0.1;
setb p0.3
out7: pop acc;
lcall display;
ret;
;**************************************************
;函数名:
;功能:串口发送数据函数
;传入参数:无
;传出参数:A
;**************************************************
chuan:MOV A,p0 ;读取P1口数据
MOV SBUF,A
JNB TI,$ ;等待发送完毕
CLR TI
lcall dl30ms;
wait: jnb ri,out9;
MOV A,SBUF
CLR RI
sjmp out10;
out9: lcall display;
jmp chuan;
out10: ret;
;**************************************************
;函数名:chxianshi
;功能:显示调整函数
;传入参数:无
;传出参数:
;**************************************************
chxianshi: lcall dl30ms;
jb P0.7,set2;
set1: jnb p0.7,set1;
lcall chuan;
mov a,50h;
cjne a,#00h,nianfen
mov a,#01h;
mov 50h,a;;
sjmp set2;
nianfen: cjne a,#01h,naoling;
mov a,#02h;
mov 50h,a;
sjmp set2;
naoling: cjne a,#02h,maobiao;
mov a,#03h;
mov 50h,a;
sjmp set2;
maobiao: mov a,#00h;
mov 50h,a;
set2: lcall display;
out: ret;
;**************************************************
;函数名:k2
;功能:调整位移位函数
;传入参数:无
;传出参数:
;**************************************************
k2: lcall dl30ms;
jb P0.6,set11;判断是否有键按下
set10: jnb p0.6,set10;
lcall chuan;
mov a,51h;
cjne a,#00h,zliang
mov a,#01h;
mov 51h,a;;
sjmp set11;
zliang: cjne a,#01h,gliang;
mov a,#02h;
mov 51h,a;
sjmp set11;
gliang: cjne a,#02h,bliang;
mov a,#03h;
mov 51h,a;
sjmp set11;
bliang: cjne a,#03h,set11
mov a,#00h;
mov 51h,a;
set11: lcall display;
ret;
;**************************************************
;函数名: jimiao
;功能: 计秒程序
;传入参数:无
;传出参数:无
;**************************************************
jimiao: push PSW;
push acc;
lcall dl30ms;
jb p0.4,out5;
jimao1:jnb p0.4,jimao1;第一次开中断计秒
mov a,50h;
cjne a,#03h,out5;
setb et1;
setb tr1;
jimao2:call display;第二次停止
jb p0.4,jimao2;
lcall display;
jb p0.4,out5;
jimao3:jnb p0.4,jimao3;
clr tr1;
clr et1;
jimao4:call display;第三次清0
jb p0.4,jimao4;
lcall display;
jb p0.4,out5;
jimao5:jnb p0.4,jimao5;
mov mao_sfw ,#00h;秒的十分位
mov mao_bfw ,#00h;秒的百分位
mov mao_sw,#00h ;秒的十位
mov mao_gw,#00h ; 秒的各位
mov mao_qw,#00h;
mov mao_bw,#00h;
out5: pop acc;
pop PSW;
ljmp start;
;;***********************************************
;函数名 time1
;功能:t1中断函数
;传入参数:无
;************************************************
time1:
push PSW
push acc
mov TL1,#0f0h;
mov TH1,#0d8h;T1初值为fc18h定时1ms
mov r1,#mao_bfw;指向秒计时单元
lcall add1;调用加1程序
mov a,r2;将经过处理的数据放入a中
cjne a,#99h,outT01;当秒到未到达60时跳出中断
mov 5ah,#00h
mov 5bh,#00h;将秒清零
mov r1,#mao_gw;指向分计时单元
lcall add1;调用加1程序
mov a,r2;将经过处理的数据放入a中
cjne a,#60h,outT01;当分钟未到达60时跳出中断
mov 5ch,#00h;
mov 5dh,#00h;
mov r1,#mao_bw;指向小时计时单元
lcall add1;调用加1程序
mov a,r2;将经过处理的数据放入a中
cjne a,#60h,outT0;当小时未到达60时跳出中断
mov 5eh,#00h;
mov 5fh,#00h;
outt01:
pop acc
pop psw;恢复现场
reti ;中断返回
;**************************************************
;函数名: time0
;功能:t0中断处理程序函数
;传入参数:无
;**************************************************
time0:
push PSW
push acc
push b ;保护现场
push 02h
push 01h
clr ET0;关T0中断允许
clr TR0;关T0定时中断
mov th0,#3ch;
mov a,#0b0h
add a,TL0
mov TL0,a;给定时器重新装值
setb TR0;允许计时
djnz r4,outT0;定时没到1s就退出中断
mov r4,#20;给r0重新赋值
mov r1,#secH;指向秒计时单元
lcall add1;调用加1程序
mov a,r2;将经过处理的数据放入a中
cjne a,#60h,outT0;当秒到未到达60时跳出中断
addmin:;否则分钟加1
mov secL,#0
mov secH,#0;将秒清零
mov r1,#minH;指向分计时单元
lcall add1;调用加1程序
mov a,r2;将经过处理的数据放入a中
cjne a,#60h,outT0;当分钟未到达60时跳出中断
addhour: ;否则小时加1
mov minL,#0
mov minH,#0;将分清零
mov r1,#hourH;指向小时计时单元
lcall add1;调用加1程序
mov a,r2;将经过处理的数据放入a中
cjne a,#24h,outT0;当小时未到达60时跳出中断
lcall rili ;调用日历子程序
outT0:
pop 01h
pop 02h
pop b
pop acc
pop psw;恢复现场
setb ET0;开放中断
reti ;中断返回
;**************************************************
;函数名: rili
;功能: 日历处理程序函数
;传入参数:无
;传出参数:
;**************************************************
rili:
addday:mov hourL,#0
mov hourH,#0;将小时清零
mov r1,#dayH;指向天计时单元
lcall add1;调用加1程序
mov a,r2;将经过处理的数据放入a中
day31:
cjne a,#32h,day30;看是不是31号
ajmp addmon;是的话,加月
day30:
mov r5,a
cjne a,#31h,day29;看是不是30号;是的话,处理
mov a,#0h
mov a,monL
swap a
orl a,monh;将月份放入a中
cjne a,#04h,outri;判断是不是4,6,9,11中的某一月
cjne a,#06h,outri
cjne a,#09h,outri
cjne a,#11h,outri;不是的话跳出
ajmp addmon;是的话,加月
day29:
mov a,r5
cjne a,#30h,day28;看是不是29号
mov a,#0h
mov a,monL
swap a
orl a,monH
cjne a,#02h,outri;是的话,看月份是不是2月
ajmp addmon
day28:
mov a,r5
cjne a,#29h,outri;看是不是28号,不是的话跳出
mov a,#0h
mov a,monL
swap a
orl a,monH
cjne a,#02h,outri;看月份是不是2月;是2月,则判断是不是润年
mov a,#0h
mov a,yearL
swap a
orl a,yearH
da a
mov b,#04h
div ab
mov r5,b
cjne r5,#0h,outri
ajmp addmon
addmon:;月加1
mov dayL,#0
mov dayH,#0;将天清零
mov r1,#monH;指向月计时单元
lcall add1;调用加1程序
mov a,r2;将经过处理的数据放入a中
cjne a,#12h,outri;当月未到达12时
addyear:;年加1
mov monL,#0
mov monH,#0;将月清零
mov r1,#yearH;指向年计时单元
lcall add1;调用加1程序
mov a,r2;将经过处理的数据放入a中
outri:
ret
;**************************************************
;函数名: add1
;功能:加一函数
;传入参数:r1存的是地址指针
;r2存的是返回的处理数据
;**************************************************
add1:
mov a,#0;对a进行清零
dec r1;指向高四位数据地址
mov a,@r1;将高四位移入a
inc r1;指向低四位
swap a;a中高四位与低四位互换
orl a,@r1;将低四位显示数据放入a中
add a,#01h;
da a;对a中数据进行加1,并作十进制调整
mov r2,a;将处理后的数据移入r2中,注意r2中存的是十进制对应的bcd码
mov r3,a;下面是将a中然数据恢复为高位与低位
anl a,#0f0h;取高四位
swap a
dec r1;
mov @r1,a;将高四位移入低位地址中
mov a,r3;将暂存数据移回
anl a,#0fh;取其低四位
inc r1;指针指向高四位地址
mov @r1,a;将低四位移到高位地址中
ret;子程序返回
;**************************************************
;函数名: display
;功能: 显示处理程序函数
;传入参数:无
;传出参数:
;**************************************************
display:mov a,50h;
cjne a,#00H,dat;00h是时间显示不等则转到年份显示
timdis: mov r0,#secL;
sjmp aa
dat:cjne a,#01h,ala;若为01h则显示年份,否则显示闹钟
mov r0,#dayL;
sjmp aa;
ala: cjne a,#02h,mbiao
mov r0,#als_l;
sjmp aa;
mbiao: mov r0,#mao_sfw;
nop;
aa: mov p2,#0ffh;
mov a,@r0
mov dptr,#TAB
movc a,@a+dptr;
mov p1,a;
mov a,51h;
cjne a,#01h,aa01;
mov a,r4;
rrc a;
jnc aa02;
aa01: mov p2,#0feh;
aa02:lcall dl5ms;
lcall dl5ms;
mov p2,#0FFh;
inc r0;
mov a,@r0
mov dptr,#TAB
movc a,@a+dptr;
mov p1,a;
mov a,51h;
cjne a,#01h,bb01;
mov a,r4;
rrc a;
jnc bb02;
bb01: mov p2,#0fdh;
bb02: lcall dl5ms;
lcall dl5ms;
mov p2,#0ffh;
inc r0;
mov a,@r0
mov dptr,#TAB
movc a,@a+dptr;
mov p1,a;
mov a,51h;
cjne a,#02h,cc01;
mov a,r4
rrc a;
jnc cc02
cc01: mov p2,#0fbh;
cc02: lcall dl5ms;
lcall dl5ms;
mov p2,#0ffh;
inc r0;
mov a,@r0
mov dptr,#TAB
movc a,@a+dptr;
mov p1,a;
mov a,51h;
cjne a,#02h,dd01;
mov a,r4
rrc a;
jnc dd02
dd01: mov p2,#0f7h;
dd02: lcall dl5ms;
lcall dl5ms;
mov p2,#0ffh;
inc r0;
mov a,@r0
mov dptr,#TAB
movc a,@a+dptr;
mov p1,a;
mov a,51h;
cjne a,#03h,ee01;
mov a,r4
rrc a;
jnc ee02
ee01: mov p2,#0efh;
ee02: lcall dl5ms;
lcall dl5ms;
mov p2,#0ffh;
inc r0;
mov a,@r0
mov dptr,#TAB
movc a,@a+dptr;
mov p1,a;
mov a,51h;
cjne a,#03h,ff01;
mov a,r4
rrc a;
jnc ff02
ff01: mov p2,#0dfh;
ff02: lcall dl5ms;
lcall dl5ms;
ret;
;;;;;;;;;;;;
;延时程序;;;
;1ms延时;;;;
;;;;;;;;;;;;
delay1ms:
mov R6,#14H
dl1:mov R7,#19H
dl2:djnz R7,dl2
djnz R6,dl1
ret
dl5ms: mov 55h,#03h;
d2: mov 56h,#0fh;
d1: djnz 56h,d1;
djnz 55h,d2;
ret;
dl30ms: lcall dl5ms;
lcall dl5ms;
lcall dl5ms;
lcall dl5ms;
lcall dl5ms;
lcall dl5ms;
ret;
dl20ms: lcall dl5ms;
lcall dl5ms;
lcall dl5ms;
lcall dl5ms;
ret;
TAB:DB 0C0H,0f9h,0a4h,0b0h,99h,92h,82h,0f8h,80h,90h;
end 闹钟:
实现闹钟功能主要有两个步骤,首先是能在按键中把闹钟数值写进寄存器,实现存储功能。其次是根据在查询按键服务程序中作判别,检查当前时间是否与闹铃时间相等,如果相等,则使在相应时间时对蜂鸣器提供驱动电流即可。就实现了闹钟设置的功能。 整点报时:
整点报时是在查询按键程序中调用到zhengdi子程序,检查当前的时间是否整点,如果是,则点亮整点指示灯,并响蜂鸣器,停留约2秒钟,自行熄灭与关闭。
按键消抖:
按键消抖可以采用硬件消抖跟软件消抖。我们初定了两种方案:
1是利用数字电路的反相器或斯密特触发器进行整形,如图:
2是采用软件消抖技术
应该说用硬件消抖可以达到更好的效果,不过由于提供的材料跟自身手上的材料没有以上元件,故采用软件消抖。软件的消抖主要是调整出一个切到好处的延迟检测时间,一般为5-30ms。经过我们的多次调试,我们最终得到不错的去抖动效果。在程序中为DMS子程序实现。软件延时是用的最多的消抖方法,但是耗时间。在CPU耗不起时间的情况下,硬件消抖会更好
在本程序中设置了30ms的按键消抖。
感想体会:
本实验花了我们四天的时间,由于该大作业是用汇编语言写的,很多语句掌握都不是很牢固,但是经过这么长时间的实验,我基本掌握了部分汇编语言的用法,特别是实验中经常用到的按键查询,跳转语句,以及汇编的方法。
刚开始的时候,我什麽都不懂,根本不知怎样入门,后来查找了一些系统资料,渐渐有了些了解,才开始写自己的程序。虽然如此,中间还是遇到过不少困难,不如些按键查询的时候,仿真不出来,不知道哪里出错了,也不知道是不是程序有问题,后来在小组成员的帮助下,终于找到问题所在,通过不断的琢磨,后来不仅实现了老师的要求的基本功能,更加了秒表,闹铃还有整点报时。本来还想加上纪念日和音乐闹铃,当一方面时间有限,另一方面尝试后失败了就暂时搁下。
调试的时候,刚上去的时候,板子工作很不稳定,虽然有时候能够显示到正确的东西,当大多数时间都是显示的杂乱无章,鉴于有时候能够正确显示,我们是板子焊的不好,于是重新焊过,第二个版子刚上电的时候,还是不能很正确的工作,后来,一步一步的调试,先用简单的程序检查板子,发现板子是没有问题的,于是就确定是程序的问题,我把程序分为好几块,一块一块的调试,一段好了之后,在加上一段。最后发现是在一个子程序里边用了一个错误的ljmp。 改正了之后就完全正确了。
经过这次试验,确实学到我好多好多的东西。