Реализация уровня протокола CAN в программном обеспечении

Задний план

Я разрабатываю проект, для которого потребуются скромные характеристики микроконтроллера:

  • 8 12-битных АЦП с частотой 10 кГц
  • 1 КБ ОЗУ
  • 48-QFN или меньше
  • Помехоустойчивый протокол связи с исправлением ошибок с последовательным подключением на скорости 20 кбит/с

Требования к обработке сигналов довольно низкие, и большинство из них можно экспортировать в главный процессор в системе. Первые три спецификации легко выполнить, и их можно сделать менее чем за 2 доллара. Однако связь будет происходить в среде с очень сильным электрическим шумом, поэтому уязвимые к помехам сети, такие как LIN и I2C, исключены. Дополнительным аргументом против LIN является то, что я бы хотел, чтобы все это работало при напряжении 5 В или 3,3 В, а приемопередатчики LIN требуют 12 В, поэтому для каждой сенсорной платы потребуется дополнительный регулятор или провод. Я изначально выбрал CAN для этой задачи. Однако контроллеры CAN значительно увеличивают стоимость, и мне любопытно, можно ли это сделать программно.

Физический уровень CAN

Спецификация CAN определяет канальный и физический уровни эталонной модели сети OSI. Для реализации физического уровня существует множество недорогих 8-контактных ИС, таких как NXP TJA1040/50 , Maxim MAX3058/59 , Microchip MCP2551 и TI SN65HVD1050 . Реализация физического уровня с цифро-аналоговыми преобразователями или операционными усилителями будет затруднена, если не невозможна, поэтому эти ИС стоят примерно 1 доллар, за который они стоят.

Канал передачи данных CAN/уровень протокола

Для уровня канала передачи данных некоторые микроконтроллеры добавляют модули протокола CAN к базовым уровням связи UART, I2C и SPI. Однако они значительно дороже базовых чипов.

Исследование стоимости модулей протокола CAN

Чтобы обосновать это утверждение, вот несколько популярных микроконтроллеров в версиях CAN и не-CAN из:

  • ATmega16 — ATMEGA16M1 (с CAN): 3,87 доллара США, ATMEGA168A (без CAN): 3,23 доллара США.
  • dsPIC — DSPIC33FJ64MC802 (с CAN): 6,14 долл. США, DSPIC33FJ64GP202 (без CAN): 5,48 долл. США
  • PIC18 - PIC18F2480 (с CAN): 6,80 долл. США, PIC18F24J10 (без CAN): 2,10 долл. США
  • Cortex-M3 — STM32F103C4T6A (с CAN): 6,50 долл. США, STM32F100C4T6B (без CAN): 2,73 долл. США

Справедливости ради, я сравнивал только микроконтроллеры с эквивалентным объемом памяти, однако многие версии без CAN доступны с меньшим объемом памяти и стоят дешевле. Внешние CAN-контроллеры, такие как Microchip MCP2515 , стоят почти 2 доллара, поэтому, если у вас есть возможность, интегрировать CAN в микроконтроллер, очевидно, более выгодно с точки зрения затрат.

Интересно, что часть ATmega на сегодняшний день является самой дешевой частью, оснащенной CAN, в ассортименте Digikey.

Функция уровня протокола CAN

Модуль CAN в микроконтроллерах dsPIC выполняет следующие функции:

Модуль шины CAN состоит из ядра протокола и буферизации/управления сообщениями. Механизм протокола CAN выполняет все функции для приема и передачи сообщений по шине CAN. Сообщения передаются путем предварительной загрузки соответствующих регистров данных. Статус и ошибки можно проверить, прочитав соответствующие регистры. Любое сообщение, обнаруженное на шине CAN, проверяется на наличие ошибок, а затем сопоставляется с фильтрами, чтобы определить, должно ли оно быть получено и сохранено в одном из регистров приема.

Это кажется вполне выполнимым в программном обеспечении.

Вопрос

Можно ли использовать программный уровень протокола для реализации спецификации CAN только с недорогим микроконтроллером с UART и приемопередатчиком CAN? Если да, существуют ли какие-либо реализации с открытым исходным кодом?

В качестве альтернативы, можно ли использовать приемопередатчики CAN с UART для реализации пользовательского протокола? Я согласен с топологией с одним мастером; Я понимаю, что арбитраж может быть трудно настроить в пользовательском протоколе.

CAN тоже 12В, так как он был разработан для использования в автомобилях.
@Kenny - уровни напряжения, используемые на вышеуказанных трансиверах, составляют 5 В.
Если вы собираетесь рассматривать серию STM32F, могу ли я предложить и эту часть NXP? Это ядро ​​Cortex-M0. search.digikey.com/scripts/DkSearch/…
@Jon - Это не обязательно рассматривалось, и M0 был бы идеальным для этого варианта использования. Однако учтите, что части Nuvoton M052LAN также являются Cortex-M0 и примерно вдвое дешевле в количестве (1,21 доллара против 2,35 доллара), но нет модуля CAN. Такая разница в цене - моя мотивация.
вы также можете рассмотреть операционный рейтинг. Большинство деталей с поддержкой CAN будут промышленными или автомобильными, а не коммерческими для вариантов без CAN.
Фантастические ресурсы: документы микрочипа an713, an754 и an228. Вот an713: ww1.microchip.com/downloads/cn/AppNotes/cn_00713a.pdf

Ответы (4)

Я думаю, что реализовать протокол CAN только в прошивке будет сложно, и потребуется некоторое время, чтобы все исправить. Это плохая идея.

Тем не менее, ваши цены высоки. Я только что проверил, и dsPIC 33FJ64GP802 в корпусе QFN продается за 3,68 доллара США на microchipdirect за 1000 штук. Цена будет ниже при реальных объемах производства.

Аппаратное периферийное устройство CAN делает для вас некоторые реальные вещи, и прирост цены на него далеко не соответствует тому, что вы заявляете.

Добавлен:

Поскольку вы, похоже, полны решимости попробовать способ прошивки, вот некоторые из очевидных проблем, которые приходят на ум. Скорее всего, будут и другие проблемы, которые еще не возникали у меня.

Вы хотите использовать CAN на скорости 20 кбит/с. Это очень низкая скорость для CAN, которая достигает 1 Мбит/с как минимум на 10 секундах метров. Чтобы дать вам одну точку данных, стандарт бортовой сигнализации NMEA 2000 накладывается на CAN со скоростью 200 кбит/с, и это предназначено для передачи от одного конца большого корабля к другому.

Вы можете подумать, что все, что вам нужно, это одно прерывание на бит, и вы можете делать все, что вам нужно, в этом прерывании. Это не сработает, потому что в каждом бите CAN происходит несколько вещей. В частности, на уровне суббитов необходимо сделать две вещи. Первый обнаруживает столкновение, а второй регулирует битрейт на лету.

На шине CAN есть два состояния сигнализации: рецессивное и доминантное. Рецессивный - это то, что происходит, когда никто не управляет автобусом. Обе линии стянуты общим сопротивлением 60 Ом. Обычная шина CAN, реализуемая обычными микросхемами, такими как MCP2551, должна иметь терминаторы по 120 Ом на обоих концах, следовательно, всего 60 Ом, пассивно стягивающих две дифференциальные линии вместе. Доминантное состояние — это когда обе линии активно расходятся, где-то около 900 мВ от рецессивного состояния, если я правильно помню. По сути, это похоже на шину с открытым коллектором, за исключением того, что она реализована с помощью дифференциальной пары. Шина находится в рецессивном состоянии, если CANH-CANL < 900 мВ, и доминантном, если CANH-CANL > 900 мВ. Доминантное состояние сигнализирует 0, а рецессивное 1.

Всякий раз, когда узел «записывает» в шину 1 (отпускает ее), он проверяет, не записывает ли какой-либо другой узел 0. текущий бит, который вы отправляете, равен 1, то это означает, что кто-то еще отправляет тоже. Коллизии имеют значение только тогда, когда два отправителя не согласны, и правило состоит в том, что отправитель рецессивного состояния отступает и прерывает свое сообщение. Узел, отправляющий доминирующее состояние, даже не знает, что это произошло. Так работает арбитраж на шине CAN.

Правила арбитража шины CAN означают, что вы должны наблюдать за шиной на полпути через каждый бит, который вы отправляете как 1, чтобы убедиться, что кто-то другой не отправляет 0. Эта проверка обычно выполняется примерно на 2/3 пути в бите. , и является основным ограничением длины CAN-шины. Чем медленнее скорость передачи, тем больше времени остается для распространения в худшем случае от одного конца шины к другому и, следовательно, тем длиннее может быть шина. Эта проверка должна выполняться для каждого бита , когда вы считаете, что владеете шиной и отправляете 1 бит.

Еще одна проблема — регулировка битрейта. Все узлы на шине должны согласовывать скорость передачи данных более точно, чем с RS-232. Чтобы предотвратить накопление небольших расхождений часов в значительные ошибки, каждый узел должен иметь возможность выполнять бит немного длиннее или короче своего номинального значения. Аппаратно это реализуется за счет запуска часов где-то в 9-20 раз быстрее, чем скорость передачи данных. Циклы этих быстрых часов называются квантами времени. Есть способы определить, что начало новых битов смещено относительно того места, где, по вашему мнению, они должны быть. Затем аппаратные реализации добавляют или пропускают один квант времени для повторной синхронизации. Есть и другие способы реализовать это, если вы можете приспособиться к небольшим различиям в фазе между вашим ожидаемым битовым временем и фактическим измеренным битовым временем.

