Forum: Mikrocontroller und Digitale Elektronik 18f2550 - Interrupt feuert nicht


von CJ (Gast)


Lesenswert?

Hallo liebes Forum,

ich habe ein Problem mit meinem Pic18F2550 und dem externen 
INT0-Interrupt. Der Interrupt soll auslösen, sobald eine positive Flanke 
an INT0 ankommt. INT0 liegt auf dem RB0-Pin. Ich benutze den 
ICD2-Debugger von Microchip.

Hier ist mein Interrupt-Config-Bereich:

bsf  TRISB,0    ; RB0 als Eingang
bsf  INTCON2,INTEDG0    ; Interrupt on rising edge
bcf  INTCON,INT0IF    ; Interrupt-Flag löschen
bsf  INTCON,INT0IE    ; Interrupt 0 an Port RB0 erlauben
bsf  RCON,IPEN    ; Priority-Disable

bsf  INTCON,GIE    ; Global Interrupt erlauben


Danach geht das Programm in eine Endlosschleife. Wenn ich jetzt mit 
einem Funktionsgenerator ein 5V, 20ms Rechteck auf RB0 gebe passiert 
nichts.
Wenn ich den Debugger anhalte und per Hand das INT0IF-Flag-Bit von "0" 
auf "1" setze springt das Programm zum Interrupt, d.h. die positive 
Flanke setzt aus irgendeinem Grund nicht das INT0IF-Bit.

Bin für jeden Tip dankbar :)

von CJ (Gast)


Lesenswert?

Nachtrag:

Mal nur zum Verständnis:
Das INT0IF-Flag wird doch immer gesetzt, sobald eine Flanke ankommt, 
oder? Oder muss man das vorher irgendwo enabeln?
Weil ich kann machen, was ich will, dieses INT0IF-Bit wird einfach nicht 
gesetzt. Ich habe z.B. schon versucht, INT0 auf konstante 5V zu legen 
und dann wieder auf Masse usw.
Habe auch schon das Gleiche an INT1 probiert. Aber auch hier wird INT1IF 
nicht gesetzt...

von Meister E. (edson)


Lesenswert?

>Das INT0IF-Flag wird doch immer gesetzt, sobald eine Flanke ankommt,
>oder? Oder muss man das vorher irgendwo enabeln?

Da hast du schon recht, INT0IF wird immer gesetzt. Nur der Sprung in die 
ISR muss per INT0IE 'enabled' werden.

>Habe auch schon das Gleiche an INT1 probiert. Aber auch hier wird INT1IF
>nicht gesetzt...

Das ist schon sehr seltsam, ich denke der Fehler liegt ganz woanders...
Wie sieht denn die Hardware aus, bzw. ConfigurationBits?

Gruss,
Edson

von CJ (Gast)


Lesenswert?

mhm... also hier mal der Config-Bereich, glaube aber nicht, dass da der 
Fehler liegt:


processor    PIC18F2550
  #include  <P18F2550.INC>

;Config-Bereich
  CONFIG    PLLDIV = 5
  CONFIG      FOSC = HSPLL_HS     ; HS 48 MHz
  CONFIG    CPUDIV = OSC1_PLL2
  CONFIG      PWRT = ON           ; power up timer on
  CONFIG      BOR = OFF           ; brown out detect off
  CONFIG      WDT = OFF           ; watchdog off
  CONFIG      LVP = OFF           ; lvp off = Low Voltage Programming 
wird abgeschaltet

von CJ (Gast)


Lesenswert?

achso.. und Hardware:
Ich benutze dieses Test-Board:
http://www.holger-klabunde.de/usb/18f2550.htm

An den Pins VPP, PGD, PGC, VDD und GND hängt der ICD2, Pin21 (=INT0) und 
Pin22(=INT1) gehen direkt an den Pic.

von Der M. (steinadler)


Lesenswert?

Hallo,

hast du auch entsprechend das TRISB Register gesetzt? ('1' für Eingang).
Ansonsten steht auch im Datenblatt, welches INTxIE zu welchem Interrupt 
gehört.
Dann musst du auch aufpassen, dass die Priorität der Interrupts stimmt. 
Es gibt da nämlich High und Low priority.

von CJ (Gast)


Lesenswert?

@Micha

Ja, RB0 ist als Eingang konfiguriert (s.o. bsf TRISB,0)

Das Problem ist wohl, dass das INT0IF nicht gesetzt wird, weniger der 
Quellcode. Ich verstehe aber nicht, warum...

Jetzt mal ganz von Anfang:

Habe mir ein ganz einfaches Programm geschrieben, welches RB0 als 
Eingang konfiguriert und dann in eine Endlosschleife geht:
1
  processor    PIC18F2550      
2
  #include  <P18F2550.INC>
