0.asm
ORG 000H
LJMP MAIN
ORG 1000H
MAIN: MOV 53H, #00H ;初始化各数据
MOV 52H, #00H
MOV 51H, #00H
MOV 50H, #00H
MOV R5, #53H
KEYSUB: MOV A, #03H ;键盘扫描, 设置8155的工作方式 , PA, PB输出, PC口输入
MOV DPTR, #7F00H ;向8155写入命令字
MOVX @DPTR, A
BEGIN: ACALL DIS ;调用显示函数
ACALL CLEAR
ACALL CCSCAN ;调用扫描函数
JNZ INK1 ;若有键按下,则听到INK1, 否则重新扫描
AJMP BEGIN
INK1: ACALL DIS
ACALL DL1MS ;延时去抖
ACALL DL1MS ;延时去抖
ACALL CLEAR
ACALL CCSCAN ;再次扫描, 确保去抖后, 还能检测到有键按下
JNZ INK2
AJMP BEGIN
INK2: MOV R2, #0FEH ;先扫描最左边列的按键
MOV R4, #00H
COLUM: MOV DPTR, #7F01H ;拉低某一列
MOV A, R2
MOVX @DPTR, A
INC DPTR
INC DPTR
MOVX A, @DPTR ;读取PC口, 即扫描行
JB A. 0 , LONE ;若第一行没有有键按下, 则跳到LONE
MOV A, #00H ;第一行有键按下, A为0
AJMP KCODE
LONE: JB A. 1 , NEXT ;判断是否第二行有键按下
MOV A, #04H ;第二行有键按下, A为4
KCODE: ADD A, R4
ACALL PUTBUF ;将键码存入存储区, 先从53H到50H
PUSH A
KON: ACALL DIS ;按键释放检测
ACALL CLEAR
ACALL CCSCAN
JNZ KON ;若一直有键被按下, 则一直等待键被释放
POP A
NEXT : INC R4 ;扫描列左移
MOV A, R2
JNB A. 3 KERR ;全部列已扫描完, 则重新开始
RL A ;列左移一位
MOV R2, A
AJMP COLUM 扫描行
KERR: AJMP BEGIN
CCSCAN: MOV DPTR, #7F01H ;扫描检测是否有键被按下函数, 若有键被按下, A不为0, 没有则A为0
MOV A, #00H
MOVX @DPTR, A
INC DPTR
INC DPTR
MOVX A, @DPTR
CPL A ;取反后, 没有键按下时, 低2位都为0, 有键按下时, 低2位都为1
ANL A, #03H ;使A是否为0取决于低2位的值
RET
CLEAR: MOV DPTR, #7F02H ;消除余辉
MOV A, #00H
MOVX @DPTR, A
RET
DIS: PUSH A ;显示函数, 将当前50H~53H单元中的数据显示在数码管上
PUSH 00H ;前三条指令用于现场保护
PUSH 03H
MOV A, #03H ;键盘扫描, 设置8155的工作方式 , PA, PB输出, PC口输入
MOV DPTR, #7F00H
MOVX @DPTR, A
MOV R0, #50H
MOV R3, #0F7H ; 先从最左边这位数码管开始显示
MOV A, R3
AGAIN: MOV DPTR, #7F01H ;选中一个数码管
MOVX @DPTR, A
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A + DPTR
MOV DPTR, #7F02H ;送入7段码
MOVX @DPTR, A
ACALL DL1MS
INC R0
MOV A, R3
JNB A. 0 , OUT ;已显示完4单元数据, 退出显示函数
RR A
MOV R3, A
AJMP AGAIN ;显示下一个单元
OUT: POP 03H
POP 00H
POP A
RET
TABLE: DB 03FH, 06H, 05BH, 04FH, 066H, 06DH, 07DH, 07H
DL1MS: MOV R7, #01H ;延时函数, 延时1ms
DL0: MOV R6, #0FFH
DL1: DJNZ R6, DL1
DJNZ R7, DL0
RET
PUTBUF:PUSH 00H ;将键码存入存储器单元的函数
PUSH A
MOV A, R5
MOV R0, A
POP A
MOV @R0, A
DEC R5
CJNE R5, #04FH, GOBACK
MOV R5, #53H
GOBACK: POP 00H
RET
END
LJMP MAIN
ORG 1000H
MAIN: MOV 53H, #00H ;初始化各数据
MOV 52H, #00H
MOV 51H, #00H
MOV 50H, #00H
MOV R5, #53H
KEYSUB: MOV A, #03H ;键盘扫描, 设置8155的工作方式 , PA, PB输出, PC口输入
MOV DPTR, #7F00H ;向8155写入命令字
MOVX @DPTR, A
BEGIN: ACALL DIS ;调用显示函数
ACALL CLEAR
ACALL CCSCAN ;调用扫描函数
JNZ INK1 ;若有键按下,则听到INK1, 否则重新扫描
AJMP BEGIN
INK1: ACALL DIS
ACALL DL1MS ;延时去抖
ACALL DL1MS ;延时去抖
ACALL CLEAR
ACALL CCSCAN ;再次扫描, 确保去抖后, 还能检测到有键按下
JNZ INK2
AJMP BEGIN
INK2: MOV R2, #0FEH ;先扫描最左边列的按键
MOV R4, #00H
COLUM: MOV DPTR, #7F01H ;拉低某一列
MOV A, R2
MOVX @DPTR, A
INC DPTR
INC DPTR
MOVX A, @DPTR ;读取PC口, 即扫描行
JB A. 0 , LONE ;若第一行没有有键按下, 则跳到LONE
MOV A, #00H ;第一行有键按下, A为0
AJMP KCODE
LONE: JB A. 1 , NEXT ;判断是否第二行有键按下
MOV A, #04H ;第二行有键按下, A为4
KCODE: ADD A, R4
ACALL PUTBUF ;将键码存入存储区, 先从53H到50H
PUSH A
KON: ACALL DIS ;按键释放检测
ACALL CLEAR
ACALL CCSCAN
JNZ KON ;若一直有键被按下, 则一直等待键被释放
POP A
NEXT : INC R4 ;扫描列左移
MOV A, R2
JNB A. 3 KERR ;全部列已扫描完, 则重新开始
RL A ;列左移一位
MOV R2, A
AJMP COLUM 扫描行
KERR: AJMP BEGIN
CCSCAN: MOV DPTR, #7F01H ;扫描检测是否有键被按下函数, 若有键被按下, A不为0, 没有则A为0
MOV A, #00H
MOVX @DPTR, A
INC DPTR
INC DPTR
MOVX A, @DPTR
CPL A ;取反后, 没有键按下时, 低2位都为0, 有键按下时, 低2位都为1
ANL A, #03H ;使A是否为0取决于低2位的值
RET
CLEAR: MOV DPTR, #7F02H ;消除余辉
MOV A, #00H
MOVX @DPTR, A
RET
DIS: PUSH A ;显示函数, 将当前50H~53H单元中的数据显示在数码管上
PUSH 00H ;前三条指令用于现场保护
PUSH 03H
MOV A, #03H ;键盘扫描, 设置8155的工作方式 , PA, PB输出, PC口输入
MOV DPTR, #7F00H
MOVX @DPTR, A
MOV R0, #50H
MOV R3, #0F7H ; 先从最左边这位数码管开始显示
MOV A, R3
AGAIN: MOV DPTR, #7F01H ;选中一个数码管
MOVX @DPTR, A
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A + DPTR
MOV DPTR, #7F02H ;送入7段码
MOVX @DPTR, A
ACALL DL1MS
INC R0
MOV A, R3
JNB A. 0 , OUT ;已显示完4单元数据, 退出显示函数
RR A
MOV R3, A
AJMP AGAIN ;显示下一个单元
OUT: POP 03H
POP 00H
POP A
RET
TABLE: DB 03FH, 06H, 05BH, 04FH, 066H, 06DH, 07DH, 07H
DL1MS: MOV R7, #01H ;延时函数, 延时1ms
DL0: MOV R6, #0FFH
DL1: DJNZ R6, DL1
DJNZ R7, DL0
RET
PUTBUF:PUSH 00H ;将键码存入存储器单元的函数
PUSH A
MOV A, R5
MOV R0, A
POP A
MOV @R0, A
DEC R5
CJNE R5, #04FH, GOBACK
MOV R5, #53H
GOBACK: POP 00H
RET
END
设计题目: 倒计时秒表
设计所使用的电路图(注意与上面的电路图的微小区别, 差别就体现在代码中)
1. 在显示器显示任意4位十六进制数.
1.asm
ORG 000H
LJMP MAIN
ORG 1000H
;与之前的不同, 设计中的电路图, 8155PA口作为数码管的数据输入, PB高4位为字选控制端
MAIN: MOV 53H, #0AH ;初始化各数据, 从左到右显示ABC9
MOV 52H, #0BH
MOV 51H, #0CH
MOV 50H, #09H
BEGIN: ACALL DIS
AJMP BEGIN
CLEAR: MOV DPTR, #7F01H ;消除余辉
MOV A, #00H
MOVX @DPTR, A
RET
DIS: PUSH A ;显示函数, 将当前50H~53H单元中的数据显示在数码管上
PUSH 00H ;前三条指令用于现场保护
PUSH 03H
MOV A, #03H ;键盘扫描, 设置8155的工作方式 , PA, PB输出, PC口输入
MOV DPTR, #7F00H
MOVX @DPTR, A
MOV R0, #50H
MOV R3, #0EFH ; 先从最右边这位数码管开始显示
MOV A, R3
AGAIN: MOV DPTR, #7F02H ;选中一个数码管
MOVX @DPTR, A
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV DPTR, #7F01H ;送入7段码
MOVX @DPTR, A
ACALL DL1MS
ACALL CLEAR ;消去余辉
INC R0
MOV A, R3
JNB A.7, OUT ;已显示完4单元数据, 退出显示函数
RL A
MOV R3, A
AJMP AGAIN ;显示下一个单元
OUT: POP 03H
POP 00H
POP A
RET
TABLE: DB 03FH, 06H, 05BH, 04FH, 066H, 06DH, 07DH, 07H, 7FH, 6FH, 77H, 7CH, 39H, 5EH, 79H, 71H
DL1MS: MOV R7, #01H ;延时函数, 延时1ms
DL0: MOV R6, #0FFH
DL1: DJNZ R6, DL1
DJNZ R7, DL0
RET
END
ORG 000H
LJMP MAIN
ORG 1000H
;与之前的不同, 设计中的电路图, 8155PA口作为数码管的数据输入, PB高4位为字选控制端
MAIN: MOV 53H, #0AH ;初始化各数据, 从左到右显示ABC9
MOV 52H, #0BH
MOV 51H, #0CH
MOV 50H, #09H
BEGIN: ACALL DIS
AJMP BEGIN
CLEAR: MOV DPTR, #7F01H ;消除余辉
MOV A, #00H
MOVX @DPTR, A
RET
DIS: PUSH A ;显示函数, 将当前50H~53H单元中的数据显示在数码管上
PUSH 00H ;前三条指令用于现场保护
PUSH 03H
MOV A, #03H ;键盘扫描, 设置8155的工作方式 , PA, PB输出, PC口输入
MOV DPTR, #7F00H
MOVX @DPTR, A
MOV R0, #50H
MOV R3, #0EFH ; 先从最右边这位数码管开始显示
MOV A, R3
AGAIN: MOV DPTR, #7F02H ;选中一个数码管
MOVX @DPTR, A
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV DPTR, #7F01H ;送入7段码
MOVX @DPTR, A
ACALL DL1MS
ACALL CLEAR ;消去余辉
INC R0
MOV A, R3
JNB A.7, OUT ;已显示完4单元数据, 退出显示函数
RL A
MOV R3, A
AJMP AGAIN ;显示下一个单元
OUT: POP 03H
POP 00H
POP A
RET
TABLE: DB 03FH, 06H, 05BH, 04FH, 066H, 06DH, 07DH, 07H, 7FH, 6FH, 77H, 7CH, 39H, 5EH, 79H, 71H
DL1MS: MOV R7, #01H ;延时函数, 延时1ms
DL0: MOV R6, #0FFH
DL1: DJNZ R6, DL1
DJNZ R7, DL0
RET
END
2.
2.asm
ORG 000H
LJMP MAIN
ORG 1000H
MAIN: MOV 53H, #00H ;初始化各数据
MOV 52H, #00H
MOV 51H, #00H
MOV 50H, #00H
MOV R5, #53H
KEYSUB: MOV A, #03H ;键盘扫描, 设置8155的工作方式 , PA, PB输出, PC口输入
MOV DPTR, #7F00H ;向8155写入命令字
MOVX @DPTR, A
BEGIN: ACALL DIS ;调用显示函数
ACALL CLEAR
ACALL CCSCAN ;调用扫描函数
JNZ INK1 ;若有键按下,则听到INK1, 否则重新扫描
AJMP BEGIN
INK1: ACALL DIS
ACALL DL1MS ;延时去抖
ACALL DL1MS ;延时去抖
ACALL CLEAR
ACALL CCSCAN ;再次扫描, 确保去抖后, 还能检测到有键按下
JNZ INK2
AJMP BEGIN
INK2: MOV R2, #07FH ;先扫描最左边列的按键
MOV R4, #00H
COLUM: MOV DPTR, #7F02H ;拉低某一列
MOV A, R2
MOVX @DPTR, A
INC DPTR
INC DPTR
MOVX A, @DPTR ;读取PC口, 即扫描行
JB A.2, LONE ;若第一行没有有键按下, 则跳到LONE
MOV A, #00H ;第一行有键按下, A为0
AJMP KCODE
LONE: JB A.1, NEXT ;判断是否第二行有键按下
MOV A, #04H ;第二行有键按下, A为4
KCODE: ADD A, R4
ACALL PUTBUF ;将键码存入存储区, 先从53H到50H
PUSH A
KON: ACALL DIS ;按键释放检测
ACALL CLEAR
ACALL CCSCAN
JNZ KON ;若一直有键被按下, 则一直等待键被释放
POP A
NEXT: INC R4 ;扫描列右移
MOV A, R2
JNB A.4 KERR ;全部列已扫描完, 则重新开始
RR A ;列右移一位
MOV R2, A
AJMP COLUM 扫描行
KERR: AJMP BEGIN
CCSCAN: MOV DPTR, #7F02H ;扫描检测是否有键被按下函数, 若有键被按下, A不为0, 没有则A为0
MOV A, #00H
MOVX @DPTR, A
INC DPTR
INC DPTR
MOVX A, @DPTR
CPL A ;取反后, 没有键按下时, 1,2位都为0, 有键按下时, 1,2位都为1
ANL A, #06H ;使A是否为0取决于1,2位的值
RET
CLEAR: MOV DPTR, #7F01H ;消除余辉
MOV A, #00H
MOVX @DPTR, A
RET
DIS: PUSH A ;显示函数, 将当前50H~53H单元中的数据显示在数码管上
PUSH 00H ;前三条指令用于现场保护
PUSH 03H
MOV A, #03H ;键盘扫描, 设置8155的工作方式 , PA, PB输出, PC口输入
MOV DPTR, #7F00H
MOVX @DPTR, A
MOV R0, #53H
MOV R3, #07FH ; 先从最左边这位数码管开始显示
MOV A, R3
AGAIN: MOV DPTR, #7F02H ;选中一个数码管
MOVX @DPTR, A
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV DPTR, #7F01H ;送入7段码
MOVX @DPTR, A
ACALL DL1MS
DEC R0
MOV A, R3
JNB A.4, OUT ;已显示完4单元数据, 退出显示函数
RR A
MOV R3, A
AJMP AGAIN ;显示下一个单元
OUT: POP 03H
POP 00H
POP A
RET
TABLE: DB 77H, 07H, 39H, 6FH
DB 7CH, 7FH, 5EH, 06H
DL1MS: MOV R7, #01H ;延时函数, 延时1ms
DL0: MOV R6, #0FFH
DL1: DJNZ R6, DL1
DJNZ R7, DL0
RET
PUTBUF:PUSH 00H ;将键码存入存储器单元的函数
PUSH A
MOV A, R5
MOV R0, A
POP A
MOV @R0, A
INC R5
CJNE R5, #054H, GOBACK
MOV R5, #50H
GOBACK: MOV R0, 50H ;低位的数
MOV R1, #51H ;高一位的数
XCH1: MOV A, R0
XCH A, @R1 ;50~53H, 向左移一字节, 53H移到50H
MOV R0, A
INC R1
CJNE R1, #54H, XCH1
MOV 50H, R0
POP 00H
RET
END
ORG 000H
LJMP MAIN
ORG 1000H
MAIN: MOV 53H, #00H ;初始化各数据
MOV 52H, #00H
MOV 51H, #00H
MOV 50H, #00H
MOV R5, #53H
KEYSUB: MOV A, #03H ;键盘扫描, 设置8155的工作方式 , PA, PB输出, PC口输入
MOV DPTR, #7F00H ;向8155写入命令字
MOVX @DPTR, A
BEGIN: ACALL DIS ;调用显示函数
ACALL CLEAR
ACALL CCSCAN ;调用扫描函数
JNZ INK1 ;若有键按下,则听到INK1, 否则重新扫描
AJMP BEGIN
INK1: ACALL DIS
ACALL DL1MS ;延时去抖
ACALL DL1MS ;延时去抖
ACALL CLEAR
ACALL CCSCAN ;再次扫描, 确保去抖后, 还能检测到有键按下
JNZ INK2
AJMP BEGIN
INK2: MOV R2, #07FH ;先扫描最左边列的按键
MOV R4, #00H
COLUM: MOV DPTR, #7F02H ;拉低某一列
MOV A, R2
MOVX @DPTR, A
INC DPTR
INC DPTR
MOVX A, @DPTR ;读取PC口, 即扫描行
JB A.2, LONE ;若第一行没有有键按下, 则跳到LONE
MOV A, #00H ;第一行有键按下, A为0
AJMP KCODE
LONE: JB A.1, NEXT ;判断是否第二行有键按下
MOV A, #04H ;第二行有键按下, A为4
KCODE: ADD A, R4
ACALL PUTBUF ;将键码存入存储区, 先从53H到50H
PUSH A
KON: ACALL DIS ;按键释放检测
ACALL CLEAR
ACALL CCSCAN
JNZ KON ;若一直有键被按下, 则一直等待键被释放
POP A
NEXT: INC R4 ;扫描列右移
MOV A, R2
JNB A.4 KERR ;全部列已扫描完, 则重新开始
RR A ;列右移一位
MOV R2, A
AJMP COLUM 扫描行
KERR: AJMP BEGIN
CCSCAN: MOV DPTR, #7F02H ;扫描检测是否有键被按下函数, 若有键被按下, A不为0, 没有则A为0
MOV A, #00H
MOVX @DPTR, A
INC DPTR
INC DPTR
MOVX A, @DPTR
CPL A ;取反后, 没有键按下时, 1,2位都为0, 有键按下时, 1,2位都为1
ANL A, #06H ;使A是否为0取决于1,2位的值
RET
CLEAR: MOV DPTR, #7F01H ;消除余辉
MOV A, #00H
MOVX @DPTR, A
RET
DIS: PUSH A ;显示函数, 将当前50H~53H单元中的数据显示在数码管上
PUSH 00H ;前三条指令用于现场保护
PUSH 03H
MOV A, #03H ;键盘扫描, 设置8155的工作方式 , PA, PB输出, PC口输入
MOV DPTR, #7F00H
MOVX @DPTR, A
MOV R0, #53H
MOV R3, #07FH ; 先从最左边这位数码管开始显示
MOV A, R3
AGAIN: MOV DPTR, #7F02H ;选中一个数码管
MOVX @DPTR, A
MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR
MOV DPTR, #7F01H ;送入7段码
MOVX @DPTR, A
ACALL DL1MS
DEC R0
MOV A, R3
JNB A.4, OUT ;已显示完4单元数据, 退出显示函数
RR A
MOV R3, A
AJMP AGAIN ;显示下一个单元
OUT: POP 03H
POP 00H
POP A
RET
TABLE: DB 77H, 07H, 39H, 6FH
DB 7CH, 7FH, 5EH, 06H
DL1MS: MOV R7, #01H ;延时函数, 延时1ms
DL0: MOV R6, #0FFH
DL1: DJNZ R6, DL1
DJNZ R7, DL0
RET
PUTBUF:PUSH 00H ;将键码存入存储器单元的函数
PUSH A
MOV A, R5
MOV R0, A
POP A
MOV @R0, A
INC R5
CJNE R5, #054H, GOBACK
MOV R5, #50H
GOBACK: MOV R0, 50H ;低位的数
MOV R1, #51H ;高一位的数
XCH1: MOV A, R0
XCH A, @R1 ;50~53H, 向左移一字节, 53H移到50H
MOV R0, A
INC R1
CJNE R1, #54H, XCH1
MOV 50H, R0
POP 00H
RET
END
对应代码下载:
0.asm
1.asm
60分钟倒计时秒表
功能:
1. 带有启动键Start, 暂停键Pause, 停止键Stop, 复位键Reset;
2. 4位数码管显示分(两位)秒(两位);
3. 按启动键启动从60分开始倒计时, 按暂停键暂停,显示保持原来计时时间, 再次按启动键继续计时, 按停止键停止计时, 复位键复位, 到零停止计时.
4. 按停止键后, 可按中间的4个键, 分别对应分的十位(2键), 个位(4键), 和秒的十位(5键), 个位(9键), 按动一下, 相应的位增1, 并保证时间的正确值, 再按一次停止键, 保存设置值, 按其它键则放弃设置时间值, 恢复原来的时间.
电路图:
计时器工作模式:
编码(54H单元) | 当前工作模式 |
00H | Reset |
01H | Start |
02H | Pause |
03H | Stop |
主程序流程:
主程序代码段
主程序代码段:
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP TIMER0
ORG 1000H
MAIN: ACALL INIT ;初始化定时器
SETB EA ;开总中断
SETB ET0 ;开定时器0中断
MOV A, #03H ;设置8155的工作模式, PA, PB输出, PC输入.
MOV DPTR, #7F00H
MOVX @DPTR, A
BEGIN: ACALL DIS
ACALL CLEAR
ACALL CCSCAN
JNZ INK1
AJMP BEGIN
INK1: ACALL DIS
ACALL CLEAR
ACALL CCSCAN
JNZ INK2
AJMP BEGIN
INK2: MOV R2, #7FH ;从最左边列开始扫描
MOV R4, #00H
COLUM: MOV DPTR, #7F02H
MOV A, R2
MOVX @DPTR, A
INC DPTR
MOVX A, @DPTR
JB ACC.2, LONE
MOV A, #00H
AJMP KCODE
LONE: JB ACC.1, NEXT
MOV A, #04H
KCODE: ADD A, R4
ACALL PUTBUF
KON: ACALL DIS
ACALL CLEAR
ACALL CCSCAN
JNZ KON
NEXT: INC R4
MOV A, R2
JNB ACC.4, KERR
RR A
MOV R2, A
AJMP COLUM
KERR: AJMP BEGIN
CCSCAN: MOV DPTR, #7F02H
MOV A, #00H
MOVX @DPTR, A
INC DPTR
MOVX A, @DPTR
CPL A
ANL A, #03H
RET
CLEAR: MOV DPTR, #7F01H
MOV A, #00H
MOVX @DPTR, A
RET
INIT: MOV 53H, #06H ;分十位
MOV 52H, #00H ;分个位
MOV 51H, #00H ;秒十位
MOV 50H, #00H ;秒个位
MOV 54H, #00H ;存放当前工作模式, 00:Reset, 01 Start, 02 Pause, 03 Stop
MOV 55H, #0AH ;定时计数用, 定时器每次中断0.1s, 计数10次, 定时1s
CLR TR0
MOV TMOD, 01H ;定时器工作在方式1, 16位定时器
MOV TH0, #3CH
MOV TL0, #0B0H
RET
主程序代码段:
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP TIMER0
ORG 1000H
MAIN: ACALL INIT ;初始化定时器
SETB EA ;开总中断
SETB ET0 ;开定时器0中断
MOV A, #03H ;设置8155的工作模式, PA, PB输出, PC输入.
MOV DPTR, #7F00H
MOVX @DPTR, A
BEGIN: ACALL DIS
ACALL CLEAR
ACALL CCSCAN
JNZ INK1
AJMP BEGIN
INK1: ACALL DIS
ACALL CLEAR
ACALL CCSCAN
JNZ INK2
AJMP BEGIN
INK2: MOV R2, #7FH ;从最左边列开始扫描
MOV R4, #00H
COLUM: MOV DPTR, #7F02H
MOV A, R2
MOVX @DPTR, A
INC DPTR
MOVX A, @DPTR
JB ACC.2, LONE
MOV A, #00H
AJMP KCODE
LONE: JB ACC.1, NEXT
MOV A, #04H
KCODE: ADD A, R4
ACALL PUTBUF
KON: ACALL DIS
ACALL CLEAR
ACALL CCSCAN
JNZ KON
NEXT: INC R4
MOV A, R2
JNB ACC.4, KERR
RR A
MOV R2, A
AJMP COLUM
KERR: AJMP BEGIN
CCSCAN: MOV DPTR, #7F02H
MOV A, #00H
MOVX @DPTR, A
INC DPTR
MOVX A, @DPTR
CPL A
ANL A, #03H
RET
CLEAR: MOV DPTR, #7F01H
MOV A, #00H
MOVX @DPTR, A
RET
INIT: MOV 53H, #06H ;分十位
MOV 52H, #00H ;分个位
MOV 51H, #00H ;秒十位
MOV 50H, #00H ;秒个位
MOV 54H, #00H ;存放当前工作模式, 00:Reset, 01 Start, 02 Pause, 03 Stop
MOV 55H, #0AH ;定时计数用, 定时器每次中断0.1s, 计数10次, 定时1s
CLR TR0
MOV TMOD, 01H ;定时器工作在方式1, 16位定时器
MOV TH0, #3CH
MOV TL0, #0B0H
RET
显示子函数
DIS: PUSH ACC
PUSH 00H
PUSH 03H
MOV A, #03H
MOV DPTR, #7F00H
MOVX @DPTR, A
MOV R0, #50H
MOV R3, #0EFH
MOV A, 54H
CJNE A, #03H, DIS0
MOV R0, #60H
DIS0: MOV A, R3
AGAIN: MOV DPTR, #7F02H
MOVX @DPTR, A
MOV A, @R0
MOV DTPR, DATAS
MOVC A, @A+DPTR
MOV DPTR, #7F01H
MOVX @DPTR, A
ACALL DL1MS
INC R0
MOV A, R3
JNB ACC.0, OUT
RL A
MOV R3, A
AJMP AGAIN
OUT: POP 03H
POP 00H
POP ACC
RET
DATAS: DB 03FH, 06H, 05BH, 04FH, 066H, 06DH, 07DH
DB 07H, 7FH, 6FH, 77H, 7CH, 39H, 5EH, 79H, 71H
DL1MS: MOV R7, #01H
DL0: MOV R6, #0FFH
DL1: DJNZ R6, DL1
DJNZ R7, DL0
RET
DIS: PUSH ACC
PUSH 00H
PUSH 03H
MOV A, #03H
MOV DPTR, #7F00H
MOVX @DPTR, A
MOV R0, #50H
MOV R3, #0EFH
MOV A, 54H
CJNE A, #03H, DIS0
MOV R0, #60H
DIS0: MOV A, R3
AGAIN: MOV DPTR, #7F02H
MOVX @DPTR, A
MOV A, @R0
MOV DTPR, DATAS
MOVC A, @A+DPTR
MOV DPTR, #7F01H
MOVX @DPTR, A
ACALL DL1MS
INC R0
MOV A, R3
JNB ACC.0, OUT
RL A
MOV R3, A
AJMP AGAIN
OUT: POP 03H
POP 00H
POP ACC
RET
DATAS: DB 03FH, 06H, 05BH, 04FH, 066H, 06DH, 07DH
DB 07H, 7FH, 6FH, 77H, 7CH, 39H, 5EH, 79H, 71H
DL1MS: MOV R7, #01H
DL0: MOV R6, #0FFH
DL1: DJNZ R6, DL1
DJNZ R7, DL0
RET
按键功能
PUTBUF: MOV R1, A
JNZ CHKSTART
ACALL RESETFUNC
SJMP GOBACK
CHKSTART: CJNE R1, #03H, CHKPAUSE
ACALL STARTFUNC
SJMP GOBACK
CHKPAUSE: CJNE R1, #04H, CHKSTOP
ACALL PAUSEFUNC
SJMP GOBACK
CHKSTOP: CJNE R1, #07H, CHKOTHER
ACALL STOPFUNC
SJMP GOBACK
CHKOTHER: ACALL OTHERFUNC
GOBACK: RET
PUTBUF: MOV R1, A
JNZ CHKSTART
ACALL RESETFUNC
SJMP GOBACK
CHKSTART: CJNE R1, #03H, CHKPAUSE
ACALL STARTFUNC
SJMP GOBACK
CHKPAUSE: CJNE R1, #04H, CHKSTOP
ACALL PAUSEFUNC
SJMP GOBACK
CHKSTOP: CJNE R1, #07H, CHKOTHER
ACALL STOPFUNC
SJMP GOBACK
CHKOTHER: ACALL OTHERFUNC
GOBACK: RET
重置代码段
RESETFUNC: MOV R0, 54H
CJNE R0, #00H, RESET0
RET
CJNE R0, #01H, RESET0
RET
RESET0: ACALL INIT
MOV 54H, #00H
RET
RESETFUNC: MOV R0, 54H
CJNE R0, #00H, RESET0
RET
CJNE R0, #01H, RESET0
RET
RESET0: ACALL INIT
MOV 54H, #00H
RET
开始功能代码段
STARTFUNC: MOV R0, 54H
CJNE R0, #01H, START0
RET
START0: MOV 54H, #00H
SETB TR0
RET
STARTFUNC: MOV R0, 54H
CJNE R0, #01H, START0
RET
START0: MOV 54H, #00H
SETB TR0
RET
暂停功能代码段
PAUSEFUNC: MOV R0, 54H
CJNE R0, #01H, PAUSE0
CLR TR0
MOV 54H, #02H
SJMP PAUSE1
PAUSE0: CJNE R0, #02H, PAUSE1
SETB TR0
MOV 54H, #01H
PAUSE1: RET
PAUSEFUNC: MOV R0, 54H
CJNE R0, #01H, PAUSE0
CLR TR0
MOV 54H, #02H
SJMP PAUSE1
PAUSE0: CJNE R0, #02H, PAUSE1
SETB TR0
MOV 54H, #01H
PAUSE1: RET
停止功能代码段
STOPFUNC: MOV R0, 54H
CJNE R0, #03H, STOP0
MOV 54H, #02H
MOV R0, #50H
MOV R1, #60H
STOP1: MOV A, @R1
MOV @R0, A
INC R0
INC R1
CJNE R0, #54H, STOP1
RET
STOP0: CLR TR0
MOV 54H, #03H
MOV R0, #60H
MOV R1, #50H
STOP2: MOV A, @R1
MOV @R0, A
INC R0
INC R1
CJNE R1, #54H, STOP2
RET
STOPFUNC: MOV R0, 54H
CJNE R0, #03H, STOP0
MOV 54H, #02H
MOV R0, #50H
MOV R1, #60H
STOP1: MOV A, @R1
MOV @R0, A
INC R0
INC R1
CJNE R0, #54H, STOP1
RET
STOP0: CLR TR0
MOV 54H, #03H
MOV R0, #60H
MOV R1, #50H
STOP2: MOV A, @R1
MOV @R0, A
INC R0
INC R1
CJNE R1, #54H, STOP2
RET
其他功能代码段
OTHERFUNC: MOV R0, 54H
CJNE R0, #03H, OTHER0
CJNE R1, #01H, OTHER1
MOV R0, #63H
INC @R0
CJNE @R0, #06H, OTHER0
MOV @R0, #00H
SJMP OTHER0
OTHER1: CJNE R1, #02H, OTHER2
MOV R0, #62H
INC @R0
CJNE @R0, #0AH, OTHER0
MOV @R0, #00H
SJMP OTHER0
OTHER2: CJNE R1, #05H, OTHER3
MOV R0, #61H
INC @R0
CJNE @R0, #06H, OTHER0
MOV @R0, #00H
SJMP OTHER0
OTHER3: CJNE R1, #06H, OTHER0
MOV R0, #60H
INC @R0
CJNE @R0, #0AH, OTHER0
MOV @R0, #00H
SJMP OTHER0
OTHER0: RET
OTHERFUNC: MOV R0, 54H
CJNE R0, #03H, OTHER0
CJNE R1, #01H, OTHER1
MOV R0, #63H
INC @R0
CJNE @R0, #06H, OTHER0
MOV @R0, #00H
SJMP OTHER0
OTHER1: CJNE R1, #02H, OTHER2
MOV R0, #62H
INC @R0
CJNE @R0, #0AH, OTHER0
MOV @R0, #00H
SJMP OTHER0
OTHER2: CJNE R1, #05H, OTHER3
MOV R0, #61H
INC @R0
CJNE @R0, #06H, OTHER0
MOV @R0, #00H
SJMP OTHER0
OTHER3: CJNE R1, #06H, OTHER0
MOV R0, #60H
INC @R0
CJNE @R0, #0AH, OTHER0
MOV @R0, #00H
SJMP OTHER0
OTHER0: RET
中断定时代码段
;使用定时器0, 工作模式1, 定时0.1s, 晶振频率为6MHz
;定时器初值 X = 65536 – 50000 = 15536 = 3CB0H
TIMER0: MOV TH0, #3CH
MOV TL0, #0B0H
DJNZ 55H, EXIT0 ;判断是否已定时中断10, 即1秒
MOV 55H, #0AH
MOV R0, #50H
GOON0: DEC @R0
CJNE @R0, #0FFH, EXIT0
MOV @R0, #09H
INC R0
DEC @R0
CJNE @R0, #0FFH, EXIT0
MOV @R0, #05H
INC R0
DEC @R0
CJNE @R0, #0FFH, EXIT0
MOV @R0, #09H
INC R0
DEC @R0
CJNE @R0, #0FFH, EXIT0 ; 倒计时结束, 停止计时, 显示全”0”
ACALL INIT
MOV 53H, #00H
MOV 54H, #03H
EXIT0: RET
;使用定时器0, 工作模式1, 定时0.1s, 晶振频率为6MHz
;定时器初值 X = 65536 – 50000 = 15536 = 3CB0H
TIMER0: MOV TH0, #3CH
MOV TL0, #0B0H
DJNZ 55H, EXIT0 ;判断是否已定时中断10, 即1秒
MOV 55H, #0AH
MOV R0, #50H
GOON0: DEC @R0
CJNE @R0, #0FFH, EXIT0
MOV @R0, #09H
INC R0
DEC @R0
CJNE @R0, #0FFH, EXIT0
MOV @R0, #05H
INC R0
DEC @R0
CJNE @R0, #0FFH, EXIT0
MOV @R0, #09H
INC R0
DEC @R0
CJNE @R0, #0FFH, EXIT0 ; 倒计时结束, 停止计时, 显示全”0”
ACALL INIT
MOV 53H, #00H
MOV 54H, #03H
EXIT0: RET