Konfigurieren des MCP2515

CAN-Knoten komplett klein

Hier zeige ich euch wie ihr mit Hilfe des CAN-Controllers Nachrichten über den CAN-Bus versenden und empfangen könnt.
Die Kommunikation zwischen dem CAN-Controller und dem Mikrocontroller geschieht mit den vorhin erklärten Befehlen über das SPI Interface des Controllers.

Bevor der CAN-Controller verwendet werden kann, muss er eingestellt werden.
Hierfür verwende ich in meinem Programm ein Unterprogramm mit dem Namen „MCP2515_Init“ und dieses Programm sieht so aus:

Sub Mcp2515_init


Reset Cs


Spdr = Spi_reset
Do
Loop Until Spsr.spif = 1
Set Cs


Write_register Canctrl , &H88 


Write_register Caninte , &H01    


Bitmodify Txb0ctrl , &H03 , &H03    


Write_register Cnf1 , &H03
Write_register Cnf2 , &HA0
Write_register Cnf3 , &H02


Write_register Rxb0ctrl , &H20
Write_register Rxb1ctrl , &H20


Bitmodify Canctrl , &HE0 , &H0  


End Sub

Bei der Konfiguration des CAN-Controllers ist ein sehr genaues studieren des Datenblattes wichtig! Es gibt viele Fallstricke über die ich teilweise selber gestolpert bin, weswegen der ganze Spaß nicht funktionieren kann.
Auf einige Fallstricke gehe ich aber noch etwas genauer ein. Ich werde in meiner Erklärung des Programmes öfters Seiten aus dem Datenblatt nennen.
Für ein genaueres Verständnis des Programmes wäre es sinnvoll das Datenblatt parat zu haben ;)
Wie man sieht, besteht dieses Programm fast nur aus aufrufen des Unterprogrammes „Write_Register“. Wie diese Unterprogramme funktionieren wird hier genauer erklärt.
So aber was macht dieses Programm nun genau?
Durch die Zeilen

Reset Cs


Spdr = Spi_reset
Do
Loop Until Spsr.spif = 1
Set Cs

wird der CAN-Controller resetet. Dies sorgt dafür, dass der CAN-Controller bei jedem Neustart des Programmes auf dem Mikrocontroller immer den selben Ausgangszustand annimmt.

-> Das CANCTRL-Register:

Durch die Zeile

Write_register Canctrl , &H88

wird das „CANCTRL“-Register beschrieben. Hierzu wird das das Unterprogramm „Write_Register“ aufgerufen und es werden die Adresse des Registers „CANCTRL“ sowie ein Variablenwert, in diesem Fall &H88, in das Unterprogramm übergeben.
Dieses Register besteht aus folgenden Bits:

CANCTRL
Ab Seite 58 des Datenblattes wird dieses Register genauer erklärt.

Umgerechnet ist der Hexwert &H88 = &B10001000 und auf das Register übertragen bedeutet dies, dass das „OSM“ und das „REQOP2“ Bit gesetzt werden.
Das „OSM“ Bit dient dazu, dass jede Nachricht nur einmal versendet wird.
Mit Hilfe der „REQOP“ Bits wird der CAN-Controller in verschiedene Betriebsmodi versetzt.
Hier wird er in den Configuration Mode versetzt, da laut Seite 57 des Datenblattes die Register CNF1-3, TXRTSCTRL sowie die Filter- und Maskenregister nur beschrieben werden können wenn sich der Controller in diesem Modus befindet.
Den Rest der Bits setze ich auf 0. Wenn der CAN-Controller nun aber mit seiner Taktquelle einen Mikrocontroller versorgen soll, müssen noch die Bits „CLKEN“ sowie „CLKPRE“ gesetzt werden. Dadurch wird der Takt des CAN-Controllers an dem „CLKOUT“-Pin ausgegeben.

-> Das CANINTE-Register:

Die nächste Zeile beschäftigt sich mit dem aktivieren notwendiger Interrupts.
Theoretisch ist sie eher optional, da die Interrupts keine wirklich notwendige Rolle spielen.
Sie dienen nur dazu, damit der Mikrocontroller weiß wenn eine Nachricht eingengen ist, ein Buffer leer ist oder ein Fehler aufgetreten ist.
Diese Dinge kann man natürlich auch rausfinden wenn man die ganze Zeit das Interruptregister des CAN-Controllers ausließt, aber da dies keine wirklich schöne Methode ist und die Zeit bis zum auslesen maßgeblich durch das zusätzlich auszuführende Programm beeinflusst wird, habe ich mich für die Interruptmethode entschieden.

WICHTIG!
Hierbei muss man sehr vorsichtig sein. Man sollte zusätzliche Interrupts nur aktivieren, wenn man weiß wie sie bearbeitet werden. Ich habe die Erfahrung selber gemacht, als ich einfach alle eingeschaltet habe und mich dann gewundert habe warum der Mikrocontroller immer wieder in die ISR gesprungen ist.
Dies hatte den Grund, dass gerade der Error-Interrupt IMMER aktiv ist, sprich man kann ihn über das „CANINTE“-Register nicht abstellen. Vielmehr kann man nur abgestellt werden, dass das Bit im Errorflagregister auftaucht. Und gerade dieser Errorinterrupt wird immer dann ausgeführt wenn diese nicht sorgfältig abarbeitet und alaysiert werden
Da diese für meine Zwecke nicht notwendig sind, habe ich sie vorerst ignoriert.

Mit der Zeile

Write_register Caninte , &H01

beschreibe ich das „Interrupt Enable“ Register.
Dieses Register sieht wie folgt aus:

CANINTE
Ab Seite 50 des Datenblattes wird dieses Register genauer erklärt.

Da ich erstmal nur mit einem Recieve Buffer arbeiten möchte, schreibe ich nur eine 1 in das Register.
Dadurch wird nur der Interrupt vom Recieve Buffer 0 aktiviert.

-> Das TxB0nCTRL-Register:

Der nächste Schritt besteht darin, dass der Transmit Buffer eingestellt werden muss.
Auch hier verwende ich der Einfachheit halber erstmal nur einen Buffer.
Dieser Buffer wird mit dieser Zeile eingestellt:

Write_register Txb0ctrl , &H03

Zusätzlich zu dem Befehl schauen wir uns das Register mal genauer an:

TXBnCTRL
Ab Seite 18 des Datenblattes wird dieses Register genauer erklärt.

Wie zu erkennen ist, setze ich mit dem Befehl die Priorität dieses Buffers auf „Highest“.
Natürlich kann auch jede andere Priorität gewählt werden (bei einem Buffer ist sie auch egal, nur falls später mehrere Buffer verwendet werden sollte die Priorität mit berücksichtigt werden).

-> Die Register CNF1-3:

Mit Hilfe der „Configuration“-Register werden die ganzen Bittimings eingestellt.
Auf das Bittiming gehe ich hier nochmal genauer ein.
Die Codezeilen hierfür sehen wie folgt aus:

Write_register Cnf1 , &H03
Write_register Cnf2 , &HA0
Write_register Cnf3 , &H02

Da ich diese Werte direkt aus dem „Microchip CAN Bit Timing Calculator“ habe und die Berechnung auf einer anderen Seite erklärt habe, gehe ich jetzt nicht gesondert auf diese Register ein.

-> Das RxBnCTRL Register:

Nun werden die Recieve Buffer konfiguriert. In meinem Programm habe ich direkt beide Buffer eingestellt, obwohl ich erstmal nur einen verwende.
Die Codezeile ist für beide Buffer identisch (abgesehen von der Registeradresse) und lautet:

Write_register Rxb0ctrl , &H20

Wichtig anzumerken ist, dass die Register vom Aufbau her etwas verschieden sind. Das Register für Buffer 0 beinhaltet ein „Roll-over“-Bit, welches dafür sorgt das Nachrichten in den Buffer 1 kopiert werden sobald Buffer 0 voll ist und eine neue Nachricht eintrifft.
Für Buffer 1 gibt es dieses Bit nicht. Dafür hat Buffer 1 ein Bit mehr um den Filter auszuwählen.
Da ich in meinem Programm nur Buffer 0 verwende, gehe ich erstmal stärker auf diesen ein.
Das Controlregister für diesen Buffer sieht wie folgt aus:

RXBnCTRL
Ab Seite 27 des Datenblattes wird dieses Register genauer erklärt.

In diesem Register wird nur „RXM0“-Bit auf 1 gesetzt.
Dadurch empfängt der CAN-Controller alle Nachrichten. Durch dieses Bit kann man bestimmen ob der Controller Nachrichten mit einem Standard Identifier (11 Bit) oder Nachrichten mit einem Extendes Identifier (26 Bit) empfangen soll.

WICHTIG!
Dieses Bit berücksichtigt nicht die Filter, sprich selbst wenn der Controller Nachrichten mit einem Standard Identifier empfangen soll, aber die Nachricht einen anderen Identifier besitzt als der Filter, wird die Nachricht abgewiesen.
Es muss also beides stimmen….der Identifier UND der Identifiertyp!

 

-> Zurück zum CAN-Bus

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Time limit is exhausted. Please reload CAPTCHA.