电子日历时钟(附源程序代码)_第1页
电子日历时钟(附源程序代码)_第2页
电子日历时钟(附源程序代码)_第3页
电子日历时钟(附源程序代码)_第4页
电子日历时钟(附源程序代码)_第5页
已阅读5页,还剩28页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、单片机课程设计实验报告 实验题目 电子日历时钟 学 院 电子与信息学院 专 业 电子信息科学类 姓名学号 分组编号 提交日期 一.实验目的课程标志性内容的设计理解和综合运用,鼓励独立性设计和功能扩展的创新实践。二.实验设计功能: 1. 基本性要求显示北京时间;能够校准时间;使用汇编语言;时、分、秒之间以及年、月、日间以小数点分隔;2. 发挥性要求显示公历日期能够校准日期闹钟功能三.总体设计方案说明1. 硬件部分 采用6位led数码管显示日期、时间、闹钟 显示器驱动采用“动态扫描驱动”,连接方式为共阳极,单片机的p1口作为显示器的位选线,p0口作为段选线 键盘的按键采用“一键多用”的设计方案,减

2、少了按键的数目,简化实验电路。其中按键key0连接单片机的外部中断1接口,按键key1连接单片机的外部中断0接口 利用显示器显示“off”、“on”表示闹钟的设置状态 在单片机p1.0口增加了蜂鸣器驱动电路,作为闹钟提示装置 实验电路做成pcb板 2.软件部分“时钟”基准时间由单片机内部的定时中断提供,定时时间应是“秒”的整除数,且长短适宜。最长不能超过16位定时器的最长定时时间;最短不能少于中断服务程序的执行时间。本实验设计中采用定时器t0,工作方式1,基准时间设置为0.05秒,计数器为20,实现秒的定时,则定时器t0的初始值计算如下:th0=(65536-50000)/256=3chtl0

3、=(65536-50000)%256=0b0h 根据基准时间用计数器对定时中断次数进行计数即可实现“秒”的定时, 本实验设计中基准时间为0.5秒,因此计数值设定为20即可,同理可以实现“分”“时”定时,以及“日”“月”“年”定时 led 数码管显示器采用“动态扫描驱动”,由于驱动信号的维持时间必须大于“起辉时间”(电流大起辉时间短),而驱动信号的间歇时间必须小于“余辉时间”(电流大余辉时间长),因此在单片机的p1口,即显示器的段选线加上三极管,增加驱动电压,实现“动态扫描驱动”动态扫描显示方式在更新显示内容时,考虑到因led数码管余辉的存在可能会造成显示字符的模糊,所以新内容写入显示器之前将所

4、有的led数码管熄灭关于自动识别“月大月小”和“平年润年”问题的考虑a) 月大和月小 2月另外计算;4月6月9月11 月为月小30天,其余为月大31天。b) 平年和润年(年号能被4整除的就是润年)平年的2月为28天;润年的2月为29天。 采用软件延时的方法消除按键抖动四.系统电路原理图、布线图、实物图 加上附加功能后的系统电路原理图如下所示 布线后的电路截图如下:上图是修改完善之后的图片,前面布线时没有考虑芯片下面的布线,结果很不好焊接,所以后来改了一下布线的图实物图:五.程序流程图 1.主程序 初始化闹钟到?提示音主程序 2.定时器0中断子程序 定时0中断子程序若到12月,则年加1,月置0中

5、断返回恢复现场日加1月加1日置0月加1日置029日?31日?30日?28日?闰年?1,3,5,7,8,10,12月2月?1个月?秒加1,或向前进位,实现分时定时1秒到?保护现场重载初值 中断返回恢复现场若到12月,则年加1,月置0 3.外部中断0子程序调整模式有闪烁?切换显示模式时间调整调整时间?调整日期?调整闹钟?日期调整时间、日期、闹钟、闹钟设置、显示循环切换闹钟调整ynnynnnyyykey1按下?外部中断0程序保护现场延时消抖恢复现场中断返回4.外部中断1子程序 保护现场带显示延时key0按下?设置闹钟?打开/关闭闹钟闪烁循环切换闪烁切换模式恢复现场ynn外部中断1子程序中断返回六.系

