cancel
Showing results for 
Search instead for 
Did you mean: 

CAN Baud rate

pisaacs9
Associate II
Posted on February 20, 2012 at 04:11

Im trying to use the CAN interface on the STM32F4 discovery board. I am using the STM code sample which says it configures it to 1Mbit baud rate but this doesnt seem to be the case, with an oscilloscope hooked I am getting a baud rate of 2kBit and a 5us sync pulse (it should be about 250ns for 1Mbit from what I have read.

/* Enable GPIO clock */
RCC_AHB1PeriphClockCmd(CAN_GPIO_CLK, ENABLE);
/* Connect CAN pins to AF9 */
GPIO_PinAFConfig(CAN_GPIO_PORT, CAN_RX_SOURCE, CAN_AF_PORT);
GPIO_PinAFConfig(CAN_GPIO_PORT, CAN_TX_SOURCE, CAN_AF_PORT); 
/* Configure CAN RX and TX pins */
GPIO_InitStructure.GPIO_Pin = CAN_RX_PIN | CAN_TX_PIN;
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_GPIO_PORT, &GPIO_InitStructure);
/* CAN configuration ********************************************************/ 
/* Enable CAN clock */
RCC_APB1PeriphClockCmd(CAN_CLK, ENABLE);
/* CAN register init */
CAN_DeInit(CANx);
/* CAN cell init */
CAN_InitStructure.CAN_TTCM = DISABLE;
CAN_InitStructure.CAN_ABOM = DISABLE;
CAN_InitStructure.CAN_AWUM = DISABLE;
CAN_InitStructure.CAN_NART = DISABLE;
CAN_InitStructure.CAN_RFLM = DISABLE;
CAN_InitStructure.CAN_TXFP = DISABLE;
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
/* CAN Baudrate = 1 MBps (CAN clocked at 30 MHz) */
CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
CAN_InitStructure.CAN_Prescaler = 2;

CAN_Init(CANx, &CAN_InitStructure);

This is all the standard code with a comment towards the end that it sets it up for 1Mbit with a 30MHz clock, the only thing I can think of is that the 30MHz clock asumption is wrong, I cant see where this would be coming from. From what I can find the APB1 clock should just be running off the HSI clock but this doesnt seem to be the case. Can anyone point me in the right direction for fixing this? (I am using IAR for my IDE if that makes any difference)
12 REPLIES 12
bjoern2
Associate II
Posted on February 22, 2012 at 14:06

Hi i.philip,

I also try to set up the can interface. Here my code, which is unfortunatly also not working:

  CAN_InitTypeDef       CAN_InitStructure;

  CAN_FilterInitTypeDef CAN_FilterInitStructure;

  GPIO_InitTypeDef  GPIO_InitStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); //for CAN1

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE); //for CAN2

 

 

  /* GPIOD Periph clock enable */

  //RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // GPIO B Takt

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

 

  GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);

  GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);

  /* Configure PD0 in R */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

 // GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

 // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

 // GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

  GPIO_Init(GPIOD, &GPIO_InitStructure);

  /* Configure PD1 out T */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

  GPIO_Init(GPIOD, &GPIO_InitStructure);

  CAN_DeInit(CAN1);

  CAN_StructInit(&CAN_InitStructure);

  // CAN cell init

  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_InitStructure.CAN_Mode=CAN_Mode_LoopBack;

  CAN_InitStructure.CAN_Mode = CAN_Mode_Silent;

 

  // CAN Bitrate

  CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;    // SJW (1 bis 4 möglich)

  CAN_InitStructure.CAN_BS1=CAN_BS1_13tq;   // Samplepoint 72%

  CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;    // Samplepoint 72%

 

  //CAN_InitStructure.CAN_Prescaler=1;        // 2000 kbit/s

  //CAN_InitStructure.CAN_Prescaler=2;        // 1000 kbit/s

  //CAN_InitStructure.CAN_Prescaler=4;        //  500 kbit/s

  //CAN_InitStructure.CAN_Prescaler=5;        //  400 kbit/s

  //CAN_InitStructure.CAN_Prescaler=8;        //  250 kbit/s

  //CAN_InitStructure.CAN_Prescaler=10;       //  200 kbit/s

  CAN_InitStructure.CAN_Prescaler=16;       //  125 kbit/s

  //CAN_InitStructure.CAN_Prescaler=20;       //  100 kbit/s

  //CAN_InitStructure.CAN_Prescaler=40;       //   50 kbit/s

  //CAN_InitStructure.CAN_Prescaler=80;       //   40 kbit/s

  //CAN_InitStructure.CAN_Prescaler=200;      //   10 kbit/s

  //CAN_InitStructure.CAN_Prescaler=1023;      //    ganz langsam

  CAN_Init(CAN1, &CAN_InitStructure);

  // CAN filter init

  CAN_FilterInitStructure.CAN_FilterNumber=1;

  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;

  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;

  CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;

  CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;

  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;

  CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;

  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;

  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;

  CAN_FilterInit(&CAN_FilterInitStructure);

  // CAN FIFO0 message pending interrupt enable

  CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);

  CAN_ITConfig(CAN1, CAN_IT_FMP1, ENABLE);                           //Nachrichten im FIFO ''1''

  CAN_ITConfig(CAN1, CAN_IT_SLK, ENABLE);                            //gesetzt wenn CAN im sleep mode

Maybe this helps you or you got an idea from what is wrong in my code.

donald2
Associate II
Posted on February 22, 2012 at 16:23

Disclaimer: I've used CAN on the F1, but not on the F4.

CAN needs a stable, precise clock.  That means a crystal or a precision resonator, not the HSI clock.  There are a few places in the documentation that mention this.

bjoern2
Associate II
Posted on February 23, 2012 at 08:22

Hi all,

just something I was thinking about, since my last post. I connected a can bus to my ports PD0 and PD1. I have a tool called PCANopen Magic pro which tells, that there is traffic on the can bus, I see the IDs and the data. But my receive fifo doesn´t receive anything.

I tried to monitor this with:

CanRxMsg*        RxMessage;   

CanRxMsg          Rx;

FlagStatus           flagfifo0 = RESET;

  RxMessage = &Rx;

 

 

  /* Clear R_xMessage */

  RxMessage->StdId=0x01;

  RxMessage->ExtId=0x02;

  RxMessage->IDE=4;

  RxMessage->DLC=0;

  RxMessage->FMI=0;

  for(uint8_t i=0; i<8; i++)

  {

    RxMessage->Data[i]=0x00;

  }

  flagfifo0 = CAN_GetFlagStatus(CAN1,CAN_FLAG_FMP0);

  flagfifo0 = CAN_GetFlagStatus(CAN1,CAN_FLAG_FMP0);

  if(flagfifo0 == SET)

    CAN_Rec(CAN1,CAN_FIFO0,&Rx);

Greetings Bjoern

 

bjoern2
Associate II
Posted on February 23, 2012 at 15:36

Hello all,

after checking today I found out that the can initialsation (CAN_init) is returning CAN_InitStatus_Failed. After that I think the CAN controller is not working normally. In the Reference Manual is written that about the INAK bit 0 in the CAN->MSR register, which goes to 0 by hardware after init, if CAN->MCR INRQ gets 0 and 11 consecutive recessive bits are on CAN RX signal. As I have a CAN bus running on the input, what does this mean??

Thanks in advance

Bjoern

bjoern2
Associate II
Posted on February 29, 2012 at 09:09

Hello again,

I finaly solved the problem. The main thing is that my adjusting to the Baudrate was wrong. The AHB1 Bus (Can is conected to) is running with 42MHz compared to 36 MHz on the old STMF103 controllers. Therefore I had to calculate the numbers new. In the RM0090 side