3
;Config-Bereich            
4
  CONFIG      FOSC = HS           ; HS 20 MHz 
5
     CONFIG      PWRT = ON           ; power up timer on 
6
     CONFIG      BOR = OFF           ; brown out detect off 
7
     CONFIG      WDT = OFF           ; watchdog off 
8
     CONFIG      LVP = OFF           ; lvp off = Low Voltage Programming wird abgeschaltet
9
10
;Start
11
  ORG     0x800          ; Code wird ab 0x0800 in den Speicher gelegt
12
    goto    Main                ; Sprung zu Main
13
14
Main
15
  bsf    TRISB,0          ; RB0=INT0 als Eingang
16
  
17
Loop 
18
  Goto  Loop          ; Endlosschleife
19
20
21
  END

Im Debugger klicke ich "Start" an und das Programm läuft. Nun gebe ich 
Rechtecke oder konstante 5V und dann wieder GND an RB0 und rücke auf 
Pause und schaue mir das INTCON-Register an aber INT0IF wird einfach 
nicht gesetzt auf 1 gesetzt...

Hat irgendjemand eine Idee, wo der Fehler ist?

von Der M. (steinadler)


Lesenswert?

CJ wrote:
> Hat irgendjemand eine Idee, wo der Fehler ist?

Ja... da fehlt das INT0IE-Bit. Das muss 1 sein.
1
bsf INTCON, 3

von Analog (Gast)


Lesenswert?

Interner Pullup enabled?

von CJ (Gast)


Lesenswert?

@Micha

Ja, das wäre dann der nächste Schritt. In dem Miniprogramm geht es mir 
nur darum, dass zunächst mal das INT0IF-Flag gesetzt wird.

@Analog
Nein, hatte ich nicht...
Habe jetzt noch
bcf    INTCON2,7   ;PORTB-pull-ups enable
hinzugefügt. Scheint aber auch nichts zu helfen...

von Der M. (steinadler)


Lesenswert?

Poste noch mal bitte den kompletten Code

von CJ (Gast)


Lesenswert?

1
  processor    PIC18F2550      
2
  #include  <P18F2550.INC>
3
;Config-Bereich            
4
  CONFIG      FOSC = HS           ; HS 20 MHz 
5
     CONFIG      PWRT = ON           ; power up timer on 
6
     CONFIG      BOR = OFF           ; brown out detect off 
7
     CONFIG      WDT = OFF           ; watchdog off 
8
     CONFIG      LVP = OFF           ; lvp off = Low Voltage Programming wird abgeschaltet
9
10
;Start
11
  ORG    0x000
12
  goto  Main
13
  ORG     0x800          ; Code wird ab 0x0800 in den Speicher gelegt
14
    goto    Main                ; Sprung zu Main
15
16
Main
17
  bsf    TRISB,0          ; RB0=INT0 als Eingang
18
  bcf    INTCON2,7        ; PORTB-pull-ups enable
19
20
Loop 
21
  Goto  Loop          ; Endlosschleife
22
23
END

Wie gesagt: Alles was ich zur Zeit will ist, dass INT0IF (INTCON,2) auf 
1 geht, wenn ich ein Rechteck (5V, 20ms) an RB0 gebe... Der Sprung zum 
Interrupt usw. funktioniert, wenn ich "per Hand" im Debugger das INT0IF 
auf 1 setze.

von Der M. (steinadler)


Lesenswert?

Warum hast du meinen Rat nicht befolgt???
1
bsf INTCON, 3

Die Zeile fehlt.
du musst doch das Interrupt-Enable Flag setzen.

und das GIE und PEIE fehlt ja auch noch.

von CJ (Gast)


Lesenswert?

@Micha

Weil ich mit diesem mini Programm nicht den Interrupt auslösen, sondern 
nur herausfinden möche, warum INT0IF nicht gesetzt wird. Und soweit ich 
weiß sollte INT0IF immer gesetzt werden sobald eine positive oder 
negative Flanke an INT0 anliegt, ganz egal ob jetzt die anderen Bits 
(GIE, INT0IE usw.) gesetzt sind oder nicht...

Habe jetzt aber trotzdem mal das PRogramm wiefolgt erweitert:
1
  processor    PIC18F2550      
2
  #include  <P18F2550.INC>
3
;Config-Bereich            
4
  CONFIG      FOSC = HS           ; HS 20 MHz 
5
     CONFIG      PWRT = ON           ; power up timer on 
6
     CONFIG      BOR = OFF           ; brown out detect off 
7
     CONFIG      WDT = OFF           ; watchdog off 
8
     CONFIG      LVP = OFF           ; lvp off = Low Voltage Programming wird abgeschaltet
9
10
;Start
11
  ORG    0x000
12
  goto  Main
13
  ORG     0x800          ; Code wird ab 0x0800 in den Speicher gelegt
