stm32 und die doofe CAN-Schnittstelle

OP #1492761
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.
#1492776
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.
OP #1493161
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?
#1493207
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.
#1493216
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) ;
OP #1493225
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.
#1493228
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;
#1493243
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren