Ich versuche, diesen Code zu kompilieren, um LED mit Button Interrupt zu blinken, indem ich den xc8-Compiler und PIC18F4550 verwende. Ich habe diese Warnung bekommen, also werden die Codezeilen ignoriert und das Programm funktioniert nicht richtig (durch Klicken auf die Schaltfläche passiert nichts)
newmain.c:45: warning: (335) unknown pragma "code"
newmain.c:46: warning: (335) unknown pragma "interrupt"
newmain.c:65: warning: (335) unknown pragma "code"
Programmcode
#define _XTAL_FREQ 4000000
#include <pic18f4550.h>
// BEGIN CONFIG
#pragma config OSC = HS
static int cpt = 1;
void IntExternal_INT(void) {
TRISB0 = 1; // PORT B0 as input
INT0E = 1;
INTCONbits.PEIE = 1; //enable periphyrical interrupts
INTCONbits.GIE = 1;
INTEDG0 = 0; //: Interrupt Edge Select bit : 1 = Interrupt on rising edge of RB0/INT pin
// 0 = interrupt on falling edge
INT0F = 0;
}
void delay() {
volatile int i, j;
for (i = 0; i < 2000; i++)
for (j = 0; j < 10; j++);
}
#pragma code isr = 0x08 // Store the below code at address 0x08
#pragma interrupt isr // let the compiler know that the function isr() is an interrupt handler
void iscr(void) {
cpt++;
if (INT0IF) //If External Edge INT Interrupt
{
LATDbits.LATD0 = 1; // RD-0 to High
LATDbits.LATD1 = 1; // RD-1 to High
delay();
LATDbits.LATD0 = 0; // RD-0 to LOW
LATDbits.LATD1 = 0; // RD-1 to LOW
delay();
INT0IF = 0; // clear the interrupt
}
}
#pragma code // Return to the default code section
void main(void) {
IntExternal_INT();
TRISD = 0xF0; // PORT B Setting: Set all the pins in port D to Output.
while (1) {
if (cpt % 2 == 0) {
delay();
LATDbits.LATD0 = 1; // RD-0 to High
LATDbits.LATD1 = 1; // RD-1 to High
delay();
LATDbits.LATD0 = 0; // RD-0 to LOW
LATDbits.LATD1 = 0; // RD-1 to LOW
}
}
}
Haben Sie die XC8-Bedienungsanleitung gelesen ? Abschnitt 5.9 befasst sich mit Interrupts.
Darin heißt es:
Der Funktionsbezeichner interrupt (oder __interrupt) kann auf eine C-Funktionsdefinition angewendet werden, sodass sie ausgeführt wird, sobald der Interrupt auftritt. Der Compiler verarbeitet die Interrupt-Funktion anders als alle anderen Funktionen und generiert Code zum Speichern und Wiederherstellen aller verwendeten Register und kehrt mit einer speziellen Anweisung zurück.
Und:
Eine Interrupt-Funktion muss als Typ void interrupt deklariert werden und darf keine Parameter haben. Dies ist der einzige Funktionsprototyp, der für eine Interrupt-Funktion sinnvoll ist, da sie nie direkt im Quellcode aufgerufen werden.
Dann folgt ein Beispiel:
int tick_count;
void interrupt tc_int(void)
{
if (TMR0IE && TMR0IF) {
TMR0IF=0;
++tick_count;
return;
}
// process other interrupt sources here, if required
}
Der Compiler übernimmt selbst das Einfügen des Codes an der richtigen Stelle in der Vektortabelle, um die ISR aufzurufen.
Standardmäßig verwendet es den Unterbrechungsvektor mit hoher Priorität. Um stattdessen den Vektor mit niedriger Priorität anzugeben, fügen Sie das Attribut ein low_priority
:
void interrupt low_priority tc_int()
while(1);
. Wenn die LED leuchtet, funktioniert der ISR-Code und Ihr Problem liegt woanders.Neben der richtigen Antwort von Majenko haben Sie noch andere Probleme mit Ihrem Code. Es sieht so aus, als hätten Sie eine Konfigurationseinstellung aus einem Beispiel übernommen, das Sie irgendwo gefunden haben. Leider sind die Konfigurationseinstellungen auf jedem PIC unterschiedlich. Die einzige Ausnahme hiervon sind PICs innerhalb derselben Familie. Sie können nicht einfach Konfigurationseinstellungen aus dem Quellcode für einen anderen PIC kopieren und hoffen, dass es funktioniert. So wie es ist, wird Ihr Code aufgrund fehlender richtiger Konfigurationseinstellungen nicht funktionieren.
Glücklicherweise ist es sehr einfach, die richtigen Konfigurationseinstellungen zu erhalten. Angenommen, Sie verwenden MPLAB X, gehen Sie zu Windows->PIC Memory Views->Configuration Bits. Am unteren Bildschirmrand sollte sich eine neue Registerkarte mit dem Namen "Configuration Bits" öffnen. Passen Sie die Einstellungen nach Bedarf in der Spalte Optionen an (Tipp: Sie sollten WDT ausschalten und FOSC auf HS stellen, alles andere kann wahrscheinlich gleich bleiben). Klicken Sie dann auf die Schaltfläche "Quellcode zur Ausgabe generieren". Es wird eine lange Liste von "#pragma config"-Zeilen erzeugt. Kopieren Sie alles und fügen Sie es am Anfang Ihres Codes ein.
volatile
Schlüsselworts Atomblöcke beim Zugriff auf gemeinsam genutzte Variablen und warum Sie nicht int
zum Zählen einer Zahl kleiner als 256 verwenden sollten.
Wladimir Cravero
Wladimir Cravero