14
    goto    Main                ; Sprung zu Main
15
16
Main
17
  bsf    TRISB,0          ; RB0=INT0 als Eingang
18
  bcf    INTCON2,7        ; PORTB-pull-ups enable
19
20
  bsf    INTCON,INT0IE      ; INT0 Enable
21
  bsf    INTCON,PEIE        ; 
22
  bsf    INTCON,GIE
23
24
25
Loop 
26
  Goto  Loop          ; Endlosschleife
27
28
  ORG  0008h
29
  nop
30
  nop
31
  bsf    PORTC,1
32
  bcf    INTCON,RBIF
33
  RETFIE
34
  ORG 0018h
35
  nop
36
  nop
37
  bsf    PORTC,1
38
  bcf    INTCON,RBIF
39
  RETFIE
40
41
  END

Wenn das Programm jetzt in der Endlosschelife hängt sieht INTCON wie 
folgt aus: 11010001
d.h.
GIE = 1
PEIE = 1
INT0IE = 1
INT0IF = 0 (Bit1, zweite Stelle von Rechts,arrrgghhhh)
RBIF = 1 (kommt denke ich, weil der Debugger an RB6 und RB7 hängt... 
Sollte aber mit meinem Problem nichts zu tun haben)

Wenn ich nun auf Pause drücke, das INTCON auf 11010011 ändere, also 
einfach nur INT0IF auf 1 setzte, springt das Programm nach 0008h, also 
zum High-Priority-Vektor. So soll es ja auch sein, nur eben automatisch 
wenn ein Rechteckt von 0V auf 5V für 20ms kommt...

von Meister E. (edson)


Lesenswert?

@CJ

Dein PIC geht nach dem Reset mit RB0...4 als analoge Eingänge an den 
Start. Eine Flankenerkennung ist so ja wohl nicht möglich. Lösche das 
Bit PBADEN in der Config, dann klappts auch mit dem Interrupt.

Gruss,
Edson

von holger (Gast)


Lesenswert?

Oder einfach ADCON1 auf 0x0F setzen.

von CJ (Gast)


Lesenswert?

@ Meister Eder

Vielen vielen Dank :) Das war die Lösung.

@Micha
Auch Dir vielen Dank für Deine Hilfe

Für die Nachwelt, hier das funktionierende Programm:
1
  processor    PIC18F2550      
2
  #include  <P18F2550.INC>
3
;Config-Bereich            
4
  CONFIG      FOSC = HS           ; HS 20 MHz 
5
     CONFIG      PWRT = ON           ; power up timer on 
6
     CONFIG      BOR = OFF           ; brown out detect off 
7
     CONFIG      WDT = OFF           ; watchdog off 
8
     CONFIG      LVP = OFF           ; lvp off = Low Voltage Programming wird abgeschaltet
9
  CONFIG    PBADEN = OFF    ; <- LÖSUNG DES PROBLEMS!
10
11
;Start
12
  ORG    0x000
13
  goto  Main
14
  ORG     0x800          ; Code wird ab 0x0800 in den Speicher gelegt
15
    goto    Main                ; Sprung zu Main
16
17
Main
18
  bsf    TRISB,0          ; RB0=INT0 als Eingang
19
  bcf    INTCON2,7        ; PORTB-pull-ups enable
20
21
  bsf    INTCON,INT0IE      ; INT0 Enable
22
  bsf    INTCON,PEIE        ; 
23
  bsf    INTCON,GIE
24
25
26
Loop 
27
  Goto  Loop          ; Endlosschleife
28
29
  ORG  0008h
30
  nop
31
  nop
32
  bcf    INTCON,INT0IF
33
  RETFIE
34
  ORG 0018h
35
  nop
36
  nop
37
  bcf    INTCON,INT0IF
38
  RETFIE
39
40
  END

von Guido (Gast)


Lesenswert?

Hallo...


in Bezug auf den PIC 18F2550 habe ich folgendes Problem und erhoffe 
hilfreiche Tipps zu erhalten. Ich möchte eine Abfrage eines 
Eingangsports erstellen (z.B. PortA), ob dessen Bit1 einen bestimmten 
Zustand führt. Dieses soll in einer ständigen Schleife geführt werden 
bis der Zustand des Bits1 das entsprechende Signal führt und weiter zum 
Ablauf eines weiteren Programmteils geleitet wird. Bei der ständigen 
Abfrage des Bit1 am Port soll aber auch die Möglichkeit bestehen, diese 
Schleife durch einen Interrupt zu unterbrechen.
Jetzt bin ich mir unschlüssig, wie ich den PortA als Eingangsport bzw. 
den Interrupteingang(inkl. dessen Enable/Disenable-Funktion) 
initialisieren muss.
Ich hoffe die Beschreibung meines Anliegens ist soweit verständlich.


Guido...

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.