| | |
;按键扫描程序070831
;********定义存器************
status equ 3h ;定义状态寄存器地址
portb equ 6h ;定义端口B数据寄存器地址
trisb equ 86h ;定义端口B方向控制寄存器地址
portc equ 7h ;定义端口C数据寄存器地址
trisc equ 87h ;
rp0 equ 5h ;定义状态寄存器中的体选位
rp1 equ 5h
z equ 2h ;定义零标志位置
fsr equ 04h
option_reg equ 81h ;定义选项寄存器
rbup equ 7 ;定义上拉电阻使能位位地址
data1 equ 20h ;定义延时变量寄存器
data2 equ 21h
n2 equ 0ffh ;定义延时常数
value equ 22h ;暂存按键列码和位置码
table equ 40h ;建在RAM中的按键位置码表表头
;地址,该表由16个元素单元组成,
;对应16个键
;*******主程序**************
org 0000h
nop
bcf status,rp1 ;选择状态寄存器体0
bsf status,rp0 ;置位RP0为1
movlw 00h
movwf trisc ;设置端口C为输出口
movlw 0ffh
movwf trisb ;设置端口了为输入口
bcf status,rp0
movlw 0f0h ;11110000送C显示
movwf portc
;********建立查表*************
movlw 77h ;0健健值码
movwf 40h
movlw 0b7h ;1
movwf 41h
movlw 0d7h ;2
movwf 42h
movlw 0e7h ;3
movwf 43h
movlw 7bh ;4
movwf 44h
movlw 0bbh ;5
movwf 45h
movlw 0dbh ;6
movwf 46h
movlw 0ebh ;7
movwf 47h
movlw 7dh ;8
movwf 48h
movlw 0bdh ;9
movwf 49h
movlw 0ddh ;A
movwf 4ah
movlw 0edh ;B
movwf 4bh
movlw 7eh ;C
movwf 4ch
movlw 0beh ;D
movwf 4dh
movlw 0deh ;E
movwf 4eh
movlw 0eeh ;F
movwf 4fh
check
call keyscan ;调用按键扫描程序
comf value,0 ;取反键值存储结果放入W
btfsc status,z ;测试是否有键按下?有!跳过下一条指令
goto check ;无,则循环检测
movlw .13 ;送立即数13到DATA1
movwf data1
call delay ;调用延时程序,去抖动
call keyscan ;再次调用键盘扫描程序
comf value,0 ;
btfsc status,z ;再次判断是否有按键按下
goto check ;无,继续检测
call translate ;调用位置码翻译程序
movf fsr,0 ;FSR内容送到W
movwf portc ;送C口显示
check1
movlw .117
movwf data1 ;送立即数117以便产生100MS延时
call delay ;调用延时
call delay
movlw 0f0h ;送11110000到W
xorwf portc,1 ;C端口寄存器内容与W内容异或
;提示按键未放开
call keyscan ;再次调用按键扫描程序
comf value,0 ;位置码取反送W
btfss status,z ;测试按键是否放开?是,跳过下一条指令
goto check1 ;否,则循环检测
goto check ;是,大循环
;*********键盘扫描程序和按键识别子程序******************
;出口参数,有键按下时寄存器calue=等于按键位置码,无按下时=ff
keyscan
bcf status,rp1 ;设置到体1
bsf status,rp0
bcf option_reg,rbup ;启用上拉电阻
movlw 0fh ;送00001111到B端口方向寄存器
movwf trisb ;RB0-RB3为输出,RB4-7为输入口
bcf status,rp0 ;设置到体0
movlw 00h
movwf portb ;送00000000到B口寄存器
nop
nop ;空指令等数据稳定
movf portb,0 ;B口内容传给W
andlw 0fh ;B口寄存器与00001111相与结果放入W
movwf value ;结果放健值寄存器
xorlw 0fh ;与00001111相异或
btfsc status,z ;结果是否为零无键按下,为1有键按下
goto nokey ;为0无键按下
bsf status,rp0 ;有键按下,设置文件体1
bcf option_reg,7
movlw 0f0h ;送11110000到B口
movwf trisb ;设置RB0-3输入RB4-7为输出
bcf status,rp0 ;恢复体0
movf value,0 ;键值寄存器内容入W
movwf portb ;放入B口寄存器
nop
nop
movf portb,0 ;读B口寄存器内容,放入W
andlw 0f0h ;B口和FFFF0000相与
iorwf value,1 ;将行码秘列码合起来放入键值寄存器
return
nokey
movlw 0ffh ;建立一个标志值
movwf value
return
;*******健位码/键值翻译程序*********
;出口参数:正常时寄存器FSR=键值;失常时=AAh
translate
movlw 40h ;指针地址,FSR设置表头地址
movwf fsr ;也就是给文件选择寄存器设置初始置
loopt1
movf 0,0 ;以间接寻址方式读表,并入W
xorwf value,0 ;与键值寄存器内容比较
btfsc status,z ;相等吗?否,跳过下一步
goto loopt2 ;是,跳转
incf fsr,1 ;地址指针加一
btfss fsr,4 ;查到尾了吗?
goto loopt1 ;否,继续查表
movlw 0aah ;是,位置码超限
movwf fsr ;返回以01010101做标志
return ;子程序返回
loopt2
bcf fsr,6 ;等效FSR-40H
return ;在FSR中得到健值
;*******延时程序******************
;入口参数,外循环这量data1作定时常数
delay
lp0 movlw n2
movwf data2
lp1 decfsz data2,1
goto lp1
decfsz data1,1
goto lp0
return
end
高手指点一下哪里有错
回复第3帖
|