Пролог
CAN — это двухпроводный, дифференциальный, последовательный, полудуплексный интерфейс для передачи бинарных данных между электронными платами (PCB). В качестве кабеля чаще всего применяют одну экранированную витую пару проводов с именами: CAN_L и CAN_H. Образно выражаясь CAN — это труба для чисел.
CAN определяет аж два уровня модели OSI-7 (стек сетевых протоколов): физический и канальный. То есть CAN определяет также и бинарную структуру пакета в кабеле. В пакете CAN фигурируют такие переменные, как ID пакета, 8 байт данных, длина пакета, 15 битная контрольная сумма, биты подтверждения ACK, начало и конец пакета.
Где применяется интерфейс CAN?
В каждом автомобильном микроконтроллере есть CAN шина. CAN - это нервная система автомобиля. Именно по САN передаются сигналы от датчиков и команды к исполнительным механизмам агрегатов. Еще CAN используется в поездах, пожарных сигнализациях, лифтах, и даже космических орбитальных спутниках.
Теоретический минимум

CAN bus‑Off — это состояние CAN трансивера. Передатчик переходит в состояние BusOff, если счетчик неудачных передач TEC превысил значение 255. Находясь в состоянии BusOff, трансивер просто физически отключается от CAN шины. Он обязательно прекращает передачу и подтверждение CAN пакетов. Будет ли он продолжать получать кадры, зависит от реализации конкретного CAN трансивера и его настроек.
CAN‑матрица — это схема организации данных в сети CAN, определяющая, какие данные передаются между какими устройствами, и как эти данные интерпретируются. CAN‑матрица обычно представляет собой таблицу, в которой указаны идентификаторы сообщений, данные, которые они содержат, и устройства, которые их отправляют и получают. Она позволяет разработчикам настраивать и управлять обменом данными в сети CAN.
Погрешность — разность между измеренным (установленным) значением величины, и подлинным значением величины. При конфигурации CAN нужно минимизировать погрешность между желаемой и установившейся длительностью 1 бита передаваемых данных.
Физический уровень
Физика CAN очень проста. Есть два скрученных провода с именами CAN_H и CAN_L. Скрутка позволяет преодолевать электромагнитные помехи. Классический CAN позволяет подключить до 127 устройств. По концам шины нужны терминирующие резисторы. В режиме IDLE пины подтянуты одновременно и к земле и к питанию. Поэтому там как правило 2.5V

Стрелка осциллографа показывает вот твой CAN сигнал.

Шина CAN на минимальной битовой скорости 10 кбит/с может достигать аж пяти километров. На максимальной битовой скорости 1 Мбит/с - 40 метров. На одну шину можно пристегнуть максимум 127 абонентов.
Канальный уровень
Биты образуют массив, который формирует пакет CAN. Пакет содержит идентификаторы данные и служебные биты (подтверждение, длина поля данных). CAN пакет передает массив с цифрами (пакет). В пакете самое важное это 8 байт (64 бит) полезных данных. Это называют сообщением. Внутри сообщения есть параметры (они же сигналы). У каждого параметра есть номер. Параметры могут быть как вдавлены друг в друга, так и размазаны по битам поля данных. Максимум в одном сообщении может быть 64 параметра (сигнала) (по одному биту на параметр в предельном случае). В идеологии CAN классического запрос-ответ нет, как, например, в modbus. Обычно ноды просто непрерывно флудят в шину и тот, кому надо выхватывает то, что ему надо. Но это зависит от протокола прикладного уровня.
Главное преимущество интерфейса CAN - это разрешение коллизий налету, то есть без потери битовой скорости. Если два узла начнут передавать пакет, то продолжит передачу то устройство у которого меньше ID. Таким образом, ID определяет приоритет ноды во всей сети.
Бинарная структура пакета CAN Classic пакета
Пакет - это по сути массив битов.

Бинарную структуру CAN пакета можно изучить тут

