Forum: Mikrocontroller und Digitale Elektronik Probleme mit CAN-Bus am STM32F103


von Michael M. (eos400dman)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich beschäftige mich in letzter Zeit intensiver mit dem STM32F103. Nun 
habe ich die Aufgabe bekommen, mich in die Verwendung des CAN-Buses 
einzuarbeiten. Dies versuche ich nun schon eine Weile. Als Gegenstelle 
zum STM32 steht mir ein CAN-Case der Firma Vector zu Verfügung.

Als Transreciver verwendet ich einen MAX 3059. Wenn ich mit dem Oszi die 
Spannung zwischen CAN_H und CAN_L messe, sehe ich auch ein, meiner 
Meinung nach, sauberes Signal. (Bild reiche ich nach). Aktuell versuche 
ich eine Baudrate von 125k zu erreichen. Allerdings zeigt mir der PC 
nichts als Bit Error (RX) an. Leider kenne ich mich weder mit der 
Software noch mit dem CAN-Bus des STM32 aus. Deshalb hoffe ich, dass ihr 
mir helfen könnte.

Vielen Dank im Voraus!!
1
int main(void)
2
{
3
  SystemInit();
4
5
  RCC_Configuration();
6
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
7
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
8
9
  GPIO_InitTypeDef GPIO_InitStructure;
10
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
11
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
12
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
13
  GPIO_Init(GPIOA, &GPIO_InitStructure);
14
15
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
16
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
17
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
18
  GPIO_Init(GPIOA, &GPIO_InitStructure);
19
20
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
21
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
22
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
23
  GPIO_Init(GPIOB, &GPIO_InitStructure);
24
25
  CAN_InitTypeDef CAN_InitStructure;
26
  CAN_InitStructure.CAN_Prescaler = 26;
27
  CAN_InitStructure.CAN_BS1 = CAN_BS1_10tq;
28
  CAN_InitStructure.CAN_BS2 = CAN_BS2_4tq;
29
30
  CAN_InitStructure.CAN_TTCM = DISABLE;
31
  CAN_InitStructure.CAN_ABOM = DISABLE;
32
  CAN_InitStructure.CAN_AWUM = DISABLE;
33
  CAN_InitStructure.CAN_NART = ENABLE;
34
  CAN_InitStructure.CAN_RFLM = DISABLE;
35
  CAN_InitStructure.CAN_TXFP = ENABLE;
36
  CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
37
  CAN_InitStructure.CAN_SJW = CAN_SJW_4tq;
38
  uint8_t temp = CAN_Init(CAN1, &CAN_InitStructure);
39
40
  CanTxMsg canMessage;
41
42
  canMessage.StdId = 0x123;
43
  canMessage.RTR = CAN_RTR_DATA;
44
  canMessage.IDE = CAN_ID_STD;
45
46
  canMessage.DLC = 4;
47
48
  canMessage.Data[0] = 0;
49
  canMessage.Data[1] = 1;
50
  canMessage.Data[2] = 2;
51
  canMessage.Data[3] = 3;
52
53
    while(1)
54
    {
55
      GPIOB->ODR ^= GPIO_Pin_10;  
56
      CAN_Transmit(CAN1, &canMessage);
57
      Delay(1700000);
58
    }
59
}

von Klaus D. (Firma: MHS-Elektronik GmbH & Co. KG) (mhs-elektronik)


Angehängte Dateien:

Lesenswert?

Hallo Michael,

ich habe zwar mit dem STM32 keine Erfahrung, mit dem CAN Bus aber um so 
mehr.
Sieht eigentlich alles Ok aus, bis auf die BitTiming Register, siehe 
Bild.

Ich gebe aber zu BitCalc ist noch eine Bata-Version :-)
Einfach mal probieren.

Grüße
Klaus

von Dr. Sommer (Gast)


Lesenswert?

Hast du denn in der Vector Software (CANoe?) in den Hardware 
Einstellungen eingestellt, dass das CANcase das ACK-Bit senden soll? 
120Ohm Terminierungswiderstände dran (die scheinen selbst unter 
Laborbedingungen nötig zu sein)?

von Michael M. (eos400dman)


Angehängte Dateien:

Lesenswert?

Zu erst einmal danke für deine Antwort Klaus.
Allerdings hat das anpassen des Bit-Timing-Registers nichts geholfen.

Im Anhang mal ein Oszi-Bild.

Gruß Michael

von EMV (Gast)


Lesenswert?

Vermutlich falsches Timing auf dem STM32.

Versuchs mal damit:
Beitrag "STM32 CAN Baudrate Berechnung (Can Bit Timing)"

Überprüfe wie hoch der Takt ist auf dem STM32 (AHB1). Hier kann es 
schnell passieren das man sich verhaut mit dem PLL und der clock-source.

- Terminierung ist immer nötigt (120 Ohm, im Labor reicht auf einer 
Seite)
- CANH/CANL vertauscht?

von EMV (Gast)


Lesenswert?

EMV schrieb:
> Überprüfe wie hoch der Takt ist auf dem STM32 (AHB1)

Noch zur Präzisierung: In deinem Timing Calculator hattest du 50Mhz 
eingestellt. Der CAN hängt am AHB1, nicht am SysClock.
Maximal sind das beim F1 wenn ichs recht im Kopf habe 30 oder 36MHz. 
Beim F2/F4 glaube ich 48 oder 84 MHz - blick ins Reference Manual gibt 
darüber aufschluss.

von EMV (Gast)


Lesenswert?

Michael Mayer schrieb:
> CAN_InitTypeDef CAN_InitStructure;
>   CAN_InitStructure.CAN_Prescaler = 26;
>   CAN_InitStructure.CAN_BS1 = CAN_BS1_10tq;
>   CAN_InitStructure.CAN_BS2 = CAN_BS2_4tq;

