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
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
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?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.