6、统使用和操作说明 系统初始状态:接上电源,日期默认为12年9月3日,时间为0时0分0秒闹钟0点整,默认关闭(1)显示状态切换:不断按k0键就会依次循环显示时间、日期、闹钟时间、闹钟状态设置(2)调节时间日期: 按k0键切换调节的显示状态,再按k1键选择修改的位,不断按k1键会闪烁,每次闪烁2个数码管。闪烁的位可以修改,按k0键可以实现增加,不能递减,例如要调慢时间要按到循环到较慢时间,之后再按k0键至数码管全部停止闪烁为止,即实现玩调整时间日期(3)闹钟使用 :由于程序原因,闹钟到现在为止只能实现闹钟状态设置,时间设置,但是蜂鸣器还是不能响,接下来还会继续解决七.系统故障诊断与排除 1、硬件部

7、分1. 在焊接电路板的过程中就遇到了比较棘手的事,起先由于自己第一次布线,缺乏经验,所以在芯片下面布了不少线,这就给焊接带来了很大的麻烦,知道最后也没找到什么好的解决方法,有几个是直接焊接,有几个焊点则是用了飞线。2. 在画原理图的时候没有考虑到给蜂鸣器加上拉电阻,以为对蜂鸣器电路有影响,后来却发现,加上了上拉电阻之后还是没能解决闹钟时间的蜂鸣器发声问题。3. 由于焊接时的马虎,在调试电路时吃亏很大,起先是很多点忘了焊接,可检查完所有焊接错误后发现还是不亮,这样的检查了很久之后才找出和晶振相连的两个电容焊接错了,电容直接被短路了,导致所有数码管全部不亮,这个在改正之后就没问题了。 2、软件部分

8、 本程序在老师给的奇数组程序基础上进行修改与添加闹钟功能 程序所默认采取的晶振计数频率是6mhz,但是所提供器件则是12mhz,所以根据晶振的不同,定时器的基准时间变为0.05s。按照该程序运行的话,计数时间为0.5s。这就需要设置计数次数tick_cnt为#14h,即0.05s*20=1s原来程序设置的外部中断延时过短,导致操作过于灵敏,即按键k0、k1按下时,跳变过快。通过修改中断子程序ex0_int和ex1_int中的lcalldis_delay的延时时间,解决了这个问题闹钟时间到了之后,蜂鸣器不能正常发声,只是发出很小的声音,对此多次修改蜂鸣器部分的发音程序,但还是没有很好的解决这个问

9、题,接下来会继续研究修改八.原器件清单品名型号数量led七段数码管共阳bs6三极管s85507电阻3k9电阻2008微型按钮4脚3瓷片电容30p2电解电容10uf1晶体振荡器12mhz1小型蜂鸣器自发声1排针无6icat89s521ic74ls2441ic座40脚1ic座20脚1九.课程设计心得与体会 十.源程序代码 ;变量定义tick_cntequ20h;t0溢出计数器second_bcdequ21hminute_bcdequ22hhour_bcdequ23hday_bcdequ24hmonth_bcdequ25hyear_bcdequ26hflash_flagequ27h;r7: 0时间;

10、1日期;2-闹钟;3-闹钟状态设置asecond_bcd equ 2bhaminute_bcd equ 2ch ahour_bcd equ 2dhtsecond_bcd equ 2ehtsecond1_bcd equ 2fh tminute_bcd equ 30halam_state equ 32h ;闹钟开启标志alam_on1 equ 33h ;闹钟状态显示alam_on2 equ 34halam_on3 equ 35halam_off1 equ 36halam_off2 equ 37halam_off3 equ 38h; 中断向量表org0000hljmpmainorg0003hljmp

11、ex0_int; port int0org000bhljmpt0_int ; port t0org0013hljmpex1_int; port int1;主程序org 0030hmain:nop ; main program;初始化堆栈movsp,#60h;初始化变量movsecond_bcd,#00h; bcd of secondmovminute_bcd,#00h; bcd of minutemovhour_bcd,#00h; bcd of hour mov asecond_bcd,#00h; alam_bcd of secondmovaminute_bcd,#00h; alam_bcd

12、of minutemovahour_bcd,#00h; alam_bcd of hourmovday_bcd,#03h; bcd of daymovmonth_bcd,#09h; bcd of monthmovyear_bcd,#12h; bcd of yearmovflash_flag,#00h;flag for un-flash/flashmovr7,#00h; flagforshift(time/date) mov alam_on1,#00h; 闹钟状态显示mov alam_on2,#43hmov alam_on3,#05hmov alam_off1,#00hmov alam_off2,

