Forum: Mikrocontroller und Digitale Elektronik PIC 18F2685 - Ext. Interrupt funktioniert nicht


von Marco (Gast)


Lesenswert?

Ich hab ein Problem.
Leider reagiert der besagte PIC nicht auf einen ext. Interrupt an Pin 
RB0. Der Timerinterrupt hingegen klappt wunderbar.
Wie man sieht toggelt der Timerinterrupt eine LED an Port RC0, der 
Interrupt von Pin RB1 soll das bei jeder steigenden Flanke an RC1 tun.

Hier mal mein Quellcode(MPLAB+C18):
1
/** I N C L U D E S **********************************************************/ 
2
#include <p18cxxx.h> 
3
#include "delays.h"                       // für die Warteschleife 
4
  
5
/** Configuration ********************************************************/ 
6
#pragma config OSC = HS   
7
#pragma config PWRT = ON 
8
#pragma config BOREN = OFF 
9
#pragma config WDT = OFF  //Watchdog Timer 
10
#pragma config LVP = OFF  //Low Voltage ICSP 
11
#pragma config PBADEN = OFF //PB0-PB4 digital inputs
12
13
void high_isr(void);
14
15
#pragma code high_vector=0x08
16
void interrupt_at_high_vector(void)
17
  {
18
    _asm goto high_isr _endasm
19
  }
20
21
#pragma code
22
23
#pragma interrupt high_isr
24
void high_isr (void)
25
{
26
TMR0L = 218;             // preset for timer register
27
  if(INTCONbits.TMR0IF)  //Timerinterrupt?
28
  {
29
      if(LATCbits.LATC0) //LED Toggeln
30
    {
31
        LATCbits.LATC0 = 0;
32
        }
33
        else
34
      {
35
          LATCbits.LATC0 = 1;
36
        }
37
    INTCONbits.TMR0IF = 0;  //Timer-Int-Flag rucksetzen
38
    INTCONbits.RBIE = 1;
39
    INTCONbits.INT0IE = 1;  //
40
    INTCONbits.GIE = 1;
41
  }
42
43
44
  if(INTCONbits.RBIF)
45
  {
46
    if(LATCbits.LATC1)
47
    {
48
        LATCbits.LATC1 = 0;
49
        }
50
        else
51
      {
52
          LATCbits.LATC1 = 1;
53
        }
54
    INTCONbits.RBIF = 0;
55
  INTCONbits.RBIE = 1;
56
    T0CONbits.TMR0ON = 0;
57
    INTCONbits.GIE = 1;
58
  INTCONbits.GIEL = 1;
59
    }
60
  if(INTCONbits.INT0IF)
61
  {
62
    LATCbits.LATC0 = 1;
63
    INTCONbits.INT0IF = 0;
64
    T0CONbits.TMR0ON = 1;
65
    INTCONbits.GIE = 1;
66
  INTCONbits.GIEL = 1;
67
    }
68
}
69
70
void main(void){
71
  TRISA = 0x00;
72
  LATA = 0x00;
73
  TRISB = 0xFF;
74
  LATC = 0x00;  
75
  TRISC = 0xF0;
76
  
77
78
  T0CONbits.T08BIT = 1;
79
  T0CONbits.T0CS = 0;
80
  T0CONbits.PSA = 1;
81
  T0CONbits.TMR0ON = 1;
82
  INTCONbits.TMR0IE = 1;
83
    INTCONbits.RBIE = 1;
84
  INTCON2bits.RBIP = 1;
85
  INTCON2bits.INTEDG0 = 1;
86
87
  INTCONbits.GIE = 1;
88
  INTCONbits.GIEL = 1;
89
  while(1);
90
}

Danke schonmal im Voraus für eure Hilfe.
Gruß

Marco

von René (Gast)


Lesenswert?

Hallo Marco,

also wenn ich deinen Code richtig verstehe und mir das Datenblatt zum 
Pic ansehe, dann ziehst du beim externen Interrupt lediglich den RC0 auf 
High Pegel.
1
if(INTCONbits.INT0IF) {
2
    LATCbits.LATC0 = 1;
3
    INTCONbits.INT0IF = 0;
4
    T0CONbits.TMR0ON = 1;
5
    INTCONbits.GIE = 1;
6
    INTCONbits.GIEL = 1;
7
}

Das schalten des RC1 erzeugst du über den RB State change, der laut 
Datenblatt nur über die Pin RB7:RB4 funktioniert. Da du über die Port 
Pins RB7:RB4 nichts gesagt hast, gehe ich davon aus das du die auch 
nicht verwendest.
1
if(INTCONbits.INT0IF) {
2
    if(LATCbits.LATC1) {
3
        LATCbits.LATC1 = 0;
4
    }
5
    else {
6
        LATCbits.LATC1 = 1;
7
    }
8
    INTCONbits.INT0IF = 0;
9
}

Die Interrupt Enable bits müssen nicht noch einmal in der ISR gesetzt 
werden. Da du die an keiner Stelle im Code deaktivierst. Es muss 
lediglich das Interrupt Flag für den INT0 wieder gelöscht werden.

Gruß René

von Marco (Gast)


Lesenswert?

So, ich hänge immer noch (wieder da dran)....habe jetzt mal den Code 
sehr simpel gestaltet. An RB0 liegt ein 1Hz Rechteck. Im Debugmodus 
lässt sich PortB ja anzeigen, da erkennt er auch wunderbar das Rechteck 
- allerdings setzt er nicht das Interrupt-Flag und geht nicht in die 
ISR...
1
#include <p18cxxx.h> 
2
  
3
/** Configuration ********************************************************/ 
4
#pragma config OSC = HS   
5
#pragma config PWRT = ON 
6
#pragma config BOREN = OFF 
7
#pragma config WDT = OFF  //Watchdog Timer 
8
#pragma config LVP = OFF  //Low Voltage ICSP 
9
10
void high_isr(void);
11
12
int temp;
13
#pragma code high_vector=0x08
14
void interrupt_at_high_vector(void)
15
  {
16
    _asm goto high_isr _endasm
17
  }
18
19
#pragma code
20
21
#pragma interrupt high_isr
22
void high_isr (void)
23
{
24
      if(LATCbits.LATC0==0) //LED Toggeln
25
    {
26
        LATCbits.LATC0 = 1;
27
        }
28
        else
29
      {
30
          LATCbits.LATC0 = 0;
31
        }
32
temp = PORTB;
33
INTCONbits.INT0IF = 0;
34
}
35
36
void main(void)
37
{
38
ADCON1 = 0xFF;
39
TRISB  = 0x01; 
40
RCONbits.IPEN = 1;    // Enable High Priority Interrupts
41
INTCONbits.GIEH  = 1;  
42
INTCON2bits.INTEDG0 = 1;
43
INTCONbits.INT0IE=1;
44
INTCONbits.GIE=1;
45
46
47
while(1)
48
{
49
50
}
51
}

von Marco (Gast)


Lesenswert?

Äh, ich hab mein Problem entdeckt.

Es lag weder am Controller noch am Quellcode:
Es war der "Animate" Modus beim Debugen...wenn man den Controller normal 
laufen lässt (egal ob im debug oder nicht) geht es vollkommen 
problemlos. Blöderweise kann man dort halt nicht "zuschaun" was die Bits 
so tun...

von Andreas B. (biosniper)


Lesenswert?

Marco schrieb:

>       if(LATCbits.LATC0==0) //LED Toggeln
>     {
>         LATCbits.LATC0 = 1;
>         }
>         else
>       {
>           LATCbits.LATC0 = 0;
>         }
>

Toggle macht man einfacher so:
1
LATCbits.LATC0 = !LATCbits.LATC0;

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.