mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Interupt on Change PIC


Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie kann ich bei einem PIC16F886 einen Interrupt on change an PortB,7 
auslösen?
Ich komm einfachn nicht in die Interrupt routine rein :(

Bitte um kurze hilfestellung, welche Bits ich setzen bzw, löschen muss.

Vielen Danke!

Autor: tastendrücker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wäre es mit ein bisschen Code? Sonst raten sich alle einen Wolf...

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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_

Autor: tastendrücker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du musst in deiner INIT-Routine den PortB auf Digital-I/O schalten (ist 
nach PowerON auf Analog IN)

 BANKSEL 3
 MOVLW   0
 MOVWF   ANSELH
 BANKSEL 0

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
RBIE in INTCON zu setzen dürfte auch nicht schaden.

Autor: Tom (Gast)
Datum:

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

noch eine Idee?

Autor: tastendrücker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> RBIE in INTCON zu setzen dürfte auch nicht schaden.

stimmt
(waren die nicht früher auf '1' nach PON?...)

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
RBIE  hat leider auch nichts genutzt

Autor: tastendrücker (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
naja, mit dem PortC,3 überprüfe ich, ob ich auch in den Interupt 
gesprungen bin.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@tastendrücker
>(waren die nicht früher auf '1' nach PON?...)

The interrupt-on-change feature is
disabled on a Power-on Reset.


Wüsste nicht das es jemals anders war ;)

Autor: tastendrücker (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PIC läuft
aber der interrupt nicht.
Wo kann ich denn einstellen, ob der Pin auf Lo->Hi oder Hi-Lo reagiert?
oder reagiert der auf beide flanken?

Autor: tastendrücker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Reagiert auf beide Flanken. Und: Das Interrupt-Flag musst du in der ISR 
wieder löschen, sonnst wird kein neuer Interrupt ausgelöst.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, ich habe alles so gemacht wie er vorgeschlagen hat.
Ist es vielleicht noch wichtig zu erwähnen, dass ich ein PicKit2 
verwende?

Autor: tastendrücker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dass heisst: Ein Pin toggelt im Betrieb vor sich hin - aber der 
Interrupt löst nicht aus...

Poste doch noch mal den aktuellen Code

Wie wird denn der Pin angesteuert?

Autor: Sven Stefan (stepp64) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: tastendrücker (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
                ^

Autor: Sven Stefan (stepp64) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann musst du aber auch das richtige Bit xor'en

  movlw  b'00000010'
                 ^

Autor: tastendrücker (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

   :

Autor: Sven Stefan (stepp64) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ooops, was hab ich denn da mal in meinem Programm geschrieben (ich hab 
das nur aus einem meiner Programme rauskopiert gehabt)? Ich schreib doch 
eigentlich immer

  xorwf   PORTC,f   (und nicht PORTC,1)

Wo ich mir doch nie merken kann was die 1 bzw. 0 hinter dem Komma 
bedeutet ;-)

Gruß
Sven

Autor: tastendrücker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, man sollte wenn möglich die Symbole verwenden

 w = 0 = WREG  (Ergebnis der Operation wird ins WREG gespeichert)
 f = 1 = file  (Ergebnis der Operation wird ins file gespeichert)

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Sven Stefan (stepp64) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Sven Stefan (stepp64) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja, deine LED toggelt nun in der Startschleife mit einer Frequenz 
von ein paar Megaherz. Du wirst das also nicht bemerken. Die LED wird 
immer leuchten.

Autor: Sven Stefan (stepp64) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.