Elektroda.pl
Elektroda.pl
X
Elektroda.pl
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[16f887][asm] Przerwanie na porcie z weak pull up.

06 Lip 2009 11:28 1757 5
  • Poziom 2  
    Witam.
    Uc 16f887 ma na porcie rb0 i rb1 pushbuttony ktore zwieraja je do masy.
    Oba te piny maja podciaganie do zasilania.
    RB0 nacisniety w dowolnej chwili ma zmusic uC do przeczytania stanow portow (np re0, re1, re2 i wiele innych) i zmiane dzialania w zaleznosci od wybranych ustawien.

    RB1 dziala inaczej, kazde kolejne nacisniecie pushbuttona powoduje wybor jednego z czterech trybow pracy urzadzenia.

    Te 2 piny oczywiscie beda wyzwalaly przerwanie.

    1. Gdzie mam fizycznie umiescic podprogram obslugi przerwania?
    Tutaj:

    ORG 0x000 ; processor reset vector
    goto main ; go to beginning of program

    ;- - - - - - - - - INTERRUPT - - - - - - - - - - - - - -

    ORG 0x004 ; interrupt vector location
    TUTAJ MA BYC OBSLUGA PRZERWANIA WPISANA?
    NOP

    main .....reszta programu......

    2. Jezeli styki sie trzesa to najlepiej aby pierwsze wyzwolenie przerwania powodowalo ze uC jest nieczuly na przerwanie np przez 80ms, jak mam to zrobic? Wylaczajac przerwanie na ten czas?
    Mam zastosowac taki algorytm:
    przerwanie:
    a. wylaczyc przerwanie
    b. ktory pushbutton zostal nacisniety?
    c. odczekac 80ms petla delay
    d. wykonac faktyczne przerwanie grzebiac w rejestrach sfr
    e. wlaczyc ponownie przerwanie
    f. wyjsc z przerwania spowrotem do programu

    Czy moze jakos inaczej?

    3. Czy potrzebuje wlozyc przerwanie w jakies szczegolne komorki pamieci?

    4. Co sie znajduje w pamieci programu pomiedzy Reset Vector i Interrupt Vector: 0001h, 0002h, 0003h ?
  • Poziom 11  
    Witam,
    1. aby natąpiło przerwanie trzeba utawić maski.
    2. ORG 0x004 ; interrupt vector location - to adres wpisywany do licznika, tutaj musi być pierwszy rozkaz programu (w przerwaniu).
    Często jest to skok, skok do dowolnego adresu.
    3. a. wylaczyc przerwanie (dobrze jest to zrobić - choć nie jest to w 100% konieczne).
    4. b. ktory pushbutton zostal nacisniety? - odczytać RB a jeśli iskrzenie to odczytać kilkakrotnie lub c. odczekac 80ms petla delay (też może być).
    5. wykonać obsługę - coś wczytać, wykonać, zapisać, itp
    "d. wykonac faktyczne przerwanie grzebiac w rejestrach sfr "
    grzebać jak najmniej, ale na koniec koniecznie wyzerować flagę przerwania (...IF), włączyć przerwania (GIE=1), RETI. (Chyba RETI ustawia GIE)
    To wszystko, program działa od miejsca skąd nastąpiło przerwanie

    3. Czy potrzebuje wlozyc przerwanie w jakies szczegolne komorki pamieci? tylko 1 instrukcja w 0004. Oczywiście jeśli w 0004 jest CALL to po powrocie musi wystąpić RETI

    4. Co sie znajduje w pamieci programu pomiedzy Reset Vector i Interrupt Vector: 0001h, 0002h, 0003h ? to co wpiszesz! Jeśli w 0h jest skok i nic dalej to w 0001h, 0002h, 0003h jest FF, w niektórych kopilatorach czasem w 0001h coś przypadkowego (niezupełnie przypadkowego ale dla nas tak jak przyp). Po skasowaniu cała pamięć ma same FF, więc jeśli nic nie wpiszemy to tak pozostaje. FF to NOP lub w niektórych procesorach inny nieaktywny rozkaz, chyba we wszystkich PIC to NOP.
    0001h, 0002h, 0003h możesz wykorzystywać dowolnie: program, dane, nic.
  • Poziom 2  
    1. Jakie maski?
    2. Czyli jak wystapia wakunki przerwania to do PC jest wpisywany adres 0004h i sa wykonywane rozkazy. Czy moge wpisac tu "litanie" 250 linii bedacej przerwaniem? czy musze wpisac ruz po 0004h nop a potem call i tutaj nastepuje skok do wlasciwego przerwania.
    3. Co zrobic najpierw? Czy zczytac port, czy wylaczyc przerwanie?
    4. Ok
    5. Gdzie jest ta flaga?
    Czy mozna zrobic tak zeby przerwanie ustawialo jakas flage, a pod koniec lub poczatek programu flaga byla sprawdzana i program wykonywal faktyczne przerwanie na samym koncu lub poczatku.

    Chodzi mi o to ze program niezle grzebie w flagach, i przerwanie po srodku moze spowodowac nieprzewidziane skutki.

    6. Czy jako FF rozumiesz 11111111?

    ----
    Update.
    Tak to wyglada.
    Code:

       INP_CH   EQU      0X20      ;INPUTS AND HEX DIVISION: TA, TB, FO, SIM
       MODE   EQU      0X21   


    ;**********************************************************************
       ORG     0x000             ; processor reset vector
       goto    main              ; go to beginning of program
       
    ;- - - - - - - - - INTERRUPT - - - - - - - - - - - - - -

          ORG     0x004             ; interrupt vector location
          NOP   
          
          BANKSEL      PORTB
          MOVF      PORTB,W
          MOVWF      INT_CPY      ;STATE OF PORT B WAS COPIED INTO REGISTER
          
          BANKSEL      IOCB
          MOVLW      B'00000000'   ;ALL INTERRUPTS ARE SWITCHED OFF
          MOVWF      IOCB
          
          BANKSEL      PORTA      ;DELAY 80 MS - MOVE TO BANK 0      
          MOVLW      0x7F
          MOVWF      D1
          MOVLW      0x3F
          MOVWF      D2
    DEL0
          DECFSZ      D1, f
          GOTO      $+2
          DECFSZ      D2, f
          GOTO      DEL0

             ;2 cycles
          GOTO      $+1
       
          BTFSS      INT_CPY,0   ;WHAT IS REASON FOR INTERRUPT?
          GOTO      UPD_REG      ;REASON IS SW2 = UPDATE REGISTERS
          BTFSS      PORTB,1      ;IS REASON SW3 = SELECT INPUT?
          GOTO      SEL_INP      ;YES, REASON IS SELECT INPUT
          RETFIE               ;NO REASON, GO OUT FROM INTERRUPT - IT SHOULD NEVER HAPPEN!!!!!!!!!

    ;SEL INP BUTTON
    SEL_INP   BTFSC      INP_CH,7   ;IF INTERRUPT HAPPENED BECAUSE OF SW3 (SELECT BUTTON) SHIFT INPUT LIKE BELOW
          GOTO      INP_TB      ;TACHO A -> TACHO B
          BTFSC      INP_CH,6
          GOTO      INP_FO      ;TACHO B -> FIBRE OPTICS
          BTFSC      INP_CH,5
          GOTO      INP_SIM      ;FIBRE OPTICS -> SIMULATION
          GOTO      INP_TA      ;SIMULATION -> TACHO A

    ;TACHO A -> TACHO B
    INP_TB   BSF         INP_CH,6      ;TACHO B ON
          BCF         INP_CH,7      ;TACHO A OFF
          GOTO      RF

    ;TACHO B -> FIBRE OPTICS
    INP_FO   BSF         INP_CH,5      ;FIBRE OPTICS ON
          BCF         INP_CH,6      ;TACHO B OFF
          GOTO      RF

    ;FIBRE OPTICS -> SIMULATION
    INP_SIM   BSF         INP_CH,4         ;SIMULATION   ON
          BCF         INP_CH,5         ;FIBRE OPTICS OFF
          GOTO      RF

    ;SIMULATION -> TACHO A
    INP_TA   BSF         INP_CH,7         ;TACHO A ON
          BCF         INP_CH,4         ;SIMULATION OFF
          GOTO      RF


    ;UPDATE REGISTERS BUTTON - SW2
    UPD_REG   BCF         MODE,6         ;DO DIRECTION (CLEAR FLAG)
          BTFSC      PORTE,0         ;CHECK SW4 FOR DIRECTION
          BSF         MODE,6         ;BACKWARD (1 IN REGISTER) WHEN INPUT HIGH

          BCF         MODE,5         ;DO FREQUENCY (CLEAR FLAGS FIRST)
          BCF         MODE,4         ;FREQ:     25KHZ, 50KHZ, 100KHZ, 175KHZ   (READ THIS TABLE VERITICALLY)
          BTFSC      PORTE,1         ;RE1,RE2:   00     01      10       11
          BSF         MODE,5         ;21H5,21H4  00     01      10       11
          BTFSC      PORTE,2
          BSF         MODE,4

          BTFSS      PORTB,2         ;DO TTL OR RS422      (BOTH LOW OR BOTH HIGH ARE NOT CONSIDERED !!!!!!!!!!!!!!!!!! )
          BCF         MODE,7         ;PORTB,2 IS LOW = CLEAR FLAG = TTL
          BTFSS      PORTB,3         
          BSF         MODE,7         ;PORTB,3 IS LOW = SET FLAG = RS
          ;IF BOTH PINS ARE GROUNDED, OR BOTH ARE FREE IT MIGHT BEHAVE IN OAKWOOD WAY !!!!!!!!!!!!!!!!!!!!!!!!!

          BCF         MODE,3         ;DO DIVISION OF FREQUENCY DIVIDOR - CLEAR REGISTERS FIRST
          BCF         MODE,2
          BCF         MODE,1
          BCF         MODE,0
          BTFSC      PORTA,3         ;HIGH ON HEX DIP -> HIGH IN REGISTER, LOW ON HEX DIP -> LOW ON REGISTER
          BSF         MODE,0      
          BTFSC      PORTA,2
          BSF         MODE,1
          BTFSC      PORTA,1
          BSF         MODE,2
          BTFSC      PORTA,0
          BSF         MODE,3
                
    RF      NOP
          BANKSEL      IOCB         ;INTERRUPT IS ON ONCE AGAIN
          MOVLW      B'00000011'   
          MOVWF      IOCB

          RETFIE                    ; return from interrupt
  • Poziom 24  
    Przerwania z RB0 i RB1, oraz poprawione odtwarzanie rejestru W, przy zakończeniu jego obsługi.

    Code:
       org   0
    
              goto    start             
       org   4
          movwf   w_copy         ;zachowaj rejestr W         
          movfw   STATUS         
          movwf   s_copy         ;zachowaj rejestr STATUS
    ;------------------------------------------
          movf   PORTB,F      
          btfss   INTCON,INTF      ;nacisniety przycisk na RB0 ?
          goto   BUTT_1         ;nie !, przycisniety na RB1
    ; obsluga przerwania od BUTT_0
          goto   int_end
    BUTT_1      
    ; obsluga przerwania od BUTT_1
    ;------------------------------
    int_end   movfw   s_copy   
          movwf   STATUS          ;odtworz rejestr STATUS       
             swapf    w_copy ,F
             swapf    w_copy ,W       ;odtworz rejestr W
          bcf      INTCON,INTF       ;kasowanie falgi przerw.     
          bcf      INTCON,RBIF       ;kasowanie falgi przerw.
          retfie                   
    ;=====================================
          
    start   movlw   0e0h
          movwf   STATUS      ;bank 3
          clrf   ANSELH
          clrf   STATUS      ;bank 0
          bsf      STATUS,RP0   ;bank 1
          movlw   3
          movwf   TRISB      ;RB0,RB1 wejscia, reszta wejscia
          movwf   IOCB      ;przerwanie na zmiane stanu
          movlw   7Fh         ;wyzerowany bit RBPU-podciaganie wlaczone
             movwf   OPTION_REG
          clrf   STATUS      ;bank 0
             movlw   88h    ;GIE=1 , RBIE=1
             movwf   INTCON  ;wlaczenie przerwan
    ;      --------        ;kiedy nacisniej dowolny
    ;      --------        ;przycisk juz wystapi przerwanie
    ;      --------


    Oprócz w_copy i s_copy możesz zachować rownież inne rejestry
    Obsługa przerwania może byc w dowolnym miejscu , ale zawsze musi zaczynac sie pod org 4.
    Przyjęcie przerwania kasuje bit GIE w rejestrze INTCON, instrukcja RETFIE ustawia ten bit, tym samym wlącza system przerwań, także nie potrzeba robić tego ręcznie (zbedne jest u Ciebie - movwf IOCB)
  • Poziom 15  
    Metoda zachowania rejestru STATUS, która proponuje adamwesola zawiera bład.
    Podczas odtwarzania rejestru W ulega zniszczeniu bit Z w rejestrze STATUS.

    movfw w_copy ;modyfikuje bit Z w rejestrze STATUS w zależnosci od wartosci w_copy

    Instrukcja SWAPF nie zmienia żadnego bitu rejestru STATUS.
    Dlatego rejestry nalezy zachowywać i odtwarzać w nastepujacy sposób:

    Code:
    org   4 
    
          movwf w_copy       ;zachowaj rejestr W
          swapf STATUS ,W
          clrf STATUS        ;zeruje bity RP0 RP1 i IRP w rejestrze STATUS
          movwf s_copy       ;zachowaj rejestr STATUS

          swapf s_copy,W
          movwf STATUS       ;odtworz rejestr STATUS
          swapf w_copy ,F
          swapf w_copy ,W    ;odtworz rejestr W
          retfie                   
    ;=====================================


    Zmienne w_copy i s_copy najlepiej umiescić w obszarze wspólnym dla wszystkich banków pamieci 70h - 7Fh
  • Poziom 24  
    No chyba masz kolego racje !
    =====================
    Poprzedni mój post zmieniłem, zgodnie ze spostrzeżeniem kol. mkaczor , a także odpowiednio do typu procesora.