www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik stm32 und die doofe CAN-Schnittstelle


Autor: Benni Nori (benninori)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich versuche immernoch vergeblich meine CAN-Schnittstelle zum laufen zu 
bringen. Es geht nur um den Test der Hardware, dass heißt ich will 
einfach mal was senden. Ich komme in den Initialisierungsmodus und kann 
die Register nach belieben beschreiben. Aber irgendwie komme ich da 
nicht mehr raus. Ich steh jetzt schon ne Weile auf dem Schlauch und 
komme nicht weiter. Am Ausgang (CAN_High) wird das Signal von High 
(Ruhezustand) auf LOW gesetzt und das wars. Hier mal meine Funktion:

void CanInit()
{

  pCAN->MCR   = can_init;           //Initialisierungsmodus

  while (!(pCAN->MSR & can_init))   //weiter wenn Initialisierungsmodus
  {
  }

  pCAN->BTR   = can_null;           //normal operation
  pCAN->BTR  |= can_lbkm;           //loop back
  pCAN->BTR  |= can_sjw;            //SJW=2
  pCAN->BTR  |= can_ts2;            //TS2=TS1=4
  pCAN->BTR  |= can_ts1;
  pCAN->BTR  |= can_baud;           //Baudrate=1000000

  pCAN->MCR   = can_init;
  pCAN->MCR  |= can_fifopriority;   //Priorität = chronologisch
  pCAN->MCR  |= can_sendonce;       //nur einmal senden

  pCAN->MCR  &= can_initexit;       //normaler Modus

  while (!(pCAN->MSR && can_null))  //weiter wenn normaler Modus
  {
    pCAN->MCR  &= can_initexit;     //normaler Modus
  }
}

Ich bleibe dann immer in der while-Schleife am Schluss hängen. Wenn ich 
mir den Registerinhalt anschaue sind alle Register wie geplant 
initialisiert und auch das INRQ-Bit im MCR-Register wieder auf 0. Aber 
das INAK-Bit im MSR-Register wird nicht zurückgesetzt. Da kann ich 
machen was ich will. Zusätzlich ist immer noch das WKUI-Bit gesetzt. Das 
sollte allerdings keine Auswirkungen haben. Fällt da jemandem ein 
Denkfehler auf?

Wo ich mir auch nicht sicher bin: Wenn ich den Initialisierungsmodus 
verlasse und in den normalen Modus wechsle sollte sich die Schnittstelle 
ja mit den Signalleitungen synchronisieren. Was muss da ablaufen? Habe 
einen umsetzer von USB uf CAN von der Firma PEAK auf der anderen Seite. 
Der sendet aber im Ruhezustand auch nichts. Ist das vielleicht mein 
Problem, das da eine Kommunikation ablaufen müsste?

Danke schonmal für eure/deine Hilfe.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was stört dich an stm32f10x.h?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dass "&&" was anderes ist als "&" weisst du?

Autor: Benni Nori (benninori)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habs mit dem Beispielprojekt von ST versucht, bin damit nicht großartig 
weit gekommen. Hast aber recht die stm32fx.h kann ich mir nochmal 
genauer anschauen.


das mit dem '&&' war jetzt nur ein verzweifelter versuch zum Schluss. 
Eigentlich hatte ich da nur ein '&' stehen.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ben Nor schrieb:

> Hast aber recht die stm32fx.h kann ich mir nochmal
> genauer anschauen.

Ich bezog mich dabei auf das herzallerliebste Thema Bitnamen. Erst 
kommst du mit Hex pur (und den dabei unvermeidlichen falschen Bits drin, 
warauf du aber nicht eingegangen bist) und nun mit eigenen Definitionen 
mit eigenen Bezeichnungen die kein Schwein ausser dir kennt.

Du tust ziemlich viel dafür, anderen Leuten die Hilfestellung so schwer 
wie möglich zu machen. Das kann natürlich jeder so halten wie er will, 
aber wenn man dann Hilfe braucht sieht's halt schlecht aus.

Autor: Benni Nori (benninori)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, hats ja recht. ich geb mein bestes das jetzt verständlicher zu 
gestalten.

Autor: Benni Nori (benninori)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gut, hat zwar jetzt ne ganze weile gedauert, aber ich hab jetzt mal 
meine Initialisierungsfunktionen umgeschrieben:


void CanInit()
{

  CAN1->MCR   = CAN_MCR_INRQ;         //Initialisierungsmodus

  while (!(CAN1->MSR & CAN_MSR_INAK)) //weiter wenn 
Initialisierungsmodus
  {
  }

  CAN1->BTR   = CAN_BTR_BRP;          //Baudrate
  CAN1->BTR  |= CAN_BTR_LBKM;         //loop back
  CAN1->BTR  |= CAN_BTR_SJW;
  CAN1->BTR  |= CAN_BTR_TS2;
  CAN1->BTR  |= CAN_BTR_TS1;

  CAN1->MCR  = CAN_MCR_TXFP | CAN_MCR_NART;  //normaler Modus; Priorität 
= chronologisch; nur einmal senden

  while (!(CAN1->MSR & 0x00000C08))  //weiter wenn normaler Modus
  {
  }
}

