Skok na přerušení ze druhé strany programu

Zdravím, mám problém s přerušením u PIC16F876A. Mám vytvořený program pro ovládání zimní zahrady. Na první stránce programového kódu (ORG 0) je samotný program pro zobrazování informací na displeji, testování vstupů atd. Pak je zde přerušení kde se čte klávesnice. K přerušení dojde při přetečení TMR0. Ostatní přerušení jsou zakázána. Na další straně programového kódu (ORG 0x900) je ovládání menu celého zařízení. Fungovat to má tak že program běží pouze na první straně kódu a pouze při stisknutí tlačítka menu na klávesnici skočí na stranu 2. Všechno funguje až do doby než pogram přeskočí na stranu 2. V tu chvíli přestane fungovat přerušení a nefunguje ani když se program vrátí na stranu 1. Musí se při skoku na jinou stranu kódu nějak ošetřovat přerušení nebo TMR0?
Děkuji předem za pomoc

Zkus si ošetřit i PCLATH, případně FSR. Taky jsem s tím měl problémy.

[code] org 0x0004 ; vektor přerušení
;*********************************
PRERUS
MOVWF TMP_W
MOVF STATUS,W
MOVWF TMP_S
movf PCLATH,w
movwf TMP_PCLATH
; movf FSR,w
; movwf TMP_FSR
; movf INDF,w
; movwf TMP_INDF

pagesel	0		;TOTO DELA DOBREJ BORDEL
banksel	0		;TOTO DELA DOBREJ BORDEL
bcf		STATUS,IRP

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

; vykon

;********************************
;dokončit přerušení
;--------------------------------
INT_END
KP
; movf TMP_INDF,w
; movwf INDF
; movf TMP_FSR,w
; movwf FSR
MOVF TMP_PCLATH,W
MOVWF PCLATH
MOVF TMP_S,W
MOVWF STATUS
SWAPF TMP_W,F
SWAPF TMP_W,W
RETFIE

[/code]

Díky moc, vypadá to že to chodí. Zatím jen v MPLABU. Doma to nahraju do PIC a uvidím. Ještě jsem akorát musel do toho přerušení doplnit CLRF PCLATH aby to přerušení proběhlo správně jinak mě to stejně odkazovalo jinam. Ještě v tom mám trochu zmatek :slight_smile:

pagesel 0 je místo clrf PCLATH, ale je fakt, že já ho tam mám taky. pagesel 0 nevynuluje celej PCLATH. Mám ho, ale těsně před obsluhou přerusení (v tom výkonu). :smiley:

Aha to jsou věci. banksel ani pagesel neznám. Ještě budu muset nasbírat nějaký informace. Asi jsem si s tím programem vzal velký sousto :slight_smile:

A PAGE 1 jako org 0x900 je dle mě špatně. PAGE 1 je od 0x0800 do 0x0FFF. PAGE 2 je od 0x1000 do 0x17FF, PAGE 3 je od 0x1800 do 0x1FFF, viz datasheet str. 11

Aha takže se vlastně okrádam o kousek prostoru protože mám prostor mezi 0x800 a 0x900 nevyužitej. Tu adresu jsem našel v knížce o PIC16876. Díky za upozornění

Myslím, že jsi v tomto případě o nic nepřišel. Jsou to pseudoinstrukce, které assemler nahradí kódem BCF a jak výše uvedeno “TOTO DELA DOBREJ BORDEL”
Nevidím jediný důvod tuto konstrukci používat.

pagesel X, u 876x 0-3, nastavuje STATUS,RP0 a RP1. Používám ho, když skáču do jiné stránky, ale používám ho jako pagesel MAIN. tak mam jistotu, že se RPx nastaví tak jak má a já to nemusím hlídat. Nechápu, co ti na použití této pseudoinstrukce vadí? Něco podobného platí i pro banksel

Nějak jsem totiž nepochopil funkci direktivy banksel a nebo dělám někde hrubou chybu.
Když napíšu krátký prográmek:

list P=PIC16F877 #include <P16F877.INC> errorlevel -302 lab0 EQU 0x00 lab1 EQU 0x01 lab2 EQU 0x02 lab3 EQU 0x03 ;--------- ZACATEK PROGRAMU ------------------------------------------- org 0x0000 ; zacatek programu loop movlw B'01100000' movwf STATUS banksel lab0 banksel lab1 banksel lab2 banksel lab3 banksel lab0 goto loop end ; konec programu

Tak překlad tohoto prográmku vypadá takto:

0000 3060 MOVLW 0x60 0001 0083 MOVWF 0x3 0002 1283 BCF 0x3, 0x5 0004 1283 BCF 0x3, 0x5 0006 1283 BCF 0x3, 0x5 0008 1283 BCF 0x3, 0x5 000A 1283 BCF 0x3, 0x5 000C 2800 GOTO 0

No a s tím výsledkem si nějak nevím rady.

Já to zblbl

pagesel x je, že nastavení PCLATH bude dle stránek
a
banksel x je, že dojde k nastavení STATUS, RP0 a RP1

a u tebe jsou všechny v bank0, tak proto je ten překlad stejnej. Neboli BCF STATUS, RP0. Akorát nevím, jak by to vypadalo, kdyby jsi byl v bank 2 nebo 3

Až ted jsem to pochopil. Ty jsi nastavil RP0 a RP1 do 1
To pak nemůže fungovat.

EDIT: Ale je zajímavé, že když to kroukuješ v MPLABu, tak to u prvního banksel hodí RP1 i RP0 do nuly. Nikdy jsem o tom takhle nepřemýšlel, ale musí to fungovat, protože to používám a nikdy jsem s tímhle problém neměl.

   list      P=PIC16F877A     
   #include <P16F877A.INC>        
 errorlevel -302
lab0 EQU 0x20
lab1 EQU 0xA0
lab2 EQU 0x120
lab3 EQU 0x1A0
;--------- ZACATEK PROGRAMU -------------------------------------------
   org   0x0000                  ; zacatek programu
loop
	movlw	b'01100000'
	movwf	STATUS
	banksel lab0
	banksel lab1
	banksel lab2
	banksel lab3
	banksel lab0
	goto loop
    end                         ; konec programu[/code]

Tohle krásně přepíná STATUS, ale překlad je hroznej

[code] MOVLW 0x60
  MOVWF 0x3
  BCF 0x3, 0x5
  BSF 0x3, 0x5 
  BCF 0x3, 0x5 
  BSF 0x3, 0x5
  BCF 0x3, 0x5 
  GOTO 0

Je legrační, že jsem svůj program upravil prakticky do stejné podoby. Všiml jsem si také stejného efektu při simulaci jako ty. Ale především se podívej na svůj výsledek:

MOVLW 0x60 MOVWF 0x3 BCF 0x3, 0x5 BSF 0x3, 0x5 BCF 0x3, 0x5 BSF 0x3, 0x5 BCF 0x3, 0x5 GOTO

Tohle přece nepřepíná správně ! Přepíná to pouze mezi bankou 0 a 1.

Jsem to napsal blbě. Jako že při simulaci to přepíná správně. Ale proč to teda funguje správně v reálu?

To teda nevím. V simulaci se to chová naprosto správně a ten rozpor mě vadí. Nedovedu to vysvětlit.

Když to zhrnu, tak v simulaci a reálně to funguje, ale podle překladu by to fungovat nemělo. Divné.

Asi jsem na to přišel

bcf STATUS,RP0 - 1283
bsf STATUS,RP0 - 1683
bcf STATUS,RP1 - 1303
bsf STATUS,RP1 - 1703

A když dáš banksel 0, tak je v HEXU kod 1283 1303, banksel lab3 dá 1683 1703, takže je to dobře, akorát ten disassemler je nějak zmatenej, ale v HEXu je to dobře.
Ale co teda nefunguje, je příkaz banksel 1,2,3 atd. To udělá to samé, jako banksel, 0. Takže příkaz banksel funguje jen se jménem registru!!

EDIT: A jak tak koukám, tak i v tom disassembleru je to dobře. Jeden příkaz, jeden řádek. Ale u banksel jeden chybí. Takže to není jen zobrazené. 00,01,02,04,06,08,0A,0C,0D,0E,0F

0000 3060 MOVLW 0x60 12: movlw b'01100000' 0001 0083 MOVWF 0x3 13: movwf STATUS 0002 1283 BCF 0x3, 0x5 14: banksel lab0 0004 1683 BSF 0x3, 0x5 15: banksel lab1 0006 1283 BCF 0x3, 0x5 16: banksel lab2 0008 1683 BSF 0x3, 0x5 17: banksel lab3 000A 1283 BCF 0x3, 0x5 18: banksel lab0 000C 2800 GOTO 0 19: goto loop 000D 0000 NOP 20: nop 000E 0000 NOP 21: nop 000F 0000 NOP 22: nop

Jsem dobrej :smiley: :smiley: :smiley: :smiley:

Nejsi jen dobrej, jsi nejlepší :smiley: :smiley: :smiley:
Je to opravdu skryté, ale v hex kódu to je obsaženo. Hned budu klidněji spát

Nasadil jsi mi s tím brouka do hlavy. Bych to asi přestal používat, i když jsem s tím zatím problémy neměl. Ale můžu v klidu usnout a čekat, kdo, co jak a proč se stane zítra. :smiley: :smiley: :blush: :smiley: :blush:

K těm dohadům okolo BANKSEL - správně se ta konstrukce používá takto: BANKSEL jmeno_registru, např. BANKSEL TRISB, překladač už sám určí, která je to banka. Význam je, že člověk nemusí tolik čumět do datasheetu.

Spíš vidím výhodu v tom, že když už mám napsanej třeba skoro celej program a najednou potřebuju registr přemístit někam jinam, tak když to mám ošetřene banksel, tak o tom registru nemusím vůbec přemýšlet.