Filtrovanie...zákmity tlačidla. To môže trvať aj dlhšie ako 20ms. Tlačidlá je dobré ošahať a stav uložiť do registra. Hlavý program si to v registri nájde, vykoná čo treba. Po každom prebehu riadiaceho cyklu si môžeš stav tlačidiel (register) presunúť do druhého registra, čím získaš info v nasledujúcom cykle štyri-info o tom tlačidle:
1- čerstvo stlačené
2-už dlhšie stlačené
3-čerstvo pustené
4-dlhšie pustené
Hlavný program beží v slučke
Podľa tlačidiel zapína porty, nastavuje časovače, zapisuje segmetové registre,vypína porty.
Stále dokola.
IT routina aktualizované časovače dekremetuje, a posiela segmetové registre na port-mux, trebárs každých 10ms, alebo aj pomalšie.
Toto používam pre začiatok a koniec IT rutiny
Kód: Vybrat vše
;**********************************************************************************
;
itvector ORG 0x004 ; interrupt vector location
movwf w_temp ; save off current W register
swapf STATUS,W ; STATUS save to W
clrf STATUS ; banky do 0
movwf status_temp ; save off contents of STATUS register
movfw PCLATH
movwf pclath_temp
clrf PCLATH
if ITUP == 1
pagesel _IntRout
goto _IntRout
else
;==================================================================================
#include <Tgit60502sr.inc> ;TU JE PRERUŠOVACIA ROUTINA
;==================================================================================
endif
RetItRut
movfw pclath_temp
movwf PCLATH
swapf status_temp,w
movwf STATUS
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie ; return from interrupt set up GIE
Uloží sa kontext programu (STATUS, W reg, PCHL) a potom sa všetko vráti späť, aby hlavý program mohol nerušene pokračovať.
Tie registre (w_temp, status_temp, pchl_temp) je dobré umiestniť v oblasti GPS od 0x70 aby sa nemuselo riešiť "bank-ovanie" zložito, pretože prerušenie môže vzniknúť a v inom stave ako BANK0.
Samotná IT rutina môže byť aj v inom PAGESEL0 pri väčších pamätiach, preto je tam aj inštukcia
V prerušovacom programe dekrementuj čítače (môžeš ich mať aj viac pre rôzne použitie).
V hlavnom programe nastavíš hodnotu čítača a potom sleduješ kedy sa dopočíta k nule a vykonáš čo potrebuješ. Ku každému čítaču je dobré mať aj indikátor, že sa požaduje po uplynutí času nejaká akcia. Pri zahájení akcie sa ten indikátor zhodí (vynuluje)
Takéto macro používam v IT routine. Trebárs aj 16 časovačov TIMn =TIM0....TIM15 ( n funguje až do 32)
Každému TIMeru je priradených v registri TER0 a TER1 32 bitové pole pre do ktorého sa po dočítaní čítača zapíše jednotka.
Hlavný program sleduje tento byt (timer-flag) a vie že časovač práve dočítal.
Kód: Vybrat vše
; CASOVAC TIMn pre interupt rutinu
RTM_M macro n
tstf TIM#v(n)
BZ GoTIM#v(n+1)
decf TIM#v(n),F
_Z_TSC
bsf TER#v(n/8),#v(n-(n/8)*8)
GoTIM#v(n+1)
endm
V hlavnom programe sa časovač štartuje zase ako makro ak hodnoty časovačov sú uložené v EERAM
Kód: Vybrat vše
; Code pre Start casovaca TIM(timer) s konstantou TK(tk)
START_TIM_M macro timer,tk
StartTIM#v(timer)TK#v(tk)
movlw TK#v(tk)-H'2100'
LETR#v($)
if LETR#v($)/2048 == 0
call EEData_Read
else
pagesel p0
call EEData_Read
pagesel p1
endif
movwf TIM#v(timer)
bcf TER#v(timer/8),#v(timer-(timer/8)*8)
endm
EEData_Read je funkcia, ktorá vyberie z pamäte EERAM príslusnú hodnotu daného časovača. Na záver makra sa hodnota zapíše do časovača a vymaže sa (pre istotu) príslušný timer-flag-bit v registri TER0/1.
Zápis makra je zložitý, lebo platí pre každý TIM0...31 s príslušným flagom.
V programe je potom jednoduché
Kód: Vybrat vše
.
.
JeVozNaIS ;staci ak na jednej slucke je voz - nahod TIM2,tk2 ;
call StartTIM2TK2 ; tk2 cca ( 0,25 - 0,5 sekundy doporuceny )
NaEndIS
.
.
call StartTIM12TK12
.
.
;******************************************
; SLUCKY
START_TIM_M 2,2 ; staci 0,5sek
return
;testovanie fotosyst
START_TIM_M 12,12 ;
return
;******************************************
Vyššie popísané makro casovača v IT_routine sa zapíšu napr. takto.
Na úpravu rozsahov je v príklade ešte použité ďalšie delenie pre čítače 7,8,9 a ďalšie pre 10,11,12 a tiež pomalšie pre 13, 14, 15
Kód: Vybrat vše
CasovaceIt
; takt osc/4
;compare na hodnotu nastavenu pri inicializacii
;CCPIF
banksel WTCON1 ; preddelicka
decf WTCON1,F
BNZ WEndCas
movlw WTCON1K ; obnov reddelicku
movwf WTCON1
STWCas
clrwdt
incf WTCON,F ; 62,5ms
W1Cas ; CWC1 CWC2
movfw WTCON ; max T 32 64 128 256 512
andlw CW1C ;konstanta pre W2Cas 0X00 / 0X01 / 0X03 / 0X07 / 0X0F /
_Z_TSS ; 1/2 1/4 1/8
goto WEndCas
; konstanta pre CWC1 0x01
RTM_M 0 ; ***31,875sek.*** krok 0,125s
RTM_M 1 ;
RTM_M 2
RTM_M 3
RTM_M 4
RTM_M 5
RTM_M 6
W2Cas
movfw WTCON
andlw CW2C ;konstanta pre W2Cas 0x07
_Z_TSS
goto WEndCas
RTM_M 7 ; max. ***127,5sek. krok 0,5sek
RTM_M 8
RTM_M 9
W3Cas
movfw WTCON
andlw CW3C ;konstanta pre W3Cas 0x1F
_Z_TSS
goto WEndCas
RTM_M 10 ; max. ***510sek. krok 2
RTM_M 11
RTM_M 12
W4Cas
movfw WTCON
andlw CW4C ;konstanta pre W4Cas 0x3F
_Z_TSS
goto WEndCas
RTM_M 13 ;***1020sek.=**8,5min krok 4s
RTM_M 14 ; 4s krok max 1000s/ 16min
RTM_M 15
W5Cas
; RTM_M 16 ;
; RTM_M 17 ;
; RTM_M 18 ;
; RTM_M 19 ;
; RTM_M 20 ;
; RTM_M 21 ;
; RTM_M 22 ;
; RTM_M 23 ;
;
WEndCas
_TACT_S ; idikacia ze preslo 0.125 sec / 0.0625sec
bcf PORTA,0
_TMR1IF_C ; povodne sysytemy pracovali bez CCP
_CCP1IF_C ; CCP sa nastavi na lub. dlzku TMR1
; mozno tak urychlovat cyklus riadenia
; pri 14
EndItRout
banksel 0
if ITUP == 1
pagesel 0
goto RetItRut
endif
Makrá sú výhodné pri častom používaní rovnakých algoritmov nad rôznymi registrami a adresami, prípadne aj bitmi. Takéto adresovanie však je možné iba počas prekladu. Prekladač je schopný matematickými a logickými operáciami vygenerovať podľa parametrov makra adresy registrov a adresy návestí, prípadne aj bitov v registroch.