13、#26hmov alam_off3,#01hmov alam_state,#00h; 初始化闹钟状为off;mov tl0,#0b0h; constant for 0.1smov th0,#3ch; 50,000 for 6mhzmov tick_cnt,#14h; times of overflowmov tmod,#01h; mode 1 for t0, timer modesetbet0; open t0setbex0; open int0, key1setbex1; open int1, key0setbea; total opensetbpt0; priority for t0,高优

14、先级setbtr0; start t0, runscan_alam: ; 闹钟扫描 mov a,alam_statejz scan_alam; 闹钟开关已打开?mov a,ahour_bcdcjne a,hour_bcd,waitmov a,aminute_bcdcjne a,minute_bcd,wait mov a,asecond_bcdcjne a,second_bcd,wait alarm:clr p1.0;闹铃:滴滴滴滴djnz 2ah,alarm wait: setb p1.0sjmpscan_alam; wait for interrupt; -; sub: t0 interru

15、pt; 定时器0中断t0_int: push acc movtl0,#0b0h; constant for 0.1smovth0,#3ch; timer 0重装载 time_count:djnztick_cnt,not_1s; is up to 1 second ?sjmpis_1snot_1s:ljmpt0_ret; 1秒时间到is_1s:mova,second_bcd; take bcd of secondcjnea,#59h,in3; is up to 59 seconds ?sjmpin4in3:ljmpsecond_inc; 秒加1in4:movsecond_bcd,#00h; 秒进

16、位mova,minute_bcd; take bcd of minutecjnea,#59h,in5; is up to 59 minutes ?sjmpin6in5:ljmpminute_incin6:movminute_bcd,#00h; 分进位 mova,hour_bcd ; take bcd of hour cjnea,#23h,hour_inc; is up to 23 hours ?movhour_bcd,#00h; “时”进位mova,month_bcd; take bcd of monthcjnea,#02h,not_feb; is february ?;2月处理;-feb:n

17、opacallbcd_div4; bcd of year in 26h divided by 4mova,r3; remainder in r3cjnea,#00h,not_leap_y; 00 means leap year;闰年,29天leap_y:mova,day_bcd; take bcd of day in feb.cjnea,#29h,day_inc; is up to 29 days (leap year)?movday_bcd,#01h; keep the first daymovmonth_bcd,#03h; increase monthsjmpreset_cnt;非闰年no

18、t_leap_y: mova,day_bcd; take bcd of day in feb.cjnea,#28h,day_inc; is up to 28 days (common year)?movday_bcd,#01h; keep the first daymovmonth_bcd,#03h; increase monthsjmpreset_cnt;-;非2月处理;30/31天?not_feb: nop; other month except feb.cjne a,#04h,y01; is april ?ajmp mon_30dy01:cjne a,#06h,y02; is june

19、?ajmp mon_30dy02:cjne a,#09h,y03; is september ?ajmp mon_30dy03:cjne a,#11h,t11; is november ?ajmp mon_30d;31天t11:mova,day_bcd; take bcd of daycjnea,#31h,day_inc; is up to 31 days ?ajmpnext_month;30天mon_30d:mova,day_bcd; take bcd of daycjnea,#30h,day_inc; is up to 30 days ?;天进位next_month:movday_bcd,

20、#01h; keep the first daymova,month_bcd; take bcd of monthcjnea,#12h,month_inc; is december ?; 月进位movmonth_bcd,#01h; keep the first monthmova,year_bcd; take bcd of yearcjnea,#99h,year_inc; is up to 99 years ?movyear_bcd,#00h; keep the first yearsjmpreset_cnt;年加1year_inc:mova,year_bcd; take bcd of yea

21、radda,#01h; increase yeardaa; adjust bcdmov year_bcd,a; keep yearsjmp reset_cntmonth_inc:mova,month_bcd; take bcd of monthadda,#01h; increase monthdaa; bcd码调整movmonth_bcd,a; keep monthsjmpreset_cntday_inc:mova,day_bcd; take bcd of dayadda,#01h; increase daydaa; bcd码调整movday_bcd,a; keep daysjmpreset_

22、cnthour_inc:mova,hour_bcd; take bcd of houradda,#01h; increase hourdaa; bcd码调整movhour_bcd,a; keep hoursjmpreset_cntminute_inc:mova,minute_bcd; take bcd of minuteadda,#01h; increase minutedaa; bcd码调整movminute_bcd,a; keep minutesjmpreset_cntsecond_inc:mova,second_bcd; take bcd of secondadda,#01h; incr

