本帖最后由 JLennon 于 2018-2-1 15:53 编辑
程序如下,proteus代码见附件,按键K8,K12,K16无法显示,请教是哪里出错了?实在没找到原因,谢谢赐教。
LIST P=18F4520 ;--- 器件型号定义 ---
#include <P18F4520.INC> ;--- 器件的寄存器头文件包含 ---
;--------------------------------------------------------------------------------
;--- 单片机配置字配置区 ---
CONFIG OSC = INTIO67 ;--- 配置时钟源为内部RC振荡器 ---
CONFIG WDT = OFF ;--- 禁止看门狗功能 ---
CONFIG DEBUG = OFF ;--- 禁止调试功能 ---
CONFIG LVP = OFF ;--- 禁止低电压编程功能 ---
CONFIG PBADEN = OFF ;--- 配置RB端口全为数字IO引脚 ---
;--------------------------------------------------------------------------------
;--- 全局变量定义区 ---
CBLOCK 0x10
KEYTEMP
KEY
DELAY_A
DELAY_B
DELAY_C
ENDC
;--------------------------------------------------------------------------------
;--- 程序的开始执行处 ---
ORG 0 ;--- 单片机复位地址 ---
GOTO START ;--- 跳到主程序 ---
ORG 0x30 ;--- 主程序入口地址 ---
START: NOP
;--------------------------------------------------------------------------------
;--- 初始化内部时钟源 ---
MOVLW 0x70
MOVWF OSCCON ;--- 选择内部8MHZ的RC振荡器 ---
BCF OSCTUNE,PLLEN ;--- 禁止内部4倍PLL功能 ---
;--------------------------------------------------------------------------------
;--- 初始化GPIO引脚 ---
CLRF WREG
MOVWF TRISD ;--- 配置RD端口为输出方向 ---
MOVWF LATD ;--- 让RD端口输出全为低电平 ---
BCF INTCON2,RBPU ;--- 使能RB端口的内部弱上拉功能 ---
;--------------------------------------------------------------------------------
;--- 初始化相关变量 ---
MOVLW 0x0F
MOVWF TRISB ;--- 配置RB7..4为输出引脚,RB3..0为输入引脚 ---
MOVWF LATB ;--- RB7..4输出低电平 ---
;--------------------------------------------------------------------------------
;--- 主程序:实现4X4矩阵键盘,将按键值送到LED数码管上显示 ---
MAIN: NOP
MOVF PORTB,W ;--- 检测是否有键按下 ---
ANDLW 0x0F
MOVWF KEYTEMP
MOVLW 0x0F
CPFSEQ KEYTEMP
GOTO KEYA ;--- 有键按下,则跳到指定处 ---
GOTO MAIN ;--- 无键按下,则继续检测 ---
KEYA: CALL DELAY ;--- 去按键抖动 ---
MOVF PORTB,W ;--- 检测是否真得有键按下 ---
ANDLW 0x0F
MOVWF KEYTEMP
MOVLW 0x0F
CPFSEQ KEYTEMP
GOTO KEYB ;--- 真得有键按下,则跳到指定处 ---
GOTO MAIN ;--- 表示无键按下 ---
KEYB: MOVLW 0xF0 ;--- 读取当前值之后,将行和列方向交换 ---
MOVWF TRISB
MOVWF LATB
MOVF PORTB,W ;--- 读取当前按键的代码值 ---
ANDLW 0xF0
IORWF KEYTEMP ;--- 和上次读到的按键代码值组合 ---
CLRF KEY
KEYD: MOVF KEY,W ;--- 将读取的按键代码值与KEYTAB表中值比较 ---
ADDWF WREG,W
CALL KEYTAB
CPFSEQ KEYTEMP
GOTO KEYC ;--- 没有找到,则找下一个按键代码值 ---
GOTO FIND ;--- 找到键值代码,跳到指定处 ---
KEYC: INCF KEY
MOVLW 0x10
CPFSLT KEY
GOTO NOFIND ;--- 在按键代码值中没有找到,跳到指定处 ---
GOTO KEYD
FIND: MOVF KEY,W ;--- 将找到的键值通过查找数码管显示代码值 ---
ADDWF WREG,W
CALL LEDSEG
MOVWF LATD ;--- 送出去显示 ---
NOFIND: NOP
WAIT: MOVF PORTB,W ;--- 等待按键释放 ---
ANDLW 0xF0
MOVWF KEYTEMP
MOVLW 0xF0
CPFSEQ KEYTEMP
GOTO WAIT
MOVLW 0x0F ;--- 将行和列方向交换 ---
MOVWF TRISB
MOVWF LATB
GOTO MAIN ;--- 跳到主程序开始处 ---
;--------------------------------------------------------------------------------
;--- 4x4矩阵键盘代码值 ---
KEYTAB: ADDWF PCL,F
DT 0xEE,0xED,0xEB,0xE7
DT 0xDE,0xDD,0xDB,0xD7
DT 0xBE,0xBD,0xBB,0xB7
DT 0x7E,0x7D,0x7B,0x77
;--------------------------------------------------------------------------------
;--- 定义数码管显示0-9,A-F的笔段代码 ---
LEDSEG: ADDWF PCL,F
DT 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F
DT 0x77,0x7C,0x39,0x5E,0x79,0x71
;--------------------------------------------------------------------------------
;--- 延时子程序 ---
DELAY: MOVLW 0x01
MOVWF DELAY_A
DLY_A: MOVLW 0x10
MOVWF DELAY_B
DLY_B: MOVLW 0xFF
MOVWF DELAY_C
DLY_C: DECFSZ DELAY_C
GOTO DLY_C
DECFSZ DELAY_B
GOTO DLY_B
DECFSZ DELAY_A
GOTO DLY_A
RETURN
END
|
共1人点赞
|