西安交大电信学院单片机实验报告

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

单片机实验报告
学院
系别
专业班级 XXXX班
报告人 XX
1
一、实验任务
在实验板上编程实现2012年日历和实时时钟:
1.时-分-秒(2位-2位-2位)显示。

可通过键盘置入时间值(参照电子表设置时间工作模式)。

2.可通过按键控制在LED上从右向左滚动显示年_月_日3次,如:
2012_01_20空空2012_01_20
3.实现每日闹铃提醒功能,闹铃时间可用按键设置。

闹铃采用提示音表示。

4.实现秒表功能。

5.实现定时器功能(预置定时时间,按键启动,倒计时,计到0响提示音。

6.设计实现音乐提示音。

7.设计串行通信程序,使两台实验系统同步显示。

二、硬件环境与软件控制原理
1、硬件环境
本次实验使用的单片机型号为51-MCU,它采用SST89E564RD作为仿真的核心芯片,通过串口与PC机连接。

外设包括使用SPI总线驱动的10位ADC、10位DAC,I2C总线驱动的E2PROM、日历时钟芯片,并行总线驱动的8位8段数码管、4*4键盘、外扩32KRAM(62256)、字符型LCD,单总线驱动的数字式温度传感器,基于TDA2822M放大MIC的音频功率放大器,555信号发生和整形电路,蜂鸣器,红外线发射和接收装置等模块。

SST89E564RD芯片的主要指标如下:
(1)支持KEIL C51的开发仿真环境,64K用户可使用仿真程序空间0000H~FFFFH。

(2)可仿真89C51、89C52等51内核单片机。

(3)仿真频率为0~40MHz晶振可选,系统配置11.0592MHz。

(4)程序代码可以重复装载,无需预先擦除用户程序空间。

(5)片内64K程序空间可以随时进行在线程序更新。

(6)支持汇编语言、C语言以及二者混合调试。

(7)支持同时最多10个断点。

(8)可单步、断点、全速、可参考变量、RAM变量。

并行总线器件:
(1)8位8段数码管都挂在总线上,数码管的位选地址为8FFFH,段选地址为9FFFH,段选和位选驱动均为高电平有效。

(2)4×4键盘复用了数码管的位选地址(8FFFH),写信号(/WR)控制行,读信号(/RD)控制列。

(3)62256是32K的数据存储器,有8条数据线(D0~D7),15条地址线(A0~A14)。

通过读、写线(/RD,/WR)及74HC00的组合控制单片机和62256之间的数据传送方向。

A15是62256的片选信号,A15为低电平的时候选择62256。

62256的地址空间范围是0000H~7FFFH。

I2C总线器件:
(1)AT24C02是带I2C总线接口的E2PROM存储器,具有掉电记忆功能,并能像普通RAM一样用程序改写,其容量是256B。

(2)PCF8563是一款低功耗的CMOS实时时钟/日历芯片,它提供一个可编程时钟输出,频率为:32.768KHz,1024Hz,32Hz,1Hz;一个中断输出(接在 INT1/P3.3);掉电检测器;报警和定时器。

2
CPU的引脚分布如图:
2、软件控制原理
单片微型计算机简称单片机,是典型的嵌入式微控制器(Microcontroller Unit)。

单片机由运算器,控制器,存储器,输入输出设备构成。

单片机是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计时器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的微型计算机系统,在工业控制领域的广泛应用。

从上世纪80年代,由当时的4位、8位单片机,发展到现在的32位300M的高速单片机。

8051由CPU、内部程序存储器ROM、内部寄存器RAM、可编程I/O端口、定时器/计数器、串行通信接口、中断系统、特殊功能寄存器、内部总线等部分构成。

(1)8051单片机中的CPU是8位微处理器,主要由运算器和控制器组成,其中包括振荡电路和时钟电路。

它决定了单片机的性能,是单片机的核心部件,主要完成运算和控制功能。

(2)程序存储器主要用于存放用户的应用程序,也可以存放一些原始数据和表格。

在其片外最大扩展寻址范围为64KB。

单片机片内包括ROM或EPROM存储器,而现在的单片机都进行了改进,采用Flash闪存作为程序存储器。

(3)8051片内包含128BRAM,用于存放单片机在运行期间需要保存的工作变量、中间结果或最终结果、数据暂存或缓冲、标志位等。

单片机片内数据存储器采用高速RAM的形式集成在单片机内部,提高了运行速度,降低了系统功耗。

(4)单片机设有四个8位双向并行I/O端口(P0、P1、P2、P3),每个端口都能按位编程设置,独立的用做输入或输出。

每个端口功能有所不同,但都包含8个位锁存器、8个驱动器和三态缓冲器。

P0口是一个三态双向端口,其字节地址为80H,位地址为80H~87H。

P0口可作为地址/数据分时复用总线,也可用做通用I/O口;P1是一个准双向端口,只能用作通用I/O 口,具有输入、输出、端口操作三种工作方式,其字节地址为90H,位地址为90H~97H;P2口字节地址为A0H,位地址为A0H~A7H,具有两种功能,一种作为通用I/O口使用,另一种作为扩展系统时的地址总线口输出高8位地址;P3口作为通用I/O口使用、可外接I/O设
3
备,也可作为第二功能输入口,其字节地址为B0H,位地址为B0H~B7H。

总之,四个并行口都有写端口操作、读端口操作、读-修改-写端口操作功能。

(5)定时器/计数器的核心是两个16位的加法计数器,可设置为计数方式对外部事件进行计数;也可设置为定时方式对标准时钟脉冲进行定时计时。

定时器/计数器0由两个8位的特殊功能寄存器TH0、TL0构成,定时器/计数器1由两个8位的特殊功能寄存器TH1、TL1构成。

当启动定时器/计数器工作时,计数器从THx、TLx中的初值开始计数。

特殊功能寄存器TMOD用于选择定时器/计数器0、1的工作模式和方式,TCON用于控制定时器/计数器0、1的启动和停止,同时还包含了定时器/计数器0、1的状态。

定时和计数范围可通过编程进行设定,一旦定时或计数到位就立即向CPU发出中断请求。

(6)单片机具有5个中断源,两级中断优先级,它可以接收外部中断请求、定时器/计数器中断请求和串行口中断请求,每一个中断源可以用软件独立地控制为开中或关中断状态。

中断响应过程为:置位中断触发器→PC入栈→中断服务程序入口地址入PC→执行中断服务程序→RETI(清零中断触发器,断点入PC)→返回原断点继续执行。

和中断系统相关的特殊功能寄存器有中断优先级控制寄存器IP、中断使能控制寄存器IE、定时/计数控制寄存器TCON、串行通信口控制寄存器SCON等。

电路图如下所示:
三、资源使用情况
对于C51系列单片机,其片内有4KB程序存储器(0000~0FFFH), /EA=1,单片机从片内0000H开始执行程序,片内程序执行完后会自动转到片外1000H开始执行。

4
对于片内128B的内部数据寄存器RAM,其编址为00~7FH;特殊功能寄存器(SFR)有128B,其编址为80~FFH。

单片机内部RAM块的00~1FH区是工作寄存器区,分四个组,每组包含八个工作寄存器R0~R7,用户可以通过指令改变PSW状态寄存器中RS1、RS0的值来选择要使用的工作寄存器组,多余的寄存器组所对应的地址单元可以作为一般数据缓冲区或堆栈区使用。

内部RAM的20H~2FH为位寻址区,这16个单元(128位)的每一位都有一个位地址,这16个单元构成了1位处理机的存储器空间。

内部RAM从30H~7FH是数据缓冲区,称为用户RAM区,共80个单元。

单片机至少有五个中断向量地址,规定在程序存储器0000~002FH地址之间有五个特殊地址被固定用于五个中断源的中断服务程序入口地址:外部中断0(0003H)、T0(000BH)、外部中断1(0013H)、T1(001BH)、串行口(0023H)。

当单片机复位后,程序存储器PC的内容为0000H,引导系统从0000H开始读取指令执行程序。

四、程序框图
1、时间调整模式
2、秒表模式
5
6
五、操作说明
单片机4*4矩阵键盘赋值如下:
(1) 单片机开启后,”,并开始计时。

(2)按下00键,进入时间调整模式,04、08、0C 键分别用于调整时、分、秒。

调整完毕,再次按下00键,退出时间调整模式,时钟开始计时。

(3)按下01键,LED 显示屏显示日期为“2013_03_09”,进入日期设定模式,04、08
键分别用于调整月、日,由于是2013年日历,故年份始终为2013。

另:0D 键用于日期滚动显示,日期以格式“XXXX_XX_X 空空”开始向左滚动,三遍后自动停止,恢复到滚动前的形式。

再次按下01键,退出日期设定模式,返回时钟功能。

此过程中,时钟一直在计时。

7
(4)按下02键,设置闹钟时间,04、08、0C 键分别用于设置时、分、秒,设置完毕,再按下0E 键,使单片机了解到此时已设置了闹钟,再按02键退出设置闹钟功能。

在设置闹钟时,时钟一直计时,当时钟时间到达闹钟时间时,闹铃“祝你生日快乐”响起,0F 键用于关掉正在响的闹钟。

(5)按下03键,进入秒表功能,秒表开始计时,07键用于秒表启动或暂停,0B 键用于秒表清零。

再次按下03键,退出秒表功能,返回时钟功能。

此过程中,时钟一直计时。

(6)按下0A 键,用于设定定时器,04、08、0C 键分别用于设定时、分、秒,设置完毕,按下0E 键,定时器开始倒计时,当倒计时结束时,蜂鸣器开启,“祝你生日快乐”的提示音响起。

按下0A 键,退出定时器功能,返回时钟功能。

设置及倒计时过程中,时钟一直计时。

六、调试与运作情况
操作步骤:
打开Keil ,选择Project-New project ,新建工程并保存,在弹出的对话框中,选择单片机型号SST89E564RD,点击确定。

点击File-New ,新建源程序文件,编辑单片机程序,保存为.asm 后缀的文件(汇编语言),另存到工程文件中。

选择Options for Target-Target1,修改参数,Debug 选项选择硬件仿真,Settings 选项中设置合适的端口,点击OK ,确定。

编译程序,发现错误,改正错误或者改进后,重复以上个步骤。

调试成功后,下载程序,点击运行,开始操作单片学习系统,通过按键,设置时间、日期等,验证各项功能是否能实现。

程序调试结果如下:
运作情况:调试后程序没有错误,可以正常运行,能实现实验任务要求的各项功能(第7项未做)。

验收时老师要求改动了两处小问题,一是闹铃响起时时钟仍然要保持计时,二是增加整点报时功能,整点报时是利用和闹钟相似的原理实现的,唯一的问题是一开始不清楚怎样实现几点钟报几下的功能。

此外,由于蜂鸣器是固定频率发声的,而音乐的频率范围较宽,所以蜂鸣器输出的音乐和预期有一定的差距。

七、心得体会
通过本次实验,我初步学会了Keil软件的使用,了解了单片机的构造、基本原理和功能实现,掌握了汇编语言编程在单片机方面的具体应用。

给我留下深刻印象的是要合理安排寄存器、分配内存,注意中断的使用以及模块化编程对于复杂程序的重要性。

在实验中,发现了自身存在的单片机知识的欠缺以及初次接触汇编语言编程时的种种问题,借助了图书馆以及网络查阅资料,得到了老师的悉心指导和同学的热心帮助,使我获益匪浅。

附录(本次实验的程序)
ORG 0000H
JMP MAIN
ORG 000BH
JMP TIM0
ORG 001BH
JMP TIM1
;初始程序段,定义,使能中断、装载计数初始值、设定各变量初始值
ORG 0030H
CLK EQU 00H ;用于标记闹钟状态,0为关,1为开
FLAG EQU 01H ;FLAG=1时Timer1中断服务子程序跳到秒表中断服务处;FLAG=0时Timer1中断服务子程序跳到音乐中断服务处
JS EQU 04H ;用于定时器计时
N EQU 22H ;Timer0的中断计数器
NN EQU 23H ;Timer1的中断计数器,用于定时器
SEC EQU 30H
MIN EQU 31H
HOUR EQU 32H ;秒、分、时的寄存器
DAY EQU 33H
MONTH EQU 34H
YEARL EQU 35H
YEARH EQU 36H ;年、月、日的寄存器
ALSEC EQU 37H
ALMIN EQU 38H
ALHOUR EQU 39H ;闹铃秒、分、时的寄存器
D_SEC EQU 3AH ;定时器秒、分、时的寄存器
D_MIN EQU 3BH
D_HOUR EQU 3CH
STOP_MS EQU 3DH ;秒表
STOP_S EQU 3EH
STOP_MIN EQU 3FH
8
LED1 EQU 50H ;8个数码管
LED2 EQU 51H
LED3 EQU 52H
LED4 EQU 53H
LED5 EQU 54H
LED6 EQU 55H
LED7 EQU 56H
LED8 EQU 57H
TEMP1 EQU 58H
TEMP2 EQU 59H
TEMP3 EQU 5AH
TEMP4 EQU 5BH
TEMP5 EQU 5CH
TEMP6 EQU 5DH
TEMP7 EQU 5EH
TEMP8 EQU 5FH
TEMP9 EQU 60H ;用于滚动显示时的寄存器
TEMP10 EQU 61H
TEMP11 EQU 62H
TEMP12 EQU 63H
/***************************主程序循环区**********************************/
MAIN:
MOV IE,#82H
MOV TMOD,#01H
MOV TH0,#0F1H ;模式1,装载计数初始值,约4ms中断一次
MOV TL0,#0A4H
MOV N,#00H
MOV SP,#70H ;重设堆栈指针
CLR CLK
MOV N,#00
MOV NN,#00
CLR FLAG
CLR JS
MOV SEC,#00 ;时间
MOV MIN,#00
MOV HOUR,#08
MOV ALSEC,#30 ;闹钟
MOV ALMIN,#00
9
MOV ALHOUR,#08
MOV D_SEC,#00 ;定时器的值
MOV D_MIN,#00
MOV D_HOUR,#00
MOV DAY,#09 ;日期
MOV MONTH,#03
MOV YEARL,#13
MOV YEARH,#20
SETB TR0
LOOP:
CALL TRANS ;将要显示的数字转换成数码管的段码
CALL LED_DISP ;调用显示子程序
CALL ALARM_CLK ;调用闹钟检测子程序
CALL SW ;调用按键检测子程序
CJNE A,#00H,MOD1
CALL SET_TIME
JMP LOOP ;00键用于设定时间
MOD1:
CJNE A,#01H,MOD2
CALL SET_DATE ;01键用于设定日期
JMP LOOP
MOD2: ;设置闹铃时间
CJNE A,#0DH,MOD3
CALL DATE_DISP ;0D键用于日期滚动显示
JMP LOOP
MOD3:
CJNE A,#02H,MOD4
CALL SET_CLOCK ;02键用于设定闹钟时间
JMP LOOP
MOD4:
CJNE A,#03H,MOD5
SETB FLAG
CALL STOPWATCH ;03键用于进入秒表功能
CLR FLAG
JMP LOOP
MOD5:
CJNE A,#0AH,MOD6
CALL DINGSHI ;0A键用于设定定时器
JMP LOOP
MOD6:
10
JMP LOOP
/*Timer0的中断服务子程序:*/ TIM0:
PUSH ACC
INC N ;加1
MOV A,N
CJNE A,#250,RET_1
MOV N,#0
INC SEC ;秒计数加1
MOV A,SEC
CJNE A,#60,RET_1 ;是否到1min
MOV SEC,#00
INC MIN ;分计数加1
MOV A,MIN
CJNE A,#60,RET_1 ;是否到1h
MOV MIN,#00
INC HOUR ;时计数加1
MOV A,HOUR
CJNE A,#24,RET_1 ;是否到1天
INC DAY ;天计数加1
MOV HOUR,#00
MOV DPTR,#MONTHTAB
MOV A,MONTH
MOVC A,@A+DPTR
MOV B,DAY
CJNE A,B,RET_1 ;是否到1月
INC MONTH ;月计数加1
MOV DAY,#01
MOV A,MONTH
CJNE A,#13,RET_1 ;是否到1年
MOV YEARL,#12
MOV YEARH,#20
MOV SEC,#00
MOV MIN,#00
MOV HOUR,#00
MOV DAY,#01
MOV MONTH,#01
RET_1:
MOV TL0,#0A4H
MOV TH0,#0F1H
POP ACC
RETI
/*将要显示的时间数字转换成数码管段码*/
TRANS:
MOV DPTR,#TABLE
MOV A,SEC
MOV B,#10
DIV AB ;ACC中存放秒的高位,B中存放秒的低位MOVC A,@A+DPTR ;读取程序存储器地址中的数据传送给A MOV LED2,A
MOV A,B
MOVC A,@A+DPTR
MOV LED1,A
MOV A,MIN
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV LED5,A
MOV A,B
MOVC A,@A+DPTR
MOV LED4,A
MOV A,HOUR
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV LED8,A
MOV A,B
MOVC A,@A+DPTR
MOV LED7,A
MOV LED3,#40H
MOV LED6,#40H
RET
/*数码管显示*/
LED_DISP:
PUSH 00H
PUSH 02H
PUSH 03H
MOV R0,#LED1
MOV R3,#8
MOV A,#00H
MOV R2,#01H
LED_LOOP:
MOV DPTR,#9000H
MOV A,@R0
INC R0
MOVX @DPTR,A ;把A的内容传送到16位的地址寄存器中MOV DPTR,#8000H
MOV A,R2
MOVX @DPTR,A
RL A ;A的各位依次左移一位
MOV R2,A
CALL DELAY ;延时1ms
DJNZ R3,LED_LOOP
POP 03H
POP 02H
POP 00H
RET
/**设定时间**/
SET_TIME:
CLR TR0
ST0: CALL TRANS
CALL LED_DISP
CALL SW
CJNE A,#0CH,ST1
INC SEC ;调节秒
MOV A,SEC
CJNE A,#60,ST0
MOV SEC,#00
JMP ST0
ST1: CJNE A,#08H,ST2
INC MIN ;调节分
MOV A,MIN
CJNE A,#60,ST0
MOV MIN,#00
JMP ST0
ST2: CJNE A,#04H,ST3
INC HOUR ;调节时
MOV A,HOUR
CJNE A,#24,ST0
MOV HOUR,#00
JMP ST0
ST3: CJNE A,#00H,ST0
JMP RET_2
RET_2: SETB TR0
RET
/***************************按键检测**********************************/
SW:
MOV DPTR,#9000H ;先使所有数码管熄灭
MOV A,#00H
MOVX @DPTR,A
CALL KAP
JNZ KP1
JMP END_SW
KP1: CALL DELAY
CALL KAP
JNZ KP2 ;扫描
JMP END_SW
KP2:
MOV R2,#01H ;R2代表扫描的行数
MOV R3,#00H
MOV A,R2
KP4: MOVX @DPTR,A
MOVX A,@DPTR
JNB ACC.0,L1 ;第0列为0则检查第1列
MOV A,#00H
JMP KP5
L1: JNB ACC.1,L2 ;第1列为0则检查第2列
MOV A,#04H
JMP KP5
L2: JNB ACC.2,L3 ;第2列为0则检查第3列
MOV A,#08H
JMP KP5
L3: JNB ACC.3,NEXT
MOV A,#0CH
KP5: ADD A,R3
PUSH ACC ;对应的键盘编号为(0 4 8 C)KP3: CALL DELAY ; 1 5 9 D CALL KAP ; 2 6 A E JNZ KP3 ; 3 7 B F POP ACC
RET
NEXT: INC R3 ;扫描下一行
MOV A,R2
JB ACC.3,END_SW ; 判断扫描是否结束,即当ACC.3=0时,各列均已扫描过RL A
MOV R2,A
JMP KP4
END_SW:
MOV A,#010H ;没有按键按下时,ACC的值为10H
RET
KAP:
MOV DPTR,#8000H
MOV A,#0FH
MOVX @DPTR,A
MOVX A,@DPTR
ANL A,#0FH
RET
/***************************设定日期**********************************/
SET_DATE:
SD0:
CALL TRANS1
CALL LED_DISP
CALL SW
CJNE A,#0CH,SD1
INC DAY ;调节日
MOV DPTR,#MONTHTAB
MOV A,MONTH
MOVC A,@A+DPTR
MOV B,DAY
CJNE A,B,SD0
MOV DAY,#01
JMP SD0
SD1: CJNE A,#08H,SD2
INC MONTH ;调节月
MOV A,MONTH
CJNE A,#13,SD0
MOV MONTH,#01
JMP SD0
SD2: CJNE A,#04H,SD3
MOV YEARH,#20 ;调节年,2013年日历,故年份始终为2013
MOV YEARL,#13
JMP SD0
SD3: CJNE A,#01H,SD0
JMP RET_3
RET_3: RET
/***************************将要显示的日期转换成数码管的段码**********************************/
TRANS1:
MOV DPTR,#TABLE
MOV A,DAY
MOV B,#10
DIV AB ;ACC中存放日的高位,B中存放日的低位
MOVC A,@A+DPTR
MOV LED2,A
MOV A,B
MOVC A,@A+DPTR
MOV LED1,A
MOV A,MONTH
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV LED4,A
MOV A,B
MOVC A,@A+DPTR
MOV LED3,A
MOV A,YEARL
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV LED6,A
MOV A,B
MOVC A,@A+DPTR
MOV LED5,A
MOV A,YEARH
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV LED8,A
MOV A,B
MOVC A,@A+DPTR
MOV LED7,A
RET
/*************************** 日期滚动显示**********************************/ DATE_DISP:
MOV DPTR,#TABLE
MOV A,YEARH
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV TEMP1,A
MOV A,B
MOVC A,@A+DPTR
MOV TEMP2,A
MOV A,YEARL
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV TEMP3,A
MOV A,B
MOVC A,@A+DPTR
MOV TEMP4,A
MOV TEMP5,#40H
MOV A,MONTH
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV TEMP6,A
MOV A,B
MOVC A,@A+DPTR
MOV TEMP7,A
MOV TEMP8,#40H
MOV A,DAY
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV TEMP9,A
MOV A,B
MOVC A,@A+DPTR
MOV TEMP10,A
MOV TEMP11,#00
MOV TEMP12,#00 ;Temp1~12中依次存放日期(如2013-03-09空空)
MOV LED1,#00
MOV LED2,#00
MOV LED3,#00
MOV LED4,#00
MOV LED5,#00
MOV LED6,#00
MOV LED7,#00
MOV 64H,#03 ;循环显示3次
DD1: MOV R1,#TEMP1
MOV R4,#12 ;将12个Temp中的数字显示完
DD2: MOV R5,#2FH ;R5用来延时
MOV LED8,LED7
MOV LED7,LED6
MOV LED6,LED5
MOV LED5,LED4
MOV LED4,LED3
MOV LED3,LED2
MOV LED2,LED1
MOV LED1,@R1
DD3: CALL LED_DISP
CALL SW
CJNE A,#0DH,KEEP
KEEP: DJNZ R5,DD3
INC R1
DJNZ R4,DD2
DJNZ 64H,DD1
/***************************将要显示的闹钟设定时间转换成数码管的段码**********************************/
TRANS2:
MOV DPTR,#TABLE
MOV A,ALSEC
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV LED2,A
MOV A,B
MOVC A,@A+DPTR
MOV LED1,A
MOV A,ALMIN
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV LED5,A
MOV A,B
MOVC A,@A+DPTR
MOV LED4,A
MOV A,ALHOUR
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV LED8,A
MOV A,B
MOVC A,@A+DPTR
MOV LED7,A
JB CLK,TR_1
MOV LED3,#08H
MOV LED6,#08H
JMP RET_5
TR_1: MOV LED3,#80H
MOV LED6,#80H ;闹钟开着时,LED3和LED6显示.闹钟取消时,显示_ RET_5:
RET
/***************************设定闹钟时间**********************************/
SET_CLOCK:
SC0: CALL TRANS2
CALL LED_DISP
CALL SW
CJNE A,#0CH,SC1
INC ALSEC ;调节秒
MOV A,ALSEC
CJNE A,#60,SC0
MOV ALSEC,#00
JMP SC0
SC1: CJNE A,#08H,SC2
INC ALMIN ;调节分
MOV A,ALMIN
CJNE A,#60,SC0
MOV ALMIN,#00
JMP SC0
SC2: CJNE A,#04H,SC3
INC ALHOUR ;调节时
MOV A,ALHOUR
CJNE A,#24,SC0
MOV ALHOUR,#00
JMP SC0
SC3: CJNE A,#02H,SC4
JMP RET_6
SC4: CJNE A,#0EH,SC0
CPL CLK
JMP SC0
RET_6:
RET
/***************************检查闹钟是否到点**********************************/ ALARM_CLK:
JNB CLK,RET_7
MOV A,SEC ;检查秒
CJNE A,ALSEC,RET_7
MOV A,MIN ;检查分
CJNE A,ALMIN,RET_7
MOV A,HOUR ;检查时
CJNE A,ALHOUR,RET_7
CALL MUSIC
RET_7:
RET
/**************************检查是否整点******************************/ ZHENGDIAN:
JNB CLK,RET_16
MOV A,SEC
CJNE A,#00H,RET_16
MOV A,MIN
CJNE A.#00H,RET_16
MOV A,HOUR
CJNE A,#0AH,RET_17
CALL MUSIC
RET_16:
RET
/***************************音乐**********************************/
MUSIC:
MOV TMOD,#11H ;Timer1,Timer0工作在模式1
MOV IE,#8AH ;使能Timer0和Timer1
MOV 65H,#00H ;递增的指针寄存器
MOV DPTR,#MUSICTAB
LOOP1:
MOV DPTR,#MUSICTAB
MOV A,65H
MOVC A,@A+DPTR
MOV R4,A ;R4中存放音调的高八位
INC 65H
MOV A,65H
MOVC A,@A+DPTR
MOV R5,A ;R5中存放音调的低八位
JZ RET_8 ;全0为乐曲结束符
MUSIC1:
MOV TH1,R4
MOV TL1,R5
SETB TR1
INC 65H
MOV A,65H
MOVC A,@A+DPTR
MOV R1,A ;R1中存放节拍信息
MUSIC2:
CALL DLY5ms
CALL TRANS
CALL LED_DISP
CALL SW
CJNE A,#0FH,MUSIC3 ;0F键用于关掉正在响的闹钟
JMP RET_8
MUSIC3: DJNZ R1,MUSIC2
INC 65H
JMP LOOP1
RET_8:
CLR TR1
SETB P1.6
RET
/***************************音乐**********************************/ MUSIC5:
MOV TMOD,#11H ;Timer1,Timer0工作在模式1
MOV IE,#8AH ;使能Timer0和Timer1
MOV 65H,#00H ;递增的指针寄存器
MOV DPTR,#MUSICTAB
LOOP2:
MOV DPTR,#MUSICTAB
MOV A,65H
MOVC A,@A+DPTR
MOV R4,A ;R4中存放音调的高八位
INC 65H
MOV A,65H
MOVC A,@A+DPTR
MOV R5,A ;R5中存放音调的低八位
JZ RET_8 ;全0为乐曲结束符
MUSIC6:
MOV TH1,R4
MOV TL1,R5
SETB TR1
INC 65H
MOV A,65H
MOVC A,@A+DPTR
MOV R1,A ;R1中存放节拍信息
MUSIC7:
CALL DLY5ms
; CALL TRANS
; CALL LED_DISP
CALL SW
CJNE A,#0FH,MUSIC8 ;0F键用于关掉正在响的闹钟
JMP RET_31
MUSIC8: DJNZ R1,MUSIC7
INC 65H
JMP LOOP1
RET_31:
CLR TR1
SETB P1.6
RET
/***************************Timer1中断服务子程序**********************************/ TIM1:
; JB FLAG2,DSQ ;DSQ用于定时器
JB FLAG,STOP
MOV TH1,R4 ;用于音乐
MOV TL1,R5
CPL P1.6
JMP RET_11
STOP: PUSH ACC ;STOP用于秒表
INC STOP_MS
MOV A,STOP_MS
CJNE A,#100,RET_9 ;是否到1S
MOV STOP_MS,#00
INC STOP_S
MOV A,STOP_S
CJNE A,#60,RET_9 ;是否到1MIN
MOV STOP_S,#00
INC STOP_MIN
MOV A,STOP_MIN
CJNE A,#60,RET_9
MOV STOP_MIN,#00
RET_9:
MOV TL1,#0FFH
MOV TH1,#0DBH
POP ACC
JMP RET_11
RET_11:
RETI
/***************************秒表程序**********************************/ STOPWATCH:
MOV TMOD,#11H ;Timer1,Timer0工作在模式1
MOV IE,#8AH ;使能Timer0和Timer1
MOV TH1,#0DBH
MOV TL1,#0FFH ;10ms中断一次
MOV STOP_MS,#00
MOV STOP_S,#00
MOV STOP_MIN,#00
W0: CALL TRANS3
CALL LED_DISP
CALL SW
CJNE A,#07H,W1 ;07键用于秒表启动/暂停
W0_2: SETB TR1
W0_1:
CALL TRANS3
CALL LED_DISP
CALL SW
CJNE A,#07H,W0_1
JMP PAUSE
W1: CJNE A,#0BH,W2 ;0B键用于秒表清零
MOV STOP_MS,#00
MOV STOP_S,#00
MOV STOP_MIN,#00
JMP W0
W2: CJNE A,#03H,W0
JMP RET_10
PAUSE: CLR TR1
CALL TRANS3
CALL LED_DISP
CALL SW
CJNE A,#07H,W1
JMP W0_2
RET_10: CLR TR1
RET
/***************************将要显示的秒表数字转换成数码管段码**********************************/
TRANS3:
MOV DPTR,#TABLE
MOV A,STOP_MS
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV LED2,A
MOV A,B
MOVC A,@A+DPTR
MOV LED1,A
MOV A,STOP_S
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV LED5,A
MOV A,B
MOVC A,@A+DPTR
MOV LED4,A
MOV A,STOP_MIN
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV LED8,A
MOV A,B
MOVC A,@A+DPTR
MOV LED7,A
MOV LED3,#40H
MOV LED6,#40H
RET
/***************************将要显示的定时器设定时间转换成数码管的段码**********************************/
TRANS4:
MOV DPTR,#TABLE
MOV A,D_SEC
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV LED2,A
MOV A,B
MOVC A,@A+DPTR
MOV LED1,A
MOV A,D_MIN
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV LED5,A
MOV A,B
MOVC A,@A+DPTR
MOV LED4,A
MOV A,D_HOUR
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV LED8,A
MOV A,B
MOVC A,@A+DPTR
MOV LED7,A
TK_1: MOV LED3,#40H
MOV LED6,#40H ;定时器开着时,LED3和LED6显示_ RET_13:
RET
/***************************设定定时器时间**********************************/ SET_DING:
SI0: CALL TRANS4
CALL LED_DISP
CALL SW
CJNE A,#0CH,SI1
INC D_SEC ;调节秒
MOV A,D_SEC
CJNE A,#60,SI0
MOV D_SEC,#00
JMP SI0
SI1: CJNE A,#08H,SI2
INC D_MIN ;调节分
MOV A,D_MIN
CJNE A,#60,SI0
MOV D_MIN,#00
JMP SI0
SI2: CJNE A,#04H,SI3
INC D_HOUR ;调节时
MOV A,D_HOUR
CJNE A,#24,SI0
MOV D_HOUR,#00
JMP SI0
SI3: CJNE A,#0EH,SI4
SETB JS
JMP RRET
SI4: CJNE A,#06H,SI0
RRET: RET
/***************************定时器程序**********************************/ DINGSHI:
CALL SET_DING
DG: JNB JS,RET_12
CALL DLY
CALL JISHI
CALL TRANS4
CALL LED_DISP
CALL SW
CJNE A,#06H,DG
JMP RET_12
RET_12:
MOV D_SEC,#00 ;定时器的值
MOV D_MIN,#00
MOV D_HOUR,#00
RET
/***************************定时器计时程序**********************************/ JISHI:
INC NN ;加1
MOV A,NN
CJNE A,#100,RET_14 ;是否到1s
MOV NN,#0
MOV A,D_SEC
CJNE A,#00,DSQ0
JMP DSQ1
DSQ0: DEC D_SEC ;秒计数减1
MOV A,D_SEC
CJNE A,#00,RET_14 ;是否到1min MOV D_SEC,#00
JMP RET_14
DSQ1: MOV A,D_MIN
ORL A,D_HOUR
JZ RET_15
MOV D_SEC,#59
MOV A,D_MIN
CJNE A,#00,DSQ2
JMP DSQ3
DSQ2: DEC D_MIN ;分计数减1 MOV A,D_MIN
CJNE A,#00,RET_14 ;是否到1h
MOV D_MIN,#00
JMP RET_14
DSQ3: ORL A,D_HOUR
JZ RET_15
MOV D_MIN,#59
DEC D_HOUR ;时计数减1
MOV A,D_HOUR
JMP RET_14
RET_15: CALL MUSIC5
CLR JS
RET_14: RET
DLY: ;用于定时器
MOV R6,#20
DL3: MOV R7,#14
DJNZ R7,$
DJNZ R6,DL3
RET
DLY5ms: ;5ms延时
MOV R6,#20
DL2: MOV R7,#120
DJNZ R7,$
DJNZ R6,DL2
RET
DELAY: ;1ms延时
MOV R6,#4
D1: MOV R7,#130
DJNZ R7,$
DJNZ R6,D1
RET
TABLE:
DB 3FH,06H,5BH,4FH,66H ;0~9
DB 6DH,7DH,07H,7FH,6FH
MONTHTAB:
DB 0,32,29,32,31,32,31
DB 32,32,31,32,31,32
MUSICTAB: ;祝你生日快乐DB 0FDH,82H,20,0FDH,82H,20,0FDH,0C8H,20,0FDH,82H,20,0FEH,22H,20,0FEH,06H,20 DB 0FDH,82H,20,0FDH,82H,20,0FDH,0C8H,20,0FDH,82H,20,0FEH,4FH,20,0FEH,22H,20 DB
0FDH,82H,20,0FDH,82H,20,0FEH,0C1H,20,0FEH,85H,20,0FEH,22H,20,0FEH,06H,40,0FDH,0C8H,40 DB 0FEH,9AH,20,0FEH,9AH,20,0FEH,85H,20,0FEH,22H,20,0FEH,4FH,20,0FEH,22H,20 DB 0FDH,82H,20,0FDH,82H,20,0FDH,0C8H,20,0FDH,82H,20,0FEH,22H,20,0FEH,06H,20 DB 0FDH,82H,20,0FDH,82H,20,0FDH,0C8H,20,0FDH,82H,20,0FEH,4FH,20,0FEH,22H,20 DB
0FDH,82H,20,0FDH,82H,20,0FEH,0C1H,20,0FEH,85H,20,0FEH,22H,20,0FEH,06H,40,0FDH,0C8H,40 DB 0FEH,9AH,20,0FEH,9AH,20,0FEH,85H,20,0FEH,22H,20,0FEH,4FH,20,0FEH,22H,20 DB 00H,00H
MUSICTAB1:
DB 0FEH,22H,10
MUSICTAB2:
DB 0FEH,22H,40
END。

相关文档
最新文档