23、ease seconddaa; bcd码调整movsecond_bcd,a; save back secondreset_cnt:movtick_cnt,#14h; retrieve times of overflowt0_ret:pop acc reti;-; -; sub: led display;显示子程序display:mov a,r7cjne a,#03h,display2 mov dptr,#tab2sjmp display3display2:movdptr,#tab1 ; set address of code tabledisplay3:mova,r7 ; take flag

24、for shiftcjnea,#00h,disp_date ; 00 当前显示内容为时间;r0: point to display bufferdisp_time: movr0,#second_bcd; beginning from secondsjmptsadisp_date: cjne a,#01h,disp_alam ; 01 当前显示内容为日期 movr0,#day_bcd sjmp tsadisp_alam: cjnea,#02h,disp_alam_set ; 02 当前显示内容为闹钟movr0,#asecond_bcd ; beginning from secondsjmp ts

25、adisp_alam_set: cjnea,#03h,disp_time ; 03 当前显示内容为闹钟设置mov a,alam_state; 闹钟状态显示jz showoff movr0,#alam_on1; 显示onsjmp tsashowoff: mov r0,#alam_off1;显示offsjmp tsatsa:mova,r0; begin from dayanla,#0fh; get the low half bytemovca,a+dptr; take character from code tableadd a,#80h ; 熄灭小数点 movr1,a; keep in r1 f

26、or ds6 showingmova,r0swapaanla,#0fh; get the high half bytemovca,a+dptr; take character from code table add a,#80hmovr2,a; keep in r2 for ds5 showing;-incr0mova,r0; next one from monthanla,#0fh; get the low half bytemovca,a+dptrmovr3,a; keep in r3 for ds4 showingmova,r0swapaanla,#0fh; get the high h

27、alf bytemovca,a+dptr add a,#80hmovr4,a; keep in r4 for ds3 showing;-incr0mova,r0; next one from yearanla,#0fh; get the low half bytemovca,a+dptrmovr5,a; keep in r5 for ds2 showingmova,r0swapaanla,#0fh; get the high half bytemovc a,a+dptr add a,#80hmov r6,a; keep in r6 for ds1 showing;-;p1:位选线;p0:段选线

28、noptdp:movp1,#0ffh; close all showing/;display ds6movp0,r1; send character to ds6mova,flash_flag; get flag of un-flash/flashcjnea,#03h,a02; 03 is flash on ds5&ds6sjmpa03a02:cjnea,#06h,a04; 06 is flash on ds5&ds6;=3 or 6, flash on ds5&ds6a03:mov a,tick_cnt; take counter of overflowrrc ajnc a05; check

29、 bit c ( 1 or 0 )a04:mov p1,#0fbh; turn on ds6a05:lcall delaymov p1,#0ffh; close all showing;display ds5movp0,r2; send character to ds5mova,flash_flag; get flag of un-flash/flashcjnea,#03h,b02; 03 is flash on ds5&ds6sjmpb03b02:cjnea,#06h,b04; 06 is flash on ds5&ds6;=3 or 6, flash on ds5&ds6b03:mova,

30、tick_cnt; take times of overflowrrcajncb05; check bit c ( 1 or 0 )b04:movp1,#0f7h; turn on ds5b05:lcalldelaymovp1,#0ffh; close all showing;display ds4movp0,r3; send character to ds4mova,flash_flag; get flag of un-flash/flashcjnea,#02h,c02; 02 is flash on ds3&ds4sjmpc03c02:cjnea,#05h,c04; 05 is flash

31、 on ds3&ds4c03:mova,tick_cnt; take times of overflowrrcajncc05; check bit c ( 1 or 0 )c04:movp1,#0efh; turn on ds4c05:lcalldelaymov p1,#0ffh; close all showing;display ds3mov p0,r4; send character to ds3mov a,flash_flag; get flag of un-flash/flashcjne a,#02h,d02; 02 is flash on ds3&ds4sjmp d03d02:cj

32、ne a,#05h,d04; 05 is flash on ds3&ds4d03:mov a,tick_cnt; take times of overflowrrc ajnc d05; check bit c ( 1 or 0 )d04:mov p1,#0dfh; turn on ds3d05:lcall delaymov p1,#0ffh; close all showing;display ds2mov p0,r6; send character to ds2mov a,flash_flag; get flag of un-flash/flashcjne a,#01h,e02; 01 is

33、 flash on ds1&ds2sjmp e03e02:cjne a,#04h,e04; 04 is flash on ds1&ds2e03:mov a,tick_cnt; take times of overflowrrc ajnc e05; check bit c ( 1 or 0 )e04:mov p1,#0bfh; turn on ds2e05:lcall delaymov p1,#0ffh; close all showingmov p0,r5; send character to ds1mov a,flash_flag; get flag of un-flash/flashcjn

