CAN Bus Porblem auf STM32

Gast #3376234
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)
  {

  }
}
Gast #3376305
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.
Gast #3376316
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;
Gast #3376392
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!?
Gast #3377206
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
}
Gast #3377214
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
#3377945
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
Gast #3378218
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 !

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