В любом случае, эти механизмы требуют выполнения различных действий в разное время в течение бита. Такой тайминг будет очень сложным в прошивке или потребует, чтобы шина работала очень медленно. Допустим, вы реализуете систему квантов времени в прошивке со скоростью 20 кбит/с. Минимум 9 тактов времени на бит требует прерывания 180 кГц. Это, безусловно, возможно с чем-то вроде dsPIC 33F, но будет потреблять значительную часть процессора. При максимальной частоте команд 40 МГц вы получаете 222 командных цикла на одно прерывание. Выполнение всей проверки не должно занять много времени, но, вероятно, 50-100 циклов, что означает, что 25-50% процессора будет использоваться для CAN и что ему нужно будет вытеснить все остальное, что работает. Это предотвращает многие приложения, которые эти процессоры часто запускают, как поимпульсное управление импульсным источником питания или драйвером двигателя. Задержка в 50-100 циклов для каждого другого прерывания была бы полной остановкой шоу для многих вещей, которые я делал с такими чипами.

Итак, вы собираетесь потратить деньги, чтобы каким-то образом сделать CAN. Если не в выделенном аппаратном периферийном устройстве, предназначенном для этой цели, то в получении более крупного процессора для обработки значительных накладных расходов на встроенное ПО, а затем для решения непредсказуемых и возможных больших задержек прерывания для всего остального.

Затем идет передовая инженерия. Периферия CAN просто работает. Судя по вашему комментарию, дополнительная стоимость этого периферийного устройства составляет 0,56 доллара США. Мне это кажется выгодной сделкой. Если у вас нет продукта очень большого объема, вы не сможете вернуть значительное время и затраты, которые потребуются для реализации CAN только в прошивке. Если ваши объемы настолько высоки, цены, которые мы упоминали, в любом случае нереалистичны, и разница в добавлении оборудования CAN будет ниже.

Я действительно не вижу в этом смысла.

Я ценю ваше мнение, но мне любопытно, почему никто не пытался обойти трудности - у каждого проекта будут эти проблемы! Я дам вам знать, как это получается, если я в конечном итоге попытаюсь это сделать.
При количестве 1000 я нахожу цену dsPIC33FJ64GP202 от microchipdirect в 3,12 доллара США - общая разница в стоимости составляет 560 долларов! По крайней мере стоит попытаться. Я указывал цены за каждую просто потому, что было проще получить номера для отдельных штук, не беспокоясь о намотке, стандартном количестве упаковки и т. д.
@ Кевин, низкие цены не всегда пропорциональны высоким ценам. Я не знаю, сколько из этих вещей вы планируете сделать, но 560 долларов не станут платить за разработку, чтобы сделать CAN в прошивке. Я добавлю к возможному ответу объяснение некоторых трудностей, с которыми вы столкнетесь.
Я немного поиграл с этим и обнаружил, что один знак доллара в начале сообщения испортил форматирование всего, что было после него. По-видимому, где-то в программе форматирования есть неприятная ошибка. Я заменил знак доллара на «USD», и теперь форматирование соответствует назначению.
Баг с форматированием любопытен, но я хотел сказать, что решил изучить путь прошивки - не обязательно пробовать. Я ценю ваш голос опыта, говорящий мне «Нет», но хотел убедиться, что это не будет отвергнуто сразу. Вы, безусловно, предоставили достаточно причин, чтобы отклонить его без особых дополнительных экспериментов.
@Olin, просто нит, но NMEA имеет скорость 250 КБ ( en.wikipedia.org/wiki/NMEA_2000 ). А для остальных основан на автомобильном стандарте en.wikipedia.org/wiki/J1939 .
Ответ: да, можете, но здесь я полностью согласен с Олином. Я на самом деле работаю полный рабочий день в этой области. Я использую чип dsPIC33FJ256. Время, затрачиваемое на то, чтобы все записывалось по принципу «бит-бах», просто сводит на нет ценовое преимущество аппаратного обеспечения, которое делает это за вас, а вы заново изобретаете велосипед. Не говоря уже о том, что все, что вы делаете на оборудовании, должно быть тщательно спланировано. Кроме того, мне интересно, рассматриваете ли вы другие протоколы более высокого уровня, такие как ISO14229 или OSEK/Autosar NetworkManagement?
Проблема с форматированием, вероятно, LaTeX. meta.electronics.stackexchange.com/questions/434/…
@KevinVermeer Я сейчас изучаю именно это. Игнорируя информацию Олина о том, что кто-то топает в автобусе, интерпретация физического уровня нетривиальна. Как только производители микросхем справятся с этим, будет очень легко предоставить другие бонусные чипы, такие как предложение mcp2551.

Мы используем PIC18F25K80 . Хотя у него нет DSP, его количество составляет ~ 2 доллара. Это почти прямая замена упомянутому вами PIC18F2480. Мы используем компилятор CCS и их программный стек для CAN, который, вероятно, портирован с Microchip. Он хорошо работает для всего, что мне нужно и пробовал.

ECAN не искал. Глупое название Microchip, но в следующий раз мне придется читать внимательнее! Как я уже сказал, мои потребности в обработке сигналов невелики, поэтому я не думаю, что мне нужен настоящий DSP.

Если я правильно понял, похоже, вы хотите использовать функциональность CAN, используя только UART и какую-то умную прошивку. Поверьте, это никогда не сработает — предлагаю прочитать хороший текст о тонкостях CAN или CANopen. Вы уничтожите любую экономию средств, которую вы ищете, пойдя по этому пути.

Я бы либо использовал микроконтроллер с модулем CAN и передал дополнительные 2 доллара, либо вы подумали о другом протоколе, совместимом с UART, таком как Modbus через RS-485 ?

Вы правильно читаете. Я внимательно прочитал учебный буклет Vector по CAN. Похоже, каждое сообщение нуждается в некоторой предварительной обработке для CRC, но остальная часть пакета должна быть такой же, и мне просто нужно будет продолжать проверять линию приема на предмет конфликта. На самом деле это не так сложно, как кажется, но я обязательно приму ваш совет во внимание.
Однако мне нравится идея Modbus через RS485. Похоже, что большинство этих приемопередатчиков также питаются от 5 В; У меня сложилось впечатление, что для этого требуется +/- входное напряжение, такое как RS232. Придется изучить это.
бит стук наверняка сработает! Это не тривиально, как упоминает Олин выше, но это можно сделать. Я лично добился этого как на серии PIC18F, так и на микроконтроллере серии dsPIC33. Я могу загрузить исходный код PIC18F, если вы действительно хотите его увидеть. Однако я не могу предоставить исходный код dsPIC, поскольку он является частью коммерческого проекта, над которым я работаю. В обоих случаях мы используем MCP2551, и у меня также есть LIN-код. LIN немного проще на уровне протокола, но реализация расписаний LIN немного сложнее...
@EricM - Какова была скорость передачи данных и удалось ли вам реализовать полную спецификацию CAN в программном обеспечении? Я хотел бы увидеть код PIC18F для этого.
Да, реализована полная спецификация CAN, чтобы не дублировать модуль ECAN на dsPIC, который заботится о многих аспектах. В реализации PIC18 я переделал шину до полной спецификации и позже, и этот код будет работать на dsPIC, использующем линии GPIO. Я обновлю через несколько дней со ссылкой на код.
Чип может идти в ногу с 1Mb. Я сделал много уродливых вещей, чтобы соблюсти арбитражные правила... и в основном, чтобы узнать о CAN, но не рекомендовал бы это ни для чего коммерческого. Работайте с оборудованием! MCP2551 и MCP2515 - отличные чипы...

Я также думаю о битрейте CAN-Protocol на PIC µC, так что, пожалуйста, EricM, если вы действительно это сделали, пожалуйста, ответьте и скажите хотя бы, какой битрейт на какой частоте ядра PIC18F или DSPic у вас есть. Спасибо!

В целом: RS 485 был бы решением основной проблемы, но также можно было бы использовать CAN-(или даже FlexRay)-трансиверы с неполнодуплексной связью UART (точка 2), поскольку все эти протоколы использовать NRZ-кодирование.

Но в UART/V24/RS232 полный дуплекс в основном используется, не задумываясь о деталях, поэтому, возможно, вам нужно будет немного подумать над суперпетлей или конечным автоматом вашего приложения...

Но вернемся к CAN-bitbanging: я много лет работаю с CAN и никогда не видел реализации bitbanging, но, насколько я могу думать, это должно работать для битовых таймингов до 100 кбит с современными микрочипами, такими как DSPic или ARM и т. д. (с ядрами на частоте 80 МГц или выше...)

По крайней мере, если рассматривать только обратное чтение ... Отправка будет означать некоторые накладные расходы при подготовке битовых структур, чтобы не была доступна 100% загрузка шины, но в CAN более 65% вообще редко ...

Добро пожаловать на StackExchange по электротехнике. Первая часть вашего ответа на самом деле не является ответом, поэтому вы задаете новый вопрос, если хотите. ОП специально задал вопрос о программной реализации протокола CAN, и ваш ответ, похоже, блуждает без ответа на этот вопрос; пожалуйста, старайтесь оставаться в теме вопроса.