Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Проблемы с CAN в STM32F373CCT
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
SergR
Доброго времени суток.
Проблема следующего характера. Есть 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;


Обработчик прерывания приема
Код
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();
    }


Обработчик ошибки инициализации приема 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 */
}
yes
там (в HAL) в драйвере ошибка, по-моему

--- stm32f3xx_hal_can.c
+++ stm32f3xx_hal_can.c
@@ -758,6 +758,10 @@ HAL_StatusTypeDef HAL_CAN_Transmit_IT(CAN_HandleTypeDef* hcan)
/* Request transmission */
hcan->Instance->sTxMailBox[transmitmailbox].TIR |= CAN_TI0R_TXRQ;
}
+ else
+ {
+ __HAL_UNLOCK(hcan);
+ }
}
else
{
SergR
Не совсем понял что означает
Цитата
--- stm32f3xx_hal_can.c
+++ stm32f3xx_hal_can.c
@@ -758,6 +758,10 @@

Но в stm32f3xx_hal_can.c добавил:
Нажмите для просмотра прикрепленного файла
К сожалению не помогло...
SergR
PS
Даже один Контроллер затыкается на прием, только через больший промежуток времени...
yes
посмотрите счетчики ошибок.
сброс CAN-а делаете через APBRESET (не помню точно название)? эти счетчики сбрасываются только так, по-крайней мере сброс в самом CAN-е их не изменяет.
esaulenka
Не надо счётчики сбрасывать.
Если очень вдумчиво почитать спецификацию от Боша, выяснится, что счётчики - штука информационная.
Если шина "живая", счётчики автоматически уменьшаются, через некоторое время передатчик включается автоматически.
dvi
В настройке CAN если
CanHandle.Init.ABOM = DISABLE;
надо включить
CanHandle.Init.ABOM = ENABLE;

и если с шиной все нормально счетчики ошибок сами постепенно сбросятся (как писал esaulenka).

а может проблема с самой шиной или с таймингами ?
SergR
Цитата
В настройке CAN если
CanHandle.Init.ABOM = DISABLE;
надо включить
CanHandle.Init.ABOM = ENABLE;

Да в настройках было CanHandle.Init.ABOM = DISABLE; заменил на CanHandle.Init.ABOM = ENABLE;
Но проблема не ушла. Вот скрин:
Нажмите для просмотра прикрепленного файла
Счетчики ошибок TEC и REC по нолям...

И еще, если закоментить вызов Error_Handler_CAN то при возникновении этого затыка, СТМ продолжает выставлять акноледжи на приходящие пакеты... Вот осциллограмма на ногах процессора RX - желтый TX - бирюзовый:
Нажмите для просмотра прикрепленного файла
dvi
проверь сигналы CAN-H и CAN-L. может все таки проблема в физике шины
SergR
Вот типичный сигнал на шине:
Нажмите для просмотра прикрепленного файла
dvi
а какой из них CAN-H и CAN-L ?
SergR
Желтый CAN-H
Бирюзовый CAN-L
И микросхема дайвер кана на 3.3В SN65HVD230Q
dvi
вроде у CAn-H амплитуда маленькая . вроде должно быть в примерно до 3-3.3 V.

а резисторы по 120 Ом по концам шины стоят?
ozone
Да, уровни какие то не дотягивающие.

Нажмите для просмотра прикрепленного файла
SergR
Резисторы конешно есть. Почему ампледуда на CAN-H не дотягивает до3В, сложно сказать. Возможно потому что у меня питание не 5В а 3.3В.
PS
"Маленькая" не точность!!! После CanHandle.Init.ABOM = ENABLE; затык происходит, но переинициализация CAN модуля в Error_Handler_CAN Выводит его из ступора!!! Это уже прогресс.
Neborak
Цитата(SergR @ Jul 8 2016, 17:12) *
Резисторы конешно есть. Почему ампледуда на CAN-H не дотягивает до3В, сложно сказать. Возможно потому что у меня питание не 5В а 3.3В.
PS
"Маленькая" не точность!!! После CanHandle.Init.ABOM = ENABLE; затык происходит, но переинициализация CAN модуля в Error_Handler_CAN Выводит его из ступора!!! Это уже прогресс.
Раз у Вас акнолиджи идут, значит CAN жив остается. По какой-то причине не происходит прерывание при приеме, промониторьте флаги полноты/переполнения приемного буфера при затыке.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.