Forum: Mikrocontroller und Digitale Elektronik CAN Bus Porblem auf STM32


von bibu (Gast)


Lesenswert?

Hallo ich habe folgendes Problem:

Mein Bus läuft gut auf 125 KBit. Wenn ich allerdings den Prescaler von 
16 auf 8 runter stelle läuft nichts mehr. Die Clock bzw. Timer müssten 
alle passen, sonst würde der CAN ja auch in 125k nicht laufen !?
Die LED in dem Code ist nur zur Kontrolle ob der Timer richtig läuft. 
Ossi ist vorhanden.
Hier der Code:

#define HSE_VALUE    ((uint32_t)8000000)


/* Includes */
#include <stddef.h>
#include "stm32f2xx.h"

#define CAN1_TX GPIO_Pin_12
#define CAN1_RX GPIO_Pin_11
#define CAN_PORT GPIOA
#define CAN_GPIO_CLK RCC_AHB1Periph_GPIOA
#define CAN_TX_SOURCE GPIO_PinSource12
#define CAN_RX_SOURCE GPIO_PinSource11



//====================================================================== 
=====

volatile uint8_t a=0;

void SetupPeripherie (void) {
  GPIO_InitTypeDef  GPIO_InitStructure;

  // GPIOD Takt freigeben
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

  // LED-GPIO als Ausgang konfigurieren
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);


}
void Delay(__IO uint32_t nCount) {
  while(nCount--) {
  }
}

void Timer_Initt(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBase_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
//Einstellung Timer auf 100 ms
    TIM_TimeBase_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBase_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBase_InitStructure.TIM_Period = 6000-1;
    TIM_TimeBase_InitStructure.TIM_Prescaler = 1000-1;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBase_InitStructure);

    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
    NVIC_Init(&NVIC_InitStructure);

    TIM_Cmd(TIM2, ENABLE);
}



void TIM2_IRQHandler(void){
/*
  a++;
  if (a==100)
  {
    GPIO_ToggleBits(GPIOB,GPIO_Pin_2);
    a=0;
  }
  */
  GPIO_ToggleBits(GPIOB,GPIO_Pin_2);

  CanTxMsg canMessage;

      canMessage.StdId = 0x14;
      canMessage.ExtId = 0;
      canMessage.RTR = CAN_RTR_DATA;
      canMessage.IDE = CAN_ID_STD;
      canMessage.DLC = 8;

      canMessage.Data[0] = 0;
      canMessage.Data[1] = 1;
      canMessage.Data[2] = 2;
      canMessage.Data[3] = 1;
      canMessage.Data[4] = 0;
      canMessage.Data[5] = 1;
      canMessage.Data[6] = 4;
      canMessage.Data[7] = a;

      CAN_Transmit(CAN1, &canMessage);
a++;

    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}


void CAN_Initt(void)
{


  GPIO_InitTypeDef GPIO_InitStructure;


  RCC_AHB1PeriphClockCmd(CAN_GPIO_CLK, ENABLE);

    // Connect CAN pins to AF9
  GPIO_PinAFConfig(CAN_PORT, CAN_RX_SOURCE, GPIO_AF_CAN1);
  GPIO_PinAFConfig(CAN_PORT, CAN_TX_SOURCE, GPIO_AF_CAN1);

    // Configure CAN RX and TX pins
  GPIO_InitStructure.GPIO_Pin = CAN1_TX | CAN1_RX;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(CAN_PORT, &GPIO_InitStructure);

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

  CAN_DeInit(CAN1);
  CAN_InitTypeDef CAN_InitStructure;

  CAN_InitStructure.CAN_Prescaler = 16;
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
  CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
  CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
  //CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
  //  CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq;
  //  CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
  CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
  CAN_InitStructure.CAN_TTCM = DISABLE;
  CAN_InitStructure.CAN_ABOM = DISABLE;
  CAN_InitStructure.CAN_AWUM = ENABLE;
  CAN_InitStructure.CAN_NART = DISABLE;
  CAN_InitStructure.CAN_RFLM = DISABLE;
  CAN_InitStructure.CAN_TXFP = DISABLE;
  CAN_Init(CAN1, &CAN_InitStructure);
}

