cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 CAN Trouble in Normal Mode

Posted on February 07, 2009 at 10:43

STM32 CAN Trouble in Normal Mode

7 REPLIES 7
Posted on May 17, 2011 at 12:59

hy all

yesterday, i was able to initialize can on stm32f103 rZ (100pin) (EVAL Board) by changing some lines in the CAN_Init() function. the Loopback Mode was working great, but i want

to communicate with another mcu(same board, same mcu) via can bus. i'm currently using PD0/PD1 for communication. clock, nvic ( and gpio settings should be correct.

after initialization i try to send a msg on bus and the other board should receive it, but my sending function timeouts in the state TX_PENDING. :-W

does anyone has an idea, what i have done wrong, or what i can do to make this working. pls help me, my project has to finished in a few weeks and i'm totally frustrated! :-[

ciao

mario

[ This message was edited by: mario.noessing on 14-01-2009 23:08 ]

Posted on May 17, 2011 at 12:59

Some Code Parts:

/*******************************************************************************

* Function Name : CAN_Interrupts_Config.

* Description : Configures the USB interrupts.

* Input : None.

* Output : None.

* Return : None.

*******************************************************************************/

void CAN_Interrupt_Config(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

#ifdef VECT_TAB_RAM

/* Set the Vector Table base location at 0x20000000 */

NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

#else /* VECT_TAB_FLASH */

/* Set the Vector Table base location at 0x08000000 */

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

#endif

/* Enable CAN RX Interrupts */

NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN_RX0_IRQChannel;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init( &NVIC_InitStructure );

}

/*******************************************************************************

* Function Name : GPIO_Configuration

* Description : Configures the different GPIO ports.

* Input : None

* Output : None

* Return : None

*******************************************************************************/

void GPIO_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);

//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC

| RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOD

| RCC_APB2Periph_AFIO, ENABLE);

/* Configure the KEY IO as Input Floating */

/*IO_InitStructure.GPIO_Pin = GPIO_Pin_8;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOB, &GPIO_InitStructure);*/

/* Configure the LED1, LED2, LED3 & LED4 IOs as Output PP */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOC, &GPIO_InitStructure);

/* Configure CAN Rx (PD0) */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

GPIO_Init(GPIOD, &GPIO_InitStructure );

/* Configure CAN Tx (PD1) */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_Init(GPIOD, &GPIO_InitStructure );

}

/*******************************************************************************

* Function Name : CAN_Configuration

* Description : Configuration of CAN Communication

* Input : None

* Output : None

* Return : None

*******************************************************************************/

void CAN_Configuration(void)

{

CAN_InitTypeDef CAN_InitType;

CAN_FilterInitTypeDef CAN_FilterInitType;

CanTxMsg TxMessage;

CAN_Interrupt_Config();

CAN_DeInit();

CAN_StructInit(&CAN_InitType);

/* CAN cell init */

CAN_InitType.CAN_TTCM=DISABLE;

CAN_InitType.CAN_ABOM=DISABLE;

CAN_InitType.CAN_AWUM=DISABLE;

CAN_InitType.CAN_NART=DISABLE;

CAN_InitType.CAN_RFLM=DISABLE;

CAN_InitType.CAN_TXFP=DISABLE;

/* Set Baudrate to 500MBit/s */

CAN_InitType.CAN_Mode=CAN_Mode_Normal;

//CAN_InitType.CAN_Mode=CAN_Mode_LoopBack;

//CAN_InitType.CAN_Mode=CAN_Mode_Silent;

CAN_InitType.CAN_SJW=CAN_SJW_1tq;

CAN_InitType.CAN_BS1=CAN_BS1_9tq;

CAN_InitType.CAN_BS2=CAN_BS2_2tq;

CAN_InitType.CAN_Prescaler=6;

/*CAN_InitType.CAN_Mode=CAN_Mode_Normal;

CAN_InitType.CAN_SJW=CAN_SJW_1tq;

CAN_InitType.CAN_BS1=CAN_BS1_8tq;

CAN_InitType.CAN_BS2=CAN_BS2_7tq;

CAN_InitType.CAN_Prescaler=5;*/

CAN_Init(&CAN_InitType);

CAN_FilterInitType.CAN_FilterNumber=0;

CAN_FilterInitType.CAN_FilterMode=CAN_FilterMode_IdMask;

CAN_FilterInitType.CAN_FilterScale=CAN_FilterScale_32bit;

CAN_FilterInitType.CAN_FilterIdHigh=0x0000;

CAN_FilterInitType.CAN_FilterIdLow=0x0000;

CAN_FilterInitType.CAN_FilterMaskIdHigh=0x0000;

CAN_FilterInitType.CAN_FilterMaskIdLow=0x0000;

CAN_FilterInitType.CAN_FilterFIFOAssignment=0;

CAN_FilterInitType.CAN_FilterActivation=DISABLE;

CAN_FilterInit(&CAN_FilterInitType);

CAN_ITConfig(CAN_IT_FMP0, ENABLE);

TxMessage.StdId=0x11;

TxMessage.RTR=CAN_RTR_DATA;

TxMessage.IDE=CAN_ID_STD;

TxMessage.DLC=2;

TxMessage.Data[0]=0xCA;

TxMessage.Data[1]=0xFE;

CAN_Send(&TxMessage);

}

