Forum: Mikrocontroller und Digitale Elektronik 18F4520 Interrupt Problem


von Gero N. (geronimo76)


Lesenswert?

Ich versuche seit Stunden, meinem 18F4520 Interrupt Routinen 
beizubringen. Ziel ist es, einen LOW PRIO und einen HIGH PRIO Interrupt 
abzufangen .. der LOW soll anhand PORT B Change (<7:4>) ausgelöst werden 
(INTCONbits.RBIE), der HIGH durch Timer 1 Overflow ...

LEIDER WILL ER NICHT ...

Irgenwo liegt hier ein denkfehler ... ich habe mitlerweile meinen 
Quelltext auf den PORTB CHange INT runtergestutzt ... keine änderung
1
#include <p18f4520.h>
2
#include <delays.h>
3
#include <adc.h>
4
#include <timers.h>
5
#include <string.h>
6
#include <portb.h>
7
#include "MyLCD4.h"
8
#include "eeprom.h"
9
10
/** Configuration *******************************************************/
11
#pragma config OSC   = HS
12
#pragma config FCMEN   = OFF
13
#pragma config IESO   = OFF
14
#pragma config PWRT   = ON
15
#pragma config BOREN  = OFF
16
#pragma config BORV  = 3
17
#pragma config WDT  = OFF
18
#pragma config WDTPS  = 32768
19
#pragma config CCP2MX  = PORTC
20
#pragma config PBADEN  = OFF
21
#pragma config LPT1OSC  = OFF
22
#pragma config MCLRE  = ON
23
#pragma config STVREN   = ON
24
#pragma config LVP      = OFF
25
#pragma config XINST    = OFF
26
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF, CPB = OFF, CPD = OFF
27
#pragma config WRT0 = OFF, WRT1  = OFF, WRT2 = OFF, WRT3 = OFF, WRTB  = OFF, WRTC = OFF, WRTD = OFF
28
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF, EBTRB = OFF
29
30
/** D E F I N I T I O N S ****************************************************/
31
32
#define nop      _asm nop _endasm  // verzögerung 0,25µs
33
34
35
#define Zeile1        0x80
36
#define Zeile2        0xC0
37
#define Zeile3        0x94
38
#define Zeile4        0xD4
39
/* INPINS */
40
  
41
#define Taste1      PORTBbits.RB7
42
#define Taste2      PORTBbits.RB6
43
#define Taste3      PORTBbits.RB5
44
#define Taste4      PORTBbits.RB4
45
46
47
/*=============== INTERRUPT DECLARATIONS ===============*/
48
void MY_HIGH_HANDLER(void);
49
void MY_LOW_HANDLER(void);
50
51
#pragma code MY_HIGH_INT=0x08
52
void MY_HIGH_INT (void)
53
  {
54
  _asm GOTO MY_HIGH_HANDLER _endasm
55
  }
56
57
#pragma code MY_LOW_INT=0x18
58
void MY_LOW_INT (void)
59
  {
60
  _asm GOTO MY_LOW_HANDLER _endasm
61
  }
62
#pragma code
63
#pragma interrupt MY_HIGH_HANDLER
64
void MY_HIGH_HANDLER(void)
65
  {
66
  //Abarbeitung HIGH INTERRUPT
67
  OutLcdControl(0x01); OutLcdControl(Zeile1); LCD_WriteString("HIGH INTERRUPT");
68
  INTCONbits.RBIF   = 0;          //PORT B FLAG LÖSCHEN
69
  }
70
71
#pragma interruptlow MY_LOW_HANDLER
72
void MY_LOW_HANDLER(void)
73
  {
74
  //Abarbeitung LOW INTERRUPT
75
  OutLcdControl(0x01); OutLcdControl(Zeile1); LCD_WriteString("LOW INTERRUPT");
76
77
78
  }
