cancel
Showing results for 
Search instead for 
Did you mean: 

Building a small CAN-Bus with CAN1 and CAN2 module of the STM32F105

mubinicyer
Associate II
Posted on April 03, 2014 at 01:25

Hi,

I want to build a small CAN-Bus Network using CAN1 and CAN2 module of the STM32F105RCT6. Before testing the network I noticed something in the standard periphery library from ST. In my startup file startup_stm32f10x_md.c all of the IRQ handlers are listed (defined or whatever) except IRQHandlers for CAN2. I have following Handlers regarding to CAN:

USB_HP_CAN1_TX_IRQHandler, /*!< 19: USB High Priority or CAN1 TX */
USB_LP_CAN1_RX0_IRQHandler, /*!< 20: USB Low Priority or CAN1 RX0 */
CAN1_RX1_IRQHandler, /*!< 21: CAN1 RX1 */
CAN1_SCE_IRQHandler, /*!< 22: CAN1 SCE */

Where is the IRQHandlers for CAN2. Can I just add them at the end of list? And another issue: In file stm32f10x_can.c the functionsCAN_FilterInit andCAN_SlaveStartBankuse only one parameter assuming that the CAN module being used is number 1. Is that correct? What shall I do if I want to init a filter for CAN2?
5 REPLIES 5
Posted on April 03, 2014 at 01:39

Connectivity Line?

STM32F10x_StdPeriph_Lib_V3.5.0\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm\startup_stm32f10x_cl.s

STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\CAN\DualCAN\readme.txt
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mubinicyer
Associate II
Posted on April 03, 2014 at 09:51

Oh men, thank you. I just didn't see it. I will try it.

mubinicyer
Associate II
Posted on April 03, 2014 at 22:24 Hi again, I tried the DualCAN example from the ST Library but I could not run it. I attached a probe of osciloscope at PA12, nothing happens, it stays at 2.5V also idle. My code is so:

#define CAN1_PORT GPIOA
#define CAN1_Pin_RX GPIO_Pin_11
#define CAN1_Pin_TX GPIO_Pin_12
#define CAN2_PORT GPIOB // Remap
#define CAN2_Pin_RX GPIO_Pin_5
#define CAN2_Pin_TX GPIO_Pin_6
void CAN_Configuration(void)
{
CAN_DeInit(CAN1);
CAN_DeInit(CAN2);
CAN_StructInit(&CAN_InitStructure);
CAN_InitStructure.CAN_Prescaler = 36;
CAN_InitStructure.CAN_SJW = CAN_SJW_2tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_11tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_4tq;
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
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 = ENABLE;
CAN_Init(CAN1, &CAN_InitStructure);
CAN_Init(CAN2, &CAN_InitStructure);
CAN_FilterInitStructure.CAN_FilterNumber = 1;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x6420;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
/* CAN2 filter init */
CAN_FilterInitStructure.CAN_FilterNumber = 15;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x2460;
CAN_FilterInit(&CAN_FilterInitStructure);
}
void RCC_Configuration(void)
{
//
// RCC system reset(for debug purpose)
//
RCC_DeInit();
//
// Enable HSE
//
RCC_HSEConfig(RCC_HSE_ON);
//
// Wait till HSE is ready
//
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if (HSEStartUpStatus == SUCCESS)
{
//
// HCLK = SYSCLK
//
RCC_HCLKConfig(RCC_SYSCLK_Div1);
//
// PCLK2 = HCLK
//
RCC_PCLK2Config(RCC_HCLK_Div1);
//
// PCLK1 = HCLK/2
//
RCC_PCLK1Config(RCC_HCLK_Div2);
//
// Flash 2 wait state
//
FLASH_SetLatency(FLASH_Latency_2);
//
// Enable Prefetch Buffer
//
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
//
// PLLCLK = 8MHz * 9 = 72 MHz
//
RCC_PLLConfig(0x00010000, RCC_PLLMul_9);
//
//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)
{
}
}
//
// Enable GPIOA, GPIOC and AFIO clock
//
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3 | \
RCC_APB1Periph_CAN1 | \
RCC_APB1Periph_CAN2 | \
, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | \
RCC_APB2Periph_GPIOB | \
RCC_APB2Periph_GPIOC | \
RCC_APB2Periph_ADC1 | \
RCC_APB2Periph_AFIO , ENABLE);
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
//
// Set the Vector Table base location at 0x08000000
//
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
//
// Configure one bit for preemption priority
//
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/*
* Enable the EXTI9_5 Interrupt
*/
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/*
* Enable EXTI 9-5 Lines interrupt
*/
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/*
* CAN1 RX and CAN2 RX interrupts
*/
NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE);
}
void GPIO_Configuration(void)
{
// other GPIO configurations
// ...
// CAN1-bus input and outputs
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = CAN1_Pin_RX;
GPIO_Init(CAN1_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = CAN1_Pin_TX;
GPIO_Init(CAN1_PORT, &GPIO_InitStructure);
// CAN2-bus input and outputs
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = CAN2_Pin_RX;
GPIO_Init(CAN2_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = CAN2_Pin_TX;
GPIO_Init(CAN2_PORT, &GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_Remap_CAN2, ENABLE);
}
file: stm3210x_it.c
void CAN1_RX0_IRQHandler(void)
{
CAN_Receive(CAN1, CAN_FIFO0, &CanRxMessage);
if( (CanRxMessage.StdId == 0x321) && (CanRxMessage.IDE == CAN_ID_STD) )
{
UART_Send(USART2, (const unsigned char *)''CAN2 RX0 interrupt: '');
for (i = 0; i < 
5
; ++i) {
UART_Send_Numeric(USART2, CanRxMessage.Data[i], 10);
UART_Send(USART2, (const unsigned char *)'':'');
}
UART_Send(USART2, (const unsigned char *)''

'');
}
}
void CAN2_RX0_IRQHandler(void)
{
CAN_Receive(CAN2, CAN_FIFO0, &CanRxMessage);
if( (CanRxMessage.StdId == 0x321) && (CanRxMessage.IDE == CAN_ID_STD) )
{
UART_Send(USART2, (const unsigned char *)''CAN2 RX0 interrupt: '');
for (
i
= 
0
; i < 5; ++i) {
UART_Send_Numeric(USART2, CanRxMessage.Data[i], 10);
UART_Send(USART2, (const unsigned char *)'':'');
}
UART_Send(USART2, (const unsigned char *)''

'');
}
}
void EXTI0_IRQHandler(void)
{
EXTI_ClearITPendingBit(EXTI_Line0);
uint8_t tag[5], TxMailbox, CAN_Status;
uint64_t 
rfid_tag
= 
0
;
CanTxMessage.StdId
= 
0x321
;
CanTxMessage.ExtId
= 
0
;
CanTxMessage.RTR
= 
CAN_RTR_DATA
;
CanTxMessage.IDE
= 
CAN_ID_STD
;
CanTxMessage.DLC
= 
8
;
if(GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_8)){
GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_RESET);
}else{
GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET);
}
if(RFID_ReadTag(tag)) {
for (
i
= 
0
; i < 7; ++i) {
CanTxMessage.Data[i] = 0;
}
for (
i
= 
0
; i < 5; ++i) {
rfid_tag <<= 8;
rfid_tag |= tag[i];
CanTxMessage.Data[i] = tag[i];
}
UART_Send(USART2, (const unsigned char *)''RFID Number: '');
UART_Send_Numeric(USART2, rfid_tag, 10);
UART_Send(USART2, (const unsigned char *)''

'');
}
while( !( (CAN1->TSR & CAN_TSR_TME0) || (CAN1->TSR & CAN_TSR_TME1) || (CAN1->TSR & CAN_TSR_TME2) ));
TxMailbox = CAN_Transmit(CAN1, &CanTxMessage);
CAN_Status = CAN_TransmitStatus(CAN1, TxMailbox);
UART_Send(USART2, (const unsigned char *)''TM: '');
switch (CAN_Status) {
case CAN_TxStatus_Failed:
UART_Send(USART2, (const unsigned char *)''CAN_TxStatus_Failed.'');
break;
case CAN_TxStatus_Ok:
UART_Send(USART2, (const unsigned char *)''CAN_TxStatus_Ok.'');
break;
case CAN_TxStatus_NoMailBox:
UART_Send(USART2, (const unsigned char *)''CAN_TxStatus_NoMailBox.'');
break;
case CAN_TxStatus_Pending:
UART_Send(USART2, (const unsigned char *)''CAN_TxStatus_Pending.'');
break;
default:
break;
}
UART_Send(USART2, (const unsigned char *)''

'');
if(GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_9)){
GPIO_WriteBit(GPIOC, GPIO_Pin_9, Bit_RESET);
}else{
GPIO_WriteBit(GPIOC, GPIO_Pin_9, Bit_SET);
}
}

I am receiving always ''

CAN_TxStatus_Pending''

on serial port (connected to USART2)

Posted on April 03, 2014 at 23:18

Do you have a transceiver on the bus? Is it connected to another device?

Most implementations using 105/107 parts I've seen use PD0/PD1 for CAN1

What version of the library are you using? SystemInit() should manage the clock configuration.

The CAN baud rate looks a bit odd. ~59Kbit
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
mubinicyer
Associate II
Posted on April 04, 2014 at 00:00

I want to make a connection between two CAN modules of one STM32F105RCT6. I am using CooCox IDE and the most of the RCC Configurations are added automatically. I use STM32F10x_StdPeriph_Lib_V3.5.0

I have two ISO1050 Transcievers from TI. One is connected to CAN1 and other is connected to CAN2. I connected both of the transciever with two wires (CAN_H and CAN_L, and of course they are connected to the same GND).

Let me try port remapping for CAN1.

I made the Baudrate slow in order to see it on my small osciloscope, Let me try other baudrates as well.