360 likes | 467 Views
10.3.2 数码管数字时钟电路的设计 1. 系统硬件电路的设计 单片机控制的数码管时钟电路如图 10-6 所示,它采用的是 AT89C51 单片机,只用了 P1 口和 P2 口, P0 、 P3 口可用于扩展显示年、月、日等功能。为了简化硬件电路, LED 显示采用动态扫描方式实现, P1 口输出段码数据, P2.0 ~ P2.5 端作扫描输出控制端, P2.7 作功能转换按键输入端。 LED 采用共阳极数码管,由三极管 9012 提供驱动电流。为了提高计时精度,所采用的晶振频率为 12 MHz 。.
E N D
10.3.2 数码管数字时钟电路的设计 • 1. 系统硬件电路的设计 • 单片机控制的数码管时钟电路如图10-6所示,它采用的是AT89C51单片机,只用了 P1口和P2口,P0、P3口可用于扩展显示年、月、日等功能。为了简化硬件电路,LED显示采用动态扫描方式实现,P1口输出段码数据,P2.0~P2.5端作扫描输出控制端,P2.7作功能转换按键输入端。LED采用共阳极数码管,由三极管9012提供驱动电流。为了提高计时精度,所采用的晶振频率为12 MHz。
2. 系统软件的设计 • 1) 主程序 • 主程序功能主要是初始化、正常显示时间和判断功能转换键。显示时间调用显示子程序。当P2.7端口按键按下时,转入调时功能程序。主程序流程图如图10-7所示。
2) 显示子程序 • 数码管显示的数据存放在50H~55H内存单元中,其中50H、51H单元存放秒数据,52H、53H单元存放分数据,54H、55H单元存放时数据。时间数据采用BCD码表示,对应的显示用段码表存放在ROM中。
3) 定时器T0中断服务程序 • 时钟的最小计时单位是秒,60 s进位1 min,60 min进位1 h。定时器T0用于产生最小单位1 s,定时时间为50 ms,中断累计20次即为1 s。计数单元中的十进制BCD数每逢60进位。程序流程图如图10-8所示。
4) 定时器T1中断服务程序 • 进行时间调整时,正在被调整的时间以闪烁形式表现,定时器T1用于产生闪烁的时间间隔,每隔0.3 s闪烁一次。程序流程图略。 • 5) 调时功能程序 • 调整时间程序的方法是:按下功能键,当按下时间小于1 s时,进入省电状态,大于1 s时,进入调分状态,等待操作,此时计时器停止走动。
6) 延时程序 • 系统使用三个延时程序。因为系统是动态显示,为了确保系统在有效显示时间范围内(约50 ms)必须执行显示程序,所以0.5 s的延时程序是通过执行显示程序约81遍实现的。
程序如下: • ORG 0000H • AJMP MAINT ;转主程序 • NOP • ORG 000BH • AJMP INT01 ;转定时器T0中断程序 • NOP • ORG 001BH • AJMP INT11 ;转定时器T1中断程序 • NOP
******主程序****** • MAINT: MOV R0,#7FH ;00H~7FH单元清零 • CLR A • WZ1:MOV @R0,A • DJNZ R0,WZ1 • MOV SP,#30H ;置堆栈指针 • MOV 5AH,#0AH ;放入“熄灭符”数据 • MOV TMOD,#11H ;设T0,T1为16位定时器
MOV TL0,#0B0H ;置50 ms定时初值 • MOV TH0,#3CH • MOV TL1,#0B0H • MOV TH1,#3CH • SETB EA ;开中断 • SETB ET0 ;允许T0中断 • SETB TR0 ;启动T0 • MOV R4,#14H ;用于产生1 s定时
MAINT1: LCALL XSZCX • ;调用显示子程序 • JNB P2.7,SJTZ0 • ;功能键按下,进入调时程序 • SJMP MAINT1 • SJTZ0: LCALL XSZCX • ;通过调用显示时间程序延时消抖动 • JNB P2.7,SJTZ1 • SJMP MAINT1 • ;功能键没有按下,显示时间
SJTZ1: CLR ET0 ;关闭T0中断 • CLR TR0 ;关闭T0 • LCALL YS1S ;调用1 s延时程序 • JB P2.7,KMTES • ;按键时间小于1 s,进入省电状态 • MOV R2,#06H • ;进入调时状态,置闪烁定时初值 • SETB ET1 ;允许T1中断 • SETB TR1 ;启动T1
XYZ2:JNB P2.7,XYZ1 ;P2.7端为0,等待 • CLR 01H ;置调分标志位为1 • XYZ4:JB P2.7,XYZ3 ;等待键按下 • LCALL YS05S ;延时0.5 s • JNB P2.7,XYZHH • ;按键时间大于0.5 s,转到调小时状态 • MOV R0,#53H • ;按键时间小于0.5 s,进入调分状态 • LCALL ADD1 • ;调时间加1子程序
MOV A,R3 ;取要调整的单元数据 • CLR C • CJNE A,#60,QWE ;调整单元数据与60比较 • JC XYZ4 ;小于60转到XYZ4循环 • QWE:CLR A ;大于或等于60,清零 • MOV @R0,A • DEC R0 • MOV @R0,A • CLR C • AJMP XYZ4 ;转到XYZ4循环
KMTES: SETB ET0 ;省电状态,开T0中断 • SETB TR0 ;启动T0(开时钟) • KMA: JB P2.7,$ ;无按键按下,等待 • LCALL XSZCX • ;通过调用显示时间程序延时消抖动 • JB P2.7,KMA ;是干扰返回等待 • KMA1: JNB P2.7,$ ;等待键释放 • LJMP MAINT1 ;返回主程序,显示时间
XYZHH: JNB P2.7,XYZ5 ;等待键释放 • SETB 01H ;置调小时标志位 • XYZ6: JB P2.7,XYZ7 ;等待键按下 • LCALL YS05S ;有键按下,延时0.5 s • JNB P2.7,XYZOUT • ;按下时间大于0.5 s,退出调整状态 • MOV R0,#55H • ;小于0.5 s,调整小时 • LCALL ADD1 ;调加1子程序 • MOV A,R3
CLR C • CJNE A,#24,KMB1 ;计时单元与24比较 • JC XYZ6, ;小于24转XYZ6循环 • KMB1: CLR A ;大于或等于24,则清零 • MOV @R,A • DEC R0 • MOV @R0,A • AJMP XYZ6 ;转XYZ6循环
XYZOUT: JNB P2.7,XYZOUT1 • ;退出调时状态,等待键释放 • LCALL XSZCX ;通过调用显示程序延时消抖动 • JNB P2.7,XYZOUT ;是抖动,返回XYZOUT等待 • MOV 20H,#00H ;清调时标志位 • CLR TR1 ;关闭T1 • CLR ET1 ;关T1中断 • SETB TR0 ;启动T0 • SETB ET0 ;开T0中断 • LJMP MAINT1 ;返回主程序
XYZ1: LCALL XSZCX • ;键释放等待时,调用显示子程序 • AJMP XYZ2 ;防止此时无时钟显示 • XYZ3: LCALL XSZCX • AJMP XYZ4 • XYZ5: LCALL XSZCX • AJMP XYZHH • XYZ7: LCALL XSZCX • AJMP XYZ6 • XYZOUT1: LCALL XSZCX • AJMP XYZOUT
******显示子程序****** • XSZCX:MOV R1,#50H ;显示数据首址 • MOV R5,#0FEH ;扫描控制字初值 • MAXY: MOV A,R5 ;扫描控制字送A • MOV P2,A ;输出扫描控制字 • MOV A,@R1 ;取显示数据 • MOV DPTR,#ABC ;取段码表首地址 • MOVC A,@A+DPTR ;取对应段码 • MOV P1,A ;P1口输出段码 • LCALL YS1MS ;延时1 ms
INC R1 ;显示地址增1 • MOV A,R5 ;扫描控制字送A • JNB ACC.5,ENDOUT • ;ACC.5为0时一次显示结束 • RL A ;控制字左移 • MOV R5,A ;制字送回R5中 • AJMP MAXY ;循环显示下一个数据 • ENDOUT: MOV P2,#0FFH ;一次显示结束,P2口复位 • MOV P1,#0FFH ;P1口复位 • RET ;子程序返回
******T0中断服务程序****** • INT01: PUSH ACC ;保护现场 • PUSH PSW • CLR ET0 ;关T0中断 • CLR TR0 ;关定时器T0 • MOV A,#0B7H ;修正中断响应时间 • ADD A,TL0 • MOV TL0,A
MOV A,#3CH • ADDC A,TH0 • SETB TR0 ;启动定时器T0 • DJNZ R4,INT0U ;20次中断未到退出中断 • AD1: MOV R4,#14H ;R4重新赋值 • MOV R0,#51H ;指向秒计时单元(50H,51H) • LCALL ADD1 ;调用加1 s程序 • MOV A,R3 ;秒数据放入A • CLR C ;清进位标志 • CJNE A,#60,AD2 ;小于60 s吗 • JC INT0U ;小于60 s退出中断
AD2: CLR A ;大于或等于60 s,清秒计数单元 • MOV @R0,A • DEC R0 • MOV @R0,A • MOV R0,#57H • ;指向分计时单元(56H,57H) • ACALL ADD1 ;调用加1 min程序 • MOV A,R3 ;分数据放入A • CLR C • CJNE A,#60,AD3 ;小于60 min吗 • JC INT0U ;小于60 min退出中断
AD3: CLR A ;大于或等于60 min,清分计数单元 • MOV @R0,A • DEC R0 • MOV @R0,A • MOV R0,#59H • ;指向小时计时单元(58H,59H) • ACALL ADD1 ;调用加1 h程序 • MOV A,R3 ;小时数据放入A • CLR C • CJNE A,#24,AD4 ;小于24 h吗 • JC INT0U ;小于24 h退出中断
AD4: CLR A • ;大于或等于24 h清小时计数单元 • MOV @R0,A • DEC R0 • MOV @R0,A • INT0U: MOV 52H,56H • ;中断退出时将分、时计时单元数据 • MOV 53H,57H • ;移入对应显示单元 • MOV 54H,58H • MOV 55H,59H
POP PSW ;恢复现场 • POP ACC • SETB ET0 ;开放T0中断 • RETI ;中断返回
****** T1中断服务程序****** • INT11: PUSH ACC ;保护现场 • PUSH PSW • MOV TL1,#0B0H ;装定时器T1初值 • MOV TH1,#3CH • DJNZ R2,INT1U ;0.3 s未到退出中断 • MOV R2,#06H ;重装0.3 s定时用初值 • CPL 02H • ;0.3 s定时到,对闪烁标志取反
JB 02H,CCC1 • ;02H位为1时显示单元“熄灭” • MOV 52H,56H • ;02H位为0时显示正常 • MOV 53H,57H • MOV 54H,58H • MOV 55H,59H • INT1U: POP PSW ;恢复现场 • POP ACC • RETI ;退出中断
CCC1: JB 01H,CCC2 • ;01H位为1时转小时熄灭控制 • MOV 52H,5AH • ;01H位为0时“熄灭符”放入分计时单元 • MOV 53H,5AH • MOV 54H,58H • MOV 55H,59H • AJMP INT1U ;转中断退出
CCC2: MOV 52H,56H • ;01H位为1时“熄灭符”放入小时计时单元 • MOV 53H,57H • MOV 54H,5AH • MOV 55H,5AH • AJMP INT1U ;转中断退出 • ADD1: MOV A,@R0 • ;取出现计时数据放入A • DEC R0 ;指向前一单元
SWAP A ;A中高4位与低4位互换 • ORL A,@R0 • ;前一单元中数据放入A中低4位 • ADD A,#01H ;A加1 • DA A ;十进制调整 • MOV R3,A ;移入R3寄存器 • ANL A,#0FH ;高4位变0 • MOV @R0,A ;放回前一地址单元 • MOV A,R3 ;取回R3中暂存数据 • INC R0 ;指向当前地址单元 • SWAP A ;A中高4位与低4位互换 • ANL A,#0FH ;高4位变0
MOV @R0, A ;数据存入当前地址单元 • RET ;子程序返回 • ******延时子程序****** • YS1MS: MOV R6,#14H ;延时1 ms子程序 • YS1: MOV R7,#19H • YS2: DJNZ R7,YS2 • DJNZ R6,YS1 • RET
YS1S: LCALL YS05S ;延时1 s子程序 • LCALL YS05S • RET • YS05S: MOV R3,#51H ;延时0.5 s子程序 • YS05S1: LCALL XSZCX • DJNZ R3,YS05S1 • RET • ABC: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH • END