📄 file12.lst
字号:
PAGE 1
1: ;多功能数字钟,可以设置时/分,不能设置秒
2: ;准点报时。定时报时等
3: ;现象,程序下载完成以后,数码显示000000,同时,最后两个数码管开始显示
4: ;秒,同时,有两个led指示灯按照每秒一次的闪烁,
5: ;用户可以利用三个按键来输入时/分,左边第一个输入时,中间的那个输入分
6: ;第三个用来切换,输入时的增/减,按一次第三个按键,程序自动设置成
7: ;增加/减少方式,比如我们在输入时的时候,应该输入12,结果输入了13,那
8: ;我们只要按一次最右边的那个按键(模式设置),然后按最左边的这个(设置时)
9: ;就可以调整为12了,分的设置也一样!
10: ;每到正点都会发出短鸣,到了12:00会发出特殊的定时蜂鸣!
11:
12: B B7 beep bit p3.7 ;蜂鸣器定义
13:
14: D 0080 segdata equ p0 ;数据 输出
15: B 00A7 sege equ p2.7 ;显示 选中
16: B 00A6 segb equ p2.6 ;位 选
17: B 00A5 segd equ p2.5 ;段 选
18:
19: B B5 key1 bit p3.5 ;按键定义
20: B B4 key2 bit p3.4
21: B B3 key3 bit p3.3
22: N 0056 key equ 56h
23:
24: N 0057 time_h equ 57h ;定时初值高位
25: N 0058 time_l equ 58h ;低位
26:
27: N 0060 t_h equ 60h ;时分秒对应的地址
28: N 0061 t_s equ 61h
29: N 0062 t_m equ 62h
30: N 0063 time equ 63h ;时钟计数单元
31: N 0064 timer_h equ 64h ;定时时单元
32: N 0065 timer_m equ 65h ;定时分单元
33:
34: N 00 timset bit 00h ;设置时间标志
35:
36: N 0070 disstart equ 70h ;显示单元首地址
37:
38: N 0045 int_data equ 45h ;中断数据地址
39: N 0044 count_data equ 44h ;计数单元地址
40: N 0043 timer_data equ 43h ;定时地址
41:
42: ; ************** 以上为预定义部分
43:
44: ; ************** 以下程序开始
45:
46: N 0000 org 00h ; 程序开始地址
47: 0000 02 00 30 jmp main ; 跳转到代码开始处
48:
49: N 001B org 1bh ; 定时器 T1 中断服务程序入口
50: 001B 02 00 66 jmp tim1
51:
52:
53: N 0030 org 030h ;主程序开始的地址 30H
54: 0030 75 81 30 main:mov sp,#30h ;首先定义堆栈
55: 0033 12 00 47 lcall rest ;初始化
56: 0036 12 00 81 lcall pro_set ;设置定时器开始工作
PAGE 2
57: 0039 12 01 2E lpp: lcall time_set ;接受用户设置时间
58: 003C 12 00 9A lcall timer ;时钟处理
59: 003F 12 00 FA lcall time_pro ;时间格式处理,码型变化等
60: 0042 12 00 DA lcall time_display ;显示
61: 0045 80 F2 jmp lpp
62: ; ************* 初始化程序 ***************************
63: 0047 74 00 rest: mov a,#00h ;累加器清零
64: 0049 75 F0 00 mov b,#00h
65: 004C 75 80 00 mov p0,#0 ;数码管禁止显示
66: 004F 75 60 00 mov t_h,#0 ;时单元
67: 0052 75 62 00 mov t_m,#0 ;分单元
68: 0055 75 61 00 mov t_s,#0 ;秒单元
69: 0058 75 63 00 mov time,#00h ;计数溢出次数,溢出20次为一秒
70: 005B C2 00 clr timset ;定时设置标志位,0->增加 1 ->减少
71: 005D 75 64 0C mov timer_h,#12 ;定时器时单元,设置定时为 12:00
72: 0060 75 65 00 mov timer_m,#00h ;定时器分单元
73: 0063 C2 B7 clr beep ;禁止蜂鸣器
74: 0065 22 ret ;返回
75:
76: ; *************** 定时器 T1 中断服务程序 ****
77: 0066 C2 8E tim1: clr tr1 ;首先停止定时操作
78: 0068 85 57 8D mov th1,time_h ;
79: 006B 85 58 8B mov tl1,time_l
80: 006E 05 63 inc time ;自增
81: 0070 E5 63 mov a,time ;取得溢出次数
82: 0072 B4 14 09 cjne a,#20,retend ;如果满20此表示到 1 秒
83: 0075 B2 90 cpl p1.0 ;取反p1.0,p1.1指示秒钟
84: 0077 B2 91 cpl p1.1
85: 0079 75 63 00 mov time,#00h ;重新开始等待1秒
86: 007C 05 61 inc t_s ;秒单元加1
87: 007E D2 8E retend: setb tr1 ;定时开始
88: 0080 32 reti ;中断返回
89:
90: ; ***************** 设置定时器初始化,定时时间为 50ms ****
91: 0081 90 00 00 pro_set:mov dptr,#0000h ;数据指针清零
92: 0084 75 89 10 mov tmod,#10h ;设置定时器1工作在方式1
93: 0087 75 57 3C mov time_h,#3ch ;计算定时50ms需要的初值
94: 008A 85 57 8D mov th1,time_h ;保存高位
95: 008D 75 58 C1 mov time_l,#0c1h ;低位
96: 0090 85 58 8B mov tl1,time_l ;保存低位
97: 0093 D2 AF setb ea ;总的中断允许
98: 0095 D2 AB setb et1 ;定时器1允许
99: 0097 D2 8E setb tr1 ;定时器1开始运行
100: 0099 22 ret ;返回
101:
102: ; ****************** timer 程序主要完成数据的处理 **********
103:
104: 009A E5 61 timer: mov a,t_s ;取得秒单元数据
105: 009C B4 3C 3A cjne a,#60,tend ;秒不到60返回
106: 009F 75 61 00 mov t_s,#00h ;清除秒单元
107: 00A2 05 62 inc t_m ;为分单元加1
108: 00A4 E5 62 mov a,t_m ;取得分单元数据
109: 00A6 B4 3C 30 cjne a,#60,tend ;分不等于60返回
110: 00A9 75 62 00 mov t_m,#00h ;分单元清零
111: 00AC D2 B7 setb beep ;整点短鸣提示
112: 00AE 12 01 92 lcall delay ;鸣叫延时
113: 00B1 C2 B7 clr beep ;停止蜂鸣器
114: 00B3 05 60 inc t_h ;同时为时单元加1
PAGE 3
115: 00B5 E5 60 mov a,t_h ;取得时单元数据
116: 00B7 B4 18 06 cjne a,#24,timetest ;如果不等于24,查看定时
117: 00BA 75 60 00 mov t_h,#00h ;时单元清零
118: 00BD 02 00 D9 jmp tend ;返回
119:
120: 00C0 B5 64 16 timetest:cjne a,timer_h,tend ;不等于定时的时单元,返回
121: 00C3 E5 62 mov a,t_m ;取得定时的分单元
122: 00C5 B5 65 11 cjne a,timer_m,tend ;当前分不等于定时的分单元,返回
123: 00C8 D2 B7 setb beep ;定时到,蜂鸣提示
124: 00CA 12 01 92 lcall delay
125: 00CD C2 B7 clr beep
126: 00CF 12 01 92 lcall delay
127: 00D2 D2 B7 setb beep
128: 00D4 12 01 92 lcall delay
129: 00D7 C2 B7 clr beep ;连续发出短音提示
130: 00D9 22 tend: ret ;返回
131:
132: ; ************ time_display 程序主要为显示时间值用 *************
133:
134: 00DA 78 70 time_display:mov r0,#disstart ;取得显示单元首地址
135: 00DC 79 01 mov r1,#01h ;从第一个数码管开始
136: 00DE 7A 06 mov r2,#06h ;共6个数码管
137: 00E0 C2 A7 clr sege ;显示选中
138: 00E2 86 80 dislp:mov segdata,@r0 ;获得当前单元数据
139: 00E4 D2 A5 setb segd
140: 00E6 00 nop
141: 00E7 C2 A5 clr segd
142: 00E9 08 inc r0 ;指向下一个单元
143: 00EA 89 80 mov segdata,r1 ;数码显示
144: 00EC D2 A6 setb segb
145: 00EE 00 nop
146: 00EF C2 A6 clr segb
147:
148: 00F1 E9 mov a,r1 ;为下一个数准备
149: 00F2 23 rl a ;下一个单元
150: 00F3 F9 mov r1,a ;保存
151: 00F4 12 01 F2 lcall delay3ms ;为了保证数码管亮度,
152: ;但要防止闪烁,延时3ms
153:
154: 00F7 DA E9 djnz r2,dislp ;重复显示,直到全部数据刷新过
155: 00F9 22 ret ;返回
156:
157: ; ******* time_pro 时间处理,主要为 bcd码转换,查表 ***********
158: 00FA 12 01 0B time_pro: lcall bcd ;BCD码转换
159: 00FD 78 70 mov r0,#disstart ;获得显示单元首地址
160: 00FF 7A 06 mov r2,#06h ;需要转换的个数
161: 0101 E6 prlp:mov a,@r0 ;取得当前需要转换的数据
162: 0102 90 02 05 mov dptr,#tab_nu ;获得表头
163: 0105 93 movc a,@a+dptr ;获得转换后的数据
164: 0106 F6 mov @r0,a ;存回去
165: 0107 08 inc r0 ;指向下一个
166: 0108 DA F7 djnz r2,prlp ;重复转换,直到6个全部完成
167: 010A 22 ret ;返回
168:
169: ; **************** 码型变换 ****************************************
170: 010B 78 70 bcd: mov r0,#disstart ;获得首地址
171: 010D E5 61 mov a,t_s ;获得待转化的低位
172: 010F 75 F0 0A mov b,#10 ;转化进制,如果要进行十进制转换 改为 10
PAGE 4
173: 0112 84 div ab ;计算 A/B
174: 0113 A6 F0 mov @r0,b ;第一位转换完毕,保存低位转化后的数据
175: 0115 08 inc r0 ;自增
176: 0116 F6 mov @r0,a ;保存高位
177: 0117 08 inc r0 ;取第二个数据地址
178: 0118 E5 62 mov a,t_m ;获得第二个需要转换的数据
179: 011A 75 F0 0A mov b,#10 ;十六进制
180: 011D 84 div ab ;计算
181: 011E A6 F0 mov @r0,b ;存低位
182: 0120 08 inc r0
183: 0121 F6 mov @r0,a ;存高位
184: 0122 08 inc r0 ;第三位
185: 0123 E5 60 mov a,t_h ;获得数据
186: 0125 75 F0 0A mov b,#10 ;十六进制
187: 0128 84 div ab ;计算
188: 0129 A6 F0 mov @r0,b ;存低位
189: 012B 08 inc r0
190: 012C F6 mov @r0,a ;存高位
191: 012D 22 ret ;完毕,返回
192: ;***************************************************************************************
193:
194: ; * ******** time_set 设置时间 *******************************************************
195: ; *
*
196: ; * 检测用户按键,1-> 设置时单元 2-> 设置分单元,3->设置增减方式 *
197: ; * 如果需要增加 时,先将方式设置为 增加(默认为减),即,按下 KEY3一下, *
198: ; * 然后按 KEY1 ,如果要减少时单元,需要再次按下KEY3,然后按KEY1; *
199: ; * 分的设置也是如此。
*
200: ;***************************************************************************************
201: 012E 75 80 00 time_set:mov p0,#00h ;禁止数码管显示
202: 0131 75 A0 FF mov p2,#255 ;防止按键时闪烁
203: 0134 12 01 AE lcall pro_key ;查找用户按键情况
204: 0137 E5 56 mov a,key ;查找键值
205: 0139 60 46 jz tsend ;如果等于0,表示没用按键,直接返回
206: 013B B4 01 1C cjne a,#1,tset1 ;是否等于1?没有到下一个处理程序
207: 013E 75 56 00 mov key,#00h ;等于1,表示设置时 请零,否则会引起重复设置
208: 0141 20 00 0D jb timset,tset10 ;时间设置标志位,1 ->减少,0->增加
209: 0144 E5 60 mov a,t_h ;标志位 0 ,增加,取得时单元
210: 0146 B4 17 03 cjne a,#23,ts1 ;如果时单元不等于23,转移到增加操作
211: 0149 02 01 81 jmp tsend ;等于23 直接返回
212: 014C 05 60 ts1: inc t_h ;时单元增加1
213: 014E 02 01 81 jmp tsend ;返回
214:
215: 0151 E5 60 tset10:mov a,t_h ;这里处理为减少的情况
216: 0153 60 2C jz tsend ;如果时单元为0,直接返回
217: 0155 15 60 dec t_h ;否则,数据减1
218: 0157 02 01 81 jmp tsend ;返回,以下关于分的设置一样
219: 015A B4 02 1C tset1:cjne a,#2,tset2 ;如果按键不是 2 则 转移到下一个处理
220: 015D 75 56 00 mov key,#00h ;是2,表示设置 分
221: 0160 20 00 0D jb timset,tset20 ;其余同上
222: 0163 E5 62 mov a,t_m
223: 0165 B4 3B 03 cjne a,#59,ts2
224: 0168 02 01 81 jmp tsend
225: 016B 05 62 ts2:inc t_m
226: 016D 02 01 81 jmp tsend
227:
228: 0170 E5 62 tset20:mov a,t_m
PAGE 5
229: 0172 60 0D jz tsend
230: 0174 15 62 dec t_m
231: 0176 02 01 81 jmp tsend
232:
233: 0179 B4 03 05 tset2:cjne a,#3,tsend ;等于 3 表示设置标志
234: 017C 75 56 00 mov key,#00h ;清零
235: 017F B2 00 cpl timset ;标志取反
236: 0181 22 tsend: ret ;返回
237:
238: ;******** 定时器 T0 设置 **************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -