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
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ä!?
Davon mal abgesehen: Ein Delay in einer Interruptroutine ist böseböse!
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.