Одним из популярных сетевых интерфейсов в промышленности является Controller Area Network. Его специально придумали в BOSCH, чтобы плодить сети из контроллеров. Особенно он прижился в автопроме, где часто по автомобилю идет одна CAN шина и все на нее повешено.
Причем сам стандарт не подразумевает физическую реализацию протокола. Она может быть по витой паре, оптике, радиоканалу. На чем угодно. Лишь бы можно было реализовать систему из рецессивного и доминантного бита. Т.е. два состояния одно из которых всегда подавляет другое.
Например, оптоволокно, в которое светят передатчики. Доминантное состояние это свет. Потому, что мы не можем включить темноту. Если будет хоть один передатчик светить, то светло будет всем. Если же брать проводную линию, то в линии с подтяжкой и схемой включения монтажное И будет доминантным состоянием низкий уровень. Т.к. если хоть кто-то подтянет линию к земле, то никто ее поднять не сможет.
Арбитраж
В CAN шине нет ни ведущих, ни ведомых. Все могут галдеть одновременно и обращаться кто к кому хочет. Чтобы не было коллизий существует механизм аппаратного арбитража. Основанный как раз на том самом доминантном и рецессивном состоянии. Т.е. когда два передатчика начинают вещать одновременно они выкатывают на шину бит и смотрят, не перебил ли его кто-то доминантным состоянием.
Например, доминантное состояние это 0.
Передатчик 1: 101101010
Передатчик 2: 10111х
Второй передатчик, на пятом бите попытался выставить на шину 1, а первый в это время выкатил 0. 0 бьёт единицу. Поэтому второй передатчик затыкается и ждет когда шина освободится.
Это приводит к тому, что не теряется пропускная способность шины. Но с другой стороны, требует вдумчивого составления пакета данных. Так, чтобы более приоритетные данные имели больше доминантных бит в начале посылки. Чтобы чаще выигрывать арбитраж.
Адресация
Данные по шине летают в виде стандартных кадров, в несколько байт. Где есть различные служебные данные и, собственно, передаваемая информация. У каждого кадра в CAN шине есть идентификатор, адрес кому этот кадр предназначен. Причем это не адрес физического устройства как такового. А просто идентификатор. Все кадры принимаются всеми. Но дальше, уже внутри принявшего устройства, кадр фильтруется по нужным идентификаторам и софт уже сам решает что обрабатывать, а что отбрасывать. Адресация может быть от 11 или 29 бит, в зависимости от формата кадра (расширенный и стандартный).
А раз так, то на шине может быть очень много разных адресов под кучу применений. Например, в контроллере можно каждому выводу GPIO присвоить свой ID и спрашивать сразу его. Без посылки дополнительных уточнений на тему кому куда.
Контроль ошибок и сбоев
CAN шина славится своей надежностью. Если данные приняты, то они, вероятней всего, корректны с огромной долей вероятности. На это работает куча механизмов.
1. При передаче идет контроль того, что на самом деле выставилось на линии. Это происходит всегда, т.к. именно таким образом работает механизм арбитража.
2. Дополняющие биты (bit stuffing): после передачи пяти одинаковых битов подряд автоматически передаётся бит противоположного значения. Таким образом кодируются все поля кадров данных или запроса, кроме служебных разграничителей кадра.
3. Контрольная сумма кадра. Передатчик вычисляет ее и добавляет в передаваемый кадр данных. А приемник на лету считает контрольную сумму и если она совпала, то он дает доминантный бит ACK в в специально заготовленное место кадра, в конце, перед финальным битом окончания кадра.
Дальнобойность
Дальность передачи зависит, в первую очередь, от реализации физического уровня интерфейса. Если это оптика, то тут могут быть огромные расстояния. А для обычной витой пары, что более распространено, все зависит от скорости передачи. Для самой быстрой, в 1 мегабит, это может быть около 50 метров. Если же скорость понижать, то на 10кбитах можно бросить и на 5км. Защита линии подобна RS485 и им подобным. Т.е. экранирование, разрядники, супрессоры.
Аппаратная реализация
Ну точнее одна из. Физика процесса может быть разной. Я видел, например, на оптике. Но это все же редкость. Обычно витая пара.
Часто встречается CAN интерфейс в разных микроконтроллерах, например в STM32F103 он входит в стандартный набор периферии. Но это только логический уровень. Тот что отвечает за работу всех этих фильтров, арбитражей, контрольных сумм. Аппаратно же нужна микросхема трансивер.
Типичные представители это:
- MCP2551. Напряжение питания 5 вольт. По входу CAN держит до +/-45 вольт. Имет выход опорного напряжения и токовый вход управления режимом работы передатчика.
- TJA1050 или A1050. Напряжение питания 5 вольт. По входу CAN держит до +40/-27 вольт. Имет выход опорного напряжения и вход перехода в тихий режим, когда трансивер только слушает линию, но никак на нее не влияет.
- SN65HVD230. Напряжение питания 3.3 вольт. По входу CAN держит +/-25 вольт. Дополнительных выводов не имеет
Имеют почти одинаковую распиновку, почти совместимую друг с другом. Разница заключается в двух свободных выводах, которые не обязательно использовать, но они имеют разную функцию у разных трансиверов. Я когда делаю устройство, то стараюсь заложить максимально возможное количество вариантов компонентов. Чтобы не попасть в ситуацию когда нужного трансивера нет, либо он стоит каких то невменяемых денег.
В качестве быстрого решения популярны трансиверы на TJA1050 которые за копейки продают на Али в виде модулей готовых. Правда у этого трансивера есть один прикол, он почему то не работает на низких скоростях. От 60kbaud и выше. От чего я выкинул парочку таких модулей, т.к. сначала заводил шину на низких скоростях, чтобы логический анализатор меньше тупил. И получил прикол, что один трансивер работает (он был MCP2551), а второй нет. Потом только в даташите, буквально случайно, увидел эту особенность.
Сеть выглядит следующим образом.
Обратите внимание на тип подключения к шине. Шлейфом. Без ответвлений. На высоких скоростях это может быть критичным. Отражения сигнала меньше. На малых скоростях можно и ответвления делать, но не желательно. Для других дифференциальных шин (вроде RS485) это тоже справедливо. На начальном и конечном устройстве должны стоять терминирующие резисторы на 120 ом.
Обратите внимание на обозначение выводов трансивера. Тут надо внимательно смотреть в устройство самого трансивера:
По нему видно, что RxD трансивера это ВЫХОД, т.е. он назван так потому, что идет на RxD контроллера. А TxD это, соответственно, вход. Идет с выхода TxD контроллера. Не перекрестите по привычке 🙂 Я так когда то с этой путаницей всаживал одно на другое, а потом дорожки приходилось резать и крест накрест сигнал посылать.
Еще важный момент. Видите, что тут, в отличии от ADM485 нет запрета работы входа при работе выхода. Т.е. все что попадает на выход дублируется эхом на вход одновременно. Собственно это нужно для арбитража.
Гальваническая развязка
Делается аналогично RS232 или RS485. Ставится какой нибудь оптопара H11L1 или что-то более удобное, двуканальное, вроде ISO7321/ADUM1201
Также есть изолированные трансиверы, вроде TJA1052i, но цена их кусается. Гораздо дешевле взять сборку на H11L1 или ADUM1201
В следующей статье разберу работу с CAN интерфейсом более детально. С описанием кадра передачи, адресации, фильтрации кадров. На примере STM32F103 и GD32F103 с его собственными библиотеками. Со сборкой полноценной сети и передачей данных по ней.
Комментарии к статье:
Чтобы оставить комментарий, прокрутите в самый конец статьи Комментировать материал
Всегда вопрос интересовал зачем на микросхемах физики CAN делают выход опорного напряжения. Негде его применения не видел в контексте CAN, в даташите вроде то же нечего особо не описано просто есть и всё.
Для средней точки разделенного терминатора. Интересный вопрос, сейчас дополню статью
Bosch 🙂
А можно связать два или несколько МК без драйвера шины? Ну то есть тупо RX и TX привязать к одному проводу, который через подтяжку на +3,3В пустить?
Мысль интересная. У Кан шины есть эхо, но его можно сделать программно настройками самого же Кана. Надо попробовать.
Спасибо за статью! Есть такой вопрос: насколько критична витая пара? Есть задача соединить от 30 нодов с условным мастером, но не хочется тащить витые пары к каждому, потмоу что нодов может быть и 200. Придумалось поставить шину типа рельсы (2 металлические пластины в изоляторе, длиной, скажем, до 3 м) и к ним прижимными контактами цеплять платы нодов. Будет ли CAN нормально работать при таком соединении?
Во первых критично. Во вторых 200 нодов без репитеров у вас тупо драйвер не вывезет. Правда Кан может работать ну на очень медленной скорости. Тогда это будет работать. На скорости в несколько сот бод и не больших расстояниях похрену на всё эти звоны.
Понял, спасибо за ответ! Скорости низкие, расстояния тоже небольшие (до 3х метров) и про репитеры тоже подумаем)