为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

数码管电子时钟

2011-05-14 21页 doc 313KB 65阅读

用户头像

is_729181

暂无简介

举报
数码管电子时钟单片机大作业 ——电子日历时钟的制作 班 级: 姓 名: 学 号: 编 号: 07 1、​ 题目及功能要求 1.​ 制作一个电子日历时钟,使用汇编语言进行软件编程 2.​ 实现功能 (1)​ 显示北京时间并能校准 (2)​ 时、分、秒之间以及年、月、日之间以小数点隔开 (3)​ 显示公历日期并能校准,能够自动识别“闰年”以及“大月、小月” (4)​ 运动秒表,能够后台计时,秒表精确到0.05S (5)​ 闹钟功能,有闹钟开关,并能显示当前闹钟是否开启 (6)​ 整点报时提醒 2、​ 硬件方案 1.​ AT89S52最小系统 2...
数码管电子时钟
单片机大作业 ——电子日历时钟的制作 班 级: 姓 名: 学 号: 编 号: 07 1、​ 目及功能要求 1.​ 制作一个电子日历时钟,使用汇编语言进行软件编程 2.​ 实现功能 (1)​ 显示北京时间并能校准 (2)​ 时、分、秒之间以及年、月、日之间以小数点隔开 (3)​ 显示公历日期并能校准,能够自动识别“闰年”以及“大月、小月” (4)​ 运动秒表,能够后台计时,秒表精确到0.05S (5)​ 闹钟功能,有闹钟开关,并能显示当前闹钟是否开启 (6)​ 整点报时提醒 2、​ 硬件方案 1.​ AT89S52最小系统 2.​ 显示电路采用动态扫描驱动电路,AT89S52的P0口连接74LS244总线驱动器,输出信号利用三极管8550进行放大,通过P1口对数码管进行段选扫描,AT89S52的P1.2~P1.7口对数码管进行位选扫描 3.​ 两个按键开关,分别接AT89S52的两个外部中断引脚 4.​ AT89S52的P2.0口输出经三极管9012放大,驱动有源蜂鸣器发声 3、​ 电路原理图 4、​ 系统元件布局、布线图 5、​ 元器件清单 型号及标称值 数量 AT89S52 1 HD74LS244 1 晶体管8550 6 晶体管9012 1 蜂鸣器(有源) 1 电解电容10uF 1 7段数码管(共阳) 6 3K电阻 9 200电阻 8 4.7K电阻 1 按钮开关 3 12M晶振 1 30pF瓷介电容 2 6、​ 软件方案 1.​ “时钟”基准时间由AT89S52定时器0中断提供,设置为最高优先级,定时器0设为工作方式1,即16进制计数器方式,计数初值设为15536,即可实现0.05s中断一次,连续中断20次即可实现一秒定时。 2.​ 由于使用较多数码管,显示模块使用动态扫描方式,定义全局变量,保存各个数位的BCD码,通过查表,将字模送到P0口进行输出;为了显示闹钟的状态,设置了另一字模数据表,在显示前进行判断,若为闹钟开关设置状态则调用此字模数据表。 3.​ 按键中断的时候,在2个按键都没按下的状态,2个中断引脚都为低电平,则一直调用中断0的子程序,每次进入中断0子程序中便检测中断1的引脚是否为高电平,即检测开关KEY1是否按下;相反,在按下KEY0时,进入中断1子程序,每次进入中断1子程序都检测中断0的引脚是否为高电平,为高电平则表示已按下。 4.​ 用寄存器R7来记录当前切换的功能,分别为,0-时间;1-日期;2-闹钟;3-闹钟开关;4-秒表。 5.​ 秒表的实现,采用基准时钟作为秒表时钟源,精度可以达到0.05s。 6.​ 闹钟的实现,在主程序中,循环判断闹钟设置的时分与当前时分是否相等,闹钟持续1分钟 7.​ 整点报时的实现,在主程序中,先判断当前时间的秒,若为0再判断分,再为0则使蜂鸣器嘀一声,循环判断。 7、​ 程序框图 1.​ 主程序 2.​ 定时器0中断子程序 3.​ 外部中断0子程序 4.​ 外部中断1子程序 8、​ 系统使用说明 1.​ 接通电源自动复位,读取初始状态,时钟--“00.00.00”,日期—“10.06.06”,闹钟—“06.00.00”,闹钟状态—“OFF”,秒表—“00.00.00”。 2.​ 按键KEY1为“切换功能/调节”按钮,按键KEY0为“确定/计时开始/计时暂停/闹钟开关按钮 3.​ 第一功能----电子时钟:按KEY0键进入时校准状态,“时”数码管闪烁,此时按KEY1键可以调节小时,“时”调节范围为00~24,按KEY0可切换到“分”设置,调节范围为00~59再按KEY0可切换到“秒”设置, 调节范围为00~59。 4.​ 第二功能----电子日历:在电子时钟功能下,按KEY1可以切换到电子日历功能。进入电子日历功能,可以对“年”.“月”.“日”进行校准,校准方式同电子时钟的校准方式一样,自行摸索。 5.​ 第三功能----闹钟设置:在电子日历功能下,按KEY1可以切换到闹钟设置功能。闹钟的设置同电子时钟的设置一样。 6.​ 第四功能----闹钟开关:在闹钟设置功能下,按KEY1可以切换到闹钟开关设置。默认状态为关闭闹钟功能,显示“OFF”,按KEY0可以调节闹钟开关,打开闹钟功能则显示“ON”。闹钟设置为“ON”时,最后一个数码管的小数点会亮起,可以在任何功能状态下提示闹钟功能已开启。 7.​ 第五功能----秒表:在闹钟设置功能下,按KEY1可以切换到秒表功能。进入秒表功能,按KEY0开始计时,再按KEY0则暂停计时,在秒表计时的时候按KEY1可以切换到其他功能,而秒表则在后台计时,在秒表暂停时按KEY1可以将秒表清零。 9、​ 体会 第一次使用Atmel Designer Winter 09布出一个完整的PCB制板图,并用覆铜板做成实物,最大的体会是:软件能画出来的图,我们不一定就能把这样的 电路板做出来。布线时要考虑的因素除整体布局、飞线数目外,最重要的是线的宽度、线与线的间距、焊盘的大小。唯有线宽合适、间距合 理才能做出符合要求的电路板。刚制成的电路板要先使用万用表检测各导线的连接情况,解决断路、短路的问题之后方能进行焊接。这样做 的好处是,保证了调试程序时不会受硬件接触不良等情况的影响。 由于第一次尝试完全使用汇编语言对AT89S52进行编程操作,对汇编语言的陌生给前期编程工作带来诸多不便。汇编语言不同于C或其它高级 语言,程序间的跳转,各种寄存器的压栈出栈都需要人工考虑,而这种疏漏编译器也不会给出任何提示,于是往往一些大意的疏忽,程序便 无法达到预期的效果。加之没有相关条件使用在线调试,也给故障排除带来一些障碍。 对此的体会是,确定是程序出现问题时,优先往程序间的跳转条件、重要寄存器等的现场保护、循环退出的条件方面考虑,寻找原因。由于 此次硬件电路采用低电平导通的PNP三极管,和74LS244电平驱动器,也没有将IO口做通用数据传输口用,故不需考虑上拉电阻的选用及 将相应管脚写入高电平以正确接收数据的问题。当然在调试的过程中合理的使用软件仿真机,熟练的设置程序断点,同时观察单片机各寄存 器值的变化,可以极大方便我们查找程序漏洞,解决问题。 在写代码的过程中,应该注意代码的化,尤其是使用汇编编程时,必须加上必要的注释,方便程序阅读及故障排查。对于需要使用 到的各个变量,必须在程序开头集中定义存储位置,以求一目了然,在新增变量的时候也不至于出现存储单元被重复使用而导致数据丢失的 情况。 最后,看着忙碌数日得来的劳动成果乖乖的工作,确实蛮有成就感。希望今后有更多的机会进行这样的实践实验。 10、​ 附录 ;AT89S52CLOCK_FINAL.asm ; (Electronic Calendar and Clock) ; Reference for Grade 2008, s.c.u.t. ; Key0(for shift/adjust) connected to INT1 ; Key1(for un-flash/flash) connected to INT0 ; 学生姓名:黄锦波,黄卓佳 ; 学生学号:200830240380,200830240434 ; 分组编号:007 ;变量定义 TICK_CNT EQU 20H ;T0倍乘 ;------------------ SECOND_BCD EQU 21H ;时间记录 MINUTE_BCD EQU 22H HOUR_BCD EQU 23H ;------------------ DAY_BCD EQU 24H ;日期记录 MONTH_BCD EQU 25H YEAR_BCD EQU 26H ;------------------ FLASH_FLAG EQU 27H ;是否闪烁 DIS_FLAG EQU R7 ;当前显示标志 ;DIS_FLAG: 0-时间;1-日期;2-闹钟;3-闹钟开关;4-秒表 ;------------------ NSECOND_BCD EQU 2BH ;闹钟时间 NMINUTE_BCD EQU 2CH NHOUR_BCD EQU 2DH ;------------------ TCC_BCD EQU 2EH ;秒表计时器 TBB_BCD EQU 2FH TAA_BCD EQU 30H ;------------------ TIMER_FLAG EQU 31H ;秒表模式 TIMER_START_FLAG EQU 32H ;秒表开始 ;------------------ ALAM_STATE EQU 33H ;闹钟开启标志 ;------------------ DI_40H EQU 34H ;提示音延时变量 DI_41H EQU 35H ;延时 ;------------------ ALAM_ON1 EQU 36H ;闹钟状态显示 ALAM_ON2 EQU 37H ALAM_ON3 EQU 38H ALAM_OFF1 EQU 39H ALAM_OFF2 EQU 3AH ALAM_OFF3 EQU 3BH ;------------------ ;中断向量表 ORG 0000H LJMP MAIN ORG 0003H LJMP EX0_INT ; port INT0 ORG 000BH LJMP T0_INT ; port T0 ORG 0013H LJMP EX1_INT ; port INT1 ;主程序 ORG 0030H MAIN: NOP ; main program ;初始化堆栈 MOV SP,#60H ;初始化变量 MOV SECOND_BCD,#00H ; BCD of "second" MOV MINUTE_BCD,#00H ; BCD of "minute" MOV HOUR_BCD,#00H ; BCD of "hour" MOV NSECOND_BCD,#00H ; BCD of "second" MOV NMINUTE_BCD,#00H ; BCD of "minute" MOV NHOUR_BCD,#06H ; BCD of "hour" MOV TCC_BCD,#00H ; BCD of "second" MOV TBB_BCD,#00H ; BCD of "minute" MOV TAA_BCD,#00H ; BCD of "hour" MOV TIMER_START_FLAG,#00H ;秒表工作标志 MOV TIMER_FLAG,#00H ;秒表模式标志 MOV DAY_BCD,#06H ; BCD of "day" MOV MONTH_BCD,#06H ; BCD of "month" MOV YEAR_BCD,#010H ; BCD of "year" MOV FLASH_FLAG,#00H ; flag for un-flash/flash MOV DIS_FLAG,#00H ; flag for shift(time/date) MOV ALAM_ON1,#55H ; BCD OF 闹钟状态显示 MOV ALAM_ON2,#01H MOV ALAM_ON3,#55H MOV ALAM_OFF1,#63H MOV ALAM_OFF2,#42H MOV ALAM_OFF3,#33H MOV ALAM_STATE,#00H ;初始化闹钟状态为OFF ;------------------ MOV TL0,#0B0H ; constant for 0.05s MOV TH0,#3CH ; 65536-15536=50,000 for 12MHz MOV TICK_CNT,#14H ; times of overflow 0.05*20=1s MOV TMOD,#01H ; Mode 1 for T0, Timer Mode SETB ET0 ; open T0 SETB EX0 ; open INT0, Key1 SETB EX1 ; open INT1, Key0 SETB EA ; total open SETB PT0 ; priority for T0,高优先级 SETB TR0 ; start T0, Run SCAN_HOUR: ;闹钟扫描 MOV A,SECOND_BCD CJNE A,#00H,SCANALARM MOV A,MINUTE_BCD CJNE A,#00H,SCANALARM HOUR: CLR P2.0 NOP ;整点,滴 SETB P2.0 SCANALARM: ;闹钟扫描 MOV A,ALAM_STATE JZ SCAN_HOUR ;闹钟开关已打开? MOV A,NHOUR_BCD CJNE A,HOUR_BCD,WAIT MOV A,NMINUTE_BCD CJNE A,MINUTE_BCD,WAIT ALARM: CLR P2.0 ;闹铃:滴滴滴滴`````` SETB P2.0 CLR P2.0 SETB P2.0 CLR P2.0 SETB P2.0 CLR P2.0 SETB P2.0 NOP NOP NOP WAIT: SETB P2.0 SJMP SCAN_HOUR ; wait for interrupt ; ------------------------------------------------- ; sub: T0 interrupt ; 定时器0中断 T0_INT: PUSH ACC MOV TL0,#0B0H ; constant for 0.05s MOV TH0,#3CH ; Timer 0重装载 MOV A,TIMER_START_FLAG CJNE A,#01H,TIMER_NEXT ;秒表模式? LJMP TIMER_INC ;秒表计时 TIMER_NEXT: DJNZ TICK_CNT,NOT_1S ; is up to 1 second ? SJMP IS_1S NOT_1S: LJMP T0_RET ; 1秒时间到 IS_1S: MOV A,SECOND_BCD ; take BCD of "second" CJNE A,#59H,IN3 ; is up to 59 seconds ? SJMP IN4 IN3:LJMP SECOND_INC ; 秒加1 IN4:MOV SECOND_BCD,#00H ; 秒进位 MOV A,MINUTE_BCD ; take BCD of "minute" CJNE A,#59H,IN5 ; is up to 59 minutes ? SJMP IN6 IN5: LJMP MINUTE_INC IN6: MOV MINUTE_BCD,#00H ; 分进位 MOV A,HOUR_BCD ; take BCD of "hour" CJNE A,#23H,HOUR_INC ; is up to 23 hours ? MOV HOUR_BCD,#00H ; “时”进位 MOV A,MONTH_BCD ; take BCD of "month" CJNE A,#02H,NOT_FEB ; is February ? ;2月处理 ;-------------------------- FEB: NOP ACALL BCD_DIV4 ; BCD of "year in 26H" divided by 4 MOV A,R3 ; remainder in R3 CJNE A,#00H,NOT_LEAP_Y ; "00" means leap year ;闰年,29天 LEAP_Y: MOV A,DAY_BCD ; take BCD of "day" in Feb. CJNE A,#29H,DAY_INC ; is up to 29 days (leap year)? MOV DAY_BCD,#01H ; keep the first day MOV MONTH_BCD,#03H ; increase "month" SJMP RESET_CNT ;非闰年 NOT_LEAP_Y: MOV A,DAY_BCD ; take BCD of "day" in Feb. CJNE A,#28H,DAY_INC ; is up to 28 days (common year)? MOV DAY_BCD,#01H ; keep the first day MOV MONTH_BCD,#03H ; increase "month" SJMP RESET_CNT ;--------------------------- ;非2月处理 ;30/31天? NOT_FEB:NOP ; other "month" except Feb. CJNE A,#04H,Y01 ; is April ? AJMP MON_30D Y01: CJNE A,#06H,Y02 ; is June ? AJMP MON_30D Y02: CJNE A,#09H,Y03 ; is September ? AJMP MON_30D Y03: CJNE A,#11H,T11 ; is November ? AJMP MON_30D ;31天 T11: MOV A,DAY_BCD ; take BCD of "day" CJNE A,#31H,DAY_INC ; is up to 31 days ? AJMP NEXT_MONTH ;30天 MON_30D:MOV A,DAY_BCD ; take BCD of "day" CJNE A,#30H,DAY_INC ; is up to 30 days ? ;天进位 NEXT_MONTH: MOV DAY_BCD,#01H ; keep the first day MOV A,MONTH_BCD ; take BCD of "month" CJNE A,#12H,MONTH_INC ; is December ? ; 月进位 MOV MONTH_BCD,#01H ; keep the first month MOV A,YEAR_BCD ; take BCD of "year" CJNE A,#99H,YEAR_INC ; is up to 99 years ? MOV YEAR_BCD,#00H ; keep the first year SJMP RESET_CNT ;年加1 YEAR_INC: MOV A,YEAR_BCD ; take BCD of "year" ADD A,#01H ; increase "year" DA A ; adjust BCD MOV YEAR_BCD,A ; keep "year" SJMP RESET_CNT MONTH_INC: MOV A,MONTH_BCD ; take BCD of "month" ADD A,#01H ; increase "month" DA A ; BCD码调整 MOV MONTH_BCD,A ; keep "month" SJMP RESET_CNT DAY_INC: MOV A,DAY_BCD ; take BCD of "day" ADD A,#01H ; increase "day" DA A ; BCD码调整 MOV DAY_BCD,A ; keep "day" SJMP RESET_CNT HOUR_INC: MOV A,HOUR_BCD ; take BCD of "hour" ADD A,#01H ; increase "hour" DA A ; BCD码调整 MOV HOUR_BCD,A ; keep "hour" SJMP RESET_CNT MINUTE_INC: MOV A,MINUTE_BCD ; take BCD of "minute" ADD A,#01H ; increase "minute" DA A ; BCD码调整 MOV MINUTE_BCD,A ; keep "minute" SJMP RESET_CNT SECOND_INC: MOV A,SECOND_BCD ; take BCD of "second" ADD A,#01H ; increase "second" DA A ; BCD码调整 MOV SECOND_BCD,A ; save back "second" RESET_CNT: MOV TICK_CNT,#14H ; retrieve times of overflow T0_RET: POP ACC RETI ;-------------------------------------------------------------------- ;秒表增 TIMER_INC: TCC_INC: MOV A,TCC_BCD ; take BCD of "0.05S" CLR C SUBB A,#95H JZ TBB_INC MOV A,TCC_BCD ADD A,#05H ; increase "0.05S" DA A ; BCD码调整 MOV TCC_BCD,A ; keep "0.05S" AJMP TIMER_OUT TBB_INC: MOV TCC_BCD,#00H MOV A,TBB_BCD ; take BCD of "SECOND" CLR C SUBB A,#59H JZ TAA_INC MOV A,TBB_BCD ADD A,#01H ; increase "SECOND" DA A ; BCD码调整 MOV TBB_BCD,A ; keep "SECOND" AJMP TIMER_OUT TAA_INC: MOV TBB_BCD,#00H MOV A,TAA_BCD ; take BCD of "MINUTE" CLR C SUBB A,#59H JZ TDD_INC MOV A,TAA_BCD ADD A,#01H ; increase "MINUTE" DA A ; BCD码调整 MOV TAA_BCD,A ; save back "MINUTE" AJMP TIMER_OUT TDD_INC:MOV TAA_BCD,00H TIMER_OUT: LJMP TIMER_NEXT ;返回定时器中断 ;------------------------------------------------------------------ ; ------------------------------------------------------------------- ; sub: LED Display ;显示子程序 DISPLAY: MOV A,DIS_FLAG CJNE A,#03H,DISPLAY2 ;选择不同字模 MOV DPTR,#TAB2 SJMP DISPLAY3 DISPLAY2: MOV DPTR,#TAB ; set address of code table DISPLAY3: MOV A,DIS_FLAG ; take flag for shift CJNE A,#00H,DISP_DATE ; "00" 当前显示内容为时间 ;R0: point to display buffer DISP_TIME: MOV R0,#SECOND_BCD ; beginning from "second" SJMP TSA DISP_DATE: CJNE A,#01H,DISP_ALAM ; "01" 当前显示内容为日期 MOV R0,#DAY_BCD ; "FF" for showing date SJMP TSA;显示时间或日期 DISP_ALAM: CJNE A,#02H,DISP_ALAM_SET ; "02" 当前显示内容为闹钟 MOV R0,#NSECOND_BCD ; beginning from "second" SJMP TSA DISP_ALAM_SET: CJNE A,#03H,DISP_TIMER ; "03" 当前显示内容为闹钟设置 MOV A,ALAM_STATE ; 闹钟状态显示 JZ SHOWOFF MOV R0,#ALAM_ON1 ; 显示”ON“ SJMP TSA SHOWOFF: MOV R0,#ALAM_OFF1 ;显示“OFF” SJMP TSA DISP_TIMER: ;"04"当前显示内容为秒表 MOV R0,#TCC_BCD ; beginning from "second" TSA: MOV A,@R0 ; begin from "day" ANL A,#0FH ; get the "low half byte" MOVC A,@A+DPTR ; take character from code table MOV R1,A ; keep in R1 for DS6 showing MOV A,@R0 SWAP A ANL A,#0FH ; get the "high half byte" MOVC A,@A+DPTR ; take character from code table MOV R2,A ; keep in R2 for DS5 showing ;--------------- INC R0 MOV A,@R0 ; next one from "month" ANL A,#0FH ; get the "low half byte" MOVC A,@A+DPTR MOV R3,A ; keep in R3 for DS4 showing MOV A,@R0 SWAP A ANL A,#0FH ; get the "high half byte" MOVC A,@A+DPTR MOV R4,A ; keep in R4 for DS3 showing ;------------- INC R0 MOV A,@R0 ; next one from "year" ANL A,#0FH ; get the "low half byte" MOVC A,@A+DPTR MOV R5,A ; keep in R5 for DS2 showing MOV A,@R0 SWAP A ANL A,#0FH ; get the "high half byte" MOVC A,@A+DPTR MOV R6,A ; keep in R6 for DS1 showing ;--------------------- ;P1:位选线 ;P0:段选线 NOP TDP: MOV P1,#0FFH ; close all showing/// ;Display DS6 MOV A,ALAM_STATE ;是否显示闹钟状态位?(最末位小数点) JZ DIS_NEXT MOV A,R1 ANL A,#7FH MOV R1,A DIS_NEXT: MOV A,R1 MOV P0,A ; send character to DS6 MOV A,FLASH_FLAG ; get flag of un-flash/flash CJNE A,#03H,A02 ; "03" is flash on DS5&DS6 SJMP A03 A02: CJNE A,#03H,A04; ; "03" is flash on DS5&DS6 A03: MOV A,TICK_CNT ; take Counter of overflow RRC A JNC A05 ; check bit C ( 1 or 0 ) A04: MOV P1,#0FBH ; turn on DS6 A05: LCALL DELAY MOV P1,#0FFH ; close all showing ;Display DS5 MOV P0,R2 ; send character to DS5 MOV A,FLASH_FLAG ; get flag of un-flash/flash CJNE A,#03H,B02 ; "03" is flash on DS5&DS6 SJMP B03 B02: CJNE A,#03H,B04 B03: MOV A,TICK_CNT ; take times of overflow RRC A JNC B05 ; check bit C ( 1 or 0 ) B04: MOV P1,#0F7H ; turn on DS5 B05: LCALL DELAY MOV P1,#0FFH ; close all showing ;Display DS4 MOV A,R3 ANL A,#7FH ;该位增加小数点显示 MOV P0,A ; send character to DS4 MOV A,FLASH_FLAG ; get flag of un-flash/flash CJNE A,#02H,C02 ; "02" is flash on DS3&DS4 SJMP C03 C02: CJNE A,#02H,C04 C03: MOV A,TICK_CNT ; take times of overflow RRC A JNC C05 ; check bit C ( 1 or 0 ) C04: MOV P1,#0EFH ; turn on DS4 C05: LCALL DELAY MOV P1,#0FFH ; close all showing ;Display DS3 MOV P0,R4 ; send character to DS3 MOV A,FLASH_FLAG ; get flag of un-flash/flash CJNE A,#02H,D02 ; "02" is flash on DS3&DS4 SJMP D03 D02: CJNE A,#02H,D04 D03: MOV A,TICK_CNT ; take times of overflow RRC A JNC D05 ; check bit C ( 1 or 0 ) D04: MOV P1,#0DFH ; turn on DS3 D05: LCALL DELAY MOV P1,#0FFH ; close all showing ;Display DS2 MOV A,R5 ANL A,#7FH ;该位增加小数点显示 MOV P0,A ; send character to DS2 MOV A,FLASH_FLAG ; get flag of un-flash/flash CJNE A,#01H,E02 ; "01" is flash on DS1&DS2 SJMP E03 E02: CJNE A,#01H,E04 E03: MOV A,TICK_CNT ; take times of overflow RRC A JNC E05 ; check bit C ( 1 or 0 ) E04: MOV P1,#0BFH ; turn on DS2 E05: LCALL DELAY MOV P1,#0FFH ; close all showing MOV P0,R6 ; send character to DS1 MOV A,FLASH_FLAG ; get flag of un-flash/flash CJNE A,#01H,F02 ; "01" is flash on DS1&DS2 SJMP F03 F02: CJNE A,#01H,F04 F03: MOV A,TICK_CNT ; take times of overflow RRC A JNC F05 ; check bit C ( 1 or 0 ) F04: MOV P1,#07FH ; turn on DS1 F05: LCALL DELAY MOV P1,#0FFH ; close all showing RET ; ------------------------------------------------------------------- ; ---------------------------------------- ; sub: delay (1.542ms for 12MHz, 3.084ms for 6MHz) ;延时子程序 D_CNT_2 EQU 28H D_CNT_1 EQU 29H DELAY: MOV D_CNT_2,#03H D_LOOP2: MOV D_CNT_1,#0FFH ;[1] D_LOOP1: DJNZ D_CNT_1,D_LOOP1 ;[2] DJNZ D_CNT_2,D_LOOP2 ;[2] RET ; ---------------------------------------- ; --------------------------------------------------------- ;外部中断0 ; sub: INT0 interrupt ; 处理按键K0,切换时间/日期/闹钟/闹钟设置/秒表显示或者调整 EX0_INT: NOP ; switch or adjust with date/time PUSH ACC PUSH PSW LCALL DIS_DELAY ; re-bounce (with LED display) JNB P3.3,OUT ; check port INT1 ;K0按下 NOP ; inhibit INT1 ( use k0) ;--------------------------------------------------- MOV A,FLASH_FLAG CJNE A,#00H,JUDGE_MODE ;有闪烁进入调整模式 SET_DIS: ;无闪烁进入设置显示或秒表模式 CLR P2.0 ;按键滴一声 MOV DI_41H,#19H DI_LPO: MOV DI_40H,#0FFH DI_LP: DJNZ DI_40H,DI_LP DJNZ DI_41H,DI_LPO SETB P2.0 ;--------------------------------------------------- MOV A,DIS_FLAG INC A MOV DIS_FLAG,A CJNE A,#04H,CROSSTIMER ;进入秒表? ;--------------------------------------------------- TIMER: MOV TIMER_FLAG,#01H ;进入秒表,秒表模式设置为开 LJMP EX0_RET ;退出 ;--------------------------------------------------- CROSSTIMER: ;显示模式切换 CJNE A,#05H,OUT MOV DIS_FLAG,#00H ;已到5需置零 MOV TIMER_FLAG,#00H MOV A,TIMER_START_FLAG JNZ OUT ;秒表后台工作,暂停计数时退出则对秒表清零 MOV TCC_BCD,#00H ; BCD of "second" 秒表清零 MOV TBB_BCD,#00H ; BCD of "minute" MOV TAA_BCD,#00H ; BCD of "hour" OUT: LJMP EX0_RET ; 退出 ;--------------------------------------------------- JUDGE_MODE: ;进入调整模式 MOV A,DIS_FLAG ; 读取当前显示内容为?(时间/日期/秒表/闹钟) CJNE A,#00H,JDATE ;是否进入时间调整00 ;--------------------------------------------------- JTIME: ;调整时间 MOV A,FLASH_FLAG ; take flag of un-flash/flash ADH: CJNE A,#01H,ADM ; "03" for adjusting "hour" MOV A,HOUR_BCD ; take BCD of "hour" CJNE A,#23H,JH0 ; is up to 23 hours ? MOV HOUR_BCD,#00H ; keep the first hour LJMP JHF JH0: ADD A,#01H ; increase "hour" DA A ; adjust BCD MOV HOUR_BCD,A ; keep "hour" JHF: LJMP EX0_RET ;----------------------------------------- ADM: CJNE A,#02H,ADS ; "02" for adjusting "minute" MOV A,MINUTE_BCD ; take BCD of "minute" CJNE A,#59H,JM0 ; is up to 59 minutes ? MOV MINUTE_BCD,#00H ; keep the first minute LJMP JMF JM0: ADD A,#01H ; increase "minute" DA A ; adjust BCD MOV MINUTE_BCD,A ; keep "minute" JMF: LJMP EX0_RET ADS: MOV A,SECOND_BCD ; take BCD of "second" CJNE A,#59H,JS0 ; is up to 59 seconds ? MOV SECOND_BCD,#00H ; keep the first second LJMP JSF JS0: ADD A,#01H ; increase "second" DA A ; adjust BCD MOV SECOND_BCD,A ; keep "second" JSF: NOP LJMP EX0_RET ;--------------------------------------------------- JALAM0: LJMP JALAM JDATE: CJNE A,#01H,JALAM0 ;是否进入日期调整01 JYY: NOP ; "01 to 06" is in flash MOV A,FLASH_FLAG CJNE A,#01H,JMM ; "01" for adjusting "year" ;调节年 MOV A,YEAR_BCD ; take BCD of "year" CJNE A,#99H,YY0 ; is up to 99 year ? MOV YEAR_BCD,#00H ; keep the first year LJMP YYF YY0: ADD A,#01H ; increase "year" DA A ; adjust BCD MOV YEAR_BCD,A ; keep "year" YYF: LJMP EX0_RET ;--------------------------------------- JMM: CJNE A,#02H,JDD ; "02" for adjusting "month" ;调节月 MOV A,MONTH_BCD ; take BCD of "month" CJNE A,#12H,MM0 ; is December ? MOV MONTH_BCD,#01H ; keep the first month LJMP MMF MM0: ADD A,#01H ; increase "month" DA A ; adjust BCD MOV MONTH_BCD,A ; keep "month" MMF: LJMP EX0_RET ;--------------------------------------- JDD: CJNE A,#03H,AA1 ; "03" for adjusting "day" LJMP BB1 AA1: LJMP ADH ; BB1: MOV A,MONTH_BCD ; first, should take "month" CJNE A,#02H,NFB ; is February ? IFB: NOP ACALL BCD_DIV4 ; BCD of "year in YEAR_BCD" divided by 4 MOV A,R3 ; remainder in R3 CJNE A,#00H,ANG ; "00" means leap year ARN: MOV A,DAY_BCD ; take BCD of "day" CJNE A,#29H,D0A ; is up to 29 days in Feb.? LJMP D0B D0A: LJMP DDA D0B: LJMP DD1 ANG: MOV A,DAY_BCD ; take BCD of "day" CJNE A,#28H,D0A ; is up to 28 days in Feb.? LJMP DD1 NFB: NOP ; check "little/large" month CJNE A,#04H,Y04 ; is April ? LJMP AD1 Y04: CJNE A,#06H,Y05 ; is June ? LJMP AD1 Y05: CJNE A,#09H,Y06 ; is September ? LJMP AD1 Y06: CJNE A,#11H,Y07 ; is November ? LJMP AD1 Y07: NOP ; for "large" month MOV A,DAY_BCD ; take BCD of "day" CJNE A,#31H,D0A ; is up to 31 days ? LJMP DD1 AD1: NOP ; for "little" month MOV A,DAY_BCD ; take BCD of "day" CJNE A,#30H,D0A ; is up to 30 days ? DD1: MOV DAY_BCD,#01H ; keep the first day LJMP DDF DDA: ADD A,#01H ; increase "day" DA A ; adjust BCD MOV DAY_BCD,A ; keep "day" DDF: LJMP EX0_RET ;--------------------------------------------------- JALAM: ;调整闹钟 MOV A,FLASH_FLAG ; take flag of un-flash/flash NADH: CJNE A,#01H,NADM ; "03" for adjusting "hour" MOV A,NHOUR_BCD ; take BCD of "hour" CJNE A,#23H,NJH0 ; is up to 23 hours ? MOV NHOUR_BCD,#00H ; keep the first hour LJMP NJHF NJH0: ADD A,#01H ; increase "hour" DA A ; adjust BCD MOV NHOUR_BCD,A ; keep "hour" NJHF: LJMP EX0_RET ;----------------------------------------- NADM: CJNE A,#02H,NADS ; "02" for adjusting "minute" MOV A,NMINUTE_BCD ; take BCD of "minute" CJNE A,#59H,NJM0 ; is up to 59 minutes ? MOV NMINUTE_BCD,#00H ; keep the first minute LJMP NJMF NJM0: ADD A,#01H ; increase "minute" DA A ; adjust BCD MOV NMINUTE_BCD,A ; keep "minute" NJMF: LJMP EX0_RET NADS: MOV A,NSECOND_BCD ; take BCD of "second" CJNE A,#59H,NJS0 ; is up to 59 seconds ? MOV NSECOND_BCD,#00H ; keep the first second LJMP NJSF NJS0: ADD A,#01H ; increase "second" DA A ; adjust BCD MOV NSECOND_BCD,A ; keep "second" NJSF: NOP LJMP EX0_RET ;--------------------------------------------------- EX0_RET:NOP ;中断退出 POP PSW POP ACC RETI ;--------------------------------------------------- ;--------------------------------------------------- ; sub: INT1 interrupt ; 处理按键K1,设置闪烁 EX1_INT:NOP ; revise flag(00 to 06) in FLASH_FLAG PUSH ACC PUSH PSW JNB P3.2,EX1_RET ; check port INT0 LCALL DIS_DELAY ; re-bounce (with LED display) ;;K1按键按下 NOP ; inhibit INT0 (use k1) MOV A,DIS_FLAG CJNE A,#03H,TIMER_START0 ;非设置闹钟开关模式? MOV A,ALAM_STATE CPL A ;取非 ANL A,#01H ;保留最后 MOV ALAM_STATE,A ;设置闹钟开关 AJMP DI_START ;提示音后退出 ;--------------------------------------------------- TIMER_START0: MOV A,TIMER_FLAG CJNE A,#01,FLASH_SHIFT ;非秒表模式? TIMER_START: MOV A,TIMER_START_FLAG CPL A ANL A,#01H ;保留最低位 MOV TIMER_START_FLAG,A ;设置秒表开关 ;--------------------------------------------------- DI_START: CLR P2.0 ;按键滴一声 MOV DI_41H,#19H DI_LOOPO: MOV DI_40H,#0FFH DI_LOOP: DJNZ DI_40H,DI_LOOP DJNZ DI_41H,DI_LOOPO SETB P2.0 AJMP EX1_RET ;退出 ;--------------------------------------------------- FLASH_SHIFT: ;进入切换闪烁 MOV A,FLASH_FLAG ; take flag of un-flash/flash CJNE A,#00H,ED1 ; "00" 无闪烁 MOV FLASH_FLAG,#01H ; 设置1,2号数码管闪烁 SJMP EX1_RET ED1: CJNE A,#01H,ED2 ; "01" 1,2号闪烁中 MOV FLASH_FLAG,#02H ; 设置3,4号闪烁 SJMP EX1_RET ED2: CJNE A,#02H,ED3 ; "02" 3,4号闪烁 MOV FLASH_FLAG,#03H ; 设置5,6号闪烁 SJMP EX1_RET ED3: MOV FLASH_FLAG,#
/
本文档为【数码管电子时钟】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索