sieht das gut aus für euch oder fällt euch jetzt was auf?

Autor: Benni Nori (benninori)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, jetzt hab ich auch die sendefunktion umgebaut und siehe da. es kommt 
was raus. ich muss mich nur noch genauer mit dem btr beschäftigen aber 
es kommt schonmal was. wieso nicht gleich so.

@A. K.: wäre ja nicht so, dass du das schon am Freitag gesagt hast :-)

danke

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ben Nor schrieb:

>   while (!(CAN1->MSR & 0x00000C08))  //weiter wenn normaler Modus

Und was soll dies darstellen? Ich kann mit daraus keinen Reim machen.

Autor: Benni Nori (benninori)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
eigentlich will ich da nur abragen ob das inak bit zurück gesetzt ist. 
da stören mich nur die unnötigen bits wie der zustand der rx-leitung und 
sowas. wenn du einen schickeren vorschlag hast. nur raus damit.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ben Nor schrieb:

> @A. K.: wäre ja nicht so, dass du das schon am Freitag gesagt hast :-)

Ich hatte am Freitag mehrfach um die Bitnamen gebeten. Dieses 0xC00 fiel 
mir da schon auf, aber quid pro quo.

Autor: Benni Nori (benninori)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich gestehe meine schuld ein und verneige mich tief vor dir :-)

Autor: Benni Nori (benninori)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und wo wir grad dabei sind: erare humanum est

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ben Nor schrieb:

> eigentlich will ich da nur abragen ob das inak bit zurück gesetzt ist.
> da stören mich nur die unnötigen bits wie der zustand der rx-leitung und
> sowas. wenn du einen schickeren vorschlag hast. nur raus damit.

Genau deshalb hatte ich um die Bitnamen gebeten. Du wartest hier bis 
eines der Bits für das Rx-Signal, dem letzte Sample-Point oder das 
WKUI-Bit gesetzt sind. Weiss der Geier warum. Möglicherweise wolltest du 
diese Bits loswerden, aber das geht andersrum.

Autor: Benni Nori (benninori)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, genau das ist mein problem. die sind gesetzt und ich will eigentlich 
nur das inak abfrage. weiß aber programiertechnisch nicht wie ich die 
anderen ignoriere.

Autor: Benni Nori (benninori)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich hab halt reingeschaut und gesehen, dass die in dem zustand immer 
gesetzt sind.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ben Nor schrieb:

> ich hab halt reingeschaut und gesehen, dass die in dem zustand immer
> gesetzt sind.

Jo, und was hast du davon? Das INAK-Bit hat du mit der Maske geplättet, 
also genau das was du eigentlich wissen willst.

Wenn du warten willst, bis INAK gelöscht ist, warum nicht analog zu 
oben:
  while (CAN1->MSR & CAN_MSR_INAK) ;

Autor: Benni Nori (benninori)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
klar, danke. da hab ich auf dem schlauch gestanden. ich hab mir die 
ganze zeit gedanken gemacht, wass ich in der klammer ändern muss damit 
es das macht was ich will. aber auf die idee einfach das nicht vor der 
klammer weg zu machen bin ich nicht gekommen.

da hab ich wohl den wld vor lauter bäumen nicht gesehen.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ben Nor schrieb:

NB: Man kann das:

>   CAN1->BTR   = CAN_BTR_BRP;          //Baudrate
>   CAN1->BTR  |= CAN_BTR_LBKM;         //loop back
>   CAN1->BTR  |= CAN_BTR_SJW;
>   CAN1->BTR  |= CAN_BTR_TS2;
>   CAN1->BTR  |= CAN_BTR_TS1;

auch in einem Rutsch:
   CAN1->BTR   = CAN_BTR_BRP          //Baudrate
               | CAN_BTR_LBKM         //loop back
               | CAN_BTR_SJW
               | CAN_BTR_TS2
               | CAN_BTR_TS1;

Autor: Benni Nori (benninori)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
da hst du natürlich auch recht, das habe ich an anderer stelle auch so 
gemacht.

Autor: Benni Nori (benninori)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nochmal recht herzlichen dank für deine mühe und deine hilfe.
jetzt mach ich mich mal noch genauer an das btr. wenn ich mich da wieder 
genau do doof dranstell hörst du in ein paar tagen wieder von mir ;-)

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und bleib bei den Bitnamen. Mag sein, dass es beim Schreiben vom Code 
etwas mehr zu tippen ist, aber beim Lesen vom Code macht das einen 
himmelweiten Unterschied. Du wirst feststellen, dass du auch deinen 
eigenen Code öfter liest als schreibst und dass so mancher Kommentar 
nicht wirklich weiterhilft, da er nur beschreibt, was man da eigentlich 
machen wollte und nicht was man tatsächlich tut.

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.