/*******************************************************************************

* Function Name : USB_LP_CAN_RX0_IRQHandler

* Description :

* Input : None

* Output : None

* Return : None

*******************************************************************************/

void USB_LP_CAN_RX0_IRQHandler(void)

{

CanRxMsg msg;

GPIO_WriteBit(GPIOC, 0x0040, Bit_SET);

//TB_Wait(100);

//GPIO_WriteBit(GPIOC, 0x0040, Bit_RESET);

CAN_Receive(CAN_FIFO0, &msg);

CAN_Receive_Message(&msg);

}

[ This message was edited by: mario.noessing on 14-01-2009 23:58 ]

jamessteward
Associate II
Posted on May 17, 2011 at 12:59

Hi.

I'm having pretty much the same trouble. It seems to init ok (checked the returned status from CAN_Init()), but any messages that I want to send via CAN_Transmit are pending, until all 3 mailbox holes are filled, then I get CAN_NO_MB of course. I monitored the CAN pins with a CRO, and they don't budge.

Also, the flags EWG, EPV and BOF seem to be set, which doesn't sound right.

Have you made any progress?

Posted on May 17, 2011 at 12:59

ok guys my can is already working..

attachment includes can communication projects between two STM32 EVAL boards. One board is in Silent and the other in LoopBack mode.

The only step you have to make to send / receive in Normal mode, is to configure one as LoopBack and on as Normale. Then send an CAN_INIT Message (11 recessive bits) to the bus (REMOTE) with the board in LoopBack to initialize communication on the ''Normal mode'' - board. After this step, switch the ''Loop Back'' - Board into Normal mode, and both boards are able to send/receive.

cheers,

Mario

jamessteward
Associate II
Posted on May 17, 2011 at 12:59

I got my CAN going.

I had enabled the AFIO clock, because I remapped the pins to port B 8&9, but forgot to enable the port B clock.

JS.

daviddavid91
Associate II
Posted on May 17, 2011 at 12:59

Hello CAN-people,

my CAN is working with HSE as system clock, but not with the PLL as system clock!

I am using an external crystal of 8MHz and a PLL multiplier of 8.

Since the CAN is attached to AHB1, which uses a divider of 2, I multiplied the prescaler value by 8/2=4.

Is my calculation correct?

Has anybody used the CAN with internal PLL?

Thank you for an answer!

Regards,

Michael

pandoraems
Associate II
Posted on May 17, 2011 at 12:59

CAN with PLL works (HSE feeds PLL), below is the code i use to ini clock

Code:

/* Enable HSE */

RCC_HSEConfig(RCC_HSE_ON);

/* Wait till HSE is ready */

while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET)

{

}

/* Select HSE as system clock source */

RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE);

/* Wait till HSE is ready */

HSEStartUpStatus = RCC_WaitForHSEStartUp();

if(HSEStartUpStatus == SUCCESS)

{

/* Enable Prefetch Buffer */

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

/* Flash 0 wait state */

FLASH_SetLatency(FLASH_Latency_1);

/* HCLK = SYSCLK */

RCC_HCLKConfig(RCC_SYSCLK_Div1);

/* PCLK2 = HCLK */

RCC_PCLK2Config(RCC_HCLK_Div1);

/* PCLK1 = HCLK */

RCC_PCLK1Config(RCC_HCLK_Div1);

/* PLLCLK = 8MHz * 3 = 24 MHz */

RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_3);

/* Enable PLL */

RCC_PLLCmd(ENABLE);

/* Wait till PLL is ready */

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

/* Select PLL as system clock source */

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

/* Wait till PLL is used as system clock source */

while(RCC_GetSYSCLKSource() != 0x08);

}//if

as you can see, i configure for 24mhz system clock.

here is my CAN clock config:

Code:

CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;

CAN_InitStructure.CAN_BS1=CAN_BS1_9tq;

CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;

CAN_InitStructure.CAN_Prescaler=4;

These two clock configs seem to give 1Mbps speed. I am almost certain as i have a device that presumably operates at 1Mbps, and it acknowleges the messages i send from the stm32

good luck