34、e a,#01h,f02; 01 is flash on ds1&ds2sjmp f03f02:cjne a,#04h,f04; 04 is flash on ds1&ds2f03:mov a,tick_cnt; take times of overflowrrc ajnc f05; check bit c ( 1 or 0 )f04:mov p1,#07fh; turn on ds1f05:lcall delayret; -d_cnt_2equ3ahd_cnt_1equ3bh; -; sub: delay (1.542ms for 12mhz, 3.084ms for 6mhz)delay:

35、 movd_cnt_2,#03hd_loop2:movd_cnt_1,#0ffhd_loop1:djnzd_cnt_1,d_loop1 djnzd_cnt_2,d_loop2 ret ; -; -;外部中断0; sub: int0 interrupt; 处理按键k0,切换时间/日期/闹钟/闹钟设置ex0_int:nop; switch or adjust with date/timepushpsw push acclcalldis_delay; re-bounce (with led display)jnbp3.3,out; check port int1;k0按下nop; inhibit i

36、nt1 ( use k0)mova,flash_flag; take flag of un-flash/flashcjnea,#00h,adjust; 00 is in un-flash mov a,r7 inc a mov r7,ashift: ;显示模式切换 cjne a,#04h,out mov r7,#00h ;已到4需置零 pp: lcall displayout: ljmp ex0_ret ; returnadjust: ;进入调整模式 mova,r7 ; 读取当前显示内容为?(时间/日期/秒表/闹钟) cjne a,#00h, jdate ;是否进入时间调整 jtime: ;调整

37、时间 mova,flash_flag ; take flag of un-flash/flashadh: cjnea,#01h,adm ; 01 for adjusting hourmova,hour_bcd ; take bcd of hourcjnea,#23h,jh0 ; is up to 23 hours ?movhour_bcd,#00h ; keep the first hourljmpjhfjh0: adda,#01h ; increase hourdaa ; adjust bcdmovhour_bcd,a ; keep hourjhf: ljmpex0_retadm: cjne

38、 a,#02h,ads ; 02 for adjusting minutemov a,minute_bcd ; take bcd of minutecjne a,#59h,jm0 ; is up to 59 minutes ?mov minute_bcd,#00h; keep the first minuteljmp jmfjm0: add a,#01h ; increase minuteda a; adjust bcdmov minute_bcd,a; keep minutejmf: ljmp ex0_retads: mov a,second_bcd; take bcd of secondc

39、jne a,#59h,js0 ; is up to 59 seconds ?mov second_bcd,#00h; keep the first secondljmp jsfjs0: add a,#01h ; increase second da a; adjust bcd mov second_bcd,a; keep secondjsf: nop ljmp ex0_retjalam0: ljmp jalamjdate: cjne a,#01h,jalam0 ;是否进入日期调整01jyy: nop ; 01 to 03 is in flash mov a,flash_flagcjnea,#0

40、1h,jmm ; 01 for adjusting year ;调节年mova,year_bcd ; take bcd of yearcjnea,#99h,yy0 ; is up to 99 year ?movyear_bcd,#00h ; keep the first yearljmpyyfyy0:adda,#01h ; increase yeardaa; adjust bcdmovyear_bcd,a; keep yearyyf:ljmpex0_retjmm:cjne a,#02h,jdd; 02 for adjusting month ;调节月mova,month_bcd; take b

41、cd of monthcjnea,#12h,mm0; is december ?movmonth_bcd,#01h; keep the first monthljmpmmfmm0:adda,#01h; increase month daa; adjust bcdmovmonth_bcd,a; keep monthmmf:ljmpex0_retjdd:cjne a,#03h,aa1 ; 03 for adjusting dayljmp bb1aa1:ljmp adh;bb1:mov a,month_bcd; first, should take monthcjne a,#02h,nfb ; is

42、 february ?ifb:nopacall bcd_div4; bcd of year in year_bcd divided by 4mov a,r3 ; remainder in r3cjne a,#00h,ang ; 00 means leap yeararn:mova,day_bcd ; take bcd of daycjne a,#29h,d0a ; is up to 29 days in feb.? ljmp d0bd0a:ljmp ddad0b:ljmp dd1ang:mov a,day_bcd; take bcd of daycjne a,#28h,d0a ; is up to 28 day

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论