带有键盘和中断的PIC16F84A组件

时间:2018-06-30 16:26:14

标签: assembly interrupt pic keypad

我当前正在编写一个汇编代码,该代码将 BCD计数器(通过7段显示器)。按下某个键时,计数器值将被键盘值所覆盖,然后继续递减计数。例如,如果当前计数器值为“ 8”,然后按按键5覆盖,则计数器设置为“ 5”,然后递减计数。计数器将永久递减计数,只要在键盘上按任何键,该计数器就会被覆盖。

这是我的电路

enter image description here

这是我当前编写的代码:

    COUNT EQU 0CH

    ORG 000H                                       ; reset vector
    GOTO MAIN                                      ; jump to label main during reset or startup
    ORG 004H                                       ; interrupt vector
    GOTO INT_RTN                                   ; jump to label INT_RTN or the interrupt service routine

    ;set up
    MAIN BSF STATUS, RP0 
         CLRF TRISA 
         MOVLW 0F1H
         MOVWF TRISB
         MOVLW 0DH
         MOVWF OPTION_REG
         BCF STATUS, RP0

         BSF OPTION_REG, 6                         ; interrupt event during rising edge
         BCF INTCON, INTF                          ; clear the RB0/INT interrupt flag
         BSF INTCON, INTE                          ; unmask (enable) RB0/INT interrupt source
         BSF INTCON, GIE                           ; enable all unmasked interrupt
         GOTO START

    ;Interrupt-----------------------------------------------------------
    INT_RTN BCF INTCON, GIE                        ; disable all unmasked interrupt to prevent interrupt overriding
            BTFSS INTCON, INTF                     ; check the RB0/INT interrupt flag is ‘1’ (interrupt source from RB0/INT)
            GOTO EXIT                              ; exit ISR if not RB0/INT interrupt

    ;interrupt code      
            CLRW
            BTFSC PORTB, 4
            ADDLW 01H
            BTFSC PORTB, 5
            ADDLW 02H
            BTFSC PORTB, 6
            ADDLW 04H
            BTFSC PORTB, 7
            ADDLW 08H
            CALL KEY_VAL                          ; call the array KEY_VAL
            MOVWF COUNT
            INCF COUNT
            BCF INTCON, INTF
            BSF INTCON, GIE
            GOTO CDOWN  

    EXIT  BSF INTCON, GIE                         ; enable all unmasked interrupt
          RETFIE                                  ; return from interrupt routine

    ;Program Start--------------------------------------------------------------------------------------------
    START MOVLW 0AH
          MOVWF COUNT
          MOVLW 09H 

    CDOWN MOVWF PORTA
          SLEEP
          DECFSZ COUNT, 1
          GOTO DOWN
          GOTO START

    DOWN DECF PORTA, 0
         GOTO CDOWN

    ;End of Start-----------------------------------------------------------
    KEY_VAL ADDWF PCL, F
            RETLW 01H ; returns 01H for key 1 (addr 00H)
            RETLW 02H ; returns 02H for key 2 (addr 01H)
            RETLW 03H ; returns 03H for key 3 (addr 02H)
            RETLW 00H ; returns 00H for key A (addr 03H)
            RETLW 04H ; returns 04H for key 4 (addr 04H)
            RETLW 05H ; returns 05H for key 5 (addr 05H)
            RETLW 06H ; returns 06H for key 6 (addr 06H)
            RETLW 00H ; returns 00H for key B (addr 07H)
            RETLW 07H ; returns 07H for key 7 (addr 08H)
            RETLW 08H ; returns 08H for key 8 (addr 09H)
            RETLW 09H ; returns 09H for key 9 (addr 0AH)
            RETLW 00H ; returns 00H for key C (addr 0BH)
            RETLW 00H ; returns 00H for key * (addr 0CH)
            RETLW 00H ; returns 00H for key 0 (addr 0DH)
            RETLW 00H ; returns 00H for key # (addr 0EH)
            RETLW 00H ; returns 00H for key D (addr 0FH)

     END

自然地,bcd倒计时,当按下按钮时发生中断,读取RB4中的输入-RB7在KEY_VAL给定的地址中找到数据并将其加载到PORTA

但是,我的问题是,当我按键盘上的一个按钮并开始中断时。当我阅读时,引脚RB4-RB7可获得IC给定的地址。我得到的全部都很高,所以我总是得到15(D的地址)。

如果我不按按钮,则MM74c922的引脚A B C D自然为高电平,而当按键盘上的按钮时,ic的引脚12变为高电平,地址被发送至rb4-7。问题是我认为pic控制器无法读取rb4-7中的移位,因此它总是在中断之前读取数据,而中断总是很高,因此我无法获取所需的地址。

我尝试将中断设置为在下降沿期间切换,但是同样的事情出于想法而出现,我需要帮助

如果有帮助,这是按钮的地址

    Address: 00H 01H 02H 03H 04H 05H 06H 07H 08H 09H 0AH 0BH 0CH 0DH 0EH 0FH
    Key: 1 2 3 A 4 5 6 B 7 8 9 C * 0 # D

3 个答案:

答案 0 :(得分:1)

您的中断程序看起来有些疯狂。尝试类似的东西:

; Save Data Space
Bank_shr   udata_shr   0x70
W_safe          RES 1
S_safe          RES 1

.....
;Interrupt-----------------------------------------------------------
INT_RTN 
    MOVWF    W_safe
    SWAPF    STATUS, W
    BCF      STATUS, RP0
    MOVWF    s_safe
Interrupt_code
    .......

Interrupt_End
    SWAPF    s_safe, w
    MOVWF    STATUS
    SWAPF    w_safe, F
    SWAPF    w_safe, w
    RETFIE                               ;GIE will set automatically 

请在数据表中查找更多详细信息,其中有一些示例

答案 1 :(得分:1)

从GOTO中断返回并不明智。当您进入中断时,它将发送要堆叠的位置,当您使用goto PC返回时,它不使用该lvl堆栈,直接跳转到标记为Label的GOTO。

你可以尝试

RETFIE

代替

BCF INTCON, INTF
BSF INTCON, GIE
GOTO CDOWN

让我知道是否有任何变化

答案 2 :(得分:0)

因此,显然我找到了答案,而且非常简单,我在bank 0中编辑了选项reg,使中断在下降沿开始无效。

解决方法是

MAIN BSF STATUS, RP0 
     CLRF TRISA 
     MOVLW 0F1H
     MOVWF TRISB
     MOVLW 0DH
     MOVWF OPTION_REG
     BSF OPTION_REG, 6   --move this line here--  ; interrupt event during rising edge
     BCF STATUS, RP0

     BCF INTCON, INTF                          ; clear the RB0/INT interrupt flag
     BSF INTCON, INTE                          ; unmask (enable) RB0/INT interrupt source
     BSF INTCON, GIE                           ; enable all unmasked interrupt
     GOTO START

现在代码可以正常工作了,谢谢大家的帮助