Пояснения битовых полей представлены в этой таблице.
№ | Битовое поле | Расшифровка | bits | Пояснение |
1 | SOF | Start of Frame | 1 | сообщающий о начале фрейма и позволяющий синхронизировать узлы после фазы ожидания; |
2 | ID | Identifier | 11 | Может иметь 11- или 29-битный размер. Устройство с меньшим ID выигрывает арбитраж. Соответственно, чем меньше ID, тем выше приоритет у устройства; |
3 | RTR | Remote Transmission Request | 1 | Если устройство передает данные, то бит RTR принимает рецессивное состояние. Если устройство запрашивает сообщение от другого узла – бит RTR принимает доминантное состояние; |
4 | IDE | бит-указатель на расширенный ID | 1 | Если IDE принимает доминантное состояние – это значит, что используется стандартный 11-битный идентификатор. Если IDE принимает рецессивное состояние, то принимающий контроллер должен быть готов к приему оставшейся части расширенного 29-битного идентификатора; |
5 | r0 | 1 | резервный бит | |
6 | DLC | Data Length Code | 4 | 4-битное поле длины данных , которое кодирует, сколько байтов данных будет передано в сообщении. В классическом CAN DLC может принимать значение в диапазоне 0…8. |
7 | DATA | DATA | 64 | В классическом CAN фрейм может содержать 0…8 байтов данных |
8 | CRC | CRC | 15 | 15-битный контрольный CRC-код для переданных данных |
9 | CRC D | Delimiter | 1 | бит-ограничитель для поля CRC |
10 | ACK | 1 | бит подтверждения сообщения. В исходном фрейме передатчик использует рецессивное состояние этого бита. В свою очередь приемники при отсутствии ошибок должны установить в этом бите доминантное состояние. Другими словами, если на шине есть хотя бы один активный приемник, то в этом бите будет установлено доминантное состояние; | |
11 | ACK D | 1 | бит-ограничитель (Delimiter) для ACK | |
12 | EOF | End-of-Frame | 7 | 7-битное поле окончания фрейма |
13 | IFS | Interframe Space | any | меж фреймовый интервал, необходимый для того, чтобы приемник успел поместить сообщение в буфер. |
Если трансивер передатчика не увидит бит подтверждения ACK, то передатчик (CAN MAC) будет снова и снова непрерывно передавать этот же CAN пакет, до тех пор пока его кто-нибудь не примет или случится bus-off. Таким образом, шина будет занята на 100 %. Однако некоторые микроконтроллеры всё же позволяют настроить MAC на одиночную отправку.
А это структура пакета с расширенным идентификатором (29 бит). Это позволяет адресовать больше узлов.

