1. 设计要求
(1)系统可以按“秒”进行计时。
(2)数字时钟可以显示小时(00-23)、分钟(00-59)和秒(00-59)。
(3)可通过按键K1来选择设置“小时”、“分钟”和“秒”。设置时可通过“加”和“减”按键(K2、K3)来调整时间;设置过程中时钟停止计时。
(4)无键按下三秒后,自动进入时钟的计时程序。
2. 设计方案
采用ATC51芯片作为硬件核心,其内部采用Flash ROM,具有4KB ROM 存储空间,能于3V的超低压工作,本系统的计时方案是利用单片机内部的定时/计数器进行中断定时, 配合软件延时实现对时、分、秒的计时。
整个系统的控制方案是:上电后系统自动进入时间显示,从00:00:00 开始计时。按下P1.0键,进入调秒状态,时钟停止计时;按P1.1或P1.2键可进行加1或减1操作;继续按P1.0键可分别进行分位、时调整;无键按下3秒钟后退出调整状态,自动进入时钟的计时和显示。
整个系统的硬件原理框图如图1.1,它采用的是ATC51单片机,只用了P1口。为了简化硬件电路,LED显示采用了动态扫描的方式实现, LED采用共阳极数码管,驱动电流由三极管9012提供。为了提高计数精度,所采用的晶振频率为12MHz。
第2章 硬件设计
1 单片机的选择
本课程选用ATC51型号的单片机。 ATC51 是美国ATMEL 公司生产的低电压,高性能CMOS8 位单片机,片内含4k bytes 的可反复擦写的只读程序存 储器(PEROM)和128 bytes 的随机存取数据存储器(RAM ),器件采用ATMEL 公司的高密度、非易失性存储技术生产, 兼容标准MCS-51 指令系统,片内置通用8 位 央处理器(CPU)和Flash 存储单元,功能强大ATC51 单片机可为您提供许多高性价比的应用场合,可灵活应用于各种控制领域。
主要性能参数:
·与MCS-51 产 指令系统完全兼容
·4k 字节可重擦写Flash 闪速存储器
·1000 次擦写周期
·全静态操作:0Hz-24MHz
·三级加密程序存储器
·128×8 字节内部RAM
·32 个可编程I /O 口线
·2 个16 位定时/计数器
2. 显示方案
由于系统要显示的内容较简单,显示量不多,所以选用数码管既方便又经济。LED有共阴极和共阳极两种。如图2.2所示。
二极管的阴极连接在一起,通常此公共阴极接地,而共阳极则将发光二极管的阳极连接在一起,接入+5V的电压。一位显示器由8个发光二极管组成,其中7个发光二极管构成字型“8”的各个笔划(段)a~g,另一个小数点为dp发光二极管。当在某段发光二极管施加一定的正向电压时,该段笔划即亮;不加电压则暗。为了保护各段LED不被损坏,需外加限流电阻。
图2.2 LED数码管结构原理图
众所周知,LED显示数码管通常由硬件7段译码集成电路,完成从数字到显示码的译码驱动。本系统采用软件译码,以减小体积,降低成本和功耗,软件译码的另一优势还在于比硬件译码有更大的灵活性。所谓软件译码,即由单片机软件完成从数字到显示码的转换。从LED数码管结构原理可知,为了显示字符,要为LED显示数码管提供显示段码,组成一个“8”字形字符的7段,再加上1个小数点位,共计8段,因此提供给LED数码管的显示段码为1个字节。各段码位与显示段的对应关系如表2.2。
表2.2 各段码位的对应关系
| 段码位 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
| 显示段 | dp | g | f | e | d | c | b | a |
根据ATC2051单片机灌电流能力强,拉电流能力弱的特点,我们选用共阳数码管。将ATC2051的P1.0~P1.7分别与共阳数码管的a~g及dp相连,高电平的位对应的LED数码管的段暗,低电平的位对应的LED数码管的段亮,这样,当P0口输出不同的段码,就可以控制数码管显示不同的字符。例如:当P0口输出的段码为1100 0000,数码管显示的字符为0。
表2.3 LED显示段码
| 字型 | 共阳极段码 | 共阴极段码 | 字型 | 共阳极段码 | 共阴极段码 |
| 0 | C0H | 3FH | 9 | 90H | 6FH |
| 1 | F9H | 06H | A | 88H | 77H |
| 2 | A4H | 5BH | B | 83H | 7CH |
| 3 | BOH | 4FH | C | C6H | 39H |
| 4 | 99H | 66H | D | A1H | 5EH |
| 5 | 92H | 6DH | E | 86H | 79H |
| 6 | 82H | 7DH | F | 84H | 71H |
| 7 | F8H | 07H | 空白 | FFH | 00H |
| 8 | 80H | 7FH | P | 8CH | 73H |
(2)“空白”字符即没有任何显示。
数码管显示器有二种工作方式,即静态显示方式和动态扫描显示方式。为节省端口及降低功耗,本系统采用动态扫描显示方式。动态扫描显示方式需解决多位LED数码管的“段控”和“位控”问题,本电路的“段控”(即要显示的段码的控制)通过P0口实现;而每一位的公共端,即LED数码管的“位控”,则由P3口控制。这种连接方式由于多位字段线连在一起,因此,要想显示不同的内容,必然要采取轮流显示的方式,即在某一瞬间,只让其中的某一位的字位线处于选通状态,其它各位的字位线处于断开状态,同时字段线上输出这一位相应要显示字符的字段码。在这一瞬时,只有这一位在显示,其他几位则暗。在本系统中,字位线的选通与否是通过PNP三极管的导通与截止来控制,即三极管处于“开关”状态。
第3章 软件设计
1.主程序
主程序功能主要是初始化、正常现实时间和判断功能转换键。流程图如图3.1所示。
图3.1 主程序流程图
2. 定时器T0中断服务程序
定时器T0用于时间计时。定时溢出中断周期可设为50ms,中断进入后,时钟计时累计20次(即1s)时,对秒计数单元进行加1操作。时钟计数单元在定义的6个单元70H~75H中, 70H~71H 存放秒数据, 72H~73H存放分数据, 74H~75H存放时数据。最大计时值为23小时59分59秒。在计数单元中采用十进制BCD码计数,秒、分、时之间满60进位。
3.显示子程序
数码管显示的数据放在内存单元70H~75H中,其中70H~71H存放秒数据, 72H~73H]存放分数据, 74H~75H存放时数据,每一单元内均为十进制BCD码。由于采用软件动态扫描实现数据显示功能,显示用的十进制BCD码数据的对应段码存放在ROM表中,显示时,先取出70H~75H中的某一地址中的数据,然后查表得对应的显示段码从P0口输出,P2口将对应的数码管位选中供电,就能显示该地址单元的数据值。
4.定时器T1中断服务程序
进行时间调整是,正在被调整的时间以闪烁的形式表现,定时器T1用于产生闪烁的时间间隔,每隔0.3s闪烁一次。
5.调时功能程序
通过按键K1来选择设置“小时”、“分钟”和“秒”。
通过“加”和“减”按键(K2、K3)来调整时间
6.延时程序
因为系统是动态显示,为了确保系统在有效显示时间范围内必须执行显示程序,所以使用延时程序。
7. 结论
这次课程设计项目虽然是最简单的数字时钟设计,但用的技术和知识是源于课本又远远高于课本的,比如说ATC51基本操作知识,汇编语言方面的知识等。
我负责的是软件设计的时间设置以及T1中断部分,运用到了按键部分以及定时器/计数器部分的知识。通过这次自己编写程序,使我摆脱了以往单纯的理论知识学习状态,并且在和实际设计的结合锻炼了我的综合运用所学的专业基础知识。不过在这次课设中我也遇到了不少问题,实际操作时才发现课堂知识和实际运用还是有差距的,不过最终还是在老师或同学的帮助下一个一个解决了。
通过这次对课程设计,我也认识到自己对单片机应用方面的知识的贫乏,对于书本上的很多理论知识还不能灵活运用,有很多我们掌握的知识在等着我去学习,我会在以后的学习生活中弥补我所缺少的知识。同时还从中学到了一件很重要的东西,那就是如何从理论到实践的转化。此次的课程设计给我奠定了一个实践基础,我会在以后的学习,生活中磨练自己,使自己掌握更多的技术能力。
8.参考文献
[1]杨忠义.单片机课程设计指导.北京:清华大学出版社,2009.201~217
[2]靳达.单片机应用系统开发实例导航.北京:人民邮电出版社,2004.1~37
[3]南建辉.MCS-51单片机原理及应用实例.北京:清华大学出版社,2004.92~117
[4]刘海成.单片机及应用系统设计原理与实践.北京:北京航天航空大学出版社,2009.129~180
附录
AJMP MAINT ;转主程序
ORG 000BH
AJMP INT01 ;转定时器T0中断程序
ORG 001BH
AJMP INT11 ;转定时器T1中断程序
MAINT: MOV R0,#;00H~7FH单元清零
CLR A
WZ1: ,A
,WZ1
,#;置堆栈指针
,#0AH ;放入“熄灭符”数据
,#;设T0,T1为16位定时器
MOV TL0,#0B0H ;置50 ms定时初值
MOV TH0,#3CH
MOV TL1,#0B0H
MOV TH1,#3CH
S;开中断
SETB E;允许T0中断
SETB T;启动T0
MOV R4,# ;用于产生1 s定时
MAINT1: LCALL XSZCX ;调用显示子程序
J,S;功能键按下,进入调时程序
SJMP
******T0中断服务程序******
INT01: PUSH ACC ;保护现场
CLR ET0 ;关T0中断
CLR TR0 ;关定时器T0
,# ;修正中断响应时间
ADD ,TL0
,A
M,#3CH
ADDC A,TH0
SETB TR0 ;启动定时器T0
DJNZ R4,INT0U ;20次中断未到退出中断
AD1: MOV R4,# ;R4重新赋值
,# ;指向秒计时单元(50H,51H)
LCALL ADD1 ;调用加1 s程序
,R ;秒数据放入A
CLR C ;清进位标志
CJNE A,#60H,A;小于60 s吗
AD2: ;小于60 s退出中断
C ;大于或等于60 s,清秒计数单元
MOV @R0,A
DEC R0
MOV @R0,A
,# ;指向分计时单元 (56H,57H)
ACALL ADD1 ;调用加1 min程序
,R ;分数据放入A
CLR C
,#60H,A ;小于60 min吗
AD3: JC INT0U ;小于60 min退出中断
CLR A ;大于或等于60 min,清分计数单元
M,A
DEC R0
M,A
MOV R0,# ;指向小时计时单元 (58H,59H)
A ;调用加1 h程序
M,R ;小时数据放入A
CLR C
CJNE A,#24H,A ;小于24 h吗
AD4: JC INT0U ;小于24 h退出中断
C ;大于或等于24 h清小时计数单元
MOV @R0,A
DEC R0
M,A
I MOV 52H,5 ;中断退出时将分、时计时单元数
MOV 53H,5 ;据移入对应显示单元
MOV 54H,58H
MOV 55H,59H
P ;恢复现场
POP ACC
SETB ET0 ;开放T0中断
R ;中断返回
******显示子程序******
XSZCX: MOV R1,# ;显示数据首址
,# ;扫描控制字初值
MAXY: ,R ;扫描控制字送A
,A ;输出扫描控制字
MOV A,@ ;取显示数据
,# ;取段码表首地址
MOVC A,@ ;取对应段码
MOV P1,A ;P1口输出段码
LCALL YS1MS ;延时1 ms
I ;显示地址增1
,R ;扫描控制字送A
,E ;ACC.5为0时一次显示结束
RL A ;控制字左移
,A ;制字送回R5中
AJMP MAXY ;循环显示下一个数据
E,# ;一次显示结束,P2口复位
MOV P1,# ;P1口复位
RET ;子程序返回
****** T1中断服务程序******
INT11: PUSH ;中断保护现场
P PSW
MOV TL1,#0B0H ;装定时器T1初值
MOV TH1,#3CH
DJNZ R2,I ;0.3 s未到退出中断
MOV R2,# ;重装0.3 s定时用初值
CPL 02H ;0.3 s定时到,对闪烁标志取反
JB 02H,C ;02H位为1时显示单元“熄灭”
MOV 52H,5 ;02H位为0时显示正常
MOV 53H,57H
,58H
MOV 55H,59H
INT1U: POP PSW ;恢复现场
POP ACC
RETI ;退出中断
INT0U: POP PSW ;恢复状态字(出栈)
POP ACC ;恢复累加器
RETI ;中断返回
******时钟时间调整程序******
SET0: LCALL XSZCX ;通过调用显示时间程序延时消抖动
JNB ,SJTZ1
S;功能键没有按下,显示时间
SET1: CLR ET0 ;关闭定时器T0中断
C;关闭定时器T0
MOV R2,#;进入调时状态,置闪烁定时初值
S;允许T1中断
S;启动T1
SET2: J,S;P1.0端为0(键未释放),等待
C ;置调分标志位为1
SET4: J,S;等待键按下
JNB P1.0,H;有键按下,进入调小时状态
J,S;等待键按下
JNB P1.0,M;有键按下,进入调分状态
J,S;等待键按下
JNB P1.0,S;有键按下,进入调秒状态
MOV A,R;取要调整的单元数据
CLR C
KMTES: SETB ET0 ;省电状态,开T0中断
S;启动T0(开时钟)
K,$;无按键按下,等待
L;通过调用显示时间程序延时消抖动
JB P1.1,K;是干扰返回等待
K,$;等待键释放
LJMP MAINT1 ;返回主程序,显示时间
HOUR: ,S;等待键释放
SETB 01H ;置调小时标志位
S JB P1.0,S;等待键按下
LCALL TM3s ;有键按下延时3秒
L;消抖
JNB P1.0,S;按下时间大于3秒,退出调整状态
MOV R0,#;小于3秒,调整小时
J, ;等待键按下
JNB P1.1, ;P1.1按下,调时间加1子程序
JB P1.2, ;等待键按下
JNB P1.2,S ;P1.2按下,调小时减1子程序
M,R3
CLR C
CJNE A,#24H,B;计时单元与24比较
BJ24: J, ;小于24转SET6循环
C;大于或等于24,则清零
M,A
DEC R0
M,A
AJMP SET6 ;转SET6循环
MINUTE: JNB P1.0,S;等待键释放
SETB 01H ;置调分钟标志位
JB P1.0,S;等待键按下
LCALL TM3s ;有键按下延时3秒
L ;消抖
JNB P1.0,S ;按下时间大于3秒,退出调整状态
MOV R0,#;小于3秒,调整分钟
J,S ;等待键按下
JNB P1.1, ;P1.1按下,调时间加1子程序
JB P1.2, ;等待键按下
JNB P1.2,S;P1.2按下,调分减1子程序
M,R3
CLR C
CJNE A,#60H,B;计时单元与60比较
BJ601: JC SET7, ;小于24转SET7循环
C;大于或等于24,则清零
M,A
DEC R0
M,A
AJMP SET7 ;转SET7循环
SECOND: ,S;等待键释放
SETB 01H ;置调秒钟标志位
JB P1.0,S;等待键按下
LCALL TM3s ;有键按下延时3秒
L;消抖
JNB P1.0,S;按下时间大于3秒,退出调整状态
MOV R0,#;小于3秒,调整分钟
J,S;等待键按下
JNB P1.1, ;P1.1按下,调时间加1子程序
, ;等待键按下
JNB P1.2,S;P1.2按下,调时间减1子程序
,R3
CLR C
CJNE A,#60H,B;计时单元与60比较
BJ602: JC SET8, ;小于24转SET8循环
C;大于或等于24,则清零
M,A
DEC R0
M,A
AJMP SET8 ;转SET8循环
OUT: ,S;退出调时状态,等待键释放
LCALL ;通过调用显示程序延时消抖动
JNB P1.0,SETOUT ;是抖动,返回SETOUT等待
MOV 20H,# ;清调时标志位
C ;关闭T1
C ;关T1中断
SETB T ;启动T0
SETB E ;开T0中断
LJMP MAINT1 ;返回主程序
SET1: LCALL XSZCX ;键释放等待时,调用显示子程序
AJMP SET2 ;防止此时无时钟显示
SET3: LCALL XSZCX ;等待调小时按键时时钟显示用
AJMP SET4 ;调时等待
SET5: ;键释放等待时调用显示程序(调小时)
AJMP SETHH ;防止键按下时无时钟显示
SET9: XSZCX
AJMP SET6
SET10: ;键释放等待时调用显示程序(调分钟)
AJMP SETHH ;防止键按下时无时钟显示
SET11: LCALL XSZCX
AJMP SET7
SET12: ;键释放等待时调用显示程序(调秒钟)
AJMP SETHH ;防止键按下时无时钟显示
SET13: XSZCX
AJMP SET8
SETOUT1:LCALL XSZCX
AJMP OUT
****** 加1子程序******
ADD1: ,@ ;取出现计时数据放入A
DEC R0 ;指向前一单元
SWAP A ;A中高4位与低4位互换
ORL A,@ ;前一单元中数据放入A中低4位
ADD A,# ;A加1
DA A ;十进制调整
MOV R3,A ;移入R3寄存器
ANL A,# ;高4位变0
,A ;放回前一地址单元
,R ;取回R3中暂存数据
INC R0 ;指向当前地址单元
SWAP A ;A中高4位与低4位互换
,# ;高4位变0
M, ;数据存入当前地址单元
RET ;子程序返回
****** 时减1子程序******
SUB-H: MOV A,@R0 ;取当前计时单元数据到A
DEC R0 ;指向前一地址
SWAP A ;A中数据高4位与低4位交换
ORL A,@R0 ;前一地址中数据放入A中低4位
JZ SUB-H1 ;00减1为23(小时)
DEC A ;A减1操作
SUB-H11: ,A ;移入R3寄存器
ANL A,#0FH ;高4位变0
CLR C ;清进位标志
SUBB A,#0FH; ;时个位是否大于9
SUB-H111: JC SUB-H110
MOV @R0,# ;大于等于0AH,为9
SUB-H10: MOV A,R3 ;取回R3中暂存数据
INC R0 ;指向当前地址单元
SWAP A ;A中数据高4位与低4位交换
ANL A,#0FH ;高4位变0
MOV @R0,A;时十位数据放入
RET ; 子程序返回
SUB-H1: MOV A,#23H
AJMP SUB-H11
SUB-H110: ,R;时个位小于0A不处理
ANL A,#0FH ;高4位变0
MOV @R0,A;时个位数据放入
AJMP SUB-H10
******分减1子程序******
SUB-M: MOV A,@R0 ;取当前计时单元数据到A
DEC R0 ;指向前一地址
SWAP A ;A中数据高4位与低4位交换
ORL A,@R0 ;前一地址中数据放入A中低4位
JZ SUB-M1
DEC A ;A减1操作
SUB-M11: ,A;移入R3寄存器
ANL A,#0FH ;高4位变0
CLR C ;清进位标志
SUBB A,#0AH;
SUB-M111: JC SUB-M110
MOV @R0,#;大于等于0AH,为9
SUB-M10: MOV A,R3 ;取回R3中暂存数据
INC R0 ;指向当前地址单元
SWAP A ;A中数据高4位与低4位交换
ANL A,#0FH ;高4位变0
MOV @R0,A;数据放入当前地址单元中
RET ; 子程序返回
SUB-M1: MOV A,#59H
AJMP SUB-M11
SUB-M110: ,R;移入R3寄存器
ANL A,#0FH ;高4位变0
MOV @R0,A
AJMP SUB-M10
****** 秒减1子程序******
SUB-S: MOV A,@R0 ;取当前计时单元数据到A
DEC R0 ;指向前一地址
SWAP A ;A中数据高4位与低4位交换
ORL A,@R0 ;前一地址中数据放入A中低4位
JZ SUB-S1
DEC A ;A减1操作
SUB-S11: ,A;移入R3寄存器
ANL A,#0FH ;高4位变0
CLR C ;清进位标志
SUBB A,#0BH;
SUB-S111: JC SUB-S110
MOV @R0,#;大于等于0AH,为9
SUB-S10: MOV A,R3 ;取回R3中暂存数据
INC R0 ;指向当前地址单元
SWAP A ;A中数据高4位与低4位交换
ANL A,#0FH ;高4位变0
MOV @R0,A;数据放入当前地址单元中
RET ; 子程序返回
SUB-S1: MOV A,#14H
AJMP SUB-S11
SUB-S110: ,R;移入R3寄存器
ANL A,#0FH ;高4位变0
MOV @R0,A
AJMP SUB-S10
******延时子程序******
TM1ms: MOV R6, ;延时1 ms子程序
TM1: MOV R7,#19H
TM2: ,YS2
,YS1
TM3s: ;延时3s子程序
LCALL TM05s
LCALL TM05s
TM05s: MOV R3,#;延时0.5 s子程序
YS05s1:LCALL XSZCX
,YS05s1
TAB:DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH
END