Forum: Mikrocontroller und Digitale Elektronik PIC Interrupt in Bank1 endet im nirgendwo


von Tobi D. (fanti)


Lesenswert?

hi,
ich habe ein Problem mit dem Interrupt in Verbindung mit einer 
"table-read" und finde dafür einfach keine Lösung die wirklich 
funktioniert, außer den Interrupt gernell während des Vorgangs 
abzuschalten, was aber nicht wirklich der Sinn des Interrupts ist, ich 
hoffe jemand kann mir da behilflich sein:

PIC16f - Assembler

ich habe eine große Tabelle mit Werten, da ich während der Tabelle aber 
nicht den 8bit Programmcounter überschreiten darf, habe ich die Tabelle 
auf den ProgrammSpeicherbereich von page1 gelegt. Löst nun der Interrupt 
während des Bereichs 0x800 aus, so springt der zuerst zwar zur 0x004 
Adresse aber nicht mehr weiter in den Interrupt (Adresse 0x040) sondern 
zur Adresse 0x840 auf page1 und arbeitet dort weiter.

irgendwas ist also an den Sprungadressen faul, aber wo? ich hab schon 
bei Sprut-Adressierung gesucht aber wurde nicht viel schlauer was mein 
Problem angeht

org  0x0004
  goto  interrupt ; springt zu Adresse 0x40
;-------------------------------

...
     bsf    PCLATH, 3     ;umschalten auf page1 der speicherbank
    call  z1
....

;------------------------
org 0x800
z1
  movfw  kuck
  addwf  PCL,1
  nop
  retlw  b'00011111'
  retlw  b'00011111'
          ...

von Anja (Gast)


Lesenswert?

Tobi D. schrieb:
> org  0x0004
>   goto  interrupt ; springt zu Adresse 0x40

da fehlt noch ein pagesel Befehl.
 org  0x0004
  pagesel interrupt
  goto  interrupt ; springt zu Adresse 0x40

Allerdings mußt Du vorher das PCLATH bzw. Statusregister (je nach 
verwendetem PIC) sichern sonst findet das Programm nach dem Interrupt 
nicht wieder zurück.

Alternativ habe ich auch schon Interrupt-Routinen als Makro definiert 
und auf beide Pages (an den gleichen Offset gelegt). Da spart man sich 
das rücksichern des PCLATH.

Gruß Anja

von Tobi D. (fanti)


Lesenswert?

danke für den Tipp, das mit dem pagesel wäre eigentlich die Lösung 
gewesen, nach der ich gesucht habe,
leider spuckt der Simulator mir jetzt nach einigen durchläufen "stack 
overflow" aus, ich werde es mir morgen nochmal im Einzelschrittmodus 
genauer anschauen und berichten

mit vorher retten meintest du doch das hier oder? (und am ende im 
interrupt natürlich wieder zurück)
    org  0x0004
    MOVFw    PCLATH
    MOVWF   PCLATH_TEMP
    CLRF    PCLATH
    movwf   w_temp
    swapf   STATUS,w
    movwf   status_temp
    pagesel interrupt
    goto  interrupt


den 2. Vorschlag habe ich noch nicht probiert, ist aber doch eher etwas 
als letzte Möglichkeit zu probieren, den interrupt in jede Speicherpage 
zu schreiben :-/

von Anja (Gast)


Lesenswert?

Tobi D. schrieb:
> mit vorher retten meintest du doch das hier oder? (und am ende im
> interrupt natürlich wieder zurück)

Die Reihenfolge stimmt noch nicht ganz. Erst das W-Register sichern, 
dann das Statusregister und erst dann das PCLATH-Register.

Gruß Anja

von Tobi D. (fanti)


Lesenswert?

Jipi, danke Anja :)

jetzt funktioniert es genau so wie es soll, im Debugger und in der 
Schaltung selbst

die Reihenfolge ist also entscheident,
ist mir im ersten Überblick nicht aufgefallen, aber mit deinem Hinweis 
leuchtet es ein.
wenn ich das w Register nicht sofort sichere, verändere ich es mit dem 
sichern den pclath und das veränderte w Register ist für den späteren 
Programmverlauf natürlich fatal.

nochmals danke für deine Mühe, ciao

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.