Interupt on Change PIC

Gast #904171
Lesenswert?

org  0x0
       GOTO Init
org     0x04

InterruptServiceVector
        movwf   W_save
        swapf   STATUS,W
        bcf     STATUS, RP0
        movwf   Status_save

    BTFSS  PORTC,3
    BSF    PORTC,3
    BTFSC  PORTC,3
    BCF    PORTC,3

Intende_

    BCF    INTCON,RBIF
     bcf     INTCON, T0IF
    swapf   Status_save, w
        movwf   STATUS
        swapf   W_save,f
        swapf   W_save,w

        retfie



Init
  BANKSEL    1
  movlw    b'10000000'
  movwf    TRISB

        bsf     INTCON, GIE
        bsf  IOCB,7
  BANKSEL    0
Start_

  GOTO  Start_
Gast #904197
Lesenswert?

>auch nachdem ich
> BANKSEL    1
>  movlw    b'00000000'
>  movwf    TRISC
>für den ausgabe Pin eingefügt habe gehts leider nicht.

He? Was soll'n das?  Ich denke du hast ein Problem mit IntOnChange an 
PORTB? Was hat denn die Richtung von PORTC damit zu tun?
Gast #904207
Lesenswert?

Ach so ja, die Ausgabe...

Passiert überhaupt was? Schwingt der Quarz oder nimmst du den internen 
Oszi? In deiner Start-goto-Start würde ich mal ein PORTC-Pin toggeln, um 
zu sehen, ob der PIC überhaupt läuft
Gast #904249
Lesenswert?

>PIC läuft
>aber der interrupt nicht.

Hast du den Tip von tastendrücker auch programmiert ?

>Wo kann ich denn einstellen, ob der Pin auf Lo->Hi oder Hi-Lo reagiert?
>oder reagiert der auf beide flanken?

Interrupt On Change reagiert auf beide Flanken. Bei jeder
Änderung (Change) eben. Wenn du eine bestimmte Flanke möchtest
musst du das per Software lösen.
Persönliche Seite #904265
Lesenswert?

Inwieweit banksel mit einer Konstante funktioniert kann ich nicht sagen. 
Die Syntax lautet jedenfalls "banksel label" und wird von mir nur so 
verwendet. Also z.Bsp. so:

    label  equ  0x20
    banksel label

Ansonsten solltest du RBIE noch setzen, sonst werden die IOC-Interrupts 
nicht eingeschaltet. Da RB7 nicht analog benutzt wird, dürfte das 
Umstellen auf digital keine Rolle spielen.

Weiterhin funktioniert deine LED-Toggle-Routine so nicht (hab ich auch 
Anfangs so machen wollen, geht aber nicht)

    BTFSS  PORTC,3
    BSF    PORTC,3
    BTFSC  PORTC,3
    BCF    PORTC,3

Warum? Wenn RC3 Low hat, prüfst du dies auf Zeile 1. Da nicht gesetzt, 
wird der Port auf Zeile 2 gesetzt. Nun prüfst du auf Zeile 3 ob Port 
gesetzt. Ist er nun (wegen Zeile 2) also wird er auf Zeile 4 
zurückgesetzt. Deine LED wird nie leuchten. Ich mach das immer so

   movlw  b'00001000'
   xorwf  PORTC,3      ;LED1 toggeln

Probier es ruhig mal.

Sven
Gast #904271
Lesenswert?

>Weiterhin funktioniert deine LED-Toggle-Routine so nicht (hab ich auch
>Anfangs so machen wollen, geht aber nicht)

>    BTFSS  PORTC,3
>    BSF    PORTC,3
>    BTFSC  PORTC,3
>    BCF    PORTC,3

Oops, is' mir gaanich aufgefallen...

>   movlw  b'00001000'
>   xorwf  PORTC,3      ;LED1 toggeln

muss aber sein:

   movlw  b'00001000'
   xorwf  PORTC,1      ;LED1 toggeln
                ^
Gast #904293
Lesenswert?

@Sven Stefan

nein, es gibt nur

   xorwf  PORTC,0      ; -> Ergebnis in WREG
   xorwf  PORTC,1      ; -> Ergebnis in PORTC

daher:

   movlw  b'00000001'
   xorwf  PORTC,1      ; RC0 toggeln

   movlw  b'00000010'
   xorwf  PORTC,1      ; RC1 toggeln

   movlw  b'00000100'
   xorwf  PORTC,1      ; RC2 toggeln

   movlw  b'00001000'
   xorwf  PORTC,1      ; RC3 toggeln

   :
