Я сделал следующую схему. STM32 — это STM32F103C8T6 (Blue Pills). Я пропустил очевидные провода:
смоделируйте эту схему - схема, созданная с помощью CircuitLab
TJA это:
Самое важное программное обеспечение, работающее на TX STM32:
/* CAN init function */
static void MX_CAN_Init(void)
{
static CanRxMsgTypeDef CanRX;
static CanTxMsgTypeDef CanTX;
CAN_FilterConfTypeDef sFilterConfig;
hcan.Instance = CAN1;
hcan.pRxMsg = &CanRX;
hcan.pTxMsg = &CanTX;
hcan.Init.Prescaler = 8;
hcan.Init.Mode = CAN_MODE_NORMAL;
hcan.Init.SJW = CAN_SJW_1TQ;
hcan.Init.BS1 = CAN_BS1_12TQ;
hcan.Init.BS2 = CAN_BS2_5TQ;
hcan.Init.TTCM = DISABLE;
hcan.Init.ABOM = DISABLE;
hcan.Init.AWUM = DISABLE;
hcan.Init.NART = DISABLE;
hcan.Init.RFLM = DISABLE;
hcan.Init.TXFP = DISABLE;
if (HAL_CAN_Init(&hcan) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sFilterConfig.FilterNumber = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x07ff;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x07ff;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.BankNumber = 14;
if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
}
В основном:
..
hcan.pTxMsg->StdId = 0x100;
hcan.pTxMsg->ExtId = 0x01;
hcan.pTxMsg->IDE = CAN_RTR_DATA;
hcan.pTxMsg->IDE = CAN_ID_STD;
hcan.pTxMsg->DLC = 2;
while (1)
{
hcan.pTxMsg->Data[0] = 0x10;
hcan.pTxMsg->Data[1] = 0x1;
HAL_CAN_Transmit(&hcan, 10)
HAL_Delay(1000);
}
А на TX STM32 тот же код для инициализации CAN и следующий код в main:
if (HAL_CAN_Receive_IT(&hcan, CAN_FIFO0) != HAL_OK)
{
Error_Handler();
}
void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* CanHandle)
{
if ((CanHandle->pRxMsg->StdId == 0x100) &&
(CanHandle->pRxMsg->IDE == CAN_ID_STD) &&
(CanHandle->pRxMsg->DLC == 2))
{
printf("1");
}
Однако обратный вызов никогда не вызывается.
Что я вижу с помощью логического анализатора:
Я вижу X на скриншоте ниже, не уверен, что это проблема.
Что я сделал
Вопрос:
Обновлять
Я обнаружил, что есть некоторые проблемы с передачей:
в пределах
HAL_StatusTypeDef HAL_CAN_Transmit(CAN_HandleTypeDef* hcan, uint32_t Timeout)
происходит тайм-аут (последняя строка):
while(!(__HAL_CAN_TRANSMIT_STATUS(hcan, transmitmailbox)))
{
/* Check for the Timeout */
if(Timeout != HAL_MAX_DELAY)
{
if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
{
hcan->State = HAL_CAN_STATE_TIMEOUT;
/* Cancel transmission */
__HAL_CAN_CANCEL_TRANSMIT(hcan, transmitmailbox);
/* Process unlocked */
__HAL_UNLOCK(hcan);
return HAL_TIMEOUT;
}
}
}
Я не нашел, откуда эта ошибка.
Также из-за ошибки после этого ничего не отправляется.
Сейчас нет больше времени, я проверю больше завтра или во вторник вечером.
Другие проверки:
Обновлять
Время пока ограничено, но я провел тест без использования трансиверов, а напрямую с простой схемой, как описано в этом документе (спасибо Maple). Соответствующая часть:
Однако результат все еще не работает. Стороны приемника ПОЧТИ равны, но передатчик почти ничего не передает
На детали (ниже) в выбранной рампе видна небольшая разница (их больше). Поскольку они соединены вместе, я бы не ожидал этого, но, возможно, мой дешевый логический анализатор (5 $) может вызвать это.
CANH (канал 2) и CANL (канал 0) получают информацию
Если канал 2 действительно CANH с той же временной базой, что и CANL на канале 0, то это, очевидно, ваша проблема. Он совсем не выглядит здоровым, он должен выглядеть как дифференциальное зеркало CANL.
Я подозреваю, что что-то вроде замыкания CANH на другой сигнал или что-то в цепи приемопередатчика CAN работает неправильно (плохая пайка?).
Также убедитесь, что между MCU и приемопередатчиком или внутри MCU в регистрах портов нет подтягивающих резисторов. Хотя по логике вещей, если бы это было проблемой, то это также привело бы к сбою CANL.
Всегда добавляйте 2 согласующих резистора на 120 Ом, по одному на каждом конце шины, даже если вы работаете с низкой скоростью передачи данных и на коротких расстояниях. Определенная разница импеданса примерно в 60 Ом между CANH и CANL часто необходима для того, чтобы схема CAN оставалась работоспособной.
Очевидно, подключите сигнальную землю между каждым узлом в соответствии с требованиями и требованиями стандарта CAN. В противном случае вы окажетесь во власти любого потенциала земли, который есть у ваших узлов, и если на земле питания есть высокие токи заземления, это может повлиять на связь CAN, если она не использует выделенную сигнальную землю.
Среди не инженеров ходит миф о том, что вам не нужна сигнальная земля для дифференциальных сигналов, но это чепуха, если только шина CAN не имеет гальванической развязки с помощью оптопар или чего-то подобного. Дифференциальные сигналы просто гораздо более надежны, чем другие сигналы, поэтому они могут работать по счастливой случайности, даже если конструкция системы плоха и не включает сигнальную землю. Приемопередатчики CAN могут выдержать разность потенциалов примерно до 40 В, прежде чем это повлияет на связь.
Красный крестик на вашем прицеле — это не ошибка, а битовая начинка. Ваша область добавляет их туда, чтобы указать, что они не являются частью фактических данных. Как и ожидалось, у вас всегда должен быть бит заполнения после 5 последовательных старших/младших битов в кадре CAN.
Одна очевидная проблема заключается в том, что у вас нет нагрузочных резисторов на шине CAN. Помните, что они предназначены не только для завершения линии передачи, но также являются согласующими резисторами, так что шина находится в рецессивном состоянии, когда она не управляется явно.
Если это на одной плате, вам может сойти с рук установка около 60 Ом между CANL и CANH. Если шина CAN является настоящим кабелем, установите сопротивление 120 Ом между CANL и CANH на каждом конце. В этом случае кабель также должен иметь заземление, чтобы оба устройства использовали одно и то же заземление.
Я просмотрел здесь огромное количество предложений, аргументов и контраргументов и думаю, что все это оказало вам скорее медвежью услугу. В CAN нет никакой магии, и вот доказательство:
Этот ужасный беспорядок на моем столе — быстро и грязно испытательный стенд для некоторого программного обеспечения, над которым я работаю в данный момент. Он имеет два двойных контроллера двигателей с интерфейсами CAN и AVR, подключенный к CAN через контроллер MCP2515 + трансивер TJA1050 (точно такой же, как у вас!).
Контроллеры моторов подключены 3-мя проводами (включая землю), а у ресивера их только 2. У меня даже нет прямой шины - все подключено звездой к неиспользуемому (на данный момент там был другой контроллер) штекеру DB15, который я обвел На фото. Вы можете видеть один резистор на 100 Ом, соединяющий все CANL и CANH вместе. И все это прекрасно работает на скорости 500 кбит/с.
Я не утверждаю, что это правильный способ делать вещи. Я лишь к тому, что на этих дистанциях и скоростях, без помех и со стабильной мощностью все эти мелкие детали и ноу-хау просто не имеют значения.
Итак, вот что я предлагаю.
Ваши схемы в порядке. Убедитесь, что все RX, TX, CANL, CANH подключены в соответствии с ним (даже если вы знаете, что они в порядке, проверить никогда не помешает).
Оставьте эти резисторы на 120 Ом на модулях.
Вы можете соединить земли двух TJA1050 вместе, если хотите, но если ваша установка похожа на мою, это абсолютно не имеет значения, поскольку все они питаются от одного источника, а расстояние незначительно.
Подключите логический анализатор для измерения TX (к земле) на передающей стороне и RX (к земле) на принимающей стороне. Я считаю, что это было предложено по крайней мере 3 раза уже, но я никогда не видел результатов.
Запустите свои программы. Вы должны увидеть точно такой же сигнал на RX, как и на TX. Если нет, то проблема где-то в CAN соединении. Но если вы это сделаете, проблема в программном обеспечении, скорее всего, в настройке фильтра или маски.
ОБНОВЛЯТЬ
Весь смысл прямого подключения контроллеров заключался в том, чтобы исключить (насколько это возможно) физический аспект. Если провода короткие, диоды работают быстро и подтяжка правильная, на контактах RX не должно быть никакой разницы. Убедитесь, что вы подключаете подтяжку к вашему фактическому Vcc (этот документ был написан для системы 5V).
Я предлагаю проверить ваши соединения один раз и отложить вопрос о проводке в сторону. Давайте сосредоточимся на программной части. Вот как бы я поставил диагноз.
Минимизируйте свой код. Единственное, что вы должны иметь на стороне TX, это достаточно, чтобы отправлять один кадр базовых данных один раз в секунду в цикле. Я предлагаю передавать простой однобайтовый циклический порядковый номер. Единственное, что должно быть у вашей стороны RX, - это достаточно, чтобы прочитать этот байт и, возможно, распечатать его в отладке. Он не должен ничего возвращать, чтобы не загрязнить тест.
Сначала отладьте TX. Вы упомянули, что в какой-то момент получили только одно сообщение. Итак, цель №1 — убедиться, что TX отправляет эти сообщения каждую секунду. И вы должны увидеть их своим логическим анализатором на этой однопроводной шине.
Общие проблемы здесь: неправильное использование буферов передачи, неправильная обработка EOT, искаженный кадр данных (ID, контрольные биты и т. д.). Также проверьте, как ваша библиотека/контроллер обрабатывает бит ACK. Технически это не требуется, но некоторые реализации могут пытаться повторно передавать одно и то же сообщение снова и снова, пока не будет получен ACK, тем самым блокируя буферы Tx от получения новых данных.
Общие проблемы здесь: разная скорость передачи данных, неправильное использование буферов RX, неправильная обработка прерываний, неправильный фильтр или маска фильтра. Это может помочь настроить ваши фильтры так, чтобы они принимали любое сообщение в начале.
Хотя я еще не пробовал (в конце концов, CAN мне не нужен), решение состоит в том, чтобы обновить в STM32CubeMX библиотеку HAL F1 до версии 1.7 (или выше), где реализация CAN была исправлена/изменена.
Клен
Клен
Мишель Кейзерс
Клен
Клен
Мишель Кейзерс
Питер Мортенсен
Питер Мортенсен
Мишель Кейзерс
Мишель Кейзерс
Питер Мортенсен
Питер Мортенсен
Мишель Кейзерс
Лундин
Лундин
Мишель Кейзерс
Клен
Мишель Кейзерс
Лундин
Лундин
Лундин
Джероен3
Мишель Кейзерс
Лундин
Мишель Кейзерс
Клен
Мишель Кейзерс
Мишель Кейзерс
молоток_d
Мишель Кейзерс