2019-10-13 08:28 AM
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.
2019-10-13 08:59 AM
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?
2019-10-13 09:07 AM
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
2019-10-13 09:27 AM
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.
2019-10-14 07:46 AM
tnks:)