Перейти к содержанию
    

CAN_stm32

Привет всем, новичок в этом деле. Пытаюсь настроить CAN в режиме "слушать себя". Использую CubeMX HAL, ну и ручками немного понацарапалось. Кто может мне, тугодуму, подсказать,

почему в прерывание по приему и передаче входит только раз? Может, я какие-то флаги не сбрасываю? или фильтр не правильно настроен.

Куда копать хоть...

 

настройка CAN

static void MX_CAN1_Init(void)
{

  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 16;
  hcan1.Init.Mode = CAN_MODE_SILENT_LOOPBACK;
  hcan1.Init.SJW = CAN_SJW_1TQ;
  hcan1.Init.BS1 = CAN_BS1_3TQ;
  hcan1.Init.BS2 = CAN_BS2_3TQ;
  hcan1.Init.TTCM = DISABLE;
  hcan1.Init.ABOM = ENABLE;
  hcan1.Init.AWUM = DISABLE;
  hcan1.Init.NART = DISABLE;
  hcan1.Init.RFLM = ENABLE;
  hcan1.Init.TXFP = DISABLE;
  if (HAL_CAN_Init(&hcan1) != HAL_OK)
  {
    Error_Handler();
  }

}

 

функция отправки

void CAN_Transmit(void)
{
    hcan1.pTxMsg->StdId = 0x002;
    hcan1.pTxMsg->DLC = 3;
    hcan1.pTxMsg->Data[0] = tx++;
    hcan1.pTxMsg->Data[1] = 2;
    hcan1.pTxMsg->Data[2] = 3;
    HAL_CAN_Transmit(&hcan1, 10);

 

прерывания

void CAN1_TX_IRQHandler(void)
{
  /* USER CODE BEGIN CAN1_TX_IRQn 0 */

  /* USER CODE END CAN1_TX_IRQn 0 */
  HAL_CAN_IRQHandler(&hcan1);
  /* USER CODE BEGIN CAN1_TX_IRQn 1 */
    //HAL_CAN_Transmit_IT(&hcan1);
  /* USER CODE END CAN1_TX_IRQn 1 */
}

/**
* @brief This function handles CAN1 RX0 interrupt.
*/
void CAN1_RX0_IRQHandler(void)
{
  /* USER CODE BEGIN CAN1_RX0_IRQn 0 */
    HAL_CAN_IRQHandler(&hcan1);
  /* USER CODE END CAN1_RX0_IRQn 0 */
  HAL_CAN_Receive(&hcan1,CAN_FIFO0,10);
    hcan1.pRxMsg->DLC = 0x00;
  hcan1.pRxMsg->StdId =0x00;
  hcan1.pRxMsg->Data [0] = 0x00;
  hcan1.pRxMsg->Data [1] = 0x00;
  hcan1.pRxMsg->Data [2] = 0x00;
  hcan1.pRxMsg->Data [3] = 0x00;
  hcan1.pRxMsg->Data [4] = 0x00;
  hcan1.pRxMsg->Data [5] = 0x00;
  hcan1.pRxMsg->Data [6] = 0x00;
  hcan1.pRxMsg->Data [7] = 0x00;
  /* USER CODE BEGIN CAN1_RX0_IRQn 1 */
  /* USER CODE END CAN1_RX0_IRQn 1 */
}

 

МЭЙН

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_CAN1_Init();

  /* USER CODE BEGIN 2 */
    hcan1.pTxMsg = &canTxMessage;
    hcan1.pRxMsg = &canRxMessage;
    
    //фильтры CAN
    // настраиваем фильтр — приём всех посылок
    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(&hcan1, &canFilterConfig);
    HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0); //разрешаем приём посылок
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
        CAN_Transmit();
        HAL_Delay(10);
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */

}

 

 

Что не так???? stm32105R8Tx

Изменено пользователем Ekka

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что не так???? stm32105R8Tx

похоже через хал мало кто работает с каном.

Я хз, что там скрыто в вызовах, но не вижу разрешения прерываний от кана, типа

CAN->IER = CAN_IER_ERRIE | CAN_IER_BOFIE | CAN_IER_LECIE | CAN_IER_FMPIE0 | CAN_IER_TMEIE;

 

Ну и имхо стоит без loopback сниффером глянуть, что происходит на шине.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подозреваю, что вообще никто не связывается с HAL в чем-то хоть немного сложней "помигать светодиодиком".

ТСу либо надо ковыряться в исходниках используемых библиотек, либо написать нормально — по даташиту.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Осмелюсь предположить, что нет сброса битов прерывания.

void CAN1_TX_IRQHandler(void)
{
  /* USER CODE BEGIN CAN1_TX_IRQn 0 */
    HAL_NVIC_ClearPendingIRQ(CAN1_TX_IRQn);
  /* USER CODE END CAN1_TX_IRQn 0 */
  HAL_CAN_IRQHandler(&hcan1);
  /* USER CODE BEGIN CAN1_TX_IRQn 1 */

  /* USER CODE END CAN1_TX_IRQn 1 */
}

/**
* @brief This function handles CAN1 RX0 interrupts.
*/
void CAN1_RX0_IRQHandler(void)
{
  /* USER CODE BEGIN CAN1_RX0_IRQn 0 */
    HAL_NVIC_ClearPendingIRQ(CAN1_RX0_IRQn);
  /* USER CODE END CAN1_RX0_IRQn 0 */
  HAL_CAN_IRQHandler(&hcan1);
  /* USER CODE BEGIN CAN1_RX0_IRQn 1 */

  /* USER CODE END CAN1_RX0_IRQn 1 */
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Осмелюсь предположить, что нет сброса битов прерывания.

    HAL_NVIC_ClearPendingIRQ(CAN1_TX_IRQn);
    HAL_NVIC_ClearPendingIRQ(CAN1_RX0_IRQn);
}

Это лишнее для Cortex, т.к. это делает ядро при входе в обработчик.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ткните носом, пожалуйста, где в datasheet про КАН написано, какой документ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это вам не в даташит, а в RM на линейку используемых МК.

Изменено пользователем Эдди

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

на всякий случай:

сталкивались с глюками "HAL CAN драйвера"

то есть там есть путь, в котором его состояние не убирается в IDLE и соответственно софт подвисает

ну и при интенсивной работе на прием-передачу иногда сбрасывает биты маскирования CAN RX1|2 - может проблемы с реентерабельностью или интерференция какая-то с FreeRTOS задачами - на запись работает одна задача, на чтение другая

вобщем сделал некий внешний контроль битов по таймеру и если биты сброшены, то поднимать...

 

то есть - лучше разберитесь с железом, чем использовать CAN HAL

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

разобрались потихоньку, не знаю, правильно ли, но теперь КАН в режиме loopback работает. Кому надо, может, говорите, кину.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вопрос другой возник...пытаюсь связать две stm32f105r8t6 через CAN, но после отправки всегда появляется 131 ошибка (ErrorCode=131)...потом все виснет, отчего так может быть?

 

настройка первой stm

static void MX_CAN1_Init(void)
{

  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 4;
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SJW = CAN_SJW_1TQ;
  hcan1.Init.BS1 = CAN_BS1_4TQ;
  hcan1.Init.BS2 = CAN_BS2_4TQ;
  hcan1.Init.TTCM = DISABLE;
  hcan1.Init.ABOM = DISABLE;
  hcan1.Init.AWUM = DISABLE;
  hcan1.Init.NART = ENABLE;
  hcan1.Init.RFLM = DISABLE;
  hcan1.Init.TXFP = DISABLE;
  if (HAL_CAN_Init(&hcan1) != HAL_OK)
  {
    Error_Handler();
  }

}

 

ее фильтры

hcan1.pTxMsg = &canTxMessage;
    hcan1.pRxMsg = &canRxMessage;
    CAN_FilterConfTypeDef canFilterConfig;
    canFilterConfig.FilterNumber = 0;
    canFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
    canFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
    canFilterConfig.FilterIdHigh = 0;
    canFilterConfig.FilterIdLow = 0;
    canFilterConfig.FilterMaskIdHigh = 0;
    canFilterConfig.FilterMaskIdLow = 0;
    canFilterConfig.FilterFIFOAssignment = 0;
    canFilterConfig.FilterActivation = ENABLE;
    canFilterConfig.BankNumber = 1;
    HAL_CAN_ConfigFilter(&hcan1, &canFilterConfig);

    canRxMessage.StdId = 0x801;
    canRxMessage.RTR = CAN_RTR_DATA;
    canRxMessage.IDE = CAN_ID_STD;
    canRxMessage.DLC = 2;
    HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0);
    HAL_NVIC_SetPriority(CAN1_RX0_IRQn,2,0);
    HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);

 

настройки одинаковые у обоих плат.

 

разница только в том, что первая плата отправляется команду, а вторая принимает.

 

у первой платы:

 

void CAN_Transmit()
{
    canTxMessage.StdId=0x802;
    canTxMessage.DLC=2;  
    canTxMessage.Data[0] = 0x00;
    canTxMessage.Data[1] = 0x01;
    HAL_CAN_Transmit(&hcan1,10);
}

 

в цикле ее же:

while (1)
  {
  /* USER CODE END WHILE */
        CAN_Transmit();
        HAL_Delay(2000);
  /* USER CODE BEGIN 3 */

  }

 

вторая должна принимать

void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* CanHandle)
{
    CAN_ID = CanHandle->pRxMsg->StdId;
    CAN_DLC = CanHandle->pRxMsg->DLC;
    __HAL_UNLOCK (CanHandle);
    r=HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0);
    DATA[0]=CanHandle->pRxMsg->Data[0];
    DATA[1]=CanHandle->pRxMsg->Data[1];
}

 

но первая плата после отправки уходит в ошибку 131, потом через некоторое время виснет (число ошибок зашкаливает,наверное)... что может быть не так???

 

если быть точнее, но в функции отправки уходит в таймаут и сидит там, пока статус кана не перейдет в HAL_STATE_ERROR

 

Изменено пользователем Ekka

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ребят, неужели такой ошибки не у кого не было? Понимаю,вопросы не из умных... Но надо же с чего-то начинать? Может,кто подскажет,куда копать хоть( хелп

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Копать:

1) в сторону рассмотрения шины осциллографом и заведомо работоспособным CAN-адаптером

2) в сторону понимания, что и как устроено в этом чудо HAL'е. К сожалению, качество его такое, что любой шаг в сторону от придуманного его авторами алгоритма - и ничего не работает.

 

Не уверен, что тут есть люди, которые наизусть помнят, что такое "ошибка 131". При этом многие (и я в т.ч.) имеют представление и о CAN-периферии стм-ки, и о спецификации дядьки Боша на саму шину.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ребят, неужели такой ошибки не у кого не было? Понимаю,вопросы не из умных... Но надо же с чего-то начинать? Может,кто подскажет,куда копать хоть( хелп

У вас странный подход к кану.

- проверять надо не другим стм, а сниффером. На али они стоят от 1000р, потерянное время намного дороже.

- большинство работают без хала и что такое ошибка 131 - хз. Можно было бы хоть описание ее дать.

- выше уже сказали простейший вариант - дать передачу и смотреть скопом или лог. анализатором с того-же али за 600р( saleae logic). Он еще и декодировать кан умеет, и крестиком вышивать, всегда пригодится.

 

Ну и вообще, передача по кану без хала, только работой регистрами проста и дубова. Я ее за пару часов просмотра даташита и инета написал и она сразу заработала. Но за месяц до этого заказал синффер с али.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...