检测按键并输出至数码管显示不正确

2019-03-25 18:47发布

本帖最后由 JLennon 于 2018-2-2 08:35 编辑

程序如下,proteus代码见附件,按键K8,K12,K16无法显示,请教是哪里出错了?实在没找到原因,谢谢赐教。 捕获.PNG
  1.                 LIST P=18F4520                                            ;--- 器件型号定义 ---
  2.                 #include <P18F4520.INC>                            ;--- 器件的寄存器头文件包含 ---
  3.                 ;--------------------------------------------------------------------------------
  4.                 ;--- 单片机配置字配置区 ---
  5.                 CONFIG OSC = INTIO67                        ;--- 配置时钟源为内部RC振荡器 ---
  6.                 CONFIG WDT = OFF                                     ;--- 禁止看门狗功能 ---
  7.                 CONFIG DEBUG = OFF                            ;--- 禁止调试功能 ---
  8.                 CONFIG LVP = OFF                                ;--- 禁止低电压编程功能 ---
  9.                 CONFIG PBADEN = OFF                                   ;--- 配置RB端口全为数字IO引脚 ---
  10.                 ;--------------------------------------------------------------------------------
  11.                 ;--- 全局变量定义区 ---
  12.                 CBLOCK 0x10
  13.                         KEYTEMP
  14.                         KEY
  15.                         DELAY_A
  16.                         DELAY_B
  17.                         DELAY_C
  18.                 ENDC
  19.                 ;--------------------------------------------------------------------------------
  20.                 ;--- 程序的开始执行处 ---
  21.                 ORG 0                                                                   ;--- 单片机复位地址 ---
  22.                 GOTO START                                                        ;--- 跳到主程序 ---
  23.                 ORG 0x30                                                        ;--- 主程序入口地址 ---
  24. START:        NOP
  25.                 ;--------------------------------------------------------------------------------
  26.                 ;--- 初始化内部时钟源 ---
  27.                 MOVLW 0x70
  28.                 MOVWF OSCCON                                                ;--- 选择内部8MHZ的RC振荡器 ---
  29.                 BCF OSCTUNE,PLLEN                                        ;--- 禁止内部4倍PLL功能 ---
  30.                 ;--------------------------------------------------------------------------------
  31.                 ;--- 初始化GPIO引脚 ---
  32.                 CLRF WREG
  33.                 MOVWF TRISD                                                        ;--- 配置RD端口为输出方向 ---
  34.                 MOVWF LATD                                                        ;--- 让RD端口输出全为低电平 ---
  35.                 BCF INTCON2,RBPU                                        ;--- 使能RB端口的内部弱上拉功能 ---
  36.                 ;--------------------------------------------------------------------------------
  37.                 ;--- 初始化相关变量 ---               
  38.                 MOVLW 0x0F
  39.                 MOVWF TRISB                                                        ;--- 配置RB7..4为输出引脚,RB3..0为输入引脚 ---
  40.                 MOVWF LATB                                                        ;--- RB7..4输出低电平 ---
  41.                 ;--------------------------------------------------------------------------------
  42.                 ;--- 主程序:实现4X4矩阵键盘,将按键值送到LED数码管上显示 ---
  43. MAIN:        NOP
  44.                 MOVF PORTB,W                                                ;--- 检测是否有键按下 ---
  45.                 ANDLW 0x0F
  46.                 MOVWF KEYTEMP
  47.                 MOVLW 0x0F
  48.                 CPFSEQ KEYTEMP
  49.                 GOTO KEYA                                                        ;--- 有键按下,则跳到指定处 ---
  50.                 GOTO MAIN                                                        ;--- 无键按下,则继续检测 ---
  51. KEYA:        CALL DELAY                                                        ;--- 去按键抖动 ---
  52.                 MOVF PORTB,W                                                ;--- 检测是否真得有键按下 ---
  53.                 ANDLW 0x0F
  54.                 MOVWF KEYTEMP
  55.                 MOVLW 0x0F
  56.                 CPFSEQ KEYTEMP
  57.                 GOTO KEYB                                                        ;--- 真得有键按下,则跳到指定处 ---
  58.                 GOTO MAIN                                                        ;--- 表示无键按下 ---
  59. KEYB:        MOVLW 0xF0                                                        ;--- 读取当前值之后,将行和列方向交换 ---
  60.                 MOVWF TRISB
  61.                 MOVWF LATB
  62.                 MOVF PORTB,W                                                ;--- 读取当前按键的代码值 ---
  63.                 ANDLW 0xF0
  64.                 IORWF KEYTEMP                                                ;--- 和上次读到的按键代码值组合 ---
  65.                 CLRF KEY
  66. KEYD:        MOVF KEY,W                                                        ;--- 将读取的按键代码值与KEYTAB表中值比较 ---
  67.                 ADDWF WREG,W
  68.                 CALL KEYTAB
  69.                 CPFSEQ KEYTEMP
  70.                 GOTO KEYC                                                        ;--- 没有找到,则找下一个按键代码值 ---
  71.                 GOTO FIND                                                        ;--- 找到键值代码,跳到指定处 ---
  72. KEYC:        INCF KEY
  73.                 MOVLW 0x10
  74.                 CPFSLT KEY
  75.                 GOTO NOFIND                                                        ;--- 在按键代码值中没有找到,跳到指定处 ---
  76.                 GOTO KEYD
  77. FIND:        MOVF KEY,W                                                        ;--- 将找到的键值通过查找数码管显示代码值 ---
  78.                 ADDWF WREG,W
  79.                 CALL LEDSEG
  80.                 MOVWF LATD                                                        ;--- 送出去显示 ---
  81. NOFIND:        NOP
  82. WAIT:        MOVF PORTB,W                                                ;--- 等待按键释放 ---
  83.                 ANDLW 0xF0
  84.                 MOVWF KEYTEMP
  85.                 MOVLW 0xF0
  86.                 CPFSEQ KEYTEMP
  87.                 GOTO WAIT
  88.                 MOVLW 0x0F                                                        ;--- 将行和列方向交换 ---
  89.                 MOVWF TRISB
  90.                 MOVWF LATB
  91.                 GOTO MAIN                                                        ;--- 跳到主程序开始处 ---
  92.                 ;--------------------------------------------------------------------------------
  93.                 ;--- 4x4矩阵键盘代码值 ---
  94. KEYTAB:        ADDWF PCL,F
  95.                 DT 0xEE,0xED,0xEB,0xE7
  96.                 DT 0xDE,0xDD,0xDB,0xD7
  97.                 DT 0xBE,0xBD,0xBB,0xB7
  98.                 DT 0x7E,0x7D,0x7B,0x77
  99.                 ;--------------------------------------------------------------------------------
  100.                 ;--- 定义数码管显示0-9,A-F的笔段代码 ---
  101. LEDSEG:        ADDWF PCL,F
  102.                 DT 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F
  103.                 DT 0x77,0x7C,0x39,0x5E,0x79,0x71
  104.                 ;--------------------------------------------------------------------------------
  105.                 ;--- 延时子程序 ---
  106. DELAY:        MOVLW 0x01
  107.                 MOVWF DELAY_A
  108. DLY_A:        MOVLW 0x10
  109.                 MOVWF DELAY_B
  110. DLY_B:        MOVLW 0xFF
  111.                 MOVWF DELAY_C
  112. DLY_C:        DECFSZ DELAY_C
  113.                 GOTO DLY_C
  114.                 DECFSZ DELAY_B
  115.                 GOTO DLY_B
  116.                 DECFSZ DELAY_A
  117.                 GOTO DLY_A
  118.                 RETURN               
  119.                 END
  120.                
复制代码





此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
11条回答
yang_alex
2019-03-26 23:58
解决了就好。解决了问题还能在此说明问题是怎么解决的就更好了!楼主做的好!

这个问题光看代码还真看不出来。(大牛也许可以,对汇编很熟,知道指令占空间情况)

仿真调试对于定位错误是很有帮助的,学会了会省很多时间。

一周热门 更多>