Проблема следующего характера. Есть CAN сеть из трех устройств: один Преобразователь USB в CAN на PIC18F25K80 (CAN ID = 0x480) и две платы Контроллеров на STM32F373CCT (CAN ID = 0x400 и CAN ID = 0x401). Если в сеть включены только Преобразователь и один Контроллер то все работает корректно, пакеты принимаются и отправляются без вопросов. Но если в сеть добавить второй Контроллер то по началу тоже все корректно работает, но через пару минут вылазит не понятный глюк. Один из контроллеров перестает принимать пакеты и функция HAL_CAN_Receive_IT(&hcan, CAN_FIFO0) возвращает код ошибки (0x01). Реинициализация CAN-а не помогает только полный рисет контроллера. Причем передача данных от сбойнувшего Контроллера продолжается....
Кто сталкивался с подобным на STM-ах подскажите пожалуйста как бороться с этой проблемой.
Инициализация
Код
MX_CAN_Init();
static CanTxMsgTypeDef TxMessage;
static CanRxMsgTypeDef RxMessage;
//HAL_StatusTypeDef CAN_Status;
static CanTxMsgTypeDef TxMessage;
static CanRxMsgTypeDef RxMessage;
hcan.pTxMsg = &TxMessage;
hcan.pRxMsg = &RxMessage;
// настраиваем фильтр — приём всех посылок
CAN_FilterConfTypeDef canFilterConfig;
canFilterConfig.FilterNumber = 0;
canFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
canFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
canFilterConfig.FilterIdHigh = 0x0000;
canFilterConfig.FilterIdLow = 0x0000;
canFilterConfig.FilterMaskIdHigh = 0x0000 << 5;
canFilterConfig.FilterMaskIdLow = 0x0000;
canFilterConfig.FilterFIFOAssignment = 0;
canFilterConfig.FilterActivation = ENABLE;
canFilterConfig.BankNumber = 1;
HAL_CAN_ConfigFilter(&hcan, &canFilterConfig);
HAL_CAN_Receive_IT(&hcan, CAN_FIFO0); //разрешаем приём посылок
/*##Configure Transmission process #####################################*/
hcan.pTxMsg->StdId = (MB_number == 1) ? 0x400 : 0x401;//0x321;
hcan.pTxMsg->ExtId = 0x01;
hcan.pTxMsg->RTR = CAN_RTR_DATA;
hcan.pTxMsg->IDE = CAN_ID_STD;
hcan.pTxMsg->DLC = 8;
static CanTxMsgTypeDef TxMessage;
static CanRxMsgTypeDef RxMessage;
//HAL_StatusTypeDef CAN_Status;
static CanTxMsgTypeDef TxMessage;
static CanRxMsgTypeDef RxMessage;
hcan.pTxMsg = &TxMessage;
hcan.pRxMsg = &RxMessage;
// настраиваем фильтр — приём всех посылок
CAN_FilterConfTypeDef canFilterConfig;
canFilterConfig.FilterNumber = 0;
canFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
canFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
canFilterConfig.FilterIdHigh = 0x0000;
canFilterConfig.FilterIdLow = 0x0000;
canFilterConfig.FilterMaskIdHigh = 0x0000 << 5;
canFilterConfig.FilterMaskIdLow = 0x0000;
canFilterConfig.FilterFIFOAssignment = 0;
canFilterConfig.FilterActivation = ENABLE;
canFilterConfig.BankNumber = 1;
HAL_CAN_ConfigFilter(&hcan, &canFilterConfig);
HAL_CAN_Receive_IT(&hcan, CAN_FIFO0); //разрешаем приём посылок
/*##Configure Transmission process #####################################*/
hcan.pTxMsg->StdId = (MB_number == 1) ? 0x400 : 0x401;//0x321;
hcan.pTxMsg->ExtId = 0x01;
hcan.pTxMsg->RTR = CAN_RTR_DATA;
hcan.pTxMsg->IDE = CAN_ID_STD;
hcan.pTxMsg->DLC = 8;
Обработчик прерывания приема
Код
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* CanHandle)
{
if((hcan.pRxMsg->StdId == 0x480) && (NewDataFromCAN == 0))
{
BUF_Data[0] = hcan.pRxMsg->Data[0];
BUF_Data[1] = hcan.pRxMsg->Data[1];
BUF_Data[2] = hcan.pRxMsg->Data[2];
BUF_Data[3] = hcan.pRxMsg->Data[3];
BUF_Data[4] = hcan.pRxMsg->Data[4];
BUF_Data[5] = hcan.pRxMsg->Data[5];
BUF_Data[6] = hcan.pRxMsg->Data[6];
BUF_Data[7] = hcan.pRxMsg->Data[7];//hcan.pRxMsg->Data[6];
// HAL_CAN_Transmit(&hcan, 100);//100
NewDataFromCAN = 1;
}
while(Error_Code = HAL_CAN_Receive_IT(&hcan, CAN_FIFO0) != HAL_OK)
{
/* Reception Error */
Error_Handler_CAN();
}
{
if((hcan.pRxMsg->StdId == 0x480) && (NewDataFromCAN == 0))
{
BUF_Data[0] = hcan.pRxMsg->Data[0];
BUF_Data[1] = hcan.pRxMsg->Data[1];
BUF_Data[2] = hcan.pRxMsg->Data[2];
BUF_Data[3] = hcan.pRxMsg->Data[3];
BUF_Data[4] = hcan.pRxMsg->Data[4];
BUF_Data[5] = hcan.pRxMsg->Data[5];
BUF_Data[6] = hcan.pRxMsg->Data[6];
BUF_Data[7] = hcan.pRxMsg->Data[7];//hcan.pRxMsg->Data[6];
// HAL_CAN_Transmit(&hcan, 100);//100
NewDataFromCAN = 1;
}
while(Error_Code = HAL_CAN_Receive_IT(&hcan, CAN_FIFO0) != HAL_OK)
{
/* Reception Error */
Error_Handler_CAN();
}
Обработчик ошибки инициализации приема CAN пакетов
Код
void Error_Handler_CAN(void)
{
/* USER CODE BEGIN Error_Handler */
/* User can add his own implementation to report the HAL error return state */
SPI_Data[0] = 0xFF;
SPI_Data[1] = 0xFF;
HAL_CAN_DeInit(&hcan);
while(SPI_Data[0] != 0)
{
HAL_SPI_Transmit(&hspi2, ((uint8_t*)&SPI_Data[0]),1,1000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET); // SPI strob
for(My_i=0; My_i<10; My_i++){__NOP();}
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET);
SPI_Data[0] >>= 1;
SPI_Data[1] = Error_Code;
HAL_Delay(1500);
}
MX_CAN_Init();
My_CAN_FilterConf();
/* USER CODE END Error_Handler */
}
{
/* USER CODE BEGIN Error_Handler */
/* User can add his own implementation to report the HAL error return state */
SPI_Data[0] = 0xFF;
SPI_Data[1] = 0xFF;
HAL_CAN_DeInit(&hcan);
while(SPI_Data[0] != 0)
{
HAL_SPI_Transmit(&hspi2, ((uint8_t*)&SPI_Data[0]),1,1000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET); // SPI strob
for(My_i=0; My_i<10; My_i++){__NOP();}
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET);
SPI_Data[0] >>= 1;
SPI_Data[1] = Error_Code;
HAL_Delay(1500);
}
MX_CAN_Init();
My_CAN_FilterConf();
/* USER CODE END Error_Handler */
}