2012-07-13 06:57 AM
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!Keybo2014-06-12 03:38 AM
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?
2014-06-12 12:24 PM
I don't recognise that way of connecting CAN. This is how I do it.
2014-06-12 01:44 PM
The diode trick was pretty clever.
[DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Can-Bus%20Error&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=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=1412014-12-12 12:28 AM
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 GPIOAGPIO_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.Thanks2014-12-12 05:00 AM
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
2014-12-12 10:46 PM
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 You2014-12-16 08:25 PM
2014-12-16 09:39 PM
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 library2014-12-16 10:14 PM
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.
2014-12-17 09:29 AM
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.