Forum: Mikrocontroller und Digitale Elektronik STM32F7xx CAN time calculation


von hawk (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich versuche gerade die CAN-Schnittstelle (CAN2) mit einem STM32F746 zum 
Laufen zu bringen.
Allerdings scheitere ich schon an der Frage, welchen Clock ich für die 
Timing-Berechnung nehmen soll.
Für die Berechnung verwende ich die Seite 
http://www.bittiming.can-wiki.info/.

Obwohl ich das CAN-Interface über CubeMx aktiviert habe, zeigt es mir in 
der Clock-Konfiguration kein CAN-Interface an, und so weiß ich irgendwie 
nicht, welchen Clock ich für die Berechnung nehmen soll (siehe Anhang 
Bild).

In einem Beispiel für 500K Baudrate habe ich den folgenden Code 
gefunden, doch ich möchte gerne Wissen auf welche Clockfrequenz dies 
berechnet wurde (vor allem suche ich ein Wert für die Baudrate 250K):
1
#if defined (CAN_BAUDRATE1M)
2
 /*1Mhz BaudRate Bit*/
3
  CanHandle.Init.SyncJumpWidth  = CAN_SJW_1TQ;
4
  CanHandle.Init.TimeSeg1  = CAN_BS1_2TQ;//(1~17)
5
  CanHandle.Init.TimeSeg2  = CAN_BS2_2TQ;//(1~17)
6
  CanHandle.Init.Prescaler = 10;
7
#elif defined (CAN_BAUDRATE500K)
8
  /*500Khz BaudRate Bit*/
9
  CanHandle.Init.SyncJumpWidth  = CAN_SJW_1TQ;
10
  CanHandle.Init.TimeSeg1  = CAN_BS1_5TQ;//(1~17)
11
  CanHandle.Init.TimeSeg2  = CAN_BS2_6TQ;//(1~17)
12
  CanHandle.Init.Prescaler = 9;
13
#else
14
  /*125Khz BaudRate Bit */
15
  CanHandle.Init.SyncJumpWidth  = CAN_SJW_1TQ;
16
  CanHandle.Init.TimeSeg1  = CAN_BS1_9TQ;   //(1~16)
17
  CanHandle.Init.TimeSeg2  = CAN_BS2_8TQ;   //(1~8)
18
  CanHandle.Init.Prescaler = 24;

von Harry L. (mysth)


Lesenswert?

CAN sollte an APB2 hängen.

Ansonsten: RTFM!

: Bearbeitet durch User
Beitrag #7033242 wurde vom Autor gelöscht.
von hawk (Gast)


Lesenswert?

Harry L. schrieb:
> Ansonsten: RTFM!

Sorry schwierig. Ich habe ein Board hier, und passenden CAN Code dazu, 
leider aber nur für Baudrate 1M, 500K und 125K (siehe unten)... ich 
hätte aber gerne 250K. Es ist ein externer 25MHz Oszillator eingebaut.

Ich kann anhand diesem Code nicht ermitteln mit welcher Taktrate die 
CAN-Peripherie läuft. Auch finde ich nicht heraus wie man auf die 
jeweiligen Timing-Werte gekommen ist.
Für den Board-Code kann ich leider kein CubeMx File erzeugen.

http://www.bittiming.can-wiki.info/#bxCAN spuckt ganz andere Werte raus, 
egal ob 6.25, 8, 12.5, 16, 25, 48 MHZ....


CAN timing setup:
1
  /* USER CODE END CAN2_Init 1 */
2
  hcan2.Instance = CAN2;
3
  hcan2.Init.Prescaler = 24;
4
  hcan2.Init.Mode = CAN_MODE_NORMAL;
5
  hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
6
  hcan2.Init.TimeSeg1 = CAN_BS1_9TQ; //9
7
  hcan2.Init.TimeSeg2 = CAN_BS2_8TQ; //8
8
  hcan2.Init.TimeTriggeredMode = DISABLE;
9
  hcan2.Init.AutoBusOff = DISABLE;
10
  hcan2.Init.AutoWakeUp = DISABLE;
11
  hcan2.Init.AutoRetransmission = DISABLE;
12
  hcan2.Init.ReceiveFifoLocked = DISABLE;
13
  hcan2.Init.TransmitFifoPriority = DISABLE;
14
  if (HAL_CAN_Init(&hcan2) != HAL_OK)
15
  {
16
  Error_Handler();
17
  }

Systemclock:
1
static void SystemClock_Config(void)
2
{
3
    RCC_ClkInitTypeDef RCC_ClkInitStruct;
4
    RCC_OscInitTypeDef RCC_OscInitStruct;
5
    RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; //i2c, uart etc.
6
7
    HAL_PWR_EnableBkUpAccess(); //EDT
8
    /* Enable Power Control clock */
9
    __HAL_RCC_PWR_CLK_ENABLE();
10
11
    /* The voltage scaling allows optimizing the power consumption when the device is
12
     clocked below the maximum system frequency, to update the voltage scaling value
13
     regarding system frequency refer to product datasheet.  */
14
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
15
16
    /*##-1- System Clock Configuration #########################################*/
17
    /* Enable HSE Oscillator and activate PLL with HSE as source */
18
19
/*
20
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
21
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
22
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
23
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
24
    RCC_OscInitStruct.PLL.PLLM = 25;
25
    RCC_OscInitStruct.PLL.PLLN = 400;
26
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
27
    RCC_OscInitStruct.PLL.PLLQ = 8;
28
*/
29
30
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;
31
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
32
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
33
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
34
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
35
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
36
    RCC_OscInitStruct.PLL.PLLM = 25;
37
    RCC_OscInitStruct.PLL.PLLN = 432;
38
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
39
    RCC_OscInitStruct.PLL.PLLQ = 9;              //USB PLLQ 432 / 9 = 48
40
41
    HAL_RCC_OscConfig(&RCC_OscInitStruct);
42
43
44
    /* Activate the Over-Drive mode */
45
    HAL_PWREx_EnableOverDrive();
46
47
    /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
48
     clocks dividers */
49
    RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
50
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
51
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
52
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
53
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
54
    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_6);
55
56
57
    PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_USART6;
58
    PeriphClkInitStruct.I2c3ClockSelection = RCC_I2C3CLKSOURCE_PCLK1;
59
    PeriphClkInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
60
    PeriphClkInitStruct.Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1;
61
    PeriphClkInitStruct.Usart6ClockSelection = RCC_USART6CLKSOURCE_PCLK2;
62
63
64
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
65
    {
66
      Error_Handler();
67
    }
68
}

