Captain777 0 27 августа, 2021 Опубликовано 27 августа, 2021 (изменено) · Жалоба 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 (); } } Изменено 27 августа, 2021 пользователем Captain777 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andron_h 0 1 сентября, 2021 Опубликовано 1 сентября, 2021 · Жалоба Отчитываюсь. В хале, чето не то с калбеками, отказался от них и в основном цикле проверяю на наличие сообщений в буфере,если есть то читаю>фильтрую>отправляю. Все чудесно работает. if (HAL_CAN_GetRxFifoFillLevel(&hcan, CAN_RX_FIFO0) != 0) { if (HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &RxHeader, RxData)!= HAL_OK) { Error_Handler(); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andron_h 0 28 сентября, 2021 Опубликовано 28 сентября, 2021 · Жалоба Добрый день! Возник еще вопрос по выходу из режима сна. При выходе из режима сна мы должны вызвать HAL_ResumeTick() , и я так понимаю вызывать мы его должны в прерывании CAN(1/2)_SCE_IRQHandler. Но это прерывание происходит и по ошибкам . Собственно вопрос, нужно ли проверять что мы именно проснулись? И каким запросом о статусе bxCan? Или просто вызывать HAL_ResumeTick() и в этом ничего страшного нет? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться