51单片机电子时钟课程设计实验报告

《单片机原理与应用》课程设计

总结报告

题    目单片机电子时钟的设计与实现

设计人员:                         

学    号:                          

班    级:                          

指导老师:                          

日    期:                          


   

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)年月日通过代码而不是外部芯片实现。初始值20##年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)显示子程序流程图
3)按键扫描子程序
4)模式查询子程序
日期显示及调整子程序与闹钟显示及调整子程序流程图与调时模式子程序大同小异。

a)日期显示及调整子程序送给R3/R4/R5的数据为日/月/年,按功能键1日期加1,按功能键2月份加1。至于数值的合法性在程序里有具体的判断。

b)闹钟显示及调整子程序送给R3/R4/R5的数据为闹钟开关值/闹钟分/闹钟时,按功能键1闹钟分加1,按功能键2闹钟时加1。至于数值的合法性在程序里有具体的判断。

 

5)闹钟查询子程序
6)定时器中断子程序

数值合法性在程序中处理与判断,流程图中不表现。
总结设计及调试体会

硬件设计部分:首先要通过计算与参考资料等决定参数。而后通过仿真软件等调试,确定参数无误后再开始用Protel99 SE画原理图,进而生成PCB进行布板。

软件设计部分:设计软件首先要考虑要做的功能,确定出合理的算法。合理的算法不仅要可以实现功能,而且在添加功能的时候要方便灵活。有的人为了实现某种功能用了各种各样的方法来实现,结果程序结构吃死,当想要添加功能或者修改其他功能的时候,将修改程序大部分结构,也就是说要破坏程序现有的结构。

关于调试:Keil软件调试单片机程序的时候,编译通过并不代表程序是正确的。编译通过只能说明程序没有语法上的错误。进行软件仿真或者下载到开发板上进行调试,经常会出现各种各样的错误。许多超出预期效果的现象往往是一些微小错误引起的。例如没有现场保护跟恢复现场等,所以养成良好的编程习惯也很重要。有些想达成某些功能而添加的语句,实际上确一点效果也没有。举个编程中的小问题:当有按键按下时,我们都要有软件防抖。正常的方法是调用一个延时。在实际调试中,要跳过这个抖动,需要100MS左右。如果使用正常的延时,会导致按键按下时CPU100MS内无法进行其他操作,也就是说。平均1S内100MS不调用显示子程序,这样就会导致亮度降低。这时候,考虑到显示子程序一次有十几毫秒,就特别写了一个调用7次显示的子程序来作为按键防抖的延时,实际上效果也是很不错的。这个想法就是在修改了多次程序未达到想要的效果(有按键按下时显示亮度不降低)后最终想出来的办法。

最后在做完板,焊完电路后,在接通电源之前,要用万用表仔细检查电路是否有连接错,以免烧坏芯片和数码管。

五天以来的其他体会:态度要积极,不要认为很简单就不紧不慢。很多东西并不是自己设想的那么顺利,有时候一个小问题可以花上你半天甚至一天的时间。虽然自己在程序上并没遇到太大的问题,但是因为态度不够积极,对于没画过的PCB图迟迟不去下手,在周四晚上才解决。本以为周五一天可以做完板并完成整机调试,可是各种突发事件让自己措手不及。发现板来不及做完后才将程序功能进行扩展。这是我在这次实验中的一个教训,也让我明白了对于自己不能太过于自信,态度决定一切。


图一:系统电路原理图

图二:系统电路PCB


表一:元器件清单

时钟程序源码

   

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 0000H

    AJMP    MAIN

    ORG 001BH

    AJMP    SERVE

MAIN:   MOV TMOD,#10H       ;设为模式1

    MOV YEAR_H,#20H     ;年高位赋初值20

    MOV YEAR_L,#10H     ;年低位赋初值10

    MOV MONTH,#12H      ;月份赋初值01

    MOV DAY,#24H        ;日期赋初值01

    MOV 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,#00H

    SETB    ET1         ;开中断

    SETB    EA

    SETB    TR1         ;启动T1

    MOV DPTR,#TAB       ;送段码表头

DIS:    LCALL   DISPLAY         ;重复调用显示子程序

    LCALL   KEY         ;扫描按键状态

    LCALL   NEXT            ;查询当前模式

    LCALL   BEEP            ;查询闹钟开关

    SJMP    DIS

SERVE:  PUSH    PSW         ;保护现场

    PUSH    ACC

    MOV TH1,#4CH

    MOV TL1,#00H

    ;重新赋计数初值

    DJNZ    R2,BRIDGE       ;未满10次,返回

    AJMP    BREAK1

BRIDGE: LJMP    RETURN

BREAK1: MOV R2,#14H         ;重置中断次数

    MOV A,#01H          ;秒加1

    ADD A,SECOND

    DA  A           ;转为BCD码

    MOV SECOND,A       

    CJNE    A,#60H,BRIDGE       ;未满60秒,返回

    MOV SECOND,#00H     ;秒清零

    MOV A,#01H          ;分加1

    ADD A,MINUTE

    DA  A           ;转为BCD码

    MOV MINUTE,A

    CJNE    A,#60H,RETURN       ;未满60分,返回

    MOV MINUTE,#00H     ;分钟清零

    MOV A,#01H          ;时加1

    ADD A,HOUR

    DA  A           ;转为BCD码

    MOV HOUR,A

    CJNE    A,#24H,RETURN       ;未满24小时,返回

    MOV HOUR,#00H       ;小时清零  

    MOV A,MONTH

    DA  A           ;转为BCD码

    CJNE    A,#1H,JUDGE2        ;不是1月,转跳

    AJMP    SETDAT_MAX1        

JUDGE2: CJNE    A,#3H,JUDGE3        ;不是3月,转跳

    AJMP    SETDAT_MAX1        

JUDGE3: CJNE    A,#5H,JUDGE4        ;不是5月,转跳

    AJMP    SETDAT_MAX1

JUDGE4: CJNE    A,#7H,JUDGE5        ;不是7月,转跳

    AJMP    SETDAT_MAX1

JUDGE5  :CJNE   A,#8H,JUDGE6        ;不是8月,转跳

    AJMP    SETDAT_MAX1

JUDGE6: CJNE    A,#10H,JUDGE7       ;不是10月,转跳

    AJMP    SETDAT_MAX1

JUDGE7: CJNE    A,#12H,SETDAT_MAX2  ;不是12月,转跳

SETDAT_MAX1:

    MOV DAY_MAX,#32H        ;天上限为31

    AJMP    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          ;天加1

    ADD A,DAY

    DA  A           ;转为BCD码

    MOV DAY,A

    CJNE    A,DAY_MAX,RETURN    ;未满天数上限,返回

    MOV DAY,#01H        ;天数置1

    MOV A,#01H          ;月份加1

    ADD A,MONTH

    DA  A           ;转为BCD码

    MOV MONTH,A

    CJNE    A,#13,RETURN        ;未满12月,返回

    MOV MONTH,#01H      ;月份置1

    MOV A,#01H          ;年低位加1

    ADD A,YEAR_L

    DA  A           ;转为BCD码

    MOV YEAR_L,A

    CJNE    A,#99H,RETURN       ;未满99年,返回

    MOV YEAR_L,#00H     ;年低位清零

    MOV A,#99H          ;年高位加1

    ADD A,YEAR_H

    DA  A           ;转为BCD码

    MOV YEAR_H,A

    CJNE    A,#99H,RETURN       ;未满99年,返回

    MOV YEAR_H,#00H     ;年高位清零

RETURN: POP ACC

    POP PSW         ;恢复现场

    RETI                ;中断返回                  

;========显示子程序==========================

DISPLAY:PUSH    PSW

    PUSH    ACC

    MOV     A,R3   

    ANL     A,#0FH

    MOVC    A,@A+DPTR

    MOV     P2,#0DFH

    MOV     P0,A

    LCALL   DELAY

    MOV     A,R3

    SWAP    A

    ANL     A,#0FH

    MOVC    A,@A+DPTR

    MOV     P2,#0EFH

    MOV     P0,A

    LCALL   DELAY

    MOV     A,R4

    ANL     A,#0FH

    MOVC    A,@A+DPTR

    MOV     P2,#0F7H

    MOV     P0,A

    LCALL   DELAY

    MOV     A,R4

    SWAP    A

    ANL     A,#0FH

    MOVC    A,@A+DPTR

    MOV     P2,#0FBH

    MOV     P0,A

    LCALL   DELAY

    MOV     A,R5

    ANL     A,#0FH

    MOVC    A,@A+DPTR

    MOV     P2,#0FDH

    MOV     P0,A

    LCALL   DELAY

    MOV     A,R5

    SWAP    A

    ANL     A,#0FH

    MOVC    A,@A+DPTR

    MOV     P2,#0FEH

    MOV     P0,A

    LCALL   DELAY

    POP ACC

    POP PSW

    RET

;==================按键扫描程序===============

KEY:    MOV     P1,#0FFH       

    MOV     A,P1

    CPL     A

    ANL     A,#07H

    JNZ     KEY1

    RET

KEY1:   LCALL   DAD

    MOV     A,P1

    CPL     A

    ANL     A,#07H

    JNZ     KEY2

    RET

KEY2:   MOV     BOTTON,A

    JB ACC.0,SETMODE

    RET

SETMODE:MOV     A,FLAG

    INC     A

    MOV     FLAG,A

    CJNE    A,#04H,NEXT

    MOV     FLAG,#00H

    RET

;=================模式查询程序===============

NEXT:   MOV     A,FLAG         

    CJNE    A,#00H,SETTIME

    SETB    TR1

    MOV R3,SECOND

    MOV R4,MINUTE

    MOV R5,HOUR

    MOV A,BOTTON

    JB  ACC.1,STOP

    JB  ACC.2,STOP

    RET

;===============闹钟开关/查询=================

