Я успешно установил связь CAN с CAN1 двух STM32F105vC (у которых есть два CAN), и я могу отправлять и получать кадры CAN.
Но когда я изменяю свой код для использования CAN2, он работает, я имею в виду, что он подтверждает полученные кадры CAN, но прерывание приема вообще не вызывается.
Я думал, что это конфигурация фильтра, я несколько раз менял BankNumber (пробовал 0, 1, 14, 20), не повезло.
Вот мои конфигурации:
Инициализация:
init_HAL_CAN(CAN2);
if(HAL_CAN_Receive_IT(canHandle, CAN_FIFO0) != HAL_OK)
{
/* Reception Error */
Error_Handler();
}
Получить обратный вызов:
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* CanHandle)
{
LED_DBG_TOGGLE();
// other
// stuff
// here
//...
/* Receive */
if(HAL_CAN_Receive_IT(CanHandle, CAN_FIFO0) != HAL_OK)
{
/* Reception Error */
Error_Handler();
}
}
Функция инициализации:
void init_HAL_CAN(CAN_TypeDef* _CANInstance)
{
CAN_FilterConfTypeDef sFilterConfig;
static CanTxMsgTypeDef TxMessage;
static CanRxMsgTypeDef RxMessage;
/*##-1- Configure the CAN peripheral #######################################*/
canHandle->Instance = _CANInstance;
canHandle->pTxMsg = &TxMessage;
canHandle->pRxMsg = &RxMessage;
canHandle->Init.TTCM = DISABLE; //Non time trigger communication mode //
canHandle->Init.ABOM = DISABLE; //The software automatically Bus-off management //
canHandle->Init.AWUM = DISABLE; //Sleep mode wake by software (clear CAN-> MCR SLEEP) (automatic wake-up mode)//
canHandle->Init.NART = DISABLE; //Disable automatic transfer message (non-automatic retransmission mode)//
canHandle->Init.RFLM = DISABLE; //The message is not locked, the new cover the old //
canHandle->Init.TXFP = DISABLE; // Priority is determined by the message identifier //
canHandle->Init.Mode = CAN_MODE_NORMAL;
canHandle->Init.SJW = CAN_SJW_1TQ;
canHandle->Init.BS1 = CAN_BS1_2TQ;
canHandle->Init.BS2 = CAN_BS2_1TQ;
canHandle->Init.Prescaler = 7;
if(HAL_CAN_Init(canHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
return false;
}
/*##-2- Configure the CAN Filter ###########################################*/
CAN_FilterConfTypeDef sFilterConfig;
sFilterConfig.FilterNumber = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = 0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.BankNumber = 20;
if (HAL_CAN_ConfigFilter(canHandle, &sFilterConfig) != HAL_OK)
{
/* Filter configuration Error */
Error_Handler();
return false;
}
}
IRQHandler (размещен в stm32f1xx_it.c):
void CAN2_RX0_IRQHandler(void)
{
HAL_CAN_IRQHandler(canHandle);
}
Функция MspInit (помещена в stm32f1xx_hal_msp.c):
void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan)
{
GPIO_InitTypeDef GPIO_InitStruct;
/*##-1- Enable peripherals and GPIO Clocks #################################*/
/* CAN1 Periph clock enable */
CANx1_CLK_ENABLE(); // Need to enable CAN1 clock too.
CANx2_CLK_ENABLE();
/* Enable GPIO clock ****************************************/
CANx2_GPIO_CLK_ENABLE();
/* CAN2 needs no remapping *******/
/*##-2- Configure peripheral GPIO ##########################################*/
/* CAN1 TX GPIO pin configuration */
GPIO_InitStruct.Pin = CANx2_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(CANx2_TX_GPIO_PORT, &GPIO_InitStruct);
/* CAN1 RX GPIO pin configuration */
GPIO_InitStruct.Pin = CANx2_RX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(CANx2_RX_GPIO_PORT, &GPIO_InitStruct);
/*##-3- Configure the NVIC #################################################*/
/* NVIC configuration for CAN2 Reception complete interrupt */
HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn);
}
Я должен еще раз отметить, что следующие коды отлично работают с CAN1 (конечно, с заменой CAN2 на CAN1 и т. д.).
И ясно, что CAN-контроллер работает, потому что другая плата, которая передает CAN-кадры, получает подтверждения (и не получает никаких ошибок передачи или тайм-аута), единственная проблема здесь Receive Прерывает, почему?