79
80
81
void main(void)
82
{
83
  
84
//PORT C Config
85
  TRISC = 0b11111111;
86
  PORTC = 0;
87
//PORT D Config by LCD
88
/* */
89
90
//PORT E Config
91
  TRISE = 0b00000000;
92
  PORTE = 0;
93
/* === INTERRUPT SETUP ===*/
94
ADCON1         = 0b00001111;
95
PORTB         = 1;
96
TRISB        = 0b11111111;
97
TRISBbits.TRISB7   = 1;
98
TRISBbits.TRISB6   = 1;
99
TRISBbits.TRISB5   = 1;
100
TRISBbits.TRISB4   = 1;
101
102
INTCONbits.GIEH   = 0;
103
INTCONbits.GIEL    = 0;
104
PIE1        = 0b00000000;    // Interrupts löschen
105
//PIE1        = 0b00000001;    // Interrupts löschen außer Timer 1 overflow
106
PIE2        = 0b00000000;
107
RCONbits.IPEN    = 1;
108
INTCON2bits.RBIP  = 0;        // Port B Change Prio
109
INTCON2bits.RBPU   = 1;        // PULLUPS on
110
INTCONbits.RBIF   = 0;
111
INTCONbits.RBIE   = 1;        
112
INTCONbits.PEIE   = 1;
113
INTCONbits.GIEL    = 1;
114
115
//INTCON         = 0b10001000;
116
//                  x!!!!!!!;  => GIE/GIEH = 1
117
//                  !x!!!!!!;  => PEIE/GIEL = 0
118
//                  !!x!!!!!;  => Timer 0 Interrupt OFF
119
//                  !!!x!!!!;  => INT 0 Interrupt OFF
120
//                  !!!!x!!!;  => RB PORTChange Interrupt ON
121
//                  !!!!!x!!;  => Timer 0 Interrupt Flag
122
//                  !!!!!!x!;  => INT 0 Interrupt Flag
123
//                  !!!!!!!x;  => RB PORTChange Interrupt Flag
124
LCD_INIT();                        Delay10TCYx(50);
125
  //LCD TEST
126
  OutLcdControl(0x01);
127
  OutLcdControl(Zeile1); LCD_WriteString("Zeile 1");
128
  OutLcdControl(Zeile2); LCD_WriteString("Zeile 2");
129
  OutLcdControl(Zeile3); LCD_WriteString("Zeile 3");
130
  OutLcdControl(Zeile4); LCD_WriteString("Zeile 4");
131
132
INTCONbits.RBIF   = 0;
133
while(1)
134
  {
135
  //Uhrzeit anzeigen
136
  /* */
137
  if(INTCONbits.RBIF == 1)
138
    {OutLcdControl(0x01); OutLcdControl(Zeile1); LCD_WriteString("INTERRUPT");}
139
  else
140
    {OutLcdControl(0x01); OutLcdControl(Zeile1); LCD_WriteString("Kein INT.");}
141
  if((Taste1 == 0) & (Taste2 == 0) &(Taste3 == 0) & (Taste4 == 0)){INTCONbits.RBIF = 0;}
142
143
  Delay10KTCYx(250);Delay10KTCYx(250);
144
  /* */
145
  }
146
}

in der WHILE schleife lasse ich nur ermitteln, ob er die PORT B Int. 
FLAG setzt ,,, das tut es komischer weise auch ,, aber dennoch springt 
er nicht zur LOW_INT routine

btw .. setzt ich PORT-B INT auf HIGH PRIO .. passiert ebenfalls nix ... 
FLAG wird allerdings gesetzt ....

jemand ein idee?? (BIIIIIITTTTTTTTTTTTEEEEEEEEE)

von PIC N. (eigo) Benutzerseite


Lesenswert?

GIEH ist 0

und das ist beides das selbe:
1
INTCONbits.PEIE   = 1;
2
INTCONbits.GIEL    = 1;

von Gero N. (geronimo76)


Lesenswert?

NICHT ZU FASSEN ... DAS WAR DER FEHLER ...

man sieht halt irgendwann den Wald vor lauter bäumen nicht mehr ...

VIELEN DANK

von PIC N. (eigo) Benutzerseite


Lesenswert?

Kenn' ich =)

von Lehrmann M. (ubimbo)


Lesenswert?

Gero Nimo schrieb:
> in der WHILE schleife lasse ich nur ermitteln, ob er die PORT B Int.
> FLAG setzt ,,, das tut es komischer weise auch

Das ist sehr sehr sehr sehr komisch so ein Polling in die main 
einzufügen. Damit ist ja das gesamte Konzept des Interrupts hinüber. 
Sinn gegen Null - Prgrammiertechnisch gesehen Müll ohne Niveau - ich 
hoffe das war nur zu Testzwecken - ist aber auch da total sinnlos: 
http://de.wikipedia.org/wiki/Interrupt#Zweck

von Gero N. (geronimo76)


Lesenswert?

NATÜRLICH war das nur aus testzwecken, da ich sonst keine andere 
möglichkeit habe, zu ermitteln, ob die FLAG überhaupt gesetzt wurde ...

GrundIdee lag darin, das ich früher nur mit dem Timer-Interrupt 
gearbeitet habe und meine 4 Tasten über den Portstatus innhalb der 
schleife abgefragt habe ... und es ging mit ziemlich schnell gegen den 
strich, dass ich teilweise eine taste 1/2 sekunde gedrückt halten 
musste, damit sich was tut ...

grund dafür ist das komplexes programm ... deswegen der umstieg auf 
40pin pic
(hatte das alles schon soweit fertig laufen auf einem 18F2550)
- mehrere ADC werte lesen  umrechen  ausgeben
- Uhrzeit "zählen"
- Uhrzeitabgleich mit DCF77 Modul
- Datenerfassung und EEPRom beschreibung
- LCD modul aktualisieren
- schaltsequenzen anhand der ADC werte
- ect.pp

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.