nickson.b.k 0 27 сентября, 2021 Опубликовано 27 сентября, 2021 · Жалоба Доброго времени!Появилась необходимость в умении работать с CAN шиной.Собрал проект на по примеру, https://istarik.ru/blog/stm32/159.html , вдруг кто-то знаком с данной статьёй.В примере автор запускает CAN сначала внутри самой себя используя режим Loopback.А после берёт вторую плату Bluepill и переведя проект в Normal перекидывается сообщениями между платами.А что у меня.Я взял две платы с CAN-трансиверами.Сначала одну плату настроил на Loopback…в результате чего, при помощи осциллографа я убедился, что сигнал выходит из первой платы.Начал работу со второй.Настроил ее на такой же проект, но оказалось, что в Normal режиме, вторая плата не принимает сообщения от первой.А принимает только в Silent режиме.Соответственно, если вернуться к первой плате и перевести ее в режим NORMAL, то она начинает зависать, так как ждёт когда придёт подтверждение от второй платы о принятии кадра. (ждёт выставления ACK)Получается, что на данный момент я могу передавать сообщения только в одну сторону, от устройства 1 к устройству 2. А хотелось бы освоить и общение в обе стороны.Вот что я сейчас имею.Вот это первое устройство (на данный момент передатчик). Суть: фифо настроен на приём всего подряд. А в цикле просто шлёт сообщение "HI!\r\n" int main(void) { Init_CAN(); while (1) { sprintf(buff, "HI!\r\n"); CAN_Transmit_data(0x01, buff); HAL_Delay(500); } } void Init_CAN (void){ /* * Шина настроена на 500kbit/s * Semple point = 87.5% */ HAL_Init(); MX_GPIO_Init(); MX_CAN_Init(); HAL_CAN_Start(&hcan); HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_ERROR | CAN_IT_BUSOFF | CAN_IT_LAST_ERROR_CODE); } void CAN_Transmit_data (uint32_t id_message, uint8_t Data[]){ TxHeader.StdId = 0x0; // ID_EXT TxHeader.ExtId = id_message; // от 0х00 до 1FFFFFFF (0 — 536870911) сам идентификатор TxHeader.RTR = CAN_RTR_DATA; // Указывает что будет оправляться данные или команда TxHeader.IDE = CAN_ID_EXT; // расширенный идентификатор TxHeader.DLC = 8; // количество полезных байт данных в одном сообщении TxHeader.TransmitGlobalTime = 0; // отправка счётчика времени while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) == 0); HAL_CAN_AddTxMessage(&hcan, &TxHeader, Data, &TxMailbox); } static void MX_CAN_Init(void) { CAN_FilterTypeDef sFilterConfig; // Работает, но только в loopback режиме // hcan.Instance = CAN; // hcan.Init.Prescaler = 4; // hcan.Init.Mode = CAN_MODE_LOOPBACK; // hcan.Init.SyncJumpWidth = CAN_SJW_1TQ; // hcan.Init.TimeSeg1 = CAN_BS1_13TQ; // hcan.Init.TimeSeg2 = CAN_BS2_2TQ; // hcan.Init.TimeTriggeredMode = DISABLE; // hcan.Init.AutoBusOff = ENABLE; // hcan.Init.AutoWakeUp = DISABLE; // hcan.Init.AutoRetransmission = ENABLE; // hcan.Init.ReceiveFifoLocked = DISABLE; // hcan.Init.TransmitFifoPriority = ENABLE; // копия для ээээкперимета hcan.Instance = CAN; hcan.Init.Prescaler = 4; hcan.Init.Mode = CAN_MODE_NORMAL; hcan.Init.SyncJumpWidth = CAN_SJW_1TQ; hcan.Init.TimeSeg1 = CAN_BS1_13TQ; hcan.Init.TimeSeg2 = CAN_BS2_2TQ; hcan.Init.TimeTriggeredMode = DISABLE; hcan.Init.AutoBusOff = DISABLE; // работает при DISABLE и ENABLE hcan.Init.AutoWakeUp = DISABLE; hcan.Init.AutoRetransmission = DISABLE; // повторное отправление, если не выставился ACK-бит. работает при DISABLE и ENABLE !!!Если включить режим CAN_MODE_NORMAL и ОТКЛЮЧИТЬ AutoRetransmission, то шина работает. Если включить AutoRetransmission, то шина зависает. Получается, что подтверждения от получателя! hcan.Init.ReceiveFifoLocked = DISABLE; hcan.Init.TransmitFifoPriority = ENABLE; if (HAL_CAN_Init(&hcan) != HAL_OK) { //Error_Handler(); } sFilterConfig.FilterBank = 0; sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh = 0x0000; sFilterConfig.FilterIdLow = 0x0000; sFilterConfig.FilterMaskIdHigh = 0x0000; sFilterConfig.FilterMaskIdLow = 0x0000; sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; sFilterConfig.FilterActivation = ENABLE; if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK) { //Error_Handler(); } } А вот второе устройство (приёмник). Суть: настроен так же как и передатчик но в цикл пуст, а имеет настроенное прерывание HAL_CAN_RxFifo0MsgPendingCallback, в котором при получении кадра переключает светодиод. Работает, но только в режиме CAN_MODE_SILENT. void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) == HAL_OK) { Led_Green(2); sprintf(buff,"%c%c%c%c%c%c%c%c", RxData[0],RxData[1],RxData[2],RxData[3],RxData[4],RxData[5],RxData[6],RxData[7]); for(int counter=0; counter < sizeof(buff); counter++){ USART1->DR = buff[counter]; while (!(USART1->SR & USART_SR_TC)); // ожидание завершения передачи } } } void HAL_CAN_ErrorCallback(CAN_HandleTypeDef *hcan) { } void CAN_Transmit_data (uint32_t id_message, uint8_t Data[]){ TxHeader.StdId = 0x1; // ID_EXT TxHeader.ExtId = id_message; // от 0х00 до 1FFFFFFF (0 — 536870911) TxHeader.RTR = CAN_RTR_DATA; TxHeader.IDE = CAN_ID_EXT; TxHeader.DLC = 8; TxHeader.TransmitGlobalTime = 0; while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) == 0); HAL_CAN_AddTxMessage(&hcan, &TxHeader, Data, &TxMailbox); } int main(void) { MX_CAN_Init(); TxHeader.StdId = 1; TxHeader.RTR = CAN_RTR_DATA; //CAN_RTR_REMOTE TxHeader.IDE = CAN_ID_EXT; // CAN_ID_EXT CAN_ID_STD TxHeader.DLC = 8; TxHeader.TransmitGlobalTime = 0; HAL_CAN_Start(&hcan); HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_ERROR | CAN_IT_BUSOFF | CAN_IT_LAST_ERROR_CODE); while (1) { } Прошу помощи в настройке CAN на работу в NORMAL mode и отправкой сообщений в обе стороны. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rkit 1 27 сентября, 2021 Опубликовано 27 сентября, 2021 · Жалоба В проводке всё в порядке? Особенно tx-пин на второй плате? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nickson.b.k 0 28 сентября, 2021 Опубликовано 28 сентября, 2021 · Жалоба 10 часов назад, rkit сказал: В проводке всё в порядке? Особенно tx-пин на второй плате? да, всё в порядке, так как можно первое устройство настроить как второе, а второе как первое и всё работает по той же схеме Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Edit2007 3 28 сентября, 2021 Опубликовано 28 сентября, 2021 · Жалоба 1.Тактирование МК должно быть от внешних стабильных источников (кварцевых резонаторов). У внутренних генераторов может быть раброс, из-за чего не совпадают скорости. 2. Обязательные резисторы 120 Ом (хотя бы 1 на короткой линии до 1 метра). 3.На передающем МК посмотреть, какая ошибка возникает в контроллере CAN. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться