📄 text1_last2.asm
字号:
OUTBIT equ 08002h ; 位控制口
OUTSEG equ 08004h ; 段控制口
IN equ 08001h ; 键盘读入口
Ctrl_8255 equ 09003h ; 8255控制口地址
PA_8255 equ 09000h ; 8255A口地址
LEDBuf equ 60h ; 键盘输入数字显示缓冲
LEDBuf1 equ 70h ; 六位数码管循环显示缓存
LEDBuf2 equ 50h ; 键码缓存,用于跳转用
ljmp Start
LEDMap: ; 八段管显示码
db 3fh, 06h, 5bh, 4fh, 66h, 6dh, 7dh, 07h
db 7fh, 6fh, 77h, 7ch, 39h, 5eh, 79h, 71h
;==================================== 延时子程序=======================================
Delay:
mov r7, #0
DelayLoop:
djnz r7, DelayLoop
djnz r6, DelayLoop
ret
;============================6位数码管轮流显示子程序===================================
;================显示段码存放在单片机内部RAM 20h~25h中,从最左边第一位开始显示========
DisplayLED:
mov r0, #020h
mov r1, #6 ; 共6个八段数码管
mov r2, #00100000b ; 从左边开始显示
Loop:
mov dptr, #OUTBIT
mov a, #0
movx @dptr, a ; 关所有八段管
mov a, @r0
mov dptr, #OUTSEG
movx @dptr,a
mov dptr, #OUTBIT
mov a, r2
movx @dptr, a ; 显示一位八段管
mov a, r2 ; 显示下一位
rr a
mov r2, a
inc r0
djnz r1, Loop
ret
;=============================== 单片机读入键盘行的状态子程序=========================
;=========================读入的键盘行(共4行)状态取反后存放在A中====================
TestKey:
mov dptr, #OUTBIT
mov a, #0
movx @dptr, a ; 输出线置为0
mov dptr, #IN
movx a, @dptr ; 读入键状态
cpl a
anl a, #0fh ; 高四位不用
ret
//////////////////////////////////////////////////////////////////////////////////////
KeyTable: ; 键码定义
db 16h, 15h, 14h, 0ffh
db 13h, 12h, 11h, 10h
db 0dh, 0ch, 0bh, 0ah
db 0eh, 03h, 06h, 09h
db 0fh, 02h, 05h, 08h
db 00h, 01h, 04h, 07h
;==================================== 扫描键盘子程序 ==================================
;====键盘每列依次扫描,读入键盘的行状态,判断是否有键按下,有键按下时,计算出该键在键码
;表中的位置偏移量,并查找键码表,获得按键的键码,并保存到A和R2中;没有键按下,则返回0ffh,
;保存在R2中
GetKey:
mov dptr, #OUTBIT
mov P2, dph
mov r0, #Low(IN)
mov r1, #00100000b
mov r2, #6
KLoop:
mov a, r1 ; 找出键所在列
cpl a
movx @dptr, a
cpl a
rr a
mov r1, a ; 下一列
movx a, @r0
cpl a
anl a, #0fh
jnz Goon1 ; 该列有键入
djnz r2, KLoop
mov r2, #0ffh ; 没有键按下, 返回 0ffh
sjmp Exit
Goon1:
mov r1, a ; 该键值在键码中的位置偏移量 = (列-1) X 4 + (行-1),从第1列、第1行开始
mov a, r2
dec a
rl a ;相当于(A)×2
rl a
mov r2, a ; r2 = (r2-1)*4
mov a, r1 ; r1中为读入的行值
mov r1, #4
LoopC:
rrc a ; 移位找出所在行
jc Exit
inc r2 ; r2 = r2+ 行值
djnz r1, LoopC
Exit:
mov a, r2 ; 取出键码
mov dptr, #KeyTable
movc a, @a+dptr
mov r2, a
WaitRelease: //等待该按键被释放:延时后再看是否该键被释放,
mov dptr, #OUTBIT ; 等键释放
clr a
movx @dptr, a
mov r6, #10
call Delay
call TestKey
jnz WaitRelease //(A)不为0,表明该键还没有被释放,继续等待
mov a, r2
ret
;==========================查找A中存放的数所对应LED显示段码子程序 =====================
ToLED:
mov dptr, #LEDMap
movc a, @a+dptr
ret
;======================将键码(在A中) 存放到LEDBuf2所指向的内部存储器单元===============
ToKeyTable:
mov r1,LEDBuf2
mov @r1,a
ret
;=============================初始化单片机内存子程序===================================
;===初始化20h~25h单元,20h中为0的段码,因为在上电显示时,最左边数码管显示0,其它灭====
InitLED:
mov 20h, #3fh
mov 21h, #0h
mov 22h, #0h
mov 23h, #0h
mov 24h, #0h
mov 25h, #0h
ret
////////////////////////////////// 主程序 /////////////////////////////////////////
Start:
mov LEDBuf,#020h
mov LEDBuf2,#30h
call InitLED
mov LEDBuf1+0, #0ffh ; 六位循环显示 8.8.8.8.8.8.
mov LEDBuf1+1, #0ffh
mov LEDBuf1+2, #0ffh
mov LEDBuf1+3, #0ffh
mov LEDBuf1+4, #0ffh
mov LEDBuf1+5, #0ffh
mov r4,#6
MLoop:
call DisplayLED
call TestKey ;有键入?
jz MLoop ;无键入, 继续显示,(A)为读入的行状态取反
call GetKey ;读入键码
jb 0e4h,commkey ;如果ACC.4为1,则为命令键,转到commkey处理
numkey:
mov r0,a ;保存数据a
call ToKeyTable
mov a,r0
anl a, #0fh ;显示键码
call ToLED
mov r0,LEDBuf
mov @r0,a
inc LEDBuf
inc LEDBuf2
djnz r4,MLoop
mov r4,#6
mov LEDBuf,#020h
mov LEDBuf2,#030h
ljmp MLoop
commkey: ;处理命令键
cjne a,#13h,start ;如果按下的键不是EXEC,则转向程序开始
call nextkey
;==============================把dph、dpl压入堆栈子程序================================
nextkey:
acall pickdata
push dpl
push dph
ret ;dph与dpl弹出堆栈赋给PC
;========
;单片机内部RAM30h-33h单元中存储的是从键盘输入的地址,用于改变PC,执行相应的程序;
;30h,31h中的低4位分别作为dph的高4位和低4位;32h,33h中的低4位分别作为dpl的高4位和低4位
pickdata:
mov r0,#031h ;将30H、31H 单元中的低4 位数据赋给DPH
acall pickone
mov dph,a
mov r0,#033h ;将32H、33H 单元中的4 位数据赋给DPL
acall pickone
mov dpl,a
ret
;=============================取相邻内存单元低4位子程序================================
;取出r0 与r0-1所指向的单元中低4 位数据,并保存到A中,只取低4 位,键盘上输入的每位数据(0到
;F)最多只用到4位表示
pickone:
mov a,@r0
anl a,#0fh
mov r1,a
dec r0
mov a,@r0
swap a
anl a,#0f0h
orl a,r1
ret
/////////////////////////////六位数码管轮流显示,从左到右共循环10次/////////////////////
org 0200h
mov r0,#4
clr a
mov r1,#44h
Clear:
mov @r1,a
dec r1
dec r0
cjne r0,#0,Clear
mov r3,#10 ;循环次数,可自行设置
DisplayLED1: ;轮流显示
mov r0, #LEDBuf1
mov r1, #6 ; 共6个八段管
mov r2, #00100000b ; 从左边开始显示
Loop1:
mov dptr, #OUTBIT
mov a, #0
movx @dptr, a ; 关所有八段管
mov a, @r0
mov dptr, #OUTSEG
movx @dptr, a
mov dptr, #OUTBIT
mov a, r2
movx @dptr, a ; 显示一位八段管
mov r6, #200
call Delay ;延迟值如果设定的太大的话,就会检测不到按键
mov a, r2 ; 显示下一位
rr a
mov r2, a
inc r0
djnz r1, Loop1
djnz r3, DisplayLED1
acall InitLED ;重新从左边显示
mov r4,#6
mov LEDBuf,#020h
mov LEDBuf2,#030h
ajmp MLoop
//////////////////////////8255 的PA,PB,PC 口 分别循环输出方波程序/////////////////////
org 0300h
testPort:
mov dptr,#Ctrl_8255
mov a,#80h
movx @dptr,a
mov a,#55h
mov r3,#20 ;循环次数,可自行设置
testPortA:
mov dptr,#PA_8255 ;PA 口
movx @dptr,a
inc dptr
movx @dptr,a ;PB 口
inc dptr
movx @dptr,a ;PC 口
rr a
mov r6, #200 ;输出延时,可自行设置延时时间
acall Delay
mov r4,a ;保存a
mov a,r4
djnz r3, testPortA
ajmp MLoop
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -