51单片机电子时钟课程设计实验报告
- 格式:doc
- 大小:217.50 KB
- 文档页数:22
《单片机原理与应用》课程设计总结报告题目:单片机电子时钟的设计与实现设计人员:学号:班级:指导老师:日期:目录1.题目与主要功能要求 (2)2.整体设计框图及整机概述 (3)3.各硬件单元电路的设计、参数分析及原理说明 (3)4.软件流程图和流程说明 (4)5.总结设计及调试的体会 (10)附录1.图一:系统电路原理图 (11)2.图二:系统电路PCB (12)3.表一:元器件清单 (13)4.时钟程序源码 (14)题目:单片机电子时钟的设计与实现课程设计的目的和意义课程设计的目的与意义在于让我们将理论与实践相结合。
培养我们综合运用电子课程中的理论知识解决实际性问题的能力。
让我们对电子电路、电子元器件、印制电路板等方面的知识进一步加深认识,同时在软件编程、排错调试、焊接技术、相关仪器设备的使用技能等方面得到较全面的锻炼和提高,为今后能够独立完成某些单片机应用系统的开发和设计打下一个坚实的基础。
课程设计的基本任务利用89S51单片机最小系统,综合应用单片机定时器、中断、数码显示、键盘输入、蜂鸣报警等知识,设计一款单片机和简单外设控制的电子时钟。
主要功能要求最基本要求1)使用6位数码管,前两位显示小时(24小时制),中间两位显示分钟,后两位显示秒。
时钟每走1秒,秒数码管加1显示,60秒后分钟数码管加1显示,60分钟后小时数码管加1显示。
2)设计89S51单片机最小系统3)掌握使用Protel99 绘制原理图和布板的过程、方法和技巧。
4)掌握单片机开发软件(Keil C51或 Wave)的使用和调试。
5)编写并调试单片机定时及其中断程序,以实现电子时钟的功能。
6)设计八段数码管显示电路并编写驱动程序,输入并调试拆字程序和数码显示程序。
7)掌握硬件和软件联合调试的方法。
8)完成系统硬件电路的设计和制作。
9)完成系统程序的设计。
10)完成整个系统的设计、调试和制作。
11)完成课程设计报告。
基本要求1)实现最基本要求的1~10部分。
2)键盘输入可以控制电子时钟的走时/调试。
3)设计键盘输入电路和程序并调试。
4)掌握键盘和显示配合使用的方法和技巧。
提高发挥部分1)添加“闹时”功能,设计蜂鸣器闹铃电路和程序并调试。
2)添加“整点闹时”功能。
为走时准确性设计解决算法并编程实现。
3)用液晶模块代替数码管显示,设计相应硬件电路和软件程序并调试。
3)使用专用时钟芯片,设计硬件电路和软件程序实现年月日和星期显示。
整体设计框图及整机概述整体设计框图整机概述1)开机为走时模式,正常显示时间。
在此模式下整点闹时,定点闹时有效。
2)共设置3个按键,分别为模式键、功能键1、功能键2。
按动模式键,模式将在‘走时/调时/日期显示及调整/闹钟显示及调整’4个模式下切换。
3)走时模式下,按动功能键1/功能键2停止闹时。
4)调时模式下,功能键1调整分钟数值,功能键2调整小时数值。
5)日期显示及调整模式下,功能键1调整日期数值,功能键2调整月份数值。
6)闹钟显示及调整模式下,功能键1调整闹钟分钟数值,功能键2调闹钟时钟数值。
7)由于按键设定原因:只有2个功能键,年份调整功能取消,闹钟开关默认为开。
8)年月日通过代码而不是外部芯片实现。
初始值2010年12月24号。
数码管显示101224。
9)由于开机时钟与闹钟都为00:00:00,闹钟默认开启。
开机会报时1分钟。
各硬件单元电路的设计、参数分析及原理说明电源电路元件有限没有制作电源电路部分。
使用开发板或者实验箱上的5V电源进行供电。
按键参考书本P232的键盘接口电路原理图,采用4.7 KΩ的电阻防止输入口电流过大烧坏89S51芯片。
按键释放时,P1口通过4.7 KΩ电阻与电源相连,得到一个高电平。
按下按键时,P1口接地,得到一个低电平。
通过内部代码将其转换为正逻辑。
模式键接P1.0口,功能键1接P1.1口,功能键2接P1.2口。
单片机最小系统参考实验指导书与课本及网络资料设计按键电平复位。
LED数码管首先P0口作为段码输出。
由于P0口输出级无上拉电阻,故需添加一排阻为其上拉电阻。
其次采用共阳极数码管。
段码端为低电平时导通LED,此时数码管向89S51芯片P0口灌电流,为防止芯片烧坏,还需加1个1 KΩ的限流电阻。
考虑到数码管的亮度问题,采用了PNP三极管做驱动电路。
基极接上1 KΩ电阻后再与P2口相连(P2.0~P2.5)进行位选。
发射极接5V电源,集电极接数码管位选。
蜂鸣器蜂鸣器接P3.7口。
由于使用的是有源蜂鸣器,代码的编写简单化了。
只需对P3.7口清零与置位。
P3.7口先接上1 KΩ电阻后再接PNP三极管的基极。
发射极接5V电源,集电极接蜂鸣器正极,蜂鸣器负极则接地。
软件流程图和流程说明软件流程图1)主程序流程图流程图说明初始化:包括定时器赋初值,初始化各内存单元。
开定时器中断,开CPU中断,送段码表头地址给DPTR。
调用显示子程序调用闹钟查询子程序调用按键扫描子程序调用模式查询子程序初始化开始等待定时器中断2)显示子程序流程图读R3数值,拆出低位并查表转成段码送位选码段码送P0口保护现场显示子程序调用延时子程序读R3数值,拆出高位并查表转成段码送位选码段码送P0口调用延时子程序读R4数值,拆出低位并查表转成段码送位选码 段码送P0口读R4数值,拆出高位并查表转成段码送位选码调用延时子程序调用延时子程序段码送P0口读R5数值,拆出低位并查表转成段码送位选码调用延时子程序段码送P0口读R5数值,拆出高位并查表转成段码送位选码调用延时子程序段码送P0口返回恢复现场P1数据送累加器A 并取反。
取正逻辑屏蔽高5位P1口写1按键扫描子程序YNA 值为0?存键值调用显示延时NACC.0值为0?返回YA 值为0?YN模式值加1模式值 为4?Y模式值清零N模式查询子程模式值送累加器A模式查询子程序NA 值为0?NA 值为1?A 值为2?YY走时模式设置调时模式设置Y日期显示及调整模式N闹钟显示及调整模式走时模式设置秒/分/时数据分别送R3/R4/R5TR1置1取键值送ACCNN返回ACC.1值为1?YYACC.2值为1?关闹钟,清键值日期显示及调整子程序与闹钟显示及调整子程序流程图与调时模式子程序大同小异。
a)日期显示及调整子程序送给R3/R4/R5的数据为日/月/年,按功能键1日期加1,按功能键2月份加1。
至于数值的合法性在程序里有具体的判断。
b)闹钟显示及调整子程序送给R3/R4/R5的数据为闹钟开关值/闹钟分/闹钟时,按功能键1闹钟分加1,按功能键2闹钟时加1。
至于数值的合法性在程序里有具体的判断。
5)闹钟查询子程序调时模式设置 秒/分/时数据分别送R3/R4/R5 TR1置0 取键值送ACC Y 分钟数值加1,键值清零 N ACC.1值为1? N 返回 YACC.2值为1? 小时数值加1,键值清零 闹钟查询子程序 Y取闹钟开关取闹钟数据与当前时间一致开闹钟取模式值YY 模式0? NN闹钟开? N返回6)定时器中断子程序数值合法性在程序中处理与判断,流程图中不表现。
保护现场T1中断 秒加11秒到? 1分到? 1小时? 分加11天? 时加11个月? 天加11年? 年加1月加1恢复现场返回Y Y Y Y Y Y NNNNNN总结设计及调试体会硬件设计部分:首先要通过计算与参考资料等决定参数。
而后通过仿真软件等调试,确定参数无误后再开始用Protel99 SE画原理图,进而生成PCB进行布板。
软件设计部分:设计软件首先要考虑要做的功能,确定出合理的算法。
合理的算法不仅要可以实现功能,而且在添加功能的时候要方便灵活。
有的人为了实现某种功能用了各种各样的方法来实现,结果程序结构吃死,当想要添加功能或者修改其他功能的时候,将修改程序大部分结构,也就是说要破坏程序现有的结构。
关于调试:Keil软件调试单片机程序的时候,编译通过并不代表程序是正确的。
编译通过只能说明程序没有语法上的错误。
进行软件仿真或者下载到开发板上进行调试,经常会出现各种各样的错误。
许多超出预期效果的现象往往是一些微小错误引起的。
例如没有现场保护跟恢复现场等,所以养成良好的编程习惯也很重要。
有些想达成某些功能而添加的语句,实际上确一点效果也没有。
举个编程中的小问题:当有按键按下时,我们都要有软件防抖。
正常的方法是调用一个延时。
在实际调试中,要跳过这个抖动,需要100MS左右。
如果使用正常的延时,会导致按键按下时CPU100MS内无法进行其他操作,也就是说。
平均1S内100MS不调用显示子程序,这样就会导致亮度降低。
这时候,考虑到显示子程序一次有十几毫秒,就特别写了一个调用7次显示的子程序来作为按键防抖的延时,实际上效果也是很不错的。
这个想法就是在修改了多次程序未达到想要的效果(有按键按下时显示亮度不降低)后最终想出来的办法。
最后在做完板,焊完电路后,在接通电源之前,要用万用表仔细检查电路是否有连接错,以免烧坏芯片和数码管。
五天以来的其他体会:态度要积极,不要认为很简单就不紧不慢。
很多东西并不是自己设想的那么顺利,有时候一个小问题可以花上你半天甚至一天的时间。
虽然自己在程序上并没遇到太大的问题,但是因为态度不够积极,对于没画过的PCB图迟迟不去下手,在周四晚上才解决。
本以为周五一天可以做完板并完成整机调试,可是各种突发事件让自己措手不及。
发现板来不及做完后才将程序功能进行扩展。
这是我在这次实验中的一个教训,也让我明白了对于自己不能太过于自信,态度决定一切。
图一:系统电路原理图图二:系统电路PCB表一:元器件清单器件名称编号1K电阻R121K电阻R81K电阻R71K电阻R91K电阻R101K电阻R111K电阻R131K电阻R181K电阻R171K电阻R201K电阻R191K电阻R61K电阻R151K电阻R161K电阻R144.7k电阻R34.7k电阻R44.7k电阻R210K电阻R5 11.0592M晶振Y122u电容C1 80C51单片机U3 104电容C4104电容C8 4148二极管D1 PNP三极管Q5 PNP三极管Q6 PNP三极管Q4 PNP三极管Q2 PNP三极管Q3 PNP三极管Q7 PNP三极管Q1 排阻J1数码管J2数码管J3 按键(小时)S3 按键(分钟)S2 按键(模式)S1 电源插针J4 按键(复位)S4蜂鸣器LS1时钟程序源码YEAR_H EQU 30H ;年份的高位YEAR_L EQU 31H ;年份的低位MONTH EQU 32H ;月份DAY EQU 33H ;日期DAY_MAX EQU 34H ;每月最大天数HOUR EQU 35H ;时钟MINUTE EQU 36H ;分钟SECOND EQU 37H ;秒钟BOTTON EQU 38H ;键值FLAG EQU 39H ;模式标记/0走时/1调时/2日期显示及调整/3闹钟调整及闹钟开关/BEEPH EQU 40H ;闹钟时钟BEEPM EQU 41H ;闹钟分钟ENBEEP EQU 42H ;闹钟开关ORG 0000HAJMP MAINORG 001BHAJMP SERVEMAIN: MOV TMOD,#10H ;设为模式1MOV YEAR_H,#20H ;年高位赋初值20MOV YEAR_L,#10H ;年低位赋初值10MOV MONTH,#12H ;月份赋初值01MOV DAY,#24H ;日期赋初值01MOV R2,#14H ;装入20次中断CLR A ;A清零MOV HOUR,A ;小时清零MOV MINUTE,A ;分钟清零MOV SECOND,A ;秒钟清零MOV FLAG,A ;初始化模式CLR P3.7 ;关蜂鸣器MOV ENBEEP,#01H ;闹钟默认开MOV TH1,#4CH ;赋初值MOV TL1,#00HSETB ET1 ;开中断SETB EASETB TR1 ;启动T1MOV DPTR,#TAB ;送段码表头DIS: LCALL DISPLAY ;重复调用显示子程序LCALL KEY ;扫描按键状态LCALL NEXT ;查询当前模式LCALL BEEP ;查询闹钟开关SJMP DISSERVE: PUSH PSW ;保护现场PUSH ACCMOV TH1,#4CHMOV TL1,#00H;重新赋计数初值DJNZ R2,BRIDGE ;未满10次,返回AJMP BREAK1BRIDGE: LJMP RETURNBREAK1: MOV R2,#14H ;重置中断次数MOV A,#01H ;秒加1ADD A,SECONDDA A ;转为BCD码MOV SECOND,ACJNE A,#60H,BRIDGE ;未满60秒,返回MOV SECOND,#00H ;秒清零MOV A,#01H ;分加1ADD A,MINUTEDA A ;转为BCD码MOV MINUTE,ACJNE A,#60H,RETURN ;未满60分,返回MOV MINUTE,#00H ;分钟清零MOV A,#01H ;时加1ADD A,HOURDA A ;转为BCD码MOV HOUR,ACJNE A,#24H,RETURN ;未满24小时,返回MOV HOUR,#00H ;小时清零MOV A,MONTHDA A ;转为BCD码CJNE A,#1H,JUDGE2 ;不是1月,转跳AJMP SETDAT_MAX1JUDGE2: CJNE A,#3H,JUDGE3 ;不是3月,转跳AJMP SETDAT_MAX1JUDGE3: CJNE A,#5H,JUDGE4 ;不是5月,转跳AJMP SETDAT_MAX1JUDGE4: CJNE A,#7H,JUDGE5 ;不是7月,转跳AJMP SETDAT_MAX1JUDGE5 :CJNE A,#8H,JUDGE6 ;不是8月,转跳AJMP SETDAT_MAX1JUDGE6: CJNE A,#10H,JUDGE7 ;不是10月,转跳AJMP SETDAT_MAX1JUDGE7: CJNE A,#12H,SETDAT_MAX2 ;不是12月,转跳SETDAT_MAX1:MOV DAY_MAX,#32H ;天上限为31AJMP CONTINUE ;返回SETDAT_MAX2:CJNE A,#2H,SETDAT_MAX3 ;不是2月,转跳MOV DAY_MAX,#29H ;2月,天上限28 SETDAT_MAX3:MOV DAY_MAX,#31H ;天上限为30 CONTINUE:MOV A,#01H ;天加1ADD A,DAYDA A ;转为BCD码MOV DAY,ACJNE A,DAY_MAX,RETURN ;未满天数上限,返回MOV DAY,#01H ;天数置1MOV A,#01H ;月份加1ADD A,MONTHDA A ;转为BCD码MOV MONTH,ACJNE A,#13,RETURN ;未满12月,返回MOV MONTH,#01H ;月份置1MOV A,#01H ;年低位加1ADD A,YEAR_LDA A ;转为BCD码MOV YEAR_L,ACJNE A,#99H,RETURN ;未满99年,返回MOV YEAR_L,#00H ;年低位清零MOV A,#99H ;年高位加1ADD A,YEAR_HDA A ;转为BCD码MOV YEAR_H,ACJNE A,#99H,RETURN ;未满99年,返回MOV YEAR_H,#00H ;年高位清零RETURN: POP ACCPOP PSW ;恢复现场RETI ;中断返回;========显示子程序========================== DISPLAY:PUSH PSWPUSH ACCMOV A,R3ANL A,#0FHMOVC A,@A+DPTRMOV P2,#0DFHMOV P0,ALCALL DELAYMOV A,R3SWAP AANL A,#0FHMOVC A,@A+DPTRMOV P2,#0EFHMOV P0,ALCALL DELAYMOV A,R4ANL A,#0FHMOVC A,@A+DPTRMOV P2,#0F7HMOV P0,ALCALL DELAYMOV A,R4SWAP AANL A,#0FHMOVC A,@A+DPTRMOV P2,#0FBHMOV P0,ALCALL DELAYMOV A,R5ANL A,#0FHMOVC A,@A+DPTRMOV P2,#0FDHMOV P0,ALCALL DELAYMOV A,R5SWAP AANL A,#0FHMOVC A,@A+DPTRMOV P2,#0FEHMOV P0,ALCALL DELAYPOP ACCPOP PSWRET;==================按键扫描程序=============== KEY: MOV P1,#0FFHMOV A,P1CPL AANL A,#07HJNZ KEY1RETKEY1: LCALL DADMOV A,P1CPL AANL A,#07HJNZ KEY2RETKEY2: MOV BOTTON,AJB ACC.0,SETMODERETSETMODE:MOV A,FLAGINC AMOV FLAG,ACJNE A,#04H,NEXTMOV FLAG,#00HRET;=================模式查询程序=============== NEXT: MOV A,FLAGCJNE A,#00H,SETTIMESETB TR1MOV R3,SECONDMOV R4,MINUTEMOV R5,HOURMOV A,BOTTONJB ACC.1,STOPJB ACC.2,STOPRET;===============闹钟开关/查询================= BEEP: MOV A,FLAGCJNE A,#00H,STOPMOV A,ENBEEPCJNE A,#01H,STOPBEEPLAY:MOV A,HOURCJNE A,BEEPH,STOPMOV A,MINUTECJNE A,BEEPM,STOPCLR P3.7RETSTOP: SETB P3.7MOV BOTTON,#00HRET;==================调时程序================== SETTIME:CLR TR1CJNE A,#01H,SETDATEMOV R3,SECONDMOV R4,MINUTEMOV R5,HOURMOV A,BOTTONJB ACC.1,MINJB ACC.2,HORRETMIN: MOV A,#01HADD A,MINUTEDA AMOV MINUTE,ACJNE A,#60H,BACKMOV MINUTE,#00HMOV BOTTON,#00HRETHOR: MOV A,#01HADD A,HOURDA AMOV HOUR,ACJNE A,#24H,BACKMOV HOUR,#00HMOV BOTTON,#00HRETBACK: MOV BOTTON,#00HRET;============日期显示及调整子程序================== SETDATE:CJNE A,#02H,SETBEEPMOV R3,DAYMOV R4,MONTHMOV R5,YEAR_LMOV A,BOTTONJB ACC.1,DAYSJB ACC.2,MORETDAYS: MOV A,MONTHDA A ;转为BCD码CJNE A,#1H,JUDGEA ;不是1月,转跳AJMP SETDAT_MAXAJUDGEA:CJNE A,#3H,JUDGEB ;不是3月,转跳AJMP SETDAT_MAXAJUDGEB: CJNE A,#5H,JUDGEC ;不是5月,转跳AJMP SETDAT_MAXAJUDGEC: CJNE A,#7H,JUDGED ;不是7月,转跳AJMP SETDAT_MAXAJUDGED :CJNE A,#8H,JUDGEE ;不是8月,转跳AJMP SETDAT_MAXAJUDGEE: CJNE A,#10H,JUDGEF ;不是10月,转跳AJMP SETDAT_MAXAJUDGEF: CJNE A,#12H,SETDAT_MAXB ;不是12月,转跳SETDAT_MAXA:MOV DAY_MAX,#32H ;天上限为31AJMP CONTINUE1 ;返回SETDAT_MAXB:CJNE A,#2H,SETDAT_MAXC ;不是2月,转跳MOV DAY_MAX,#29HRETSETDAT_MAXC:MOV DAY_MAX,#31H ;天上限为30 CONTINUE1:MOV A,#01H ;天加1ADD A,DAYDA A ;转为BCD码MOV DAY,ACJNE A,DAY_MAX,BACK1MOV DAY,#01HMOV BOTTON,#00HRETMO: MOV A,#01HADD A,MONTHDA AMOV MONTH,ACJNE A,#13H,BACK1MOV MONTH,#01HBACK1: MOV BOTTON,#00HRET;============闹钟调整程序==================SETBEEP:MOV R3,ENBEEPMOV R4,BEEPMMOV R5,BEEPHMOV A,BOTTONJB ACC.1,SETMJB ACC.2,SETHRETSETM: MOV A,#01HADD A,BEEPMDA AMOV BEEPM,ACJNE A,#60H,BACK2MOV BEEPM,#00HSETH: MOV A,#01HADD A,BEEPHDA AMOV BEEPH,ACJNE A,#24H,BACK2MOV BEEPH,#00HBACK2: MOV BOTTON,#00HRET;============延时子程序=====================DELAY: MOV R0,#06HDELAY1: MOV R1,#0B2HDJNZ R1,$DJNZ R0,DELAY1RET;============利用扫描显示延时实现按键防抖==========DAD: LCALL DISPLAYLCALL DISPLAYLCALL DISPLAYLCALL DISPLAYLCALL DISPLAYLCALL DISPLAYLCALL DISPLAYRETTAB: DB 0C0H,0F9H,0A4H,0B0H,99H ;段码DB 92H,82H,0F8H,80H,90HEND注:由于闰年判断程序没有实现功能,所以删除掉,2月份直接定为28天。