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


von Benni N. (benninori)


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.

von (prx) A. K. (prx)


Lesenswert?

Was stört dich an stm32f10x.h?

von (prx) A. K. (prx)


Lesenswert?

Dass "&&" was anderes ist als "&" weisst du?

von Benni N. (benninori)


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.

von (prx) A. K. (prx)


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.

von Benni N. (benninori)


Lesenswert?

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

von Benni N. (benninori)


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?

von Benni N. (benninori)


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

von (prx) A. K. (prx)


Lesenswert?

Ben Nor schrieb:

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

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

von Benni N. (benninori)


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.

von (prx) A. K. (prx)


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.

von Benni N. (benninori)


Lesenswert?

ich gestehe meine schuld ein und verneige mich tief vor dir :-)

von Benni N. (benninori)


Lesenswert?

und wo wir grad dabei sind: erare humanum est

von (prx) A. K. (prx)


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.

von Benni N. (benninori)


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.

von Benni N. (benninori)


Lesenswert?

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

von (prx) A. K. (prx)


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) ;

von Benni N. (benninori)


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.

von (prx) A. K. (prx)


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:
1
   CAN1->BTR   = CAN_BTR_BRP          //Baudrate
2
               | CAN_BTR_LBKM         //loop back
3
               | CAN_BTR_SJW
4
               | CAN_BTR_TS2
5
               | CAN_BTR_TS1;

von Benni N. (benninori)


Lesenswert?

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

von Benni N. (benninori)


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 ;-)

von (prx) A. K. (prx)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.