单片机及接口技术综合实验
——————电子万年日历系统
一、题目:电子实时时钟/万年日历系统
二、功能要求:
1. 基本要求:
⑴ 显示准确的北京时间(时、分、秒),可用24小时制式; ⑵ 随时可以调校时间。
2. 发挥要求:
⑴ 增加公历日期显示功能(年、月、日),年号只显示最后两位; ⑵ 随时可以调校年、月、日;
⑶ 允许通过转换功能键转换显示时间或日期。
三、方案考虑:
1、硬件方案:
⑴ 显示器采用6位LED数码管(共阳),可分别显示时间或日期;(通过KB键可切换) ⑵ 显示器的驱动采用动态扫描电路形式,以达到简化电路的目的。但要注意所需的驱动电流比静态驱动时要大,因此要增加驱动电路。可采用74LS244或者晶体管;其中74ls244是用来驱动段选码,晶体管是驱动位选码! ⑶采用“一键多用方案”,以减少按键数目。本方案只采用了两个按键 ⑷ 整体上要考虑:结构简单、布局美观、操作方便、成本低廉。
2、设计电路图如下:
3、元件清单:
⑴ 89C51
1个
⑵ IC座(40脚)
3个(其中1个用于接插89C
51、2个用于接插LED段数码管)。 ⑶ 74LS244
1个(用于驱动6个共阳的LED段数码管)。 ⑷ IC座(20脚)
1个(用于接插74LS244)。 (5)显示器:LED_8段数码管(共阳型)6个三极管:
(6)PNP(8550)
6个(用于驱动6个共阳型LED段数码管)。
(7)微型开关:
3个(其中1个用于复位电路、其它用于键盘)。 (8)晶体振荡器(12MHz):1个(用于振荡电路)。 (9)电阻器:
⑴ 3KΩ
1个(用于系统复位电路)。
⑵ 1KΩ
6个(用作PNP三极管基极电阻)。 ⑶ 100Ω
7个(驱动器用作74LS244输出限流电阻)。 (10)电容器:
⑴ 10μF
1个(用于系统复位电路)。 ⑵ 30 pF
2个(用于系统振荡电路)。 (11)其它:
⑴ 万能电路板(10×15):
1块 ⑵ 焊锡条:
2米 ⑶ 带插头、座的电源端子:
1条 ⑷ 各种颜色外皮的导线:
各1米 (12)工具:
1.电烙铁:
1把 2.剪钳:
1把 3.镊子:
1把 4.万用表:
1个 (13)设备:
编程器(MEP300或TOP851)
6个
4、软件方案:
只使用第一组工作寄存器,功能分布如下:
⑴ “时钟”基准时间由单片机内部定时中断来提供,定时时间应该乘以一个整数得到“秒”,且不宜太长或太短,最长不能超过16位定时器的最长定时时间,最短不能少于定时中断服务程序的执行时间。一般来说,基准时间越短,越有利于提高时钟运行的精确度。本实验定时5mS。乘以一个整数200得到“1秒”.⑵ 用一个计数器(R4)对定时中断的次数进行计数,从而可以实现“秒”定时,同理可以实现“分”定时和“时”定时,甚至于“日”、“月”、“年”定时。
⑶ 显示器采用动态驱动时要注意到:LED的 “启辉时间”和 “余辉时间”。驱动信号的维持时间必须大于启辉时间;而驱动信号的间歇时间必须小于余辉时间。“启辉时间”和 “余辉时间”与驱动电流的大小有关,驱动电流越大,启辉时间越短,而余辉时间越长。但是,驱动电流的大小受到驱动电路的驱动能力和LED极限功耗的限制。本实验采用了74ls244和晶体管8550驱动,并进行适当的延时3ms解决上述问题。
⑷ LED的余辉时间使动态驱动显示得到保证,但也要注意到它在更新显示内容时,可能造成显示字符的混乱模糊。为此,在把“更新显示内容”写入显示器之前,必须把所有的LED熄灭,即要把一个“熄灭驱动信号”先写入显示器。
⑸对于按键的处理,采用中断。产生中断后先判有无按键被按下,还要考虑到“去抖动影响”问题,可采用软件延迟法解决这个问题,延迟时间至少10mS。而单纯进行软件延时的话会令到显示管产生断续的情况,故调用显示程序作为延时时间。这样就合理地处理好这两者的矛盾了。
⑹ 把键盘的按键分两种情况来处理,操作简单。
①
调整时间时,先按下KA键,(KA键为选择调整位置的键,如选调整秒或分),而此时的KB键只是用来加一操作。在调整时间状态下,若在十秒内检测到没有任何按键按下,则返回正常显示时钟状态。
②
而不调整时间,即不按下KA键,KB的键只用来切换显示日期和时钟。 ⑺ 对于自动识别“月大、月小”和“平年、闰年”的问题,主要考虑: ① 月大、月小:
1~7月:逢单月为31天;逢双月为30天,其中2月另行处理。 8~12月:逢单月为30天;逢双月为31天。 ②平年、闰年:
仅仅处理2月份的天数:平年的2月份天数为28天,闰年的2月份天数为29天。
5、程序流程图如下: (1) 电子时钟计算程序图
(2)调整流程图
程序编写如下:
;///////////////////////////////////////////////////////// ORG 0000H
LJMP START ORG 0003H LJMP PROINT0
;int0用来切换时钟调整位置
ORG 0013H
;用来调整时间,只加不减 LJMP PROINT1
ORG 001BH
;5ms的延迟,计数200次则为1秒
LJMP PROTIME
ORG 0030H
;主程序
TABLE: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
;0 1 2 3 4 5 6 7 8 9
ORG 0050H
START: MOV TCON,#05H
;中断初始化
MOV IE ,#8DH MOV TMOD,#10H MOV TH1,#0eCH
;定时器初始化
MOV TL1,#78H
MOV 31H,#0AH
;10秒 MOV 32H,#1EH ;30分 MOV 33H,#09H ;9点 MOV 34H,#0AH MOV 35H,#06H MOV 36H,#05H MOV 37H,#14H
;10号 ;6月 ;2005年
;R7 存放切换标志 0 NORMAL , 1 HOUR ,2 MINUTE ,3 SECOND ,4 YEAR,5 MONTH,6 DAY
MOV R1,#00H
;确定在调时不按键的最长时间,10秒后返回normal状态
MOV R7,#00H
;切换标志
MOV 40H,#00H
;十六进制转换BCD的高位 MOV 41H,#00H
;十六进制转换BCD的低位
MOV R6,#00H
;调时的位闪烁的时间间隔
MOV R4,#00H
;用来计数5ms的中断次数,200次则一秒
mov r3,#00h
SETB TR1
;开始计时 AGAIN:
ACALL PROSHOW
;显示
AJMP AGAIN
PROSHOW:
CJNE R3,#00H,SHOWDATE
;如果r3等于1就显示日期,等于0就显示时钟 CJNE R7,#04H,DATE1
;显示程序
AJMP SHOWDATE
;showdate显示年月日 AJMP SHOWDATE DATE1: CJNE R7,#05H,DATE2 DATE2: CJNE R7,#06H,SHOWCLOCK AJMP SHOWDATE
showCLOCK: MOV R0,33H
;showclock显示时分秒,先显示时
ACALL PROHTOD
CJNE R7,#01H,CLK1 INC R6
CJNE R6,#03H,CLK2
;若处于调时状态,则该位闪烁
MOV R6 ,#00H CLK1: clr P2.4 mov a,41H MOV P0, a
;显示时的低位 ACALL DELAY3MS CLK2: SETB P2.4 CLR P2.5 mov a,40H
MOV P0,a
;显示时的高位 ACALL DELAY3MS SETB P2.5
MOV R0,32H
;显示分 ACALL PROHTOD CJNE R7,#02H,CLK3 INC R6
CJNE R6,#03H,CLK4
;若处于调时状态,则该位闪烁
MOV R6,#00H CLK3: CLR P2.2
mov a,41H MOV P0, a
;显示分的低位 ACALL DELAY3MS CLK4:
SETB P2.2 CLR P2.3 mov a,40h MOV P0,a
;显示分的高位 ACALL DELAY3MS SETB P2.3
MOV R0,31H
;显示秒
ACALL PROHTOD CJNE R7,#03H,CLK5 INC R6
CJNE R6,#03H,CLK6
MOV R6,#00H CLK5: CLR P2.0 mov a,41H MOV P0, a
ACALL DELAY3MS CLK6: SETB P2.0 CLR P2.1 mov a,40h MOV P0,a
ACALL DELAY3MS SETB P2.1
RET
SHOWDATE: MOV R0,36H
ACALL PROHTOD CJNE R7,#04H,DAY1 INC R6
CJNE R6,#03H,DAY2
MOV R6,#00H DAY1: CLR P2.4 MOV P0,41H
ACALL DELAY3MS DAY2: SETB P2.4 CLR P2.5 MOV P0,40H
ACALL DELAY3MS SETB P2.5
MOV R0,35H
ACALL PROHTOD CJNE R7,#05H,MONTH1
;若处于调时状态,则该位闪烁
;显示秒的低位
;显示秒的高位
;显示年
;若处于调时状态,则该位闪烁 ;显示年的低位
;显示年的高位
;显示月
INC R6
CJNE R6,#03H,MONTH2
;若处于调时状态,则该位闪烁
MOV R6,#00H MONTH1: CLR P2.2 MOV P0,41H
;显示月的低位
ACALL DELAY3MS MONTH2: SETB P2.2
CLR P2.3 MOV P0,40H
;显示月的高位
ACALL DELAY3MS SETB P2.3
MOV R0,34H
ACALL PROHTOD CJNE R7,#06H,YEAR1 INC R6
CJNE R6,#03H,YEAR2
MOV R6,#00H YEAR1: CLR P2.0
MOV P0,41H
ACALL DELAY3MS YEAR2: SETB P2.0 CLR P2.1 MOV P0,40H
ACALL DELAY3MS SETB P2.1
RET
PROHTOD:PUSH ACC
MOV A,R0 MOV B,#0AH DIV AB MOV DPTR,#0030H MOVC A,@A+DPTR MOV 40H,A MOV A,B MOVC A,@A+DPTR MOV 41H,A POP ACC RET
;显示日
;若处于调时状态,则该位闪烁
;十六进制数转换成bcd码,且可以直接输出p0口
DELAY3MS:
;DELAY3MS MOV 45H,#08H DELAY1: MOV 46H,#0FFH DELAY2: DJNZ 46H,DELAY2 DJNZ 45H,DELAY1 RET
PROINT0:
CLR EX0
;切换键中断程序 MOV R3,#00H ACALL PROSHOW MOV C,P3.2 JC IEXIT0 MOV R1,#00H INC R7 CJNE R7,#07H,IEXIT0
MOV R7,#00H INT01: MOV C,P3.2 JC INT02 ACALL PROSHOW AJMP INT01 INT02: ACALL PROSHOW IEXIT0: SETB EX0 RETI
PROINT1:CLR EX1
ACALL PROSHOW MOV C,P3.3 JC IEXIT1 LCALL ISYEAR
;判断平年闰年
LCALL ISMONTH
;判断月份,确定最大日数
MOV R1,#00H CJNE R7,#00H,NEXT1
;若不是调时状态,按此键就是切换显示日期、时钟
INC R3 CJNE R3,#02H,IEXIT1 MOV R3,#00H AJMP IEXIT1 NEXT1: mov r3,#00h
CJNE R7,#03H,NEXT2
;修改秒位 INC 31H MOV A,31H CJNE A,#3CH,INT11
;遇60变0 MOV 31H,#00H AJMP IEXIT1
NEXT2: CJNE R7,#02H,NEXT3
;修改分位
INC 32H MOV A,31H
CJNE A,#3CH,INT11
;遇60变0 MOV 31H,#00H AJMP IEXIT1 NEXT3: CJNE R7,#01H,NEXT4
;修改时位
INC 33H MOV A,33H CJNE A,#18H,INT11
;遇24变0 MOV 33H,#00H AJMP IEXIT1 NEXT4: CJNE R7,#06H,NEXT5
;修改日
INC 34H MOV A,34H CJNE A,49H,INT11
;到月底就返回月初 MOV 34H,#01H AJMP IEXIT1
NEXT5: CJNE R7,#05H,NEXT6
;修改月
INC 35H
MOV A,35H CJNE A,#0DH,INT11
;十二月过后就跳回1月 MOV 35H,#01H AJMP IEXIT1 NEXT6: CJNE R7,#04H,INT11
;修改年
INC 36H
MOV A,36H CJNE A,#64H,INT11
MOV 36H,#00H MOV C,P3.3 INT11: JC INT12 ACALL PROSHOW AJMP INT11 INT12: ACALL PROSHOW IEXIT1: setb EX1
RETI PROTIME:
MOV TMOD,#10H MOV TH1,#3CH
;定时器初始化 MOV TL1,#60H setb tr1 INC R4
CJNE R4,#0c8H,EXIT
MOV R4,#00H
;计满1秒则清零 CJNE R7,#00H,DIAOSHI
AJMP NORMAL DIAOSHI:INC R1
;调时不按键的最长时间为10秒,在此期间又键按下重新计时
CJNE R1,#0AH,EXIT MOV R7,#00H
;到10秒则返回正常显示状态 MOV R1,#00H AJMP EXIT
NORMAL:ACALL ISYEAR
;判断平闰年,返回标志48h,0为平年,1为闰年
ACALL ISMONTH
;判断哪个月,返回该月的最大日数,存放在49h
INC 31H
MOV A,31H
;秒加一 CJNE A,#3CH,EXIT MOV 31H,#00H
INC 32H
;分加一 MOV A,32H CJNE A,#3CH,EXIT MOV 32H,#00H INC 33H
;时加一 MOV A,33H CJNE A,#18H,EXIT MOV 33H,#00H INC 34H
MOV A,34H CJNE A,49H,EXIT MOV 34H,#01H INC 35H
MOV A,35H CJNE A,#0DH,EXIT MOV 35H,#01H INC 36H
MOV A,36H CJNE A,#64H,EXIT MOV 36H,#00H ;年加一 ;月加一 ;日加一 EXIT:
RETI
ISYEAR: MOV A,36H ;判断平闰年
MOV B,#04H
DIV AB MOV A,B CJNE A,#00H,EXITYEAR1 MOV 48H,#01H
;闰年 SJMP EXITYEAR MOV 48H,#00H
;平年 EXITYEAR1: EXITYEAR: RETI
ISMONTH:
MOV A,35H
;开始检查月份 CJNE A,#02H,NEXTMON1
;判断二月 MOV R2,48H
CJNE R2,#00H,RUNNIAN MOV 49H,#1DH
;平年为28天,赋29给49h AJMP EXITMONTH RUNNIAN:MOV 49H,#1EH
;闰年为29天,赋30天给49h
AJMP EXITMONTH
NEXTMON1: CJNE A,#04H,NEXTMON2
AJMP XIAOYUE
NEXTMON2:CJNE A,#06H,NEXTMON3 AJMP XIAOYUE
NEXTMON3:CJNE A,#09H,NEXTMON4 AJMP XIAOYUE NEXTMON4:CJNE A,#0BH,DAYUE XIAOYUE: MOV 49H,#1FH
;四,六,九,十一月是小月,30天,但应该赋31天给比较值49h,
AJMP EXITMONTH DAYUE: MOV 49H,#20H
;其他月份为大月,31天,赋32天给49h EXITMONTH: RETI END