783 is written how you have to calculate the numbers. Mainly it is easier to understand if you think of 42MHz divided by my Baudrate of 125KHz is 336 clock cycles .

336 clk = CAN_Prescaler * (1 + CAN_BS1 + CAN_BS2)

So if you set the CAN_Prescaler to 16 :

21 = (1 + CAN_BS1 + CAN_BS2)

And to get a sample point of 72 % you can either use

CAN_BS1 = 14 and CAN_BS2 = 6 or

CAN_BS1 = 15 and CAN_BS2 = 5

Both are working.

 // CAN Bitrate

  CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;    // SJW (1 bis 4 möglich)

 

  CAN_InitStructure.CAN_BS1=CAN_BS1_14tq;   // Samplepoint 72%

 

  CAN_InitStructure.CAN_BS2=CAN_BS2_6tq;    // Samplepoint 72%

 

  //CAN_InitStructure.CAN_Prescaler=1;        // 2000 kbit/s

  //CAN_InitStructure.CAN_Prescaler=2;        // 1000 kbit/s

  //CAN_InitStructure.CAN_Prescaler=4;        //  500 kbit/s

  //CAN_InitStructure.CAN_Prescaler=5;        //  400 kbit/s

  //CAN_InitStructure.CAN_Prescaler=8;        //  250 kbit/s

  //CAN_InitStructure.CAN_Prescaler=10;       //  200 kbit/s

  CAN_InitStructure.CAN_Prescaler=16;       //  125 kbit/s

  //CAN_InitStructure.CAN_Prescaler=20;       //  100 kbit/s

  //CAN_InitStructure.CAN_Prescaler=40;       //   50 kbit/s

  //CAN_InitStructure.CAN_Prescaler=80;       //   40 kbit/s

  //CAN_InitStructure.CAN_Prescaler=200;      //   10 kbit/s

  //CAN_InitStructure.CAN_Prescaler=1023;      //    ganz langsam

I haven´t tried this for other baudrates, let me know if it works with other numbers.

Greetings Bjoern

harshad
Associate II
Posted on December 13, 2013 at 15:15

Hi Buddy,

I am still confused about this calculation.

From where you found this equation ?

clk = CAN_Prescaler * (1 + CAN_BS1 + CAN_BS2)

And how you calculated this 72% accuracy?

As said above how 42Mhz clock is come for CAN module?

Posted on December 13, 2013 at 15:35

CAN_BitRate = CAN_CLK / (CAN_Prescaler * (CAN_SJW + CAN_BS1 + CAN_BS2))

Where CAN_CLK is the source APB/AHB clock, nominally 36 or 42 MHz, or WHATEVER you have the buses running at, which at the end of the day you control.

You are looking at the cycles that account for a BIT (aka TQ, Time Quantum), and dividing it into the clocking source used to generate the timing.

The calculation seems self evident, you could work the numbers on examples.

Not sure where the 72% comes from, or what it is referring too.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
harshad
Associate II
Posted on December 14, 2013 at 07:33

I was searching in example code for this frequency.

in example Systemcoreclock is set to 168Mhz. External crystal is 8Mhz. But I was not able to get the calculation for this APB clock how they set it to 36 or 42Mhz.

What I understand from clock study is that all peripheral is running on this APB clock. Please correct me if I am wrong.

Posted on December 14, 2013 at 07:49

The ratio of the APB1 and APB2 (peripheral) clocks with respect to the AHB (HCLK hardware) is defined in system_stm32f4xx.c

APB1 is nominally div 4 (168/4 = 42)

APB2 is nominally div 2 (168/2 = 84)

You can use RCC_GetClocksFreq() function to retrieve the frequencies of these clocks.

The CAN peripherals are on APB1

  /* CANx Periph clock enable */

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

Pretty sure the Reference Manual RM0090 has a clock tree diagram, and what devices are attached to what buses.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..