PIC16F84A Сборка с клавиатурой и прерыванием - PullRequest
0 голосов
/ 30 июня 2018

Я сейчас пишу код сборки, который будет отсчитывать Счетчик 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).

Если я не нажимаю кнопку, контакт A B C D MM74c922 естественно высокий, а когда кнопка нажимается на клавиатуре, контакт 12 ic становится высоким, и адрес отправляется на 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 голосов
/ 03 июля 2018

Вернувшись из перерыва с GOTO не мудрец. Когда вы входите в прерывание, оно отправляет место, где оно должно было стекаться, а когда вы возвращаетесь с goto PC, не использует этот уровень стека и прямо переходит на GOTO, помеченный как Label.

Можешь попробовать

RETFIE

вместо

BCF INTCON, INTF
BSF INTCON, GIE
GOTO CDOWN

дайте мне знать, если есть какие-либо изменения

0 голосов
/ 04 июля 2018

Так что, очевидно, я нашел ответ, и это было очень просто, я отредактировал опцию reg в банке 0, сделав запуск прерывания на заднем фронте бесполезным.

Исправление было

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

теперь код работает, спасибо всем за помощь

0 голосов
/ 02 июля 2018

Ваша прерывание выглядит немного сумасшедшим. Попробуйте что-то вроде:

; 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 

Пожалуйста, посмотрите более подробную информацию в таблице, есть несколько примеров

...