Wenn du wirklich einen F1 hast der mit 36MHz APB1 clock läuft, hast du 
eine Baudrate von 92.31kbit/s mit diesen Einstellungen.

Für 36MHz und 125kbit wären folgende Werte korrekt:

CAN_InitStructure.CAN_Prescaler = 16;
CAN_InitStructure.CAN_BS1 = CAN_BS1_12tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;

von Michael M. (eos400dman)


Lesenswert?

Dr. Sommer schrieb:
> Hast du denn in der Vector Software (CANoe?) in den Hardware
> Einstellungen eingestellt, dass das CANcase das ACK-Bit senden soll?
> 120Ohm Terminierungswiderstände dran (die scheinen selbst unter
> Laborbedingungen nötig zu sein)?
Beides ja.

EMV schrieb:
> Für 36MHz und 125kbit wären folgende Werte korrekt:
>
> CAN_InitStructure.CAN_Prescaler = 16;
> CAN_InitStructure.CAN_BS1 = CAN_BS1_12tq;
> CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
Habe ich auch ohne Erfolg getestet.

Auf dem Oszi ist ein "Bit" ca. 8µs lang, dies sollte ja zu 125kBaud 
passen.

Ich habe versuchsweise auch mal CAN-H und CAN-L auch mal getauscht. Dann 
kommt zwar kein Fehler aber auch sonst nichts.

von Alain S. (alain_s)


Lesenswert?

Michael Mayer schrieb:
> Habe ich auch ohne Erfolg getestet.
>
> Auf dem Oszi ist ein "Bit" ca. 8µs lang, dies sollte ja zu 125kBaud
> passen.

Zeig mal deine PLL und Clockeinstellunge. Was für ein Quarz hast du 
drauf?

von Alain S. (alain_s)


Lesenswert?

Michael Mayer schrieb:
> CAN_InitStructure.CAN_SJW = CAN_SJW_4tq;

Setz das mal noch auf 1tq

von Michael M. (eos400dman)


Lesenswert?

Alain S. schrieb:
> Zeig mal deine PLL und Clockeinstellunge. Was für ein Quarz hast du
> drauf?

Gern:
1
void RCC_Configuration(void)
2
{
3
    RCC_DeInit(); // RCC system reset(for debug purpose)
4
5
    RCC_HSEConfig(RCC_HSE_ON); // Enable HSE
6
7
    while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); // Wait till HSE is ready
8
9
    RCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK = SYSCLK
10
11
    RCC_PCLK2Config(RCC_HCLK_Div1); // PCLK2 = HCLK
12
13
    RCC_PCLK1Config(RCC_HCLK_Div2); // PCLK1 = HCLK/2
14
15
    FLASH_SetLatency(FLASH_ACR_LATENCY_2); // Flash 2 wait state
16
17
    FLASH_PrefetchBufferCmd(ENABLE);
18
19
    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); // PLLCLK = 8MHz * 9 = 72 MHz
20
21
    RCC_PLLCmd(ENABLE); // Enable PLL
22
23
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);  // Wait till PLL is ready
24
25
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // Select PLL as system clock source
26
27
    while(RCC_GetSYSCLKSource() != 0x08); // Wait till PLL is used as system clock source
28
}
Ich verwende eine 8MHz Quarz.

Alain S. schrieb:
> Setz das mal noch auf 1tq
Hab ich versucht, hilft nix.
Trotzdem Danken an Alle!!

Viele Grüße Michael

von Alain S. (alain_s)


Lesenswert?

Das sieht recht vernünftig aus. Kommen nach meiner Rechnung 36MHz raus.

8uS bittime wären soweit auch korrekt.
Kann es sein dass der Fehler gar nicht beim STM32 liegt sondern beim 
Vector-Teil? Vielleicht da noch was falsch? Vielleicht Listen-Only 
modus?

Ich habe den CAN auf F1/F2/F4 seit jahr und tag im Einsatz und noch nie 
probleme damit gehabt.
Laufen die Transmit-Mailboxes auf dem STM voll? Steht was im 
Error-Register? Ich vermute nach wie vor folgendes:
Baudrate mismatch oder fehlendes ACK.
Allenfalls auch ein elektrisches Problem wenn CANH/CANL vertauscht oder 
eines unterbrochen ist.

Verbindung (auch RX) vom Transceiver zum STM32 ist ok?

Gruss

von Klaus D. (Firma: MHS-Elektronik GmbH & Co. KG) (mhs-elektronik)


Lesenswert?

Hallo Michael,

ich glaube immer noch das es ein Bit Timing Problem ist, wenn der 
Empfänger im Listen Only Mode arbeitet würdest Du die Botschaft ja 
trotzdem sehen, nur viel zu oft :-)
Miss doch mal die Bitzeit genau nach, ca. 8us reicht für den CAN-Bus 
nicht.
Das müssen schon genau 8us sein :-)

Masse hast Du schon verbunden ?
Verwendest Du den Terminierungswiderstand im MAX3059 ?

Lade BitCalc von meiner Homepage runter dann kanst Du das Bit Timing mit
36 MHz neu berechnen.

http://www.mhs-elektronik.de
Im Download Bereich, ganz unten.

Gruß
Klaus

von Michael M. (eos400dman)


Lesenswert?

Dank für eure Hilfe, nun funktioniert es mit folgenden Werten:
1
  CAN_InitStructure.CAN_Prescaler = 31;
2
  CAN_InitStructure.CAN_BS1 = CAN_BS1_10tq;
3
  CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;
4
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
Auch wenn ich beim Nachrechnen nicht auf 125kBaud kommen...

Viele Grüße Michael

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.