Forum: Mikrocontroller und Digitale Elektronik PIC18F4550 INTERRUPT mit C18 Compiler


von Stefan (Gast)


Lesenswert?

Hi!

Ich Programmiere mit dem MPLAB C18 Compiler einen PIC18F4550.
Aufgrund der GRÖßE der Projekte möchte ich keinen Assebler-Code 
verwenden.
(Bisherige Assembler Projekte hatten über 10K Zeilen und sind einfach 
schlecht wartbar).
Deshalb bemühe ich mich um den Einstieg mit dem vorhanden C18.

Mein Problem: Ich bekomme den INT0 nicht richtig Programmiert.
Unter Assembler läuft die Hardware - also muss es an der Software 
liegen.

Hier die Interrupt-CODE Sequenzen:

/** V E C T O R  R E M A P P I N G
#pragma code Interrupt_Vector = 0x08
void Interrupt_Vector( void )
{
    _asm GOTO ISR _endasm
} // Interrupt_Vector( void )

#pragma code

/** INITIALISIERUNG

TRISB   = 0b11111111;
temp = PORTB;
INTCONbits.RBIF=0;


RCONbits.IPEN =0; //Schaltet Interrupt Prioritäten aus.
INTCON2 = 0b00000000;
INTCON3 = 0b00000000;
INTCON2bits.RBPU = 1; // PORTB Pullups OFF

INTCONbits.INT0IE = 1; //INT0 External Interrupt Enable bit 1 = Enables 
the INT0 external interrupt
INTCONbits.INT0IF = 0; //Löschen des INT0 Flags
INTCONbits.PEIE = 1;    // Enable all unmasked periphal interrupts
INTCONbits.GIE = 1;    // Enable all HighPrio Interrupt


/**Routine
/********************Interrupt****************************************/

#pragma interrupt ISR
void ISR (void)
{

  FREQ = FREQ-1;
  writeLCD(1);
  Delay10KTCYx(15);
  if (LED==0) LED=1 ;
  else LED=0;
  INTCONbits.INT0IF = 0;  // Int 0 Flag löschen.

}

//*****************************************************************/

Timerinterrupts habe ich Problemlos hinbekommen, beim INT0 wird jedoch 
ständig der RBIF des RCON Registers gesetzt!
Im Manual steht:
"A mismatch condition will continue to set this bit."

Soweitsogut. Aber woher kann solch ein MISMATCH kommen?

Gerne setzt ich auch den kompletten Code rein - aber die Displayroutinen 
sind etwas groß.



Gruß Stefan

von Stefan (Gast)


Lesenswert?

Keiner ne Idee?

von Zwirbeljupp (Gast)


Lesenswert?

Verstehe Dein Problem nicht so ganz.
Was hat das RBIF-Bit mit dem INT0 zu tun?
RBIF wird immer gesetzt, wenn sich der Zustand der eines der Pins 
PORTB<7:4> ändert.
Nunja, warum sich der Zustand der Pins ändert kann ich Dir auch nicht 
sagen, vermutlich lässt Du sie floaten (sind ja alle als Eingänge 
konfiguriert). Aber warum kümmert Dich das RBIF jetzt? Der 
Interrupt-on-Change ist doch garnicht aktiviert (also RBIE = 0), oder 
wie oder was ... hä!?

von Zwirbeljupp (Gast)


Lesenswert?

Davon mal abgesehen:
Ein Delay in einer Interruptroutine ist böseböse!

von Stefan (Gast)


Lesenswert?

Hi - danke schonmal für die antworten.

Hast wohl recht - aber ich will ja erstmal nur den Interruot zum laufen 
bekommen - in späteren Programmen mach ich die delay auf jedenfall raus.
Momentan möchte ich nur nen Drehencoder nutzen.

Zu meinem Problem: Der Interrupt an INT0 wird einfach nicht ausgelöst!
Die Befehle in dem Programm entsprechen aber der gleichen Konfiguration 
wie ich zuvor in Assembler hatte - irgendwo hat sich wohl ein dummer 
dummer fehler eingeschlichen.

Ich hab auch versucht das INT0 Flag bit zu pollen -> dabei wird 
bestätigt das das INT0 Flag einfach nie gesetzt wird. Beim Auslesen mit 
dem Debugger fiel mir jedoch auf, das das RBIF immer gesetztz ist -> und 
da im Manual:
"A mismatch condition will continue to set this bit." steht, dachte ich 
das DA der HASE im Pfeffer liegt.

Weiß jetzt nicht wie ich weiter vorgehen soll :( - hab ich irgendein 
Register vergessen?
Müßen die Ports irgendwie anders behandelt werden? Oder hab ich einfach 
ein fehler in der Initialisierung (wurde nur kopiert).

Gruß Stefan

von Zwirbeljupp (Gast)


Lesenswert?

Hallo,

das RBIF hat damit nichts zu tun. Diese "mismatch condition" bedeutet, 
dass sich der Zustand der Pins RB7:RB4 seit dem letzten Auslesen des 
PortB geändert hat. Dies wird durch das RBIF angezeigt. Um das RBIF 
löschen zu können, musst du PortB zunächst einmal auslesen, erst dann 
kann das RBIF per Software gelöscht werden. Genau das tut dein Code ja 
bei der Initialisierung bereits:
1
temp = PORTB;
2
INTCONbits.RBIF=0;

Allerdings vermute ich ja -wie oben bereits geschrieben- dass Deine Pins 
RB7:RB4 floaten und daher die Missmatch-Bedingung auftritt. Verhindern 
könntest du dies, indem Du die Pullups aktivierst.
1
INTCON2bits.RBPU = 0; // PORTB Pullups ON

Allerdings weiss ich nicht, was bei Dir am INT0 hängt.

Dass das INT0IF nicht gesetzt wird, kann eigentlich nur 2 Gründe haben:
1.) am INT0-Pin tritt einfach keine fallende/steigende Flanke auf
2.) Du löschst das INT0IF (aus Versehen) irgendwo im Code, bevor Du es 
pollst

Du schreibst da was vom Timerinterrupt. Ist der normalerweise auch 
aktiv? In dem Fall musst Du in Deiner ISR natürlich prüfen, welcher 
Interrupt überhaupt auftritt.

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.