cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 DISCOVERY CAN bus controller problem

keyboqian
Associate
Posted on July 13, 2012 at 15:57

Hi all,

I am trying to get the CAN interface working on the STM32F4DISCOVERY board.

After calling the configuration functions from the peripheral library, when I tried to transmit message with just a oscilloscope connected to the TX and RX pins it does not work. I tried usng CAN_TransmitStatus() to see the status of the mailbox and it returned ''pending''. Then I tracked down the register in the CAN controller, the error flag is up and further more it says ''BIT DOMINANT error''... 

I don't know if I need to connect to a transceiver first and hook this board onto a CAN bus before I test it out? Or is it just something wrong with the configuration.

Here is the code I had for the configuration part:

---(I just used GPIOE pin0 to see if the program is running, nothing else)

 /* Enable GPIO clock */

  RCC_AHB1PeriphClockCmd(CAN_GPIO_CLK|RCC_AHB1Periph_GPIOE, 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);

//RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);

//configure a pin for debug

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;

  GPIO_Init(GPIOE, &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);

  /* CAN filter init */

#ifdef  USE_CAN1

  CAN_FilterInitStructure.CAN_FilterNumber = 0;

#else /* USE_CAN2 */

  CAN_FilterInitStructure.CAN_FilterNumber = 14;

#endif  /* USE_CAN1 */

  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);

  

  /* Transmit Structure preparation */

  TxMessage.StdId = 0x321;

  TxMessage.ExtId = 0x01;

  TxMessage.RTR = CAN_RTR_DATA;

  TxMessage.IDE = CAN_ID_STD;

  TxMessage.DLC = 1;

  

  /* Enable FIFO 0 message pending Interrupt */

  CAN_ITConfig(CANx, CAN_IT_FMP0, ENABLE);

Any help is very appreciated. Thanks!

Keybo
36 REPLIES 36
hamed
Associate II
Posted on June 12, 2014 at 12:38

I'm so sorry. I did not explain it correctly. I've used the following circuit. Is this true? Could I connect these boards together with following circuit?

0690X00000605YWQAY.png

Mark Edwards
Associate II
Posted on June 12, 2014 at 21:24

I don't recognise that way of connecting CAN. This is how I do it.

0690X00000605YbQAI.png

Posted on June 12, 2014 at 22:44

The diode trick was pretty clever.

0690X00000605SoQAI.png

[DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Can-Bus%20Error&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=141]https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FCan-Bus%20Error&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B?tviews=141
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
evilrakshasa
Associate II
Posted on December 12, 2014 at 09:28

I am using STM32F103C8 Controller. I want to use it as a CAN transmitter to send command to another device which will respond back with data.

I am using the following code to transmit data:

  

#include ''stm32f10x.h''

#include ''misc.h''

#include ''stm32f10x_can.h''

#include ''stm32f10x_rcc.h''

#include ''stm32f10x_gpio.h''

#define LED_PORT GPIOA

GPIO_InitTypeDef GPIO_InitStructure;

int i;

void NVIC_Configuration(void);

void CAN_Polling(void);

int main(void)

{

    /* CAN1 Periph clock enable */

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;

    GPIO_Init(LED_PORT, &GPIO_InitStructure);

    /* NVIC Configuration */

    NVIC_Configuration();

   // for (i = 0; i < 2000000; i++);

    /* CAN transmit at 100Kb/s and receive by polling in loopback mode */

    CAN_Polling();

    while(1)

    {

    }

}

void CAN_Polling(void)

{

    CAN_InitTypeDef CAN_InitStructure;

    CAN_FilterInitTypeDef CAN_FilterInitStructure;

    CanTxMsg TxMessage;

    uint8_t TransmitMailbox = 0;

    /* CAN register init */

    CAN_DeInit( CAN1);

    CAN_StructInit(&CAN_InitStructure);

    /* 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_InitStructure.CAN_BS1 = CAN_BS1_8tq;

    CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq;

    CAN_InitStructure.CAN_Prescaler = 5;

    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);

    /* transmit */

    TxMessage.StdId = 0x11;

    TxMessage.RTR = CAN_RTR_DATA;

    TxMessage.IDE = CAN_ID_STD;

    TxMessage.DLC = 2;

    TxMessage.Data[0] = 0xCA;

    TxMessage.Data[1] = 0xFE;

    TransmitMailbox = CAN_Transmit(CAN1, &TxMessage);

    i = 0;

    while ((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK)

            && (i != 0xFF))

    {

        i++;

    }

}

void NVIC_Configuration(void)

{

    NVIC_InitTypeDef NVIC_InitStructure;

    /* Enable CAN1 RX0 interrupt IRQ channel */

    NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

But there in no signal generated at the CANTX pin PA12. While debugging the std_id, data and DLC is being set but while transmitting, the TX0K is not being set and the status of the transmitter is shown as pending.

But if I run the same communication in loopback mode. The transmission is successful.

Please help.

Thanks
Posted on December 12, 2014 at 14:00

Yes, you'll need to be enabling the pins with a little more care. The CAN pins would need to be properly configured, and perhaps remapped depending on which ones you're using.

/* Configure CAN pin: RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIO_CAN, &GPIO_InitStructure);
/* Configure CAN pin: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_TX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIO_CAN, &GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_Remapping_CAN , ENABLE); // If required, AFIO clock must also be enabled

See also STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\CAN\Networking\main.c
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
evilrakshasa
Associate II
Posted on December 13, 2014 at 07:46

Thank you for the quick response.

I read through the CAN example reference suggested by you and did some modifications in the existing code as:

#include ''stm32f10x.h''

#include ''misc.h''

#include ''stm32f10x_can.h''

#include ''stm32f10x_rcc.h''

#include ''stm32f10x_gpio.h''

CAN_InitTypeDef        CAN_InitStructure;

CAN_FilterInitTypeDef  CAN_FilterInitStructure;

CanTxMsg TxMessage;

uint8_t TransmitMailbox = 0;

void NVIC_Configuration(void);

void CAN_Polling(void);

int main(void)

{

NVIC_Configuration();

GPIO_InitTypeDef  GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    /* Configure CAN pin: RX */

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;

      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

      GPIO_Init(GPIOA, &GPIO_InitStructure);

      /* Configure CAN pin: TX */

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;

      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

      GPIO_Init(GPIOA, &GPIO_InitStructure);

      GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE);

      /* CAN1 Periph clock enable */

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

    CAN_Polling();

 while(1)

            {

    TxMessage.Data[0] = 0x02;

    CAN_Transmit(CAN1, &TxMessage);

    uint16_t nTime = 0x0000;

     for(nTime = 0; nTime <0xFFF; nTime++)

     {

     }

     

    }

}

void CAN_Polling(void)

{

    /* CAN register init */

    CAN_DeInit( CAN1);

    CAN_StructInit(&CAN_InitStructure);

    /* 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_InitStructure.CAN_BS1 = CAN_BS1_3tq;

    CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;

    CAN_InitStructure.CAN_Prescaler = 8;

    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);

    /* transmit */

    TxMessage.StdId = 0x321;

    TxMessage.ExtId = 0x01;

    TxMessage.RTR = CAN_RTR_DATA;

    TxMessage.IDE = CAN_ID_STD;

    TxMessage.DLC = 1;

    CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);

}

void NVIC_Configuration(void)

{

    NVIC_InitTypeDef NVIC_InitStructure;

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

    /* Enable CAN1 RX0 interrupt IRQ channel */

    NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

}

Now there is an error in transmission depicted by the setting of TERR0 bit.

I am also not sure about the baudrate setting to. How to check the clock frequency for the controller to set the BS1,BS2 and Prescalar values?

Thank You

evilrakshasa
Associate II
Posted on December 17, 2014 at 05:25

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6gj&d=%2Fa%2F0X0000000btF%2Fwxs7axi078j7Nc9jjcT4.88751WCXXAl6PjNZIO.Zfk&asPdf=false
Posted on December 17, 2014 at 06:39

What tool chain are you using? You seem to have done some odd things with the project, as the peripheral #include files are typically pulled in via stm32f10x_conf.h, provided that's in your project directory and you have the right defines passed into the compiler. USE_STDPERIPH_DRIVER

You might want to review more carefully the project templates provided in the standard library

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
evilrakshasa
Associate II
Posted on December 17, 2014 at 07:14

I am using CooCox IDE. There I have selected my controller and then from the repository I have selected CAN template. So by default the CMSIS and CMSIS_boot header files are included in the project.

Posted on December 17, 2014 at 18:29

Perhaps you should take up compiler/project issues up with them then? I'm using Keil mostly, and Yagarto as my GNU/GCC tool chain.

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