BEEP:   MOV A,FLAG

    CJNE    A,#00H,STOP

    MOV A,ENBEEP

    CJNE    A,#01H,STOP

BEEPLAY:MOV A,HOUR

    CJNE    A,BEEPH,STOP

    MOV A,MINUTE

    CJNE    A,BEEPM,STOP

    CLR P3.7

    RET

STOP:   SETB    P3.7

    MOV BOTTON,#00H

    RET

;==================调时程序==================

SETTIME:CLR     TR1

    CJNE    A,#01H,SETDATE

    MOV R3,SECOND

    MOV R4,MINUTE

    MOV R5,HOUR    

    MOV     A,BOTTON

    JB ACC.1,MIN

    JB ACC.2,HOR

    RET

MIN:    MOV A,#01H     

    ADD A,MINUTE

    DA  A  

    MOV MINUTE,A

    CJNE    A,#60H,BACK

    MOV MINUTE,#00H

    MOV BOTTON,#00H

    RET

HOR:    MOV A,#01H

    ADD A,HOUR

    DA  A

    MOV HOUR,A

    CJNE    A,#24H,BACK

    MOV HOUR,#00H

    MOV BOTTON,#00H

    RET

BACK:   MOV BOTTON,#00H

    RET

;============日期显示及调整子程序==================

SETDATE:CJNE    A,#02H,SETBEEP

    MOV R3,DAY

    MOV R4,MONTH

    MOV R5,YEAR_L

    MOV     A,BOTTON

    JB ACC.1,DAYS

    JB ACC.2,MO

    RET

DAYS:   MOV A,MONTH

    DA  A           ;转为BCD码

    CJNE    A,#1H,JUDGEA        ;不是1月,转跳

    AJMP    SETDAT_MAXA        

JUDGEA:CJNE A,#3H,JUDGEB        ;不是3月,转跳

    AJMP    SETDAT_MAXA        

JUDGEB: CJNE    A,#5H,JUDGEC        ;不是5月,转跳

    AJMP    SETDAT_MAXA

JUDGEC: CJNE    A,#7H,JUDGED        ;不是7月,转跳

    AJMP    SETDAT_MAXA

JUDGED  :CJNE   A,#8H,JUDGEE        ;不是8月,转跳

    AJMP    SETDAT_MAXA

JUDGEE: CJNE    A,#10H,JUDGEF       ;不是10月,转跳

    AJMP    SETDAT_MAXA

JUDGEF: CJNE    A,#12H,SETDAT_MAXB  ;不是12月,转跳

SETDAT_MAXA:

    MOV DAY_MAX,#32H        ;天上限为31

    AJMP    CONTINUE1       ;返回

SETDAT_MAXB:

    CJNE    A,#2H,SETDAT_MAXC   ;不是2月,转跳

    MOV DAY_MAX,#29H

    RET

SETDAT_MAXC:

    MOV DAY_MAX,#31H        ;天上限为30

CONTINUE1:

    MOV A,#01H          ;天加1

    ADD A,DAY

    DA  A           ;转为BCD码

    MOV DAY,A

    CJNE    A,DAY_MAX,BACK1

    MOV DAY,#01H

    MOV BOTTON,#00H

    RET

MO: MOV A,#01H

    ADD A,MONTH

    DA  A

    MOV MONTH,A

    CJNE    A,#13H,BACK1

    MOV MONTH,#01H

BACK1:  MOV BOTTON,#00H

    RET

;============闹钟调整程序==================

SETBEEP:MOV R3,ENBEEP

    MOV R4,BEEPM

    MOV R5,BEEPH

    MOV     A,BOTTON

    JB ACC.1,SETM

    JB ACC.2,SETH

    RET

SETM:   MOV A,#01H

    ADD A,BEEPM

    DA  A

    MOV BEEPM,A

    CJNE    A,#60H,BACK2

    MOV BEEPM,#00H

SETH:   MOV A,#01H

    ADD A,BEEPH

    DA  A

    MOV BEEPH,A

    CJNE    A,#24H,BACK2

    MOV BEEPH,#00H

BACK2:  MOV BOTTON,#00H

    RET

;============延时子程序=====================

DELAY:  MOV     R0,#06H

DELAY1: MOV     R1,#0B2H

    DJNZ    R1,$

    DJNZ    R0,DELAY1

    RET

;============利用扫描显示延时实现按键防抖==========

DAD:    LCALL   DISPLAY    

    LCALL   DISPLAY

    LCALL   DISPLAY

    LCALL   DISPLAY

    LCALL   DISPLAY

    LCALL   DISPLAY

    LCALL   DISPLAY

    RET

TAB:    DB 0C0H,0F9H,0A4H,0B0H,99H ;段码

    DB 92H,82H,0F8H,80H,90H

    END

注:由于闰年判断程序没有实现功能,所以删除掉,2月份直接定为28天。使用11.0592M晶振,故设置50MS中断一次,20次后为1S。初值为4C00H。

相关推荐