cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 CAN: Having trouble with baud rate

Rea.David
Associate II
Posted on April 10, 2013 at 15:17

Hello!

I'm working on bringing up the CAN peripheral on a STM32F207VCT6 part. I followed the CAN Programming Example in the Peripheral Driver Library manual (pertinent lines highlighted in

red

:(


GPIO_InitTypeDef GPIO_InitStructure;

CAN_InitTypeDef CAN_InitStructure;

CAN_FilterInitTypeDef CAN_FilterInitStructure;

/* CAN GPIOs configuration ***********************************/

/* Enable GPIOD clock */

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

/* Connect PD1 to CAN1_Tx pin */

GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);

/* Connect PD0 to CAN1_Rx pin */

GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);

/* Configure CAN1_Rx(PD0) and CAN1_Tx(PD1) pins */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;

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(GPIOD, &GPIO_InitStructure);

/* CAN configuration *****************************************/

Controller area network (CAN) UM1061

122/634 DocID 18540 Rev 1

/* Enable CAN1 clock */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

/* 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 = 1MBps (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(CAN1, &CAN_InitStructure);

/* CAN filter init */

CAN_FilterInitStructure.CAN_FilterNumber = 0;

CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;

CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;

CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;

CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;

CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;

CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;

CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;

CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;

CAN_FilterInit(&CAN_FilterInitStructure);

Calling the

CAN_Transmit

function successfully enqueues my test message for transmission, and the CAN peripheral begins trying to send it out on the bus. Looking at the traffic with a scope, however, the bit times appear to be about 1.25μsec long - not the 1.0μsec you'd expect running at 1Mbps. From the chip reference manual (RM0033, page 775), setting the prescaler to 2 with an APB1 clock rate of 30MHz (checked using

RCC_GetClocksFreq

) would seem to result in a time quantum duration of: (2 + 1) * (1 / 30e6) = 1e-7 = 0.1μsec With BS1 and BS2 set to 6 and 8 time quanta (respectively) the nominal bit time would then be: (1 * 0.1μsec) + [0.1μsec * 6] + [0.1μsec * 8] = 0.1μsec * (1+6+8) = 1.5μsec But this results in a baud rate of about 666Kbps, not 1Mbps as indicated in the example comments. And after verifying the register contents on my running target, I'm still getting1.25μsec bits, for a baud rate of 800Kbps. So either something is wrong with my configuration (CAN_BTR = 0x00750001) or my APB1 clock is actually running slower than 30MHz. Is there any way to check the APB1 clock rate other than the

RCC_GetClocksFreq

function? Thanks, Dave #can #stm32f207
3 REPLIES 3
Posted on April 10, 2013 at 15:41

GetClockFreq uses a computation based on HSE_VALUE (or HSI_VALUE), and is not a measurement of speed.

Check what you have HSE_VALUE set to in your project.

Check what you have the HSE running at externally.

Export clocks via an MCOx pin, measure.

If serial port baud clocks are correct, HSE_VALUE probably is too.

Check what is being set up in system_stm32fxx.c, and SystemInit()
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Rea.David
Associate II
Posted on April 11, 2013 at 14:23

Thanks for the input... Turns out the

SetSysClock

function was turning on the HSE oscillator, while I thought I was running from the HSI. Since the crystal on our board is 20MHz instead of the 25MHz part expected by

SetSysClock

, resulting in the incorrect APB1 frequency and CAN baud rate. A quick adjustment to PLL_M is all that was necessary.

Thanks again for pointing me in the right direction!

Dave

Posted on April 11, 2013 at 15:59

Awesome, thanks for the update.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..