int main(void)
{
  SystemCoreClock = HSE_VALUE;
  SetupPeripherie();
  Timer_Initt();
  CAN_Initt();

  while (1)
  {

  }
}

von bibu (Gast)


Lesenswert?

Fast vergessen: Mir ist bewusst, dass wenn ich den Prescaler auf 8 
runter stelle, dass ich dann in meinem CAN Tool 250 kBit einstellen 
muss.

von hmm.. ? (Gast)


Lesenswert?

"Porblem"?

von René K. (cyprius)


Lesenswert?

hmm.. ? schrieb:
> "Porblem"?

Vielleicht ist ein Forum nicht der geeignete Aufenthaltsort für dich, 
wenn dir die Gehirnkapazität fehlt den Zusammenhang zwischen "Porblem" 
und "Problem" herzustellen.

von ggg (Gast)


Lesenswert?

Sind die zeitquanten richtig? kann sein, dass es bei langsamer 
Kommunikation noch geht wenn die falsch sind....

von bibu (Gast)


Lesenswert?

@ René: Vielen Dank, dass du das übernommen hast.

@ ggg:
Ich habe noch
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;

30 mhz  8  (1+9+5) =250k/Bits

ausprobiert, damit dieses 75% Verhältnis eingehalten wird. Aber damit 
funktioniert es leider auch nicht. Ich weiß, ehrlich gesagt, auch nicht 
was es mit den Zeitquanten auf sich hat. Außer, dass da noch der Teiler 
weiter runter geht. Bzw. ich weiß dass was im Diller Tutorial 
http://www.diller-technologies.de/stm32.html#timer geschrieben wurde.

Ich werde mal google weiter befragen. Im Datenblatt des stm32f205 find 
ich da leider nichts.

von bibu (Gast)


Lesenswert?

Ich habe jetzt noch einmal mit den Zeitquanten gearbeitet. Jetzt bin ich 
schonmal auf 250 kBit. Dann muss ich die wohl noch weiter anpassen. Mal 
schaun ob ich noch was zu lesen dafür finde. Jetzt stehts auf :

  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
  CAN_InitStructure.CAN_BS1 = CAN_BS1_10tq;
  CAN_InitStructure.CAN_BS2 = CAN_BS2_4tq;

von Helmut (Gast)


Lesenswert?

http://www.libstock.com/projects/view/360/canculator

Dieser CAN Calculator ist ganz gut, spiel mal damit rum.

von bibu (Gast)


Lesenswert?

Danke, ich werde ihn mal ausprobieren und berichten.

von bibu (Gast)


Lesenswert?

Den Calculator habe ausprobiert. Bin jetzt auf 250kBit. Ich komme aber 
einfach nicht höher. Ich hab schon dieverse Einstellungen durch... 
Könnte das evtl daran liegen, dass ich einen schnelleren Quarz brauche, 
damit das stabil läuft? zZ. Hab ich 8 Mhz drin. Aber eigentlich sollte 
das auch damit gehen, oder!?

von Helmut (Gast)


Lesenswert?

Denke schon, der Mikroe wirft bei 8MHz und 500kbs auch nix gutes raus.

von Dr. Sommer (Gast)


Lesenswert?

Mein STM32F4 Discovery läuft gut mit 1MBit und 8MHz Quarz. Mach doch mal 
ein Oszilloskopbild...

von bibu (Gast)


Lesenswert?

Ja auf dem f4 lief das bei mir auch. Bild kommt

von ggg (Gast)


Lesenswert?

so läuft es bei mir perfect... Wie lang ist dein Bus?  Ich meine 
imDatenblatt steht die entsprechende Formel..

mit den Quanten stellst du ein an welcher stelle eines bits abgetastet 
wird. das ist vorallem für das ack wichtig!!



1
/**
2
 * @brief  Konfiguriert CAN1.
3
 * @param  None
4
 * @retval None
5
 */
