PIC18F46K80 CAN ISR

Gast #4011523
Lesenswert?
• ▲
▼
Guten Tag und ein schönes Wochenende an alle Leser und Beantworter,

ich sitze seit einigen Tagen an einer CAN-Kommunikation mittels PIC 
18F46K80. Senden, Empfangen, klappt alles wunderbar - nur an der ISR 
scheitere ich. Ich nutze MPLABX und einen XC8-Compiler. Eigentlich ist 
mit dieser Kombination die Erstellung der ISR fast trivial. Nur für mich 
irgendwie nicht.

Den globalen Interrupt habe ich freigegeben, den Peripherial genauso, 
nur in die ISR will er einfach nicht - hat jemand auf die Schnelle eine 
Idee wo mein Fehler liegt?

Vielen Dank im Voraus für alle die eine passende Antwort parat haben.
1
// PIC18F46K80 Configuration Bit Settings
2

3
// 'C' source line config statements
4

5
#include "configuration.c"
6
#include <xc.h>
7
#include "p18f46k80.h"
8

9
//Funktionsprototypen
10
void delay();
11
void InitECAN();
12
void ECAN_Transmit();
13
void interrupt ISR(void);
14

15
void delay() {
16
    int counter = 0;
17
    for (counter = 0; counter<10000; counter++) {
18
        ;
19
    }
20
}
21

22
void main(void) {
23

24
    TRISBbits.TRISB2 = 0;
25
    TRISBbits.TRISB3 = 1;
26
    TRISCbits.TRISC6 = 0;
27
    TRISCbits.TRISC7 = 1;
28
    TRISBbits.TRISB5 = 0;
29

30
    InitECAN();
31
    INTCONbits.GIE = 1;
32
    PIE5bits.RXBnIE = 1;
33
    PIE5bits.IRXIE = 1;
34
    RXB0IF = 0;
35
    RXB1IF = 0;
36
    IRXIF = 0;
37

38
    while (1) {
39
        PORTBbits.RB0 = 0;
40
        delay();
41
        PORTBbits.RB0 = 1;
42
        delay();
43
}
44

45
}
46

47
void interrupt ISR(void)
48
{
49
    if(RXB0IF && PIE5bits.RXBnIE)
50
    {
51
        RXB0IF = 0;
52
        ECAN_Transmit();
53
    }
54
}
#4011570
Lesenswert?
• ▲
▼
Ich weiß nicht wie es mit dem xc8 aussieht. Ich benutze den C18. Da 
musste der ISR immer noch ein #pragma davor um dem Compiler zu sagen, wo 
die Funktion (im Speziellen _asm GOTO ISR _endasm) liegen soll, 
Ausschnitt:

1
#pragma code high_vector=0x08
2
void HightInterrupt(void) { _asm GOTO ISR _endasm }
3
#pragma code
4

5
#pragma code low_vector=0x18
6
void LowInterrupt(void) { _asm GOTO ISR _endasm }
7
#pragma code
8

9

10
volatile uint32_t os_SysTime = 0;
11

12

13
/**
14
 * @brief Interrupt-Service-Routine des Controllers
15
 *
16
 */
17
#pragma interruptlow ISR
18
void ISR(void) {
19

20
}
#4011628
Lesenswert?
• ▲
▼
Ich weiss nicht was nach einem POR in den Registern steht, sehe jetzt 
auch nicht nach....
Aber vor der globale Interrupt Freigabe:
Mit RCON.IPEN festlegen ob mit oder ohne priorisierten Interrupt 
gearbeitet wird
Im IPRn Register festlegene ob HIGH oder LOW Interrupt.
Und sicherheitshalber die entsprechenden Flags im PIRn Register löschen.
Gast #4012117
Lesenswert?
• ▲
▼
@Erich: Interessant, dass dein Post nur den Sinn hatte mich auszulachen! 
Mal den Befehl im MPLABX mit XC8 eingegeben? Der Comnpiler unterstützt 
diesen Befehl, aber kein Problem, nicht alle Menschen haben Interesse 
daran sich weiterzubilden - und doch, der Rest hat funktioniert!! Egal 
was du glauben magst.

@Stephan Meter: ja, so kenne ich die Routine auch noch als ich sie noch 
im alten MPLAB mit C18 geschrieben habe. Auf dieser Seite:
http://microchip.wikidot.com/faq:31
wird die Implementierung beschrieben wie sie eigentlich in XC8 
vorgesehen ist. Trotzdem vielen Dank für deine Bemühungen.

@Chris B: vielen Dank für den Tipp, werde morgen nochmal schauen ob es 
daran gelegen hat, jetzt ist eindeutig schon zu spät :) hab' gerade auch 
nochmal in das DB geschaut und auf S.147 wieder das gefunden bei dem ich 
mir sicher war, dass ich es schon mal gelesen hatte.

"When the IPEN bit is cleared (default state), the interrupt priority 
feature is disabled and interrupts are compatible with PIC® mid-range 
devices. In Compatibility mode, the
interrupt priority bits for each source have no effect."

Was ich gerade allerdings auch noch gelesen habe, ist, dass das PEIE-Bit 
im INTCON-Register gesetzt werden muss. Das habe ich vergessen.

Lösung kommt, wenn ich sie habe. Wenn natürlich jemand schneller drauf 
kommt - VIELEN Dank
Gast #4019494
Lesenswert?
• ▲
▼
Auch wenn es Ignoranten wie Erich niemals glauben werden (ich hoffe 
nicht, dass ich niemals mit solchen Menschen zusammenarbeiten muss) - 
hier der funktionierende CAN-Quellcode. Geschrieben für MPLAB X mit 
XC8-Kompiler. Vielleicht hilft es jemandem weiter der im Rahmen seines 
Studiums (so wie ich) oder sonstwie damit zu tun hat. Ich wäre froh 
gewesen in diesem Forum etwas dergleichen zu finden, statt ausgelacht zu 
werden!! Gibt es hier keine Moderatoren die so einen Mist unterbinden?
1
// PIC18F46K80 Configuration Bit Settings
2

3
// 'C' source line config statements
4

5
#include "configuration.c"
6
#include <xc.h>
7
#include "p18f46k80.h"
8

9
//Funktionsprototypen
10
void delay();
11
void InitECAN();
12
void ECAN_Transmit(BYTE);
13
unsigned char ECAN_Receive();
14

15
void interrupt ISR(void)            // Interrupt-Service-Routine
16
{
17
    if(RXB1IF && PIE5bits.RXBnIE)   // bei Auslösen des CAN-Empfangen-Interrupts
18
    {
19
        RXB1IF = 0;                 // Interrupt-Flag zurücksetzen
20
        ECAN_Receive();             // Nachricht lesen
21
        ECAN_Transmit(0x02);        // Nachricht versenden
22
    }
23
}
24

25
void delay() {                      // Rudimentäre Warteschleife
26
    int counter = 0;                // Zähler=0 setzen
27
    for (counter = 0; counter<10000; counter++)
28
    {
29
        ;
30
    }
31
}
32

33
void main(void) {
34

35
    TRISBbits.TRISB2 = 0;           // RB2 als Output
36
    TRISBbits.TRISB3 = 1;           // RB3 als Input
37
    TRISCbits.TRISC6 = 0;           // RC6 als Output
38
    TRISCbits.TRISC7 = 1;           // RC7 als Input
39

40
    InitECAN();                     // Inititialisieren des ECAN-Moduls
41
    RXB0IF = 0;                     // Interrupt-Flag löschen
42
    RXB1IF = 0;                     // Interrupt-Flag löschen
43

44
    INTCONbits.GIE = 1;             // Global Interrupts freigeben
45
    INTCONbits.PEIE = 1;            // Peripheral Interrupts freigeben
46
    PIE5bits.RXBnIE = 1;            // CAN-Receive-Interrupts freigeben
47

48
    while (1) {                     // while-Schleife für Hauptprogramm
49
        PORTBbits.RB0 = 0;          // Blinkende LED zur Funktionsanzeige
50
        delay();
51
        PORTBbits.RB0 = 1;
52
        delay();
53
    }
54
}

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.