Probleme mit CAN-Bus am STM32F103

OP #3602438
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
}
Angehängte Dateien:
Gast #3602596
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)?
Gast #3602622
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.
Gast #3602634
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;
OP #3602686
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.
OP #3602726
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
#3602741
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
(Firma: MHS-Elektronik GmbH & Co. KG) #3602934
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
OP #3603697
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

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