mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik STM32 - CAN-Filter - ST Library v3.40


Autor: nexulm (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Hallo,

ich moechte gerne den CAN-Filter des STM32 (hier: STM32F103) zur 
Filterung von CAN-Botschaften (0x700 - 0x70f) nutzen.
Irgendwie klappt die Filterung aber nicht mit der unten aufgefuehrten 
Initialisierung. Bisher geht entweder alles durch oder nix.
Ich verwende hierzu die ST Library v3.40. Leider finde ich nirgendwo 
eine Beispielcode, der eine Filterung vornimmt. Auch bei den ST 
Beispielen ist der Filter immer "offen" CAN_FilterIdLow=0x0000.
Wer hat diese Struktur schon erfolgreich mit Filterfunktion im Einsatz 
und kann nochmal kurz beispielhaft aufzeigen wie ich eine einzelne 
CAN-ID filter und wie einen Bereich. Die Zusammenhaenge von 
CAN_FilterMode_IdMask und CAN_FilterMode_IdList sowie 
CAN_FilterScale_32bit und CAN_FilterScale_16bit sind mir in ihrer 
Anwendung nicht richtig klar.

/* CAN filter init */
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0700;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000; 
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x07F0;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);

Mike

Autor: nexulm (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
...Problem erkannt und geloest.
Warum ist das nur so kompliziert in die Library eingelossen!?!
Die urspruengliche Initilaisierung muss nur im 5 bit nach links 
geschiftet werden, damit die Bits an der richtigen Stelle des StdId 
ankommen.
Endlich habe ich das Datenblatt und die ST library Struktur verstanden.
Dieser Code-Schnipsel als moegliches Beispiel fuer die Nachwelt.

Endweder...
/* CAN filter init */
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0700 << 5;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x07F0 << 5;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);

...oder
/* CAN filter init */
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0xF000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFE00;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);

Autor: Christoph (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Dem kann ich leider nicht zustimmen. Laut dem Aufbau der Register musst 
du deinen kompletten Identifier von 29 Bit um 3 Bit nach links 
verschieben. Dies liegt daran, dann die ersten drei LSB reserviert sind. 
Reference Manual RM0008 Seite 664.

Hier mein Beispiel:
uint32_t ID1 = 0x1FFFFFFF << 3; //Shift um 3 nach links, da die ersten 3 LSB reserviert sind
CAN_FilterInitStructure.CAN_FilterIdHigh = ID1 >> 16;  //Shift um 16 Bit nach rechts, um an die oberen 16 Bit zu kommen. Hier können nur 16 Bit übergeben werden.
CAN_FilterInitStructure.CAN_FilterIdLow =  ID1 & 0x0000FFFF; //Maskierung der ersten 16 Bit, um an die unteren 16 Bit zu kommen. Hier können nur 16 Bit übergeben werden.

Wenn du jedoch den 11 Bit Identifier benutzt, dann stimme ich deinem << 
5 mehr zu. Alledings habe ich das nicht geprüft. Dann müsstest du aber 
auch die Auswahl bei FilterScale ändern:
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;

Nun ist sowohl die IdHigh, als auch die IdLow eine eigenständige ID. 
Reference Manual RM0008 Seite 642.

Autor: Leonhard (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Ich habe genau das selbe Problem. Die Lösung, wie von nexulm beschrieben 
funktioniert tatsächlich. Er tut so, als hätte er eine 32-Bit-ID.

Wie müsste denn die Initialisierung aussehen, wenn man das über 
Standard-IDs machen wollte. Ich habe es so versucht, weiß aber nicht, 
was daran falsch ist.
//akzeptiere ID 0x110 .. 0x11F
sFilter.CAN_FilterMode           = CAN_FilterMode_IdMask;
sFilter.CAN_FilterScale          = CAN_FilterScale_16bit;
sFilter.CAN_FilterIdHigh         = 0x0000;
sFilter.CAN_FilterIdLow          = 0x0110 << 5;   //ID   001 0001 0000
sFilter.CAN_FilterMaskIdHigh     = 0x0000;
sFilter.CAN_FilterMaskIdLow      = 0x07F0 << 5;   //Mask 111 1111 0000
sFilter.CAN_FilterFIFOAssignment = CAN_FIFO0;
sFilter.CAN_FilterActivation     = ENABLE;
sFilter.CAN_FilterNumber         = 0;
CAN_FilterInit(&sFilter);

Ich setze die FW-Lib v3.30 ein

Autor: Michael L. (michael_l93)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
...auch wenn es schon lange her ist hier der Codeschnipsel zur 
Richtigstellung zur Filterung des CAN-ID Bereiches 0x110-0x11F:
CAN_FilterInitStructure.CAN_FilterIdHigh =  0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0110 << 5;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x07F0 << 5;
Bei der Variante von Leonhard wurde der Filter durch FilterMaskIDHigh = 
0x0000; (= dont care) ausgehebelt und alle Botschaften wurden 
durchgelassen.

Autor: Meier D. (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Falls noch jemand auf diesen Thread stösst (scheint einer der 
informativsten zu sein), hier noch etwas wichtiges, wenn jemand Extended 
Identifier filtern will:
Beim Erstellen der Filter muss das IDE-Bit des CAN-Registers zusätzlich 
noch gesetzt werden:
uint32_t ID1 = 0x1FFFFFFF << 3; //Shift um 3 nach links, da die ersten 3 LSB reserviert sind
CAN_FilterInitStructure.CAN_FilterIdHigh = ID1 >> 16;  //Shift um 16 Bit nach rechts, um an die oberen 16 Bit zu kommen. Hier können nur 16 Bit übergeben werden.
CAN_FilterInitStructure.CAN_FilterIdLow =  (ID1 & 0x0000FFFF) | 0x04; //Maskierung der ersten 16 Bit, um an die unteren 16 Bit zu kommen. Zusätzlich Setzen des IDE-Bits.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.