⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 text1_last2.asm

📁 键盘每列依次扫描
💻 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 + -