Еще бывает так делают, что берут Ext ID в 29 бит, адреса узлов ставят, условно, 24 бита. А самые младшие 5 выделяют под приоритет сообщения. В результате каждый ID имеет свои отдельные уровни приоритетов (32 уровня).
Биты расширенного адреса | Размер битового поля | Назначение битового поля |
28-5 | 24 | Адрес узла |
4-0 | 5 | Приоритет сообщения |
Транспортный уровень Для классического CAN, чтобы передавать пакеты превышающие 8 байт нужен транспортный протокол. Обычно таким транспортом является протокол ISO-TP. Он же ISO 15765-2.
Уровень приложения В сетях на основе CAN на уровне приложения обычно гоняют следующие прикладные протоколы: CCP, XCP, CanOpen, UDS или J1939.
Как CAN борется с помехами и ошибками?
Протокол CAN определяет по меньшей мере пять различных способов обнаружения ошибок. Два из них работают на уровне битов, а остальные три — на уровне сообщений.
№ | Способ обнаружения ошибок | Уровень работы механизма защиты |
1 | Bit Monitoring. | бит |
2 | Bit Stuffing | бит |
3 | Frame Check | пакет |
4 | Acknowledgement Check | пакет |
5 | Cyclic Redundancy Check | пакет |
Bit Monitoring (Наблюдение за битами)
Каждый передатчик на шине CAN считывает уровень передаваемого сигнала. Если фактически считанный уровень бита отличается от переданного, выдается сигнал об ошибке бита. В процессе арбитража ошибка бита не возникает.
Bit Stuffing (Положительное выравнивание)
Когда узел передал пять последовательных битов одного уровня, он добавит шестой
бит противоположного уровня к исходящему потоку битов. Приемники удалят этот дополнительный бит. Это делается для того, чтобы избежать избыточных компонентов постоянного тока на шине, но также дает приемникам дополнительную возможность обнаруживать ошибки: если на шине встречается более пяти последовательных битов одного уровня, подается сигнал об ошибке заполнения.
Frame check (Проверка пакета)
Некоторые части сообщения CAN имеют фиксированный формат, т. е. стандарт точно определяет, какие уровни должны происходить и когда. (Этими частями являются разделитель CRC, разделитель ACK, конец кадра). Если контроллер CAN
обнаруживает недопустимое значение в одном из этих фиксированных полей, выдается сигнал об ошибке структуры пакета.
Acknowledgement Check (Проверка подтверждения)
Все узлы на шине, которые правильно получают сообщение (независимо от того, «интересуются» ли они его содержимым или нет), должны выполнить подтверждение, то есть отправить доминирующий уровень в так называемом слоте подтверждения в сообщении. Передатчик передаст здесь рецессивный уровень. Если передатчик не обнаружит доминирующий уровень в слоте ACK, выдается сообщение об ошибке подтверждения. Как правило начинается повторная отправка. После 255 повторных попыток отправки CAN трансивер электрически отключается от витой пары и генерирует прерывание CAN bus-off.
Трансиверы CAN-шины не имеют возможности выборочно подтверждать пакеты, как в шине I2C, например. Любой корректно сформированный пакет аппаратно подтверждается всеми, кто его слышит.
Если на шине несколько исправных устройств, очень сложно получить ситуацию, когда не слышит никто, и подтверждения нет.
Cyclic Redundancy Check (Циклический избыточный код)
Каждое сообщение содержит циклическую контрольную сумму (CRC), и любой узел, который обнаруживает в сообщении CRC, отличную от той, которую он рассчитал сам, сообщит об ошибке CRC.
А теперь внимание, все эти механизмы работают полностью аппаратно на уровне ASIC или MAC! То есть всё это происходит незаметно для программиста микроконтроллера с CAN. Вот так. Вам уже нравится CAN?
Схемотехника CAN интерфейса
Обычно физика CAN трансивера представлена микросхемой TJA10xx. Это дифференциальная пара проводов. На конце каждого CAN узла заложен резистор 120 Ом. Он нужен чтобы не было переотражений в длинных линиях проводов.

Если MCU не поддерживает CAN (например K1948BK018), то можно пристегнуть ASIC-трансиверы переходники с SPI на CAN. Например TJA1145T/FD, MCP2515, TCAN4550RGYRQ1 или TCAN4550-Q.
Если уж и этого нет, то ничего не мешает написать код (FSM), который по массиву семплов от CAN-RX в post обработке распознает CAN пакет. Семплы можно читать либо GPIO либо ADC. Через ADC(GPIO)+DMA записали c линии CAN_RX 0101010110000111 (однобитные семплы) за последние 1ms и положили в FIFO. Только надо много RAM памяти, чтобы семплы эти где-то хранить. Далее ЦОС обработка. Обсчитываем и извлекаем структуру пакета через конечные автоматы. Условно записали через ADC+DMA 2....5 ms c линии CAN_RX и 10ms...100ms их обсчитываем. Просто это будет работать не в real time. Плюс надо какое-нибудь фиктивное устройство, которое будет ACK ставить, так как это надо делать в real time. Без этого на стой стороне начнется flude. С отправкой всё много проще.
Сформировали массив семплов и одним залпом отправили его по GPIO(DAC) через DMA в CAN_TX. Но при этом придется пожертвовать арбитражем.
Программная часть
Алгоритм включения CAN
Что же надо сделать чтобы в микроконтроллере заработал CAN трансивер?
№ | Действие в коде |
1 | Настроить GPIO на CAN. Надо переключиться на альтернативную функцию. |
2 | Подать тактирование на CAN MAC внутри микроконтроллера |
3 | Активировать маскированные прерывания глобально. |
4 | Активировать номера прерываний, которые соответствуют нужному экземпляру CAN трансивера. |
5 | Настроить битовую скорость шины. |
6 | Написать обработчик CAN прерываний |
7 | Определить call back функции для CAN |
8 | Определить message buffer для CAN (фильтры приема ID) |
9 | Определить параметры NVRAM для CAN. |
Настроить битовую скорость шины.
Это самый ответственный этап. CAN трансиверы каждый бит делят на четыре части (сегмента). Сегмент синхронизации, всегда имеет длину в один квант, используется для синхронизации тактов. Ожидается, что здесь будет иметь место фронт бита, когда данные изменяются на шине. Сегмент распространения необходим для компенсации задержки в линиях шины. Фазовые сегменты могут быть укорочены (фазовый сегмент 1) или удлинены (фазовый сегмент 2), если необходимо поддерживать синхронизацию тактов.

Чтобы уменьшить погрешность установки периода бита надо уменьшать продолжительность временного кванта (т.е. Tq). Образно, увеличивать гранулярность. Для этого надо увеличивать значение пред делителя в регистрах CAN MAC-а.

Второй момент. Как выбрать натуральные числа для sync, prop, seg1,seg2? С математической точки зрения, сумму N четырьмя натуральными числами можно составить C(N - 1, 3) = (N - 1)(N - 2)(N - 3) / 6 способами, где C(n, k) = n! / k!(n-k)!
Сумма | Количество способов составить сумму 4мя слагаемыми. |
4 | 1 |
5 | 4 |
6 | 10 |
7 | 20 |
8 | 35 |
9 | 56 |
10 | 84 |
11 | 120 |
12 | 165 |
13 | 220 |
Уровни шины выбираются на границе между фазовым сегментом 1 и фазовым сегментом 2. Поэтому при настройке битовой скорости любого CAN драйвера вам надо будет из одного числа (желаемая битовая скорость), так или иначе вычислить 4 числа (sync, prop, seg1, seg2), которые непосредственно влияют на результирующую битовую скорость. Выбор этих четырех чисел - самое неясное при работе c CAN. Драйверы от вендоров судя по коду делают какие-то сложнейшие математический вычисления, чтобы сформировать этот пресловутый массив sync, prop, seg1, seg2.
Большинство CAN-трансиверов также предоставляют возможность делать ADC выборку три раза в течение 1го бита. В этом случае выборка происходит на границах двух квантов, которые предшествуют точке выборки. Финальное значение бита определяется электрическим голосованием внутри цифровых логических цепей CAN-трансивера. Называется это мажорирование сигналов.
Определить параметры NVRAM для CAN.
Битовую скорость CAN трансивера лучше хранить в NVRAM. По опыту могу сказать, что вы никогда заранее узнаете к какой шине и где будет подключаться очередное устройство в будущем. С NVRAM вы хоть сможете открыть UART-CLI и легко переконфигурировать трансивер без повторной сборки всей прошивки.
Обзор профессиональных средств аппаратной отладки для CAN-classic
Для пусконаладки CAN на незнакомом микроконтроллере вам, как ни крути, потребуется какой-то эталонный CAN-трансивер. Существует серия устройств-переходников для подключения CAN устройств через USB к компьютерам и LapTop-ам. Вот перечень широко распространенных вариантов для USB-CAN переходников .
№ | Переходник | Software |
1 | SYS TEC USB-CANmodul1 | CANinterpreter Lite for USB-CANmodul |
2 | USBCAN-II C | ECAN Tools |
3 | canfox | CANexplorer 4 |
4 | CH-P | CARBUS Analyzer |
5 | CANable 2.0 | Cangaroo |
6 | CAN-bus-USBnp | CANwise |
7 | Peak CAN | PCAN-View |
8 | VSCOM USB-CAN Plus ISO | ? |
К слову, многие организации даже делают свои custom версии переходников с USB на CAN. Еще вам на первых порах скорее всего потребуется логический анализатор и осциллограф.
№ | Название | Версия | Назначение |
1 | DS View | v1.3.2 | Клиентская программа для логического анализатора DS Logic |
В отладке CAN главное сразу настроить нужную битовую скорость. Это можно сделать осциллографом. Далее если подключиться электродом к MCU пину CAN_RX, то структуру самого CAN пакета можно увидеть логическим анализатором DS-logic.

Затем пристегиваем переходники с USB-CAN и смотрим таблицу отправленных и принятых пакетов. Можно проанализировать сеанс связи. PCAN-View это образно локатор для CAN пакетов.

Когда у вас накопится очень много самодостаточных CAN пакетов, вы можете их организовать в базу данных. Для этого есть утилита CANdb++ Editor.

Это специальная база данных только заточена она для хранения CAN пакетов. Там есть поиск, сортировка конкретных переменных (сигналов), который покажет какие физические величины передаются в CAN и по каким ID сообщениям. Всё хранится в одном текстовом .dbc файле. Из которого, к слову, можно даже генерировать Си-код для синтактического разбора пакетов.
Итог
Удалось получить некоторое начальное представление о том, что такое CAN-интерфейс и с какой стороны следует подходить к CAN шине.
Семейство интерфейсов CAN это далеко не единственный и, к слову, не самый дешевый выбор для разворачивания сетей типа общая шина. Есть ещё RS485, LIN, 1-Wire, DALI, MIL-STD-1553, ARINC 429 и прочие. Сравнение интерфейсов можно произвести вот в этом реестре

Акронимы
Акроним | Расшифровка |
CAN | Controller Area Network |
MB | message buffers (Mail Box) |
ASIC | Application-specific integrated circuit |
PC | personal computer |
USB | Universal Serial Bus |
MAC | medium access control |
CRC | Cyclic redundancy check |
CHI | Controller Host Interface |
PHY | physical layer |
FIFO | first in, first out |
Ссылки
Название | URL |
ЛикБез по CAN-FD | |
CANdb++ Editor | |
Протокол CAN | |
Обзор Переходника USB-CAN (SYS TEC USB-CANmodul1) | |
Обзор USB-CAN переходника USBCAN-II C | |
Обзор Протокола ISO-TP [ISO 15765-2] | |
Атрибуты Хорошего Канального Протокола Передачи Данных | |
CAN sniffer @KruFFT | |
CAN шина @Dorodnikov_viktor | |
Использование сети CAN и стека CANopen @GreyM |
Вопросы
Что такое CAN bus-off?
Зачем в CAN нужен remote кадр? В протоколе CAN Remote-кадр служит для запроса данных у другого узла, позволяя одному узлу инициировать передачу данных, запрашивая у другого узла отправить информацию определённого идентификатора. Это позволяло более эффективно управлять трафиком, уменьшая необходимость в постоянной передаче всего набора данных.
Как определить сколько time quantum (Tq) следует выделить предделителем для одного CAN бита? 10? 20? 40? Проще говоря, какое разрешение нужно для одного CAN бита? Это можно как-то математически обосновать и рассчитать? На сколько квантов разбить один CAN бит?
Допустим мы как-то решили разбить один CAN бит на N квантов. Пусть N=24. Как теперь распределить кванты на интервалы CAN бита: sync, prop, seg1 и seg2?
Как в CAN можно повысить (или понизить) приоритет конкретного ID сообщения?
Что такое CAN-матрица?
Как измерить процент загрузки CAN шины трафиком в реальном времени?