6
void CAN1_Config(void) {
7
  GPIO_InitTypeDef GPIO_InitStructure;
8
9
  /* CAN GPIOs Konfiguration **************************************************/
10
11
  /*  GPIO clock freischalten */
12
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
13
14
  /* CAN pins mit AF9 verknüpfen */
15
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);
16
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);
17
18
  /*CAN RX und TX pins konfigurieren */
19
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_0;
20
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
21
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
22
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
23
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
24
  GPIO_Init(GPIOD, &GPIO_InitStructure);
25
26
  /* CAN configuration ********************************************************/
27
  /* CAN clock freischalten */
28
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
29
30
  /* CAN Register zurücksetzen */
31
  CAN_DeInit(CAN1);
32
33
  /* CAN Einstellungen */
34
  CAN_InitStructure.CAN_TTCM = DISABLE;
35
  //CAN_InitStructure.CAN_ABOM = DISABLE;
36
  CAN_InitStructure.CAN_ABOM = ENABLE; // Automatisches Busoff Management
37
  CAN_InitStructure.CAN_AWUM = DISABLE;
38
  CAN_InitStructure.CAN_NART = DISABLE;
39
  CAN_InitStructure.CAN_RFLM = DISABLE;
40
  CAN_InitStructure.CAN_TXFP = DISABLE;
41
  CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
42
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
43
44
  /* CAN Baudrate = 1 MBps (CAN @ 42 MHz) */
45
  CAN_InitStructure.CAN_BS1 = CAN_BS1_14tq;
46
  CAN_InitStructure.CAN_BS2 = CAN_BS2_6tq;
47
  CAN_InitStructure.CAN_Prescaler = 2;
48
  CAN_Init(CAN1, &CAN_InitStructure);
49
50
  /* CAN1 filter init */
51
  /*Filter aus*/
52
  CAN_FilterInitStructure.CAN_FilterNumber = 0;
53
54
  CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
55
  CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
56
  CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
57
  CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
58
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
59
  CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
60
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
61
  CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
62
  CAN_FilterInit(&CAN_FilterInitStructure);
63
64
65
66
  /* Enable FIFO 0 Interrupt */
67
  CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
68
}

von ggg (Gast)


Lesenswert?

oh ich sehe gerade du suchst ja garnicht für den f4.... bei dir scheint 
was mit dem takt generell nicht zu stimmen. bist du sicher, dass überall 
der takt anliegt den du vermutest? hast du einen LA bzw ein Scope? 
Schicke mal eine nachricht mit nur 0xaa, denn kannst du messen, ob can 
auc wirklich so eingestellt ist, wie du denkst. ansonsten weiter an den 
quanten drehen...
viel erfolg

von Bernardo F. (bernardo)


Lesenswert?

Hallo bibu,

zur Information: unter http://www.bittiming.can-wiki.info kann man
sich einfach für den bxCAN die Einstellungen für den Abtastzeitpunkt
(Zeitsegmente 1 und 2) sowie für den Baudrate Prescaler berechnen 
lassen. Dabei ist die Kenntnis der vorher am CAN-Prescaler anliegenden 
Eingangsfrequenz aber zwingend notwendig (d.h. PCLK1=APB1-Clock, beim 
STM32F10x also z.B. max. 36 MHz; siehe Reference Manual RM008, Seite 
90).

Viele Grüße

von Waldi (Gast)


Lesenswert?

Es war mal so eine Excel Datei, in der die Werte für verschiedene 
Bauraten aufgelistet waren

von Waldi (Gast)


Lesenswert?


von bibu (Gast)


Lesenswert?

Jetzt hab ich erstmal einiges zu lesen. Besten Dank! Ich hoffe ich komm 
heute noch dazu, Ich werde dann mal Meldung geben, wenn ich Erfolg 
verbuchen kann.

von bibu (Gast)


Lesenswert?

So, eine Lösung ist gefunden. Es lag nicht an den Quanten... Ich musste
meine Erdungen an meiner Platine verändern. Dann gings auch mit den
schnelleren Baudrate. Bzw. ich habe auch noch einen anderen
DC/DC-Wandler eingesetzt.

Vielen Dank für die ganzen Hilfen !

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.