Forum: Fahrzeugelektronik CAN-Bus Sender mit STM32CubeIDE für Blue Pill erstellen


von Olli Z. (z80freak)


Lesenswert?

Ich mich kürzlich in das Thema "CAN-Botschaften mit Blue Pill senden" 
einarbeiten und habe festgestellt das sich in der HAL um 2018 rum wohl 
einiges geändert hat und praktisch alles was man so an Beispielen im 
Internet findet nicht mehr läuft. Z.B. fehlt die Typedef 
"CanTxMsgTypeDef" und auch das CAN-Handle hat andere Attribute.

Hat jemand der hier anwesenden vielleicht mal ein kleines Beispiel zur 
Hand wie man das mit der aktuellen HAL macht? Also einfach nur eine 
simple STD-ID mit DLC 8 alle 100 ms senden.

: Bearbeitet durch User
von Kevin M. (arduinolover)


Lesenswert?

Die haben um die Zeit die komplette API umgebaut. Es gibt recht gute 
Beispiele in den Beispielprojekten der HAL:

Unter Windows:
C:\Users\UserName\STM32Cube\Repository\STM32Cube_FW_XX_VX.X.X\Projects

von Olli Z. (z80freak)


Lesenswert?

Ich habe mich nun durchgewurschtelt. Da ist einiges anders seit dem 
HAL-API change in 2018...

Erste Herausforderung war die richtigen Timing-Parameter zu ermitteln. 
Folgendes habe ich nun für 125 kbit/s (MS-CAN) errechnet:
1
hcan.Init.Prescaler = 4;
2
hcan.Init.TimeSeg1 = CAN_BS1_13TQ;
3
hcan.Init.TimeSeg2 = CAN_BS2_2TQ;

Zum senden dann:
1
CAN_TxHeaderTypeDef   TxHeader;
2
uint8_t               TxData[8];
3
uint32_t              TxMailbox;
4
5
TxHeader.ExtId = 0x01;
6
TxHeader.RTR = CAN_RTR_DATA;
7
TxHeader.IDE = CAN_ID_STD;
8
TxHeader.DLC = 8;
9
TxHeader.TransmitGlobalTime = DISABLE;
10
TxHeader.StdId = 0x200;
11
12
TxData[0] = 0x00;
13
TxData[1] = 0x11;
14
TxData[2] = 0x22;
15
TxData[3] = 0x33;
16
TxData[4] = 0x44;
17
TxData[5] = 0x55;
18
TxData[6] = 0x66;
19
TxData[7] = 0x77;
20
21
if (HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox) != HAL_OK) {
22
  Error_Handler();
23
}

Man sendet also nicht synchron sondern schiebt das Datagramm in eine 
Ausgabewarteschlange (Mailbox). Der Rückgabewert der HAL-Funktion 
liefert einen Fehler wenn diese z.B. voll ist oder es Busprobleme gibt.

Was mir jetzt als nächstes fehlt ist eine Funktion um ein Datagramm 
regelmäßig zu senden. Ich stelle mir vor eine Subroutine zu erstellen 
welche die Daten einer global bekannten Struktur wie TxData regelmäßig 
sendet, z.B. alle 200 ms.

Für sowas sollten Timer gut sein. Also ein Timer welcher alle 200 ms 
einen Interrupt auslöst und meine o.g. Routine als ISR ausführt. Würde 
man das so machen?

von Olli Z. (z80freak)


Lesenswert?

Da ich mehrere Botschaften habe welche periodisch gesendet werden 
sollen, aber mit unterschiedlichen IDs in unterschiedlichen Intervallen 
benötige ich noch etwas "drumherum".

Ich denke ich mache ein Struct welches die ID, die Daten und das 
Sendeintervall in Millisekunden enthält. Davon mache ich dann ein 
volatile Array welches sowohl in meiner Serverloop als auch im ISR 
verfügbar ist. In der Serverloop ändere ich die Datenbytes wenn das 
notwendig ist.

In der ISR erhöhe ich einen ebenfalls im Struct liegenden Zähler welcher 
bei jedem ISR-Aufruf (welcher dann z.B. alle 10 Millisekunde erfolgt) 
erhöht wird und sobald diese den Wert des Sendeintervalls erreicht hat, 
schicke ich die Botschaft in die TX-Mailbox und setze den Zähler wieder 
auf 0.

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.