PIC konfigurálása 2.

Most egy kicsit bonyolítunk a helyzetünkön és bevonjuk a munkába a Timereket és használni kezdjük a megszakítást is.
A Jó öreg LED-et megtartjuk és veszünk mellé egy másikat is. A Time0-át úgy konfigoljuk, hogy kb. 1 másodpercenként okozzon megszakítást. A LED-eket pedig minden megszakításkor váltjuk. A gombokat átmenetileg elfelejtjük.
 A rajz:


A kapcsolás egyszerűsödött, de ami bent fog történni az korán sem!
Először is át kell konfigurálni a PIC regisztereit, hogy a Timer0 működjön, a megfelelő osztás szerint számáljon, és okozzon megszakítást. A megszakításhoz is be kell állítani néhány regisztert, hogy a megfelelő periféria okozhassa, és a megfelelő prioritáson hajtódjék végre.
A 16F-eknél nincs prioritás választási lehetőség, mert csak egy megszakítási pont van a 0x0004h. A 18F-eknél a két megszakítási pont a 0x0008(High), és a 0x0018(Low), ezek az első példában is jól látszanak.
Akkor lássuk, mit kell ill. nem kell módosítai az első példához képest.
A fordítási beálításokhoz, és a Config bájtokhoz nem kell nyúlni. Viszont az alap beállításoknál kis módosítást teszünk és csak a célra koncentrálunk.
Alap beállítások:
;......................... ... funkció bitek elnevezése ......................
    #DEFINE        ALL_INT_E_T      INTCON,7              ; GLOBALIS MEGSZAKITASOK ENGEDELYEZESE_TILTAS
    #DEFINE        P_INT_E_T          INTCON,6               ; PERIFERIA MEGSZAKITASOK ENGEDELYEZESE_TILTAS

;....................... PORT láb funkciók kiosztása .................................
    #DEFINE        LED_1        PORTA,0     ; ez az egyik LED
    #DEFINE        LED_2        PORTA,1     ; ez a másik LED

Makrókat most nem készítünk, és állandókra sincs most szükség.
 
;............................................. Változók ...........................................................
     CBLOCK      0X0020
        AKKU_TEMP
        STATUS_TEMP
        BSR_TEMP                            ; MEGSZAKITASKOR EZEKBE MENTJUK A FONTOS REGISZTEREKET
    ENDC

A reset és megszakítási pontot megírjuk:
;.......................RESET PONT.............................................   
    ORG    0X0000                    ; "RESET belépési pontja. Ha pl. a WDT vagy a RESET gomb aktiválódik, innen folytatódi ill.
   
GOTO    INI                        ;  kezdődik a további utasításvégrehajtás.
   
    ORG    0X0008                    ; High prioritású megszakítás pont     
    GOTO    MEGSZAK

    ORG    0X0018                     ; Low priorítású megszakítás pont
    RETFIE                               ; Erről a megszakítási pontról rögtön visszatérünk, ha véletlenü idetévedne a PIC.
                                                ;( de véletlenek itt nincsenek!)


; -------------------- Megszakítás kezelése ----------------------------------------
MEGSZAK
    BCF          ALL_INT_E_T                        ; MINDEN MEGSZAK. TILT
    MOVWF     AKKU_TEMP                       ; W REGISZTER ELTAROLASA
    MOVFF     STATUS, STATUS_TEMP     ; STATUS REG TAROLASA
    MOVFF     BSR, BSR_TEMP                   ; BSR REG TAROLASA   

    BTFSS    INTCON,TMR0IF        ; TIMER0 MEGSZAKÍTÁS?
    BRA        MEG_VÉGE                 ; Ha nem, akkor itt nincs teendő. Ebben a példában ilyen nem fordulhat elő, mert más egység nem okozhat megszakítást.

    BTFSS    LED_1                        ; LED_1 BE VAN KAPCSOLVA?
    BRA        LED_BE                     ; Ha nem, akkor bekapcs
    BCF        LED_1                        ; Ha igen akkor kikapcs
    BSF        LED_2                         ; másik meg , be
    BRA         MEG_VÉGE

LED_BE
    BSF        LED_1                ; BEKAPCS
    BCF        LED_2

;.......................................................................................
MEG_VÉGE
    MOVFF     BSR_TEMP, BSR
    MOVF     AKKU_TEMP, W
    MOVFF     STATUS_TEMP,STATUS     ; MENTETT REGISZTEREK VISSZAÁLLÍTÁSA
    BCF        INTCON,TMR0IF                    ; TIMER0 INT Flag Törlése. Erről nekünk kell gondoskodni, mert különben soha nem jutunk ki a megszakításból.
    BSF        ALL_INT_E_T                         ; MINDEN MEGSZAK. Innentől engedélyezett
    RETFIE   

; ----------------------------- Alap beállítások --------------------------------------------
INI
   CLRF    INTCON
    CLRF    INTCON2
    CLRF    INTCON3                            ; KULSO MEGSZAKITAS FORRASOK LETILTVA, FLAGEK TOROLVE

    CLRF    IPR1
    CLRF    IPR2
    CLRF    PIE1
    CLRF    PIE2
    CLRF    PIR1
    CLRF    PIR2                                    ; MEGSZAKITASOKAT KEZELO REGISZTEREK ALAPHELYZETBE ALLITVA

    SETF    CMCON                              ; COMPARATOR OFF

    BSF        INTCON2,RBPU               ; PORTB FELHÚZÓ ELLENALLAS OFF

    MOVLW    B'01111011'
    MOVWF    OSCCON                       ; Belső OSC 8MHz, Nincs freki hangolás   

    MOVLW    B'00001111'  
    MOVWF    ADCON1
                       ; PORTA DIGIT I/O

    MOVLW    B'10000100' 
    MOVWF    T0CON
                          ; TIMER0 BEÁLLÍTÁSA. TIMER0 ON, 32*-es ELŐOSZTÁS, 1 SECENKÉNT MEGSZAKÍTÁS LESZ

  Itt nézzük meg, hogy mitől fog kb. 1sec-enként a Timer0 megszakítást generálni. Miért a 32-es előosztást kellett beállítani a 16bites számlálónál? A fő oszci 8 000 000 Hz-el rezeg, a Timer0 előosztó bemenetére ennek 1/4 része jut, tehát 2 000 000 Hz. Ezt leosztja az előosztó 32-ed részre a számláló bementére, ami 62500Hz, a 16bites számláló 65535 lépésenként fog túlcsordulni, ami megszakítást okoz, így ez kb. 1Hz-nek felel meg. A LED-eknek jó lesz.

   BSF        INTCON2,TMR0IP           ; TIMER0 MEGSZAKITAS MAGAS SZINTŰ LEKEZELES. 8-as CÍM



;------------------------- PORTOK BEÁLLÍTÁSA --  1 -> BEMENET, 0 -> KIMENET ------------------------------------------
    CLRF PORTA
    CLRF LATA
    CLRF PORTB
    CLRF LATB
    CLRF PORTC
    CLRF LATC
    CLRF PORTD
    CLRF LATD
    CLRF PORTE
    CLRF LATE                                ; Ki és bemeneti tárolók törlése
    MOVLW    B'11111111'         
    MOVWF    TRISB           
    MOVLW    B'11111111'          
    MOVWF    TRISC
    MOVLW    B'11111100'            ; RA 0,1 a LED-ekre kapcsolódnak       
    MOVWF    TRISA
    MOVLW    B'11111111'           
    MOVWF    TRISD
    MOVLW    B'11101111'          ;  RE3 a reset és a Vpp-n van. Gyárilag bemenet lehet csak., Párhuzamos prot (PSP) MODUL OFF !
    MOVWF    TRISE                    ; PORTE csak 4 bites

Itt az RA 0,1 lábakon kívül, ami a LED-eket vezérli, minden más lábat bemenetnek konfigoltunk.

;************************** FOPROGI ******************************
PROGRAM
    BSF        ALL_INT_E_T           ; MINDEN MEGSZAK. SZABAD
     BSF        P_INT_E_T                ; MINDEN PERIFÉRIA MEGSZAK. SZABAD
    BSF        INTCON,TMR0IE     ; TIMER0 MEGSZAKÍTÁS ENGEDÉLYEZVE

 
   
DO
    NOP                                    ; várakuzunk a megszakításra
    BRA        DO                       ; relatív ugrás parancs a DO-ra
  

;*******************************************************************

END

Ha mindent jól írtunk be, és én sem rontottam el semmit, akkor a két LED felváltva fog villogni, kb. 1sec ütemmel.

Néhány dolog, amit talán még érdemes megemlíteni.
A megszakítás lekezelésénél látható, hogy egy bevállt módszerrel a kritikus regiszterek tartalmát nekünk kell elmenteni, majd a végén visszatölteni. Ezt a módszert lehet használni szinte minden esetben.
A megszakítások tiltása a lekezelésen belül arra jó, hogy ne lehessen a megszakítás kiszolgálása közben, újabb megszakítást kiszolgálni.
A megszakításokról még annyit, hogy a rá fordított programidőnek  minden esetben  kevesebbnek kell lenni, mint két megszakítás közti idő. Ha ez nem teljesül, akkor soha nem fog a megszakításon kívül jutni a PIC. A arányok megállapítására nem tudok jó módszert, ezt érzéssel kell csinálni.

Néhány szó a BRA-ról. A GOTO helyett használom, mert csak egy szót foglal a memóriában, szemben a GOTO-val. Viszont csak +- ~1000 címeltérést tud átfogni(pontos adatok az adatlapon). Ez kis program, vagy jól szervezett program esetén elegendő. Ha nagyobb címtartományt kell átszelni, akkor ott a GOTO. Én azt ajánlom, hogy a BRA-t használjuk mindig, és ha nem lenne elegendő a tartománya, akkor a fordító úgy is sikítani fog. Ugyanez érvényes az RCALL és a CALL esetében is.

Ismét azt kérem, hogy ha valami nem érthető, vagy hibás, esetleg más véleményetek van, írjátok meg!
Üdv! watt
watt@gportal.hu