Forum: Mikrocontroller und Digitale Elektronik MCP2515 Botschaften Empfangen


von Patrick (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich möchte gerne über einen MCP2515 den Empfang einer Nachricht an einer 
LED anzeigen lassen.

Mit Hilfe von
http://www.kreatives-chaos.com/artikel/ansteuerung-eines-mcp2515
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
habe ich es bereits geschaft das eine Nachricht vom Controller zum 
PC(Vector CANalyzer) geschickt wird.

Die Anbindung des MCP2515 zum ATMega8 ist dem CAN Testboard 
nachempfunden.
http://www.kreatives-chaos.com/artikel/can-testboard
Siehe auch Anhang: schaltplan.png

Beim Empfangen einer Nachricht komme ich nun aber mit meinen 
bescheidenen Kenntnissen nicht mehr weiter. Ich glaube hier liegt auch 
ein prinzipielles Verständnisproblem vor.

Im Anhang: Test4.c mein Code (ich arbeite mit CodeVision)

Danke im Voraus für die Unterstützung.
mfg
Patrick

von Rene S. (gigastulle)


Lesenswert?

Da gibt es mehrere möglichkeiten. ich hab das damls per Software 
realiesiert, du könntest aber auch den interruptpin Nur für den Empfang 
einer Botschaft im CAN-Controller einstellen, und den Interruptpin Als 
Anschluss für eine LED nutzen. Oder die RXD Leitung zwischen dem 
CAN-Controller und der Endstufe. Ich würde dir aber eine Softwarelösung 
ans Herz legen

gruß Rene

von Thomas F. (igel)


Lesenswert?

Nun, du hast bereits in der Initialisierung den Interrupt-Ausgang des 
MCP2515 eingeschalten:

mcp2515_write_register(CANINTE, (1<<RX1IE)|(1<<RX0IE));

Hat dieser eine komplette Botschaft empfangen, wird am Atmega der 
Interrupt 1 ausgelöst. Darauf musst du nun reagieren:

unsigned char mcp2515_read_rx_status(void)
unsigned char can_get_message(CANMessage *p_message)

Ob der Impuls lange genug ist, dass du an einer LED was siehts, weiß ich 
jetzt nicht.

von Patrick (Gast)


Lesenswert?

Dies war vielleicht unglücklich ausgedrückt.
Die Anzeige einer LED sollte nur der erste Schritt sein.
Als weiteren Schritt möchte ich natürlich CAN-Botschaften empfangen und 
entsprechend darauf reagieren.

Leider scheitert es aber an der Softewarelösung.


So wie ich das verstanden habe kann ich über den Interupt-Pin den 
Empfang einer Nachricht ermitteln. Und jene Nachricht anschließend über 
SPI abholen.
Wenn man es halt richtig macht xD, aber wie?

mfg
Patrick

von Rene S. (gigastulle)


Lesenswert?

Na auch über die SPI-Schnittstelle, aus dem entsprechenden 
Empfangspuffer RXD1 oder 2. Die SPI-befehle sind alle sehr ausfürlich im 
Datenblatt des MCP2515 beschrieben und wie eine SPI-Schnittstelle mit 
einem AVR angesprochen wird ist hier zu hauf beschrieben.

von Thomas F. (igel)


Lesenswert?

Um die SPI musst du dich gar nicht mehr kümmern, das mach die fertige 
Routine
unsigned char can_get_message(CANMessage *p_message)
vom Creativen Chaos schon für dich.

Du musst diese nur noch aufrufen, wenn INT1 ausgelöst wurde und schon 
liegen die Daten vor. Was du dann damit machst ist natürlich noch offen.

Als erstes brauchst du aber erst mal eine Interrupt-Routine zu INT1.

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmieren_mit_Interrupts

von H.Joachim S. (crazyhorse)


Lesenswert?

Also, erstmal legst du dir eine Variable an, die nur für den Empfang 
benutzt wird:

CANMessage Receive_msg;

Kommt dann der Interrupt des MCP, liest du die Botschaft aus:

// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{can_get_message(&Receive_msg);
CAN_message_received=1;
}

Damit wird schon mal die gesamte Botschaft aus dem CAN-Controller 
gelesen und der Interupt zurückgesetzt.
In der main prüfst du nun, ob die Bitvariable CAN_message_received 
gesetzt ist.
Wenn nicht, ist auf CAN-Seite nichts zu tun.
Wenn doch:

if  (CAN_message_received)
       {CAN_message_received=0;
       #asm ("cli")
       ...tue was mit der Botschaft...
       #asm ("sei")
       }

von Patrick (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

habe heute wieder etwas Zeit gefunden mich mit dem Thema auseinander zu 
setzen.

Nach einiger Zeit konnte ich alle offenen Punkte umsetzten und einige 
kleine Fehler ausbessern.
Im Anhang noch mal der Code, falls mal wer vor den gleichen Problemen 
stehen sollte.

Recht herzlichen Danke für die freundliche Unterstützung.

von H.Joachim S. (crazyhorse)


Lesenswert?

// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
     can_get_message(&Receive_msg);
     CAN_message_received=1;
     printf("Interrupt CAN Nachricht empfangen\r");

}

Das ist ganz ganz schlecht....

von Patrick (Gast)


Lesenswert?

Weil Interrupt möglichst kurz sein sollte?

Ist mir klar ist ja auch nur ein Programm zum testen und verstehen, aber 
danke für den Hinweiß.

von H.Joachim S. (crazyhorse)


Lesenswert?

Das blöde an solchen Testsachen: werden dann gerne vergessen, weil es ja 
funktioniert hat.
Sollte man sich gar nicht erst angewöhnen. Und da du auch noch die UART 
im polling verwendest, dauert die ISR tatsächlich so lange, wie das 
Senden des strings dauert. Interruptbetrieb und ausreichender 
Sendebuffer entschärfen das teilweise.

von Patrick R. (robsn)


Angehängte Dateien:

Lesenswert?

Einen schönen Abend die Herren,

ich habe meinen Aufbau und das Programm erweitert.
2x MCP2515 welche Botschaften empfangen und auf den jeweils anderen 
ausgeben sollten.


Prinzipiell kann jeder MCP2515 Botschaften schicken, aber aus einen mir 
unerfindlichen Grund, wird der Interuptpin der MCP2515 nach dem Empfang 
einer Botschaft, nicht residiert.

Da mir auf den ersten, zweiten und dritten Blick nichts mehr auf und 
eingefallen ist wollte ich mal hier nachfragen ob wer einen Tipp hätte?

Danke im Voraus.

mfg
Patrick

von Schorschi (Gast)


Lesenswert?

Hallo Pattrick,
hört sich interessant an mit 2 x MCP2515, bist du da schon weiter 
gekommen ??????

Gruß
Schorschi

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.