von Jens R. (tmaniac)


Lesenswert?

Das hier ist zwar schon ein paar Tage alt, aber falls doch noch mal 
jemand drüber stolpert.

Ich habe mir für die Registerberechnung ein ftl Script gebastelt, 
welches bei der Codegenerierung in der CubeIDE (oder MX) mit ausgeführt 
wird. So kann ich die Baudraten auch im Betrieb umschalten.

Aber mal so als ersten Ansatz für die Neueinsteiger. Wenn man eine 
funktionierende Baudrate hat, kann man über den

hcan1.Init.Prescaler = xx

Die Baudrate einfach verdoppeln oder halbieren.

: Bearbeitet durch User
von Kevin M. (arduinolover)


Lesenswert?

Was ist so schwer daran ins reference Manual zu gucken, da steht die 
Berechnung drin...

von Jens R. (tmaniac)


Lesenswert?

Hmmm, von Anfang an gelesen?
Die Ausgangsfrage war ja, was ist der Ausgangstakt welcher der 
Berechnung zu Grunde liegt. 🙄

Und hast du mal ins Manual geschaut?
Weil da muss man schon arg suchen damit man den Zusammenhang kapiert.

Ok, wenn man einmal hat, sollte es auch immer wieder aufgehen. 
Sollte....
Keine Ahnung wie oft ich raus gesucht habe, welche Clock nun am bxCAN 
ankommt.

Naja, und deswegen auch die Codegenerierung geschrieben.
Erstens wenn man es aufschreibt merkt man sich besser.
Und zweitens brauch ich jetzt nie mehr rechnen, wenn ich mal nen anderen 
Takt einstelle.


Ähm, auf was war dein Kommentar eigentlich bezogen 🤐

von Kevin M. (arduinolover)


Lesenswert?

Jens R. schrieb:
> Die Ausgangsfrage war ja, was ist der Ausgangstakt welcher der
> Berechnung zu Grunde liegt.

Auch das steht da drin.

Jens R. schrieb:
> Und hast du mal ins Manual geschaut?
> Weil da muss man schon arg suchen damit man den Zusammenhang kapiert.

Ja Inhaltsverzeichnis und dann auf die Überschrift mit bxCAN Klicken ist 
schon schwer. Ggf. muss man noch auf den Link in diesem Kapitel klicken 
der auf das RCC Kapitel verweist...

Jens R. schrieb:
> Ähm, auf was war dein Kommentar eigentlich bezogen

Auf die generelle Unfähigkei der Leute die zugehörigen Dokumente zu 
ihren verwendeten Produkten zu lesen. Das fängt schon bei 5 seitigen 
Datenblättern an, die sind ja soooo lang ...

von Jens R. (tmaniac)


Lesenswert?

Kevin M. schrieb:
> Auf die generelle Unfähigkei der Leute die zugehörigen Dokumente zu
> ihren verwendeten Produkten zu lesen. Das fängt schon bei 5 seitigen
> Datenblättern an, die sind ja soooo lang ...

Na toll, zwischen lesen und verstehen gibt es eine  Unterschied.
Bei mehreren Tausend Seiten kann es auch mal passieren das man etwas 
entscheidenes übersieht.

Also, ich dachte wir sind hier in einem Forum wo man auch mal Fragen zum 
besseren Verständnis stellen darf 🤔

Und genauso sollte es möglich sein Tipps für den Umgang mit den Dingen 
zu geben 🤷‍♂️

[das war von mir genug offtopic]

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.