Gast #906313
Lesenswert?

Vielen dank für eure Ausführungen, aber...
Geht immernoch nicht, bin ich zu doof?
Hoffentlich sagt ihr jetzt ja und erklärt mir was ich falsch mache.
Hier mein Code

#include <p16F886.inc>
#define CONFIGURATION1 _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & 
_MCLRE_ON & _CP_OFF
#define CONFIGURATION2 _BOR_OFF & _IESO_OFF & _FCMEN_OFF & _LVP_OFF & 
_DEBUG_OFF
        __CONFIG _CONFIG1, CONFIGURATION1 & CONFIGURATION2

W_save    EQU    0x26
Status_save  EQU    0x27


  org   0x00
  GOTO  Configuration

  org     0x04

Interrupt
  movwf   W_save
  swapf   STATUS,W
  bcf     STATUS, RP0
  movwf   Status_save

  movlw  b'00000100'
  xorwf  PORTC,3      ;LED3 toggeln

   BCF    INTCON,RBIF
      bcf     INTCON, T0IF

  swapf   Status_save, w
        movwf   STATUS
        swapf   W_save,f
        swapf   W_save,w
  BCF  PORTB,3
        retfie

Configuration
  clrf    PORTC
  BANKSEL    TRISC
  movfw    TRISC
  andlw    b'00000000'
  movwf    TRISC
  BANKSEL    0

  clrf    PORTB
   BANKSEL    TRISB
  movfw    TRISB
  iorlw    b'11111111'
  movwf    TRISB
  BANKSEL    0

  BANKSEL ANSEL ;
  CLRF    ANSEL
  BANKSEL ANSELH ;
  CLRF    ANSELH
  BANKSEL    0

  BSF     INTCON,RBIE
        bsf     IOCB,7
        bcf     OPTION_REG,7
   bsf     INTCON, GIE

Start_
  movlw   b'0001000'
  xorwf   PORTC,3      ;LED1 toggeln
  GOTO  Start_

     end



Mein signal das ich anlege ist... +Versorgungsspannung und GND ohne 
beschaltung.
Persönliche Seite #906471
Lesenswert?

Arbeitest du auch manchmal mit dem Simulator? Und liest du auch die 
Fehlermeldungen? Dann hättest du gesehen was falsch läuft...

1. Routine Interrupt:

    movlw  b'00000100'
    xorwf  PORTC,3      ;LED3 toggeln

   Das hatten wir doch schon hier besprochen. Da hatte ich einen Fehler 
geschrieben. Hinter xorwf PORTC,3 kann keine 3 stehen nur ein f oder w. 
Mach da also ein f draus. In dem Befehl davor (movlw b'00000100' musst 
du die 1 um eine Stelle nach links versetzen, wenn du deine LED an 
PORTC,3 angeschlossen hast.

2. Falsche Register Bank (die Zeilen vor Marke Start)

  BANKSEL    0

  BSF     INTCON,RBIE
  bsf     IOCB,7
  bcf     OPTION_REG,7
  bsf     INTCON, GIE

INTCON liegt in Bank 0 -> richtig
IOCB und OPTION_REG liegt in Bank 1 -> musst du vorher umschalten!

So, und wenn das auch nicht geht, weiß ich nicht mehr weiter.

Schönen Abend noch (und grübel ruhig selbst mal ein wenig)

Sven
Persönliche Seite #906510
Lesenswert?

Und das bcf PORTC,3 vor retfie ist zuviel nimm es raus. Dadurch löschst 
du die LED gleich wieder, nachdem du sie eingeschaltet hast.

So nun hab ich bei der Simulation den Fehler, dass das Programm nicht 
mehr aus der Interruptroutine herauskommt. Nach einem Blich ins 
Datenblatt:

This interrupt can wake the device from Sleep. The user,
in the Interrupt Service Routine, clears the interrupt by:

a) Any read or write of PORTB. This will end the
mismatch condition.

b) Clear the flag bit RBIF.

Du musst also vor dem löschen des RBIF-Bits noch den PortB lesen. Sonst 
wird das RBIF Bit nicht zurückgesetzt und die ISR kann nicht beendet 
werden.

Also bei mir läuft die Simulation. Nun du...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren