PIC18 xc8-Compiler: So beheben Sie die Warnung (335) Unbekanntes Pragma "Code"

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
        }
    }
}
Ich denke, Sie müssen Ihren iscr isr nennen, und Sie müssen ihn über dem #pragma interrupt isr deklarieren
uuuund das wird auch nicht funktionieren, weil du da oben nicht so viel Platz im Speicher hast, du brauchst ein goto zu einem geeigneten Handler.

Antworten (2)

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()
Ich habe genau das getan, was Sie gesagt haben, funktioniert aber nicht stackoverflow.com/questions/25553762/… . Also habe ich diese Methode ausprobiert, die ich in einem Tutorial gefunden habe
Ich denke, die #pragma-Methode war von C18, die jetzt veraltet ist.
Sie meinen also, dass die Interrupt-Methode dieses Codes veraltet ist und ich der ersten Methode folgen sollte (Frage zum Stapelüberlauf). Ich verwende den xc8-Compiler
Ja, da XC8 die von mir beschriebene Methode verwendet (und Sie in Ihrer anderen Frage haben), nicht die #pragma-Methode. Deshalb sagt es Ihnen ganz deutlich, wenn Sie kompilieren, dass Sie es falsch machen.
Majenco hat vollkommen Recht, meine Kommentare zu den Fragen sind da, weil ich dachte, es ginge um C18 (falsch gelesen)
Ich würde vorschlagen, Ihren Code auf das Nötigste zu reduzieren und die ISR nur eine LED und sonst nichts einzuschalten (schalten Sie sie nicht einmal wieder aus) - bestätigen Sie, ob die ISR angerufen wird oder nicht. Lassen Sie die Hauptschleife auch nichts tun, nur 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.

die konfiguration wird nicht im code geschrieben durch anklicken Quellcode generieren zur ausgabe
Weitere Dinge, die Sie berücksichtigen / lernen sollten, sind die Verwendung des volatileSchlüsselworts Atomblöcke beim Zugriff auf gemeinsam genutzte Variablen und warum Sie nicht intzum Zählen einer Zahl kleiner als 256 verwenden sollten.
@Makouda, die letzte Zeile meiner Antwort besagt, dass Sie den Text manuell kopieren und einfügen müssen. Es fügt es nicht für Sie in Ihren Code ein.
@DanLaks ok verstehe, ich kann die Ausgabekonfiguration sehen, danke