CANduino

Diese Anleitung schreib ich um Nutzern, welchen die Möglichkeiten der CANdalus-Bibliothek zu beschränkt ist, eine flexible Alternative zu ermöglichen. Alle Befehle die in CANduino möglich sind wurden auch in die CANdalus-Bibliothek implementiert.

 

Ich werde hier in diesem Artikel nicht auf alle Befehle bezug nehmen, aber auf alle die nötig sind um ein lauffertige Kommunikation aufzubauen.

Befehle

Zunächst einmal eine Liste, aller Befehle die hier behandelt werden:

 

begin();

baudConfig(int bitRate);

setMaskOrFilter(byte mask, byte b0, byte b1, byte b2, byte b3);

readDATA_ff_0(byte* length_out, byte *data_out, uint32_t *id_out, byte *ext, byte *filter)

readDATA_ff_1(byte* length_out, byte *data_out, uint32_t *id_out, byte *ext, byte *filter)

readDATA_ff_0(byte* length_out, byte *data_out, uint32_t *id_out, byte *ext, byte *filter)

readDATA_ff_1(byte* length_out, byte *data_out, uint32_t *id_out, byte *ext, byte *filter)

resetFiltersAndMasks()

buffer0DataWaiting()

buffer1DataWaiting()

 

 

Bevor ich nun die Befehle im Detail durchgehe, möchte ich auf den Artikel zum CAN-BUS verweisen. Ich empfehle diesen vorher gründlich durchzulesen.

 

begin();

Dieser Befehl initialisiert das CAN-Modul

baudConfig(int bitRate);

Dieser Befehl setzt die Bitrate in kBit/s, zu beachten ist die Maximale Bitrate 1000kBit/s

setMaskOrFilter(byte mask, byte b0, byte b1, byte b2, byte b3);

Dieser Befehl setzt Masken und Filter. Hierzu eine kleine Erläuterung:

Im Feld mask kann man folgende Möglichkeit angeben:

MASK_0, MASK_1, FILTER_0, FILTER_1, FILTER_2, FILTER_3, FILTER_4, FILTER_5

Nun folgen 4 weitere Felder b0 bis b3 welche jeweils 8 Bit lang sind.

Es kommt drauf an ob man Masken oder Filter benutzt, zunächst einmal wollen wir Masken näher betrachten.

Wenn man bei einer Maske ein Bit auf 1 setzt, wird dieses bei dem dazugehören Filter beachtet, bei einer 0 werden die Bits an gleicher Stelle als "Don't Care" betrachtet.

Beispielsweise

 

setMaskOrFilter(MASK_0,   0b11111111, 0b00000000, 0b00000000, 0b00000000);

Jetzt werden beim dazugehörigen Filter ausschließlich die ersten 8 Bit geprüft, alle dahinter liegenden Bits interessieren den Filter nicht.

Zu den Filtern:

Filter lassen Frames mit passenden (d.h. übereinstimmenden IDs) passieren. Hierbei werden aber wie oben beschrieben nur die Bits beachtet welche bei der dazugehörigen Maske auf 1 gesetzt wurden.

 

Folgende Zwei Beispiele:

setMaskOrFilter(MASK_0,   0b11111111, 0b00000000, 0b00000000, 0b00000000);

setMaskOrFilter(FILTER_1,   0b11011101, 0b10100000, 0b00000000, 0b00000000);

wobei die ID des Frames wie folgt lautet: 0b11011101000

Wegen der Maske werden nur die erste 8 Bit beachtet. Die ersten 8 Bit des Filters sind in diesem Fall exakt identisch zu den ersten 8 Bit der ID und deswegen wird die Nachricht in den Buffer durch geschickt. Zu beachten ist in diesem Beispiel auch das ein Standard-Identifier benutzt wird, und deswegen im Filter und in der ID 11 Bit benutzt werden.

 

readDATA_ff_0(byte* length_out, byte *data_out, uint32_t *id_out, byte *ext, byte *filter)

readDATA_ff_1(byte* length_out, byte *data_out, uint32_t *id_out, byte *ext, byte *filter)

Auf den ersten Blick sind die beiden Befehle nahezu identisch, bis auf die 0 bzw. die 1. Diese geben ein ob Buffer0 oder Buffer1 gelesen werden soll. Anschließend muss man der Funktion noch die Pointer übergeben.

  • Einmal die Variable in der die Länge des Datenfeldes gespeichert wird.
  • Dann das Datenfeld in der die Ankommenden Daten gespeichert werden sollen
  • Anschließend ein 32 Bit Integer für die Frame-ID
  • Und zwei Felder in denen ausgegeben wird ob es sich um Extended-Frame handelt und welcher Filter genutzt wird

load_ff_0(byte length, uint32_t *id, byte *data, bool ext)

load_ff_1(byte length, uint32_t *id, byte *data, bool ext)

die load-Befehle sind das Gegenstück zu den read-Befehlen, sie laden die nötigen Information hoch in den CAN-BUS, dafür muss man natürlich der Funktion die Länge übergeben, als auch die Speicherorte der Frame-ID und der zusendenen Daten, falls man den Extended Frame nutzt muss ext auf true gesetzt werden ansonsten auf false.

resetFiltersAndMasks()

Resetet alle Filter und alle Masken.

buffer0DataWaiting()

buffer1DataWaiting()

Überprüft ob im Buffer 0 oder Buffer 1 Daten warten, Anwendungsmöglichkeit z.B. in if-Abfragen

 

Extended Identfier


Ein paar nützliche Hinweise für den Extended Identifier:

Wie schon vorher erwähnt benutzt der Extended identifier statt 11 Bit 29 Bit.

Der Befehl setMaskOrFilter benutzt zusätzlich zu den ersten 11 Bit die hinteren 18 Bit, die drei Bit die dazwischen übrig bleiben, befinden sich alle in b1 und zwar wie folgt:

00011100

Zu beachten sind jetzt die Bits die auf 1 Gesetzt wurden (dies hab ich hier aber nur zur veranschaulichung getan)

Von Links nach Rechts:


SRR: Standard Frame Remote Transmit Request bit

IDE: Extended Identifier Flag bit (wenn der Extended ID benutzt werden soll auf 1 setzen)

nicht benutzt

 

Zu Empfehlen ist auch nochmal das Datenblatt des MCP2515 zu studieren.

 

http://www.alldatasheet.com/datasheet-pdf/pdf/166906/MICROCHIP/MCP2515.html

http://www.alldatasheet.com/datasheet-pdf/pdf/84059/MICROCHIP/MCP2551.html