《单片机原理实验》报告
——电子时钟程序设计
一 、实验目的
1、学习8051系列单片机[SSTE58RD]定时器时间计时处理
2、学习按键扫描电路的应用
3、掌握LED数码管动态显示的设计方法
二、设计任务及要求
利用实验平台上4个LED数码管, 设计带有闹铃功能的数字时钟,要求:
1、 在4位数码管上显示当前时间,显示格式为“时时分分” ;
2、 由LED闪动做秒显示;
3、 利用按键可对时间及闹玲进行设置,并可显示闹玲时间。当闹玲时间到蜂鸣器发出声响,按停止键使可使闹玲声停止。
三、实现功能概述
1、4位7段数码管上显示当前时间,显示格式为“时时 . 分分”,第三位小数点同时闪烁做秒显示;
2、由红色LED闪动做秒显示;
3、利用按键可对时间及闹铃时间进行设置,可显示闹铃时间。
4、闹铃时间到,蜂鸣器持续鸣响;
四、工作原理及设计思路
1:利用单片机定时器完成计时功能,定时器0计时中断程序每隔5ms中断一次并当作一个计数,每中断一次计数加1,当计数200次时,则表示1s到了,秒变量加1,同理再判断是否1min钟到了,再判断是否1h到了。为了将时间在LED数码管上显示,可采用静态显示法和动态显示法,由于静态显示法需要数据锁存器等较多硬件,可采用动态显示法实现LED显示。
闹铃声由交流蜂鸣器产生,电路如右图,当P1.7输出不同频率的方波,蜂鸣器便会发出不同的声音。
图:蜂鸣器电路
2:硬件电路设计及描述
由于扩展了外部存储器, P0口只能作地址/数据总线,P2口只能作地址总线高8位,P3.7、P3.6作为外部数据存储器读写信号。P3.0、P3.1作为串行输入、输出接口,在仿真模式下完成与PC机的通信,故也不可用。
实验仪上单片机可用作I/O的口仅有:P1.0--P1.7 ,8位;P3.2、P3.3、P3.4、P3.5 ,4位。其中:P1.0 用作数据线SDA,P1.1用作时钟信号CLK,所以P1.0和P1.1应该接对应跳线的A位,即跳线的中间和下面相连。P1.3、P1.4、P1.5和P1.6是四个数码管的位扫描线,其中P1.6对应数码管W1,显示小时高位;P1.5对应数码管W2,显示小时低位;P1.4对应数码管W3,显示分钟高位;P1.3对应数码管W4,显示分钟低位。P1.7连接蜂鸣器电路,输出不同频率的方波,使其发出不同的声音。P1.2 用来控制秒的闪烁显示。故,P1.2也应该接对应跳线的A位。
其显示电路如下图:
P3.2、P3.3、P3.4、P3.5分别连接单刀双掷开关S1、S2、S3、S4,从而输入高低电平。将S2 S1 定义为功能模式选择开关;S3 定义为分钟数调整开关;S4 定义为小时数调整开关。
当S2 S1=00时,显示当前时间,不进行任何操作。
当S2 S1=01时, 显示当前时间,同时可进行时钟调整,若S3=1,分钟数持续加1,若S4=1,小时数持续加1。
当S2 S1=10时,显示闹钟时间,同时可进行闹钟调整,若S3=1,分钟数持续加1,若S4=1,小时数持续加1。
当S2 S1=11 时,显示当前时间,同时关闭闹钟
五、主要模块设计流程及描述
1主模块设计概述
2时钟走时中断服务模块
模块设计描述:
1进行各端口配置、程序初始化、开定时器0中断及启动计数
2循环调用时钟显示、响铃判断、按键判断子程序
3在调用子程序时,若定时器T0计满产生中断,则开始执行时钟走时中断服务程序
4若响铃开关打开,且闹铃时间到来,定时器T1计满产生中断,则执行闹钟响铃中断服务程序
3显示模块
本实验使用的数码管为4位共阳数码管,LED的公共阳极接高电平,某个阴极接低电平时,相应的段被点亮显示,为显示不同的字形,显示器各字段所加的电平是不同的,编码也随之不同,7段显示器的字形与共阳极时编码的对应关系如下表
显示字符 | 段码 | 显示字符 | 段码 |
0 | COH | 7 | F8H |
1 | F9H | 8 | 80H |
2 | A4H | 9 | 90H |
3 | B0H | A | 88H |
4 | 99H | B | 83H |
5 | 92H | 无显示 | FFH |
6 | 82H | … | … |
4校时模块
校时模块主要是通过软件来实现的。校时模块可以调整时间和闹钟,这些通过按键扫描电路来判断。以闹铃校时为例,流程如下:
5计时模块
计时模块是通过定时器0来实现的。定时器1每5ms中断一次,达到200次中断则达到1s时间。计时模块流程图如下:
六、源程序代码及注释
注:首先将单片机用到的主要寄存器做下说明(如下);
P1.2 作秒的闪烁控制位;
P1.7 作响铃控制电平;
P3.2 、P3.3 作模式选择键S2、S1;
P3.4 作分调整键S3(分钟数+1);
P3.5 作时调整键S4(小时数+1);
R0为计数5ms的次数;R1为秒数;R2为分钟数;R3为时钟数;
R4 在显示程序中作为向LED传递数据时的左移次数标志位;
R4 在音乐闹铃程序中读取TABLE中的数据;
R5作为节拍长度;
40H 作显示的分;41H 作显示的时;42H 作闹钟的分;43H 作闹钟的时;
63H、H 存放延时程序DELAY的延时数;
60H、61H 作定时器T1的初值。
;****************************** 主程序 *******************************************
S1 BIT P3.2 ;定义模式选择键S2、S1
S2 BIT P3.3
S3 BIT P3.4 ;定义时调整键S4,分调整键S3
S4 BIT P3.5
SDA BIT P1.0
CLK BIT P1.1
ORG 0000H
AJMP MAIN
ORG 000BH ;T0的中断服务程序的入口地址
AJMP TIMER ;跳转到时钟走时中断服务程序
ORG 001BH ;T1的中断服务程序的入口地址
AJMP ALARM_OPEN ;跳转到闹钟响铃中断服务程序
ORG 0030H
MAIN: MOV 40H,#00 ;显示的分
MOV 41H,#00 ;显示的时
MOV 42H,#58 ;闹钟的分
MOV 43H,#23 ;闹钟的时
MOV R0,#00H ;寄存器清零(RO为计数5ms的次数,R1为秒数,
MOV R1,#00H ;R2为分钟数,R3为时钟数)
MOV R2,#00H
MOV R3,#00H
MOV TMOD,#11H ;设置T0,T1处于工作方式1
MOV TH0,#0EEH ;设置定时器的初值
MOV TL0,#00H
SETB EA ;允许总中断
SETB ET0 ;允许T0,T1中断
SETB ET1
SETB TR0 ;启动T0
LOOP: LCALL DISPLAY1 ;调用显示程序
LCALL ALARM ;调用闹铃程序
LCALL MODE ;调用模式判断程序
AJMP LOOP
;************************************ 时钟显示部分 *******************************
DISPLAY1:
MOV DPTR,#TAB1
MOV A,41H
MOV B,#10
DIV AB
LCALL DISP1
CLR P1.6 ;LED1数码管显示数码,即小时的高位
LCALL DELAY
SETB P1.6
JB P1.2,TD ;控制LED2数码管的小数点"dp"闪烁
AJMP TD1
TD: MOV A,B
AJMP TD2
TD1: MOV A,B
ADD A,#10
TD2: LCALL DISP1 ;LED2数码管显示数码,即小时的低位
CLR P1.5
LCALL DELAY
SETB P1.5
MOV A,40H
MOV B,#10
DIV AB
LCALL DISP1
CLR P1.4 ;LED3数码管显示数码,即分钟的高位
LCALL DELAY
SETB P1.4
MOV A,B
LCALL DISP1
CLR P1.3 ;LED4数码管显示数码,即分钟的低位
LCALL DELAY
SETB P1.3
RET
DISP1: MOVC A,@A+DPTR ;LED串并转换口从P1.0接收
MOV R4,#08H ;R4记作左循环的次数
DUP1: RLC A ;A带进位左循环移位
MOV SDA,C
CLR CLK ;上升沿触发数据接收
SETB CLK
DJNZ R4,DUP1
RET
;************************************ 闹钟显示部分 *******************************
DISPLAY2:
MOV DPTR,#TAB1
MOV A,43H
MOV B,#10
DIV AB
LCALL DISP2
CLR P1.6 ;LED1数码管显示数码,即小时的高位
LCALL DELAY
SETB P1.6
MOV A,B
LCALL DISP2
CLR P1.5 ;LED2数码管显示数码,即小时的低位
LCALL DELAY
SETB P1.5
MOV A,42H
MOV B,#10
DIV AB
LCALL DISP2
CLR P1.4 ;LED3数码管显示数码,即分钟的高位
LCALL DELAY
SETB P1.4
MOV A,B
LCALL DISP2
CLR P1.3 ;LED4数码管显示数码,即分钟的低位
LCALL DELAY
SETB P1.3
RET
DISP2: MOVC A,@A+DPTR ;LED串并转换口从P1.0接收
MOV R4,#08H ;R4记作左循环的次数
DUP2: RLC A ;A带进位左循环移位
MOV SDA,C
CLR CLK ;上升沿触发数据接收
SETB CLK
DJNZ R4,DUP2
RET
;******************************** 判断闹钟时间是否到来 *************************
ALARM:
MOV A,40H
CJNE A,#00H,MUSIC ;整点闹铃
LJMP B2
MUSIC: MOV A,43H
CJNE A,41H,B1
MOV A,42H
CJNE A,40H,B1 ;音乐闹铃
SETB P1.7
MOV 70H,#00H
NEXT: MOV A,70H
MOV DPTR,#TABLE ;从TABLE中读取数据——声响时间
MOVC A,@A+DPTR
MOV R4,A ;将TABLE中读取的数据存放在R4
JZ END0
ANL A,#0FH
MOV R5,A ;R5作为节拍长度
MOV A,R4
SWAP A
ANL A,#0FH
JNZ SING
CLR TR1
JMP D1
SING: DEC A
MOV 62H,A
RL A
MOV DPTR,#TABLE1 ;从TABLE1中读取数据——声调
MOVC A,@A+DPTR
MOV TH1,A ;设定TH1值
MOV 61H,A
MOV A,62H
RL A
INC A
MOVC A,@A+DPTR
MOV TL1,A ;设定TL1值
MOV 60H,A
MOV TH1,61H
MOV TL1,60H
SETB TR1
D1: ACALL DELAY0 ;声音延时
INC 70H
JMP NEXT
END0: CLR TR1
JMP MUSIC
DELAY0:
MOV R7,#2 ;R5的值就是声响持续时间
D2: MOV R6,#214
D3: MOV R4,#245
DJNZ R4,$
DJNZ R6,D3
DJNZ R7,D2
DJNZ R5,DELAY0
RET
B1: CLR TR1
RET
B2: MOV 61H,#0FEH
MOV 60H,#033H
MOV TH1,61H
MOV TL1,60H ;方波频率设为1KHz
SETB TR1
;******************************** 闹钟响铃中断服务程序 **************************
ALARM_OPEN:
PUSH ACC
PUSH PSW
MOV TH1,61H
MOV TL1,60H
CPL P1.7
POP PSW
POP ACC
RETI
;******************************** 时钟走时中断服务程序 ***************************
TIMER: MOV TH0,#0ECH ;重新对T0赋值,设置中断时间为5ms
MOV TL0,#78H
MOV 40H,R2
MOV 41H,R3
INC R0 ;计数5ms的次数加1
CJNE R0,#200,BACK ;不够200次,跳转到BACK
CPL P1.2 ;够200次,P1.2翻转控制LED闪动一下
MOV R0,#00H ;计数5ms的次数清0,秒数加1
INC R1
CJNE R1,#60,BACK ;不够60秒,跳转到BACK
MOV R1,#00H ;够60秒,秒数清0,分钟加1
INC R2
CJNE R2,#60,BACK ;够60分钟,跳转到BACK
MOV R2,#00H ;够60分钟,分钟数清0,小时数加1
INC R3
CJNE R3,#24,BACK ;够24小时,跳转到BACK
MOV R3,#00H ;够24小时,小时数清0
BACK: RETI
;************************************ 按键判断部分 *******************************
MODE: MOV A,P3 ;软件消抖后再判断
LCALL DELAY
CJNE A,P3,MODE
ANL A,#0CH ;对S2、S1的值判断
CJNE A,#00H,LOP1
AJMP T_BACK ;模式为00,开T1中断
LOP1: CJNE A,#04H,LOP2
AJMP T_CHANGE ;模式为01,进行时间调整
LOP2: CJNE A,#08H,LOP3
AJMP A_CHANGE ;模式为10,进行闹铃调整
LOP3: AJMP A_CLOSE ;模式为11,关闭闹钟
;............................. 时钟调整 ...............................
T_CHANGE:
LCALL DISPLAY1
LCALL DELAY1
JNB S3,T_HOUR ;S3为0,判断S4
T_MIN: MOV R5,40H
INC R5 ;S3为1,分钟数加1
CJNE R5,#60,LOP4
MOV R5,#00H
LOP4: MOV 40H,R5
MOV R2,40H
AJMP MODE
T_HOUR:
JNB S4,MODE ;S4为0,跳转到MODE
MOV R5,41H
INC R5 ;S4为,小时数加1
CJNE R5,#24,LOP5
MOV R5,#00H
LOP5: MOV 41H,R5
MOV R3,41H
AJMP MODE
;............................. 闹铃调整 ................................
A_CHANGE:
LCALL DISPLAY2
LCALL DELAY2
JNB S3,A_HOUR ;S3为0,判断S4
A_MIN: MOV R5,42H
INC R5 ;S3为1,分钟数加1
CJNE R5,#60,LOP6
MOV R5,#00H
LOP6: MOV 42H,R5
AJMP MODE
A_HOUR:
JNB S4,MODE ;S4为0,跳转到MODE
MOV R5,43H
INC R5 ;S4为1,小时数加1
CJNE R5,#24,LOP7
MOV R5,#00H
LOP7: MOV 43H,R5
AJMP MODE
;............................ 返回 .................................
T_BACK:
SETB ET1 ;开T1中断
RET
A_CLOSE:
CLR ET1 ;关T1中断
RET
;************************************ 延时程序 ********************************
DELAY:
MOV 63H,#5H ;约2.78ms
D5: MOV H,#0FFH
DJNZ H,$
DJNZ 63H,D5
RET
;************************************ 延时程序1 ********************************
DELAY1:
MOV R7,#50H
D6: LCALL DISPLAY1
DJNZ R7,D6
RET
;************************************ 延时程序2 ********************************
DELAY2:
MOV R7,#50H
D7: LCALL DISPLAY2
DJNZ R7,D7
RET
;******************************** 数码管显示的字形表 ***************************
TAB1:DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H ;数字0~9,不带小数点"dp"
DB 40H,79H,24H,30H,19H,12H,02H,78H,00H,10H ;数字0~9,带小数点"dp"
;********************************** 音乐的节拍表 *******************************
TABLE: DB 82H,01H,81H,94H,84H,0B4H,0A4H,04H
DB 82H,01H,81H,94H,84H,0C4H,0B4H,04H
DB 82H,01H,81H,0F4H,0D4H,0B4H,0A4H,94H
DB 0E2H,01H,0E1H,0D4H,0B4H,0C4H,0B4H,04H
DB 82H,01H,81H,94H,84H,0B4H,0A4H,94H
DB 0E2H,01H,0E1H,0D4H,0B4H,0C4H,0B4H,04H
DB 82H,01H,81H,0F4H,0D4H,0B4H,0A4H,94H
DB 0E2H,01H,0E1H,0D4H,0B4H,0C4H,0B4H,04H
DB 00H
;*************************** 由音乐音符设置的T1计数值 **************************
TABLE1: DW 260,440,524,580,684,777,820,8 ;音符计数值
DW 968,65030,65058,65110,65157,65178,65217
END
七、实验过程
1:启动Keil,新建一个工程,然后选择芯片(Philips——P80/P87C52X2),设置工作环境,编写汇编语言程序,保存并添加至工程中,然后进行编译。
2:将P1.0、P1.1、P1.3、P1.4、P1.5、P1.6、P3.0、P3.1的跳线接相应的A位,P1.7的跳线接相应的C位,拔掉其它不用的跳线。插好电源,插好通信线,打开实验仪电源开关,在实验上将工作模式开关SX拨到“LOAD”一档,按下复位开头RESET,然后启动DPFlash,单击“编程”,在弹出的窗口中选中“编程MON51”,再按“确定”,就将程序装载到单片机的Flash中。
关闭DPFlash。
3:将实验台上的工作模式开关SX拨到“MON”位置,按下RESET复位开关,设置S0、S1、S3和S4的状态,再运行程序,拨动S0、S1、S3和S4对应的开头,检查电子时钟功能是否完整。多次调试、修改程序,直至能正常实现设计的功能为止。
下图为keil程序编译运行完的截图。
下图为DDFlash装载成功后的截图。
下图是任意设置的时间3:07的时候红色LED闪动做秒显示的对比效果截图:
八、实验总结
这次课程设计是对单片机课程所学知识的具体应用和学习效果检验,是软件与硬件的结合。在本次实验中,我遇到了很多问题,在一一解决之后我学到了很多东西,对知识的理解也更加深刻了。
通过本次实验,我重新复习了单片机的有关知识,做实验的时候几乎把课本翻了个遍,涉及到单片机结构原理、指令、定时器、中断、子程序调用、LED显示等等,几乎又复习了一遍课本。我对知识的认识有了一个质的提高,更深刻的认识到理论与实践之间的差距。
编写电子时钟程序时,我先上网搜集了相关资料,熟悉了一下类似实验的编程思想,也从中借鉴了一些好的做法,结合自己实验的要求来取舍,由于程序庞大,特别需要注意前后变量是否冲突,寄存器的使用是否合理等细节方面。在程序的编写过程中,经常遇到不是很确定的问题时就查找有关资料或者问同学。刚编写出程序时有几个错误,有标点符号的错误,有标号的错误,还有循环和跳转的错误等等。
通过程序的编写,我掌握了模块化设计程序的思想,通过电路板的调试,我可以把软件与硬件联系起来,认识到只有软件与硬件结合才能设计出简单实用的电路。以前也用数电的知识做过时钟电路,通过比较,可知用软件加硬件结合,能更加灵活的进行设计,调整和扩展也比较方便。在试验中,我也遇到了很多的问题,经过我的耐心调试之后,都一一解决了。
总之,通过这次实验,我对于单片机课程的理解和知识的掌握都得到了加深,这对我以后继续学习、科研都有很大的好处。