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

Затык с проектом CAN шлюза на STM32F107RTB6

26.08.2021 в 11:49, andron_h сказал:

У меня сейчас в один буфер от машины в панель, в другой из панели в машину. Думаете пропускать через один? Можно взглянуть на реализацию приема передачи, сама оброботка фильтрации и подмены данных мне не интересна. С контрольками под vag я разобрался там crc8H2F с дополнительным числом в зависимости от счетчика и ID.

Настройка прерываний

void NVIC_Config_CAN(void)
{
  NVIC_InitTypeDef  NVIC_InitStructure;

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
 
  NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
   /* Enable FIFO 0 message pending Interrupt */
  CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
  
  NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

   /* Enable FIFO 1 message pending Interrupt */
  CAN_ITConfig(CAN1, CAN_IT_FMP1, ENABLE);

  NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
   /* Enable FIFO 0 message pending Interrupt */
  CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE);

 

Прием от машины всех ненужных пакетов - передача в приборку

void CAN1_RX0_IRQHandler(void)
{
   if (CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)                 
    {
      CAN_Receive(CAN1, CAN_FIFO0, &Can1RxMessage);         // Читаем почту
      
      
      
      
            Can1TxMessage.StdId = Can1RxMessage.StdId;
            Can1TxMessage.ExtId = Can1RxMessage.ExtId;
            Can1TxMessage.RTR = Can1RxMessage.RTR;
            Can1TxMessage.IDE = Can1RxMessage.IDE;
            Can1TxMessage.DLC = Can1RxMessage.DLC;
            Can1TxMessage.Data[0] = Can1RxMessage.Data[0];
            Can1TxMessage.Data[1] = Can1RxMessage.Data[1];
            Can1TxMessage.Data[2] = Can1RxMessage.Data[2];
            Can1TxMessage.Data[3] = Can1RxMessage.Data[3];
            Can1TxMessage.Data[4] = Can1RxMessage.Data[4];
            Can1TxMessage.Data[5] = Can1RxMessage.Data[5];
            Can1TxMessage.Data[6] = Can1RxMessage.Data[6];
            Can1TxMessage.Data[7] = Can1RxMessage.Data[7];
            

            CAN_Transmit(CAN2, &Can1TxMessage);
            InitCan1RxMessage ();
    }
}

Прием нужных для изменения ID и отправка в приборку

void CAN1_RX1_IRQHandler(void)
{
  if (CAN_GetITStatus(CAN1, CAN_IT_FMP1) != RESET)                 
    {
      CAN_Receive(CAN1, CAN_FIFO1, &Can1Fifo1RxMessage);
      
      Can1Fifo1TxMessage.StdId = Can1Fifo1RxMessage.StdId;
      Can1Fifo1TxMessage.ExtId = Can1Fifo1RxMessage.ExtId;
      Can1Fifo1TxMessage.RTR = Can1Fifo1RxMessage.RTR;
      Can1Fifo1TxMessage.IDE = Can1Fifo1RxMessage.IDE;
      Can1Fifo1TxMessage.DLC = Can1Fifo1RxMessage.DLC;
      Can1Fifo1TxMessage.Data[0] = Can1Fifo1RxMessage.Data[0];
      Can1Fifo1TxMessage.Data[1] = Can1Fifo1RxMessage.Data[1];
      Can1Fifo1TxMessage.Data[2] = Can1Fifo1RxMessage.Data[2];
      Can1Fifo1TxMessage.Data[3] = Can1Fifo1RxMessage.Data[3];
      Can1Fifo1TxMessage.Data[4] = Can1Fifo1RxMessage.Data[4];
      Can1Fifo1TxMessage.Data[5] = Can1Fifo1RxMessage.Data[5];
      Can1Fifo1TxMessage.Data[6] = Can1Fifo1RxMessage.Data[6];
      Can1Fifo1TxMessage.Data[7] = Can1Fifo1RxMessage.Data[7];
            
    Тут все считаем и CRC тоже  
    
                    Can1Fifo1TxMessage.Data[0] = CrcSea;
                    Can1Fifo1TxMessage.Data[1] = CrcBuf[0];
                    Can1Fifo1TxMessage.Data[2] = CrcBuf[1];            // Фильтруемые байты
                    Can1Fifo1TxMessage.Data[3] = CrcBuf[2];
                    Can1Fifo1TxMessage.Data[4] = CrcBuf[3];
                    Can1Fifo1TxMessage.Data[2] = 0x00;            // Фильтруемые байты
                    Can1Fifo1TxMessage.Data[3] = 0x00;
                  }
              }
            CAN_Transmit(CAN2, &Can1Fifo1TxMessage);
            InitCan1Fifo1RxMessage ();
    }
}

Со стороны приборки - все проще

void CAN2_RX0_IRQHandler(void)
{
   if (CAN_GetITStatus(CAN2, CAN_IT_FMP0) != RESET)                 
    {
      CAN_Receive(CAN2, CAN_FIFO0, &Can2RxMessage);         // Читаем почту
      
      //
            Can2TxMessage.StdId = Can2RxMessage.StdId;
            Can2TxMessage.ExtId = Can2RxMessage.ExtId;
            Can2TxMessage.RTR = Can2RxMessage.RTR;
            Can2TxMessage.IDE = Can2RxMessage.IDE;
            Can2TxMessage.DLC = Can2RxMessage.DLC;
            Can2TxMessage.Data[0] = Can2RxMessage.Data[0];
            Can2TxMessage.Data[1] = Can2RxMessage.Data[1];
            Can2TxMessage.Data[2] = Can2RxMessage.Data[2];
            Can2TxMessage.Data[3] = Can2RxMessage.Data[3];
            Can2TxMessage.Data[4] = Can2RxMessage.Data[4];
            Can2TxMessage.Data[5] = Can2RxMessage.Data[5];
            Can2TxMessage.Data[6] = Can2RxMessage.Data[6];
            Can2TxMessage.Data[7] = Can2RxMessage.Data[7];
            CAN_Transmit(CAN1, &Can2TxMessage);
            InitCan2RxMessage ();
           
    }
        
}

 

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

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


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

Отчитываюсь. В хале, чето не то с калбеками, отказался от них и в основном цикле проверяю на наличие сообщений в буфере,если есть то читаю>фильтрую>отправляю. Все чудесно работает.

if (HAL_CAN_GetRxFifoFillLevel(&hcan, CAN_RX_FIFO0) != 0)
{
if (HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &RxHeader, RxData)!= HAL_OK)
{
Error_Handler();
}

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


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

Добрый день! Возник еще вопрос по выходу из режима сна. При выходе из режима сна мы должны вызвать HAL_ResumeTick() , и я так понимаю вызывать мы его должны в прерывании CAN(1/2)_SCE_IRQHandler. Но это прерывание происходит и по ошибкам . Собственно вопрос, нужно ли проверять что мы именно проснулись? И каким запросом о статусе bxCan? Или просто вызывать HAL_ResumeTick() и в этом ничего страшного нет?

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


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

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

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

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

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

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

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

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

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

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