cancel
Showing results for 
Search instead for 
Did you mean: 

CAN Receive Interrupt porblem

Mohammad Rostamian
Associate III

Hi

I am new at CAN communication protocol and working with STM32f407. I used example to run fist communication. I can receive and transmit frames.

But the problem is, when a frame is sent from first board to other board, second board goes to ISR receive for two times.

if I halted the processor at ISR and continue step to step, ISR was done one time.

if some delay added at the end of ISR, it works ok.

the follow code shows CAN setting and ISR routine.

uint8_t cnt;

CanRxMsg rx;

void CAN2_RX0_IRQHandler(void)

{  

  cnt++;

  CAN_Receive(CAN2, CAN_FIFO0, &rx);  

}

static void CAN_Config(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;  

  /* Enable GPIO clock */

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

   

  /* Connect CAN pins to AF9 */

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_CAN2);

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_CAN2);

   

  /* Configure CAN RX and TX pins */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13;

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

   

   

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

  /* Enable CAN clock */

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2 | RCC_APB1Periph_CAN1, ENABLE);

   

  /* CAN register init */

  CAN_DeInit(CAN2);

   

  /* 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_15tq;

  CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;

  CAN_InitStructure.CAN_Prescaler = 7;

  CAN_Init(CAN2, &CAN_InitStructure);

   

  CAN_FilterInitStructure.CAN_FilterNumber = 14;

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

   

  /* Enable FIFO 0 message pending Interrupt */

  CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE);

}

static void NVIC_Config(void)

{

  NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

}

Tanks for helps.

Best regards.

4 REPLIES 4
JoniS
Senior

What is inside CAN_Receive function?

Also show the complete code for ​transmitting messages, are you 100% positive it's just not sending two can frames?

CAN_Receive is function at stm32f4xx_can.c

and frame is transmitted by  CAN_Transmit(CAN2, &TxMessage).

I checket rx signal by oscilloscope and I am sure just one frame was transmitted

You should propably make your cnt variable volatile, if you modify it from mainloop. Also consider not using that receive function in isr context it does perform useless stuff which just wastes your mcu clock cycles every interrupt. You could copy the important stuff from the function and put it directly inside the ISR.

I​ dont see reason why it would receive twice to be honest.

Mohammad Rostamian
Associate III

tnks🙂