Kampis Elektroecke

Konfigurieren des MCP2515

canknotenkomplett_klein.jpg

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 zurückgesetzt. 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 0x88, in das Unterprogramm übergeben.

Umgerechnet ist der Hexwert 0x88 = 1000 1000 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. Da ich erstmal nur mit einem Recieve Buffer arbeiten möchte, schreibe ich nur eine 0x01 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

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. 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. 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