Микроконтроллер в схеме шины can

На основе примера basic-can-project от Atmel (проект для IAR EWB) описывается, как CAN-интерфейс добавить в свою программу для микроконтроллера AT91SAM7X256 (или AT91SAM7X128, AT91SAM7X512). К сожалению, Atmel максимально постаралась запутать алгоритм примера. В статье сделан акцент на практику — как с минимальными усилиями добиться рабочего результата.

Сокращение CAN означает «Controller Area Network». Эта шина широко применяется в промышленности, особенно в автомобилестроении. Перед тем, как начать использовать шину CAN, нужно хотя бы бегло ознакомиться с её возможностями, см. Ссылки [1]. Сильно вчитываться не стоит, так как можно сломать голову в премудростях протокола. Для начала нужно определиться с параметрами подключения:

— скорость передачи — в этом примере используется 125 кбит/сек.
— адресация на шине — нужно задать адреса устройств, которые будут присутствовать на шине, и режим адресации (стандартный или расширенный). В статье в качестве примера будут использоваться только два устройства, на одном конце адрес 0x000 (ARM), на другом 0x077 (программа на компьютере с адаптером USB-CAN) в стандартном режиме адресации.

Теперь несколько слов о протоколе CAN и о том, как он представлен в AT91SAM7X256.

1. На том уровне протокола CAN, который удобно использовать (этот уровень используется в нашем рассматриваемом примере), передача ведется порциями по 8 байт, без запроса о подтверждении, как в протоколе UDP, т. е. отправили — и забыли. Однако на приемном конце имеется полный набор диагностики о прохождении пакета, т. е. если он пришел, то можно не заботиться о его целостности (нет необходимости заморачиваться контрольными суммами — это уже имеется в протоколе CAN).

2. В AT91SAM7X256 имеется только один интерфейс CAN. Скорость, на которую его можно настроить, выбирается из стандартного ряда скоростей 1000, 800, 500, 250, 125, 100, 50, 25, 20, 10 кбод, или кбит/сек. Внимание: атмеловский пример инициализации интерфейса CAN (процедура can.c\CAN_Init) якобы может настраивать скорости 1000, 800, 500, 250, 125, 50, 25, 10 кбод, однако 800 и 10 кбод настраиваются некорректно, а скорости 100 и 25 кбод мне проверить не удалось, так как на другом конце аппаратура их не поддерживала (это была программа PcanView и адаптер USB-CAN компании SYS TEC electronic GmbH, см. Ссылки [2]). Поэтому остаются скорости 1000, 500, 250, 125, 50 (я выбрал 125) кбод.

3. Порции данных, которые передаются по шине CAN — 8-байтные посылки — передаются на основе абстракции — так называемых почтовых ящиков (mailbox). С непривычки это может снести крышу, но как утверждают разработчики протокола (и те счастливчики, которые хоть немного разобрались в протоколе CAN) — это очень удобная фича. В микроконтроллере AT91SAM7X256 всего 8 почтовых ящиков (далее просто mailbox). Все mailbox имеют одинаковую скорость, но каждый mailbox индивидуально настраивается на прием или на передачу, и каждый mailbox может иметь свой собственный адрес на шине — так называемый CAN ID. Mailbox имеют аппаратный механизм, позволяющий прозрачно для процессора (т. е. программно не загружая его) фильтровать приходящие сообщения по CAN ID, и ненужные сообщения отбрасывать (подробнее далее).

Mailbox-ы удобно рассматривать как 8 независимых каналов передачи данных, и с помощью их настройки можно регулировать пропускающую способность шины CAN в прямом и обратном направлении. Например, если нам нужно передавать больше данных, чем принимать, то мы можем настроить, как вариант, 2 mailbox на прием, а 6 на передачу. В примере basic-can-project от Atmel все mailbox настроены изначально на прием, а при необходимости передачи нужный mailbox перенастраивается на передачу. Я такое поведение у себя в программе поменял — настроил постоянно 2 ящика на прием, и 6 на передачу, хотя реально и на прием и на передачу в программе используется только по одному ящику (один на прием, и один на передачу).

4. Интерфейс CAN AT91SAM7X256 имеет гибкую систему прерываний. В примере basic-can-project от Atmel прерывания используются на обработку ошибок и на прием и передачу сообщений, хотя реально ничего в обработчике при приеме и передаче не делается, выводятся только диагностические сообщения (передача и прием реальных данных происходят методом поллинга в основном цикле main).

5. Адресация почтовых ящиков может происходить в стандартном режиме, тогда адрес 11-битный (0x000..0x7FF), или в расширенном режиме, тогда к адресу добавляется еще 18 бит, и адрес становится 29-битным (0x00000000..0x1FFFFFFF). Какой режим адресации активен (стандартный или расширенный) — зависит от 29-го бита MIDE (AT91C_CAN_MIDE), который находится в регистре CAN_MIDx (x равен номеру почтового ящика) почтового ящика. Если бит MIDE равен 0 — стандартный режим, 1 — расширенный. В том же регистре находится адрес CAN ID — биты 28..18 для стандартного режима (11-битное поле MIDvA) и биты 17..0 расширенного режима (добавочное 18-битное поле MIDvB). Биты 31 и 30 в регистре CAN_MIDx не используются.

Видео:лекция 403 CAN шина- введениеСкачать

лекция 403  CAN шина- введение

Читайте также: Размер шин для картинга

Микроконтроллер в схеме шины can

В примере basic-can-project от Atmel бит MIDE используется, но непонятно как. Я у себя принудительно включил стандартный режим.

6. Есть возможность задать для mailbox не один адрес, а группу адресов. Это делается с помощью битовой маски в регистре CAN_MAMx. Структура регистра CAN_MAMx точно такая же, как и у CAN_MIDx — имеются те же самые поля MIDE, MIDvA, MIDvB. Если MIDE==0, то используется маска MIDvA, а если MIDE==1, то используется маска MIDvAMIDvB. Маска работает следующим образом — в тех битах, где в маске нули, биты адреса могут меняться, и адрес все равно остается валидным. Например, если маска MIDvA равна 11111111100 (стандартный режим), то допустимыми для приема сообщения будут 4 адреса:

11111111100
11111111101
11111111110
11111111111

Процедура приема сообщения следующая — из принятого фрейма берется поле адреса, и на него накладывается по & маска, получается результат A. На адрес MID также накладывается та же самая маска, получается результат B. Если A==B, то сообщение считается принятым, и результат B копируется в адрес MID, а если A не равно B, то сообщение отбрасывается (это делается аппаратно, без участия процессора). Поэтому в процессе приема адрес в регистре MID может измениться (биты адреса ящика, соответствующие нулевым битам в адресе, могут сброситься). Например, если нужно настроить почтовый ящик на прием ВСЕХ сообщений (сообщений с любым адресом), то маску в регистре CAN_MAMx нужно сбросить в 0, и при этом нет никакого смысла задавать какой-либо адрес в регистре CAN_MIDx, так как он не будет в процессе приема оказывать никакого влияния, и все равно сбросится в 0 при приеме первого же фрейма.

У каждого mailbox имеется также регистр CAN_MFIDx — family ID register. В даташите написано, что он содержит «объединение замаскированных бит адреса CAN_MIDx, и предназначен для облегчения декодирования адреса.». На самом деле смысл его состоит в том, что в нем находится порядковый номер адреса сообщения в пределах семейства, ограниченного маской. Например, в маске два нулевых бита в любом месте маски, т. е. маска соответствует 4 возможным адресам. Тогда при успешном приеме сообщения (адрес совпал с маской) в регистре CAN_MFIDx будут числа от 0 до 3, т. е. порядковый номер адреса в группе. Этот номер можно использовать в качестве индекса в массиве адресов обработчиков сообщений в почтовых ящиков, чем облегчается декодирование адреса полученного сообщения.

В примере basic-can-project от Atmel маска настраивается просто от балды. Я у себя задал маску таким образом, чтобы прием сообщения срабатывал только на один адрес.

7. Пример от Atmel basic-can-project работает примерно следующим образом. Передаются и принимаются данные в основной программе (main), с помощью вызовов CAN_Write и CAN_Read соответственно. Физическая работа с регистрами CAN при приеме и передаче ведется через обработчик CAN_Handler. И прием, и передача через CAN осуществляется через структуру CanTransfer. Переменная CanTransfer одна-единственная, так как пример basic-can-project очень упрощенный — экземпляр переменной CanTransfer работает и на прием, и на передачу. В результате после передачи нужно ждать освобождения CanTransfer, и после возвращать CanTransfer в режим приема и снова вызвать CAN_InitMailboxRegisters. Общее впечатление от примера — мусорный код, который делался впопыхах или, может быть, был выдернут из какого-то проекта. Пример я переделал под себя — в обработчике прерывания принимаемые данные пишутся в кольцевой буфер, которые впоследствии могут быть обработаны в основной программе. В результате процедура CAN_Read оказалась не нужна. Передачу я сделал из основной программы, и переменная CanTransfer у меня работает только на передачу. Структура переменной CanTransfer:

Поле canstate для оригинального примера basic-can-project очень важное, оно определяет режим работы ВСЕГО интерфейса CAN по отношению к программе, работающей в ARM. Сюда пишутся константы CAN_IDLE, CAN_SENDING, CAN_RECEIVING. Т. е. в любой момент времени программа ARM может либо воспользоваться CAN на чтение или запись, либо ждать завершения текущей операции. Алгоритм работы зависит от того, какая операция выполняется (CAN_Write или CAN_Read). Освобождает интерфейс CAN путем записи в canstate значения CAN_IDLE обработчик прерывания CAN_Handler. У меня это поле потеряло актуальность, так как переменная с типом CanTransfer у меня используется только на передачу, и canstate используется только для того, чтобы определить — закончена ли передача.

Например, как работает CAN_Write: если текущая операция чтение (canstate==CAN_RECEIVING), то прерываем её, освобождая CAN (canstate=CAN_IDLE), еще раз проверяем состояние canstate, и если он ==CAN_IDLE, переводим его в состояние передачи (canstate=CAN_SENDING) и запускаем передачу из выбранного почтового ящика (путем записи флага почтового ящика в регистры CAN_TCR и CAN_IER). Внимание! Перед вызовом CAN_Write должны быть проинициализированы все поля CanTransfer, и сделан вызов CAN_InitMailboxRegisters(&canTransfer).

Видео:MCP2515, контроллер CAN шины с интерфейсом SPIСкачать

MCP2515, контроллер CAN шины с интерфейсом SPI

Читайте также: Сколько качать шины ваз 2112

Как работает CAN_Read: если CAN занят (canstate!=CAN_IDLE), то ничего не делаем, выходим. Иначе переводим CAN на операцию чтения (canstate=CAN_RECEIVING), и запускаем прием почтового ящика (путем записи флага почтового ящика в регистр CAN_IER). Таким образом, для приема данных CAN_Read взводит режим в CAN_RECEIVING, и ждет, пока флаг не станет CAN_IDLE.

Как работает CAN_Handler: в режиме приема (определяется по полю MOT регистра CAN_MMRx почтового ящика x) данные выгружаются в структуру CanTransfer, CAN для программы освобождается (canstate=CAN_IDLE), разрешается для ящика прием следующего сообщения. В режиме передачи не делается ничего, просто CAN для программы освобождается (canstate=CAN_IDLE).

Брать пример basic-can-project «как есть» нецелесообразно, нужно выкинуть оттуда мутную логику, и взять только то, что надо. Лучше всего прием делать по одной группе почтовых ящиков, а передачу — по другой. Прием нужно реализовать исключительно в обработчике прерывания — пусть он всегда заполняет кольцевой буфер данными (вызовы CAN_Read нам уже не нужны, и не нужно заполнять CanTransfer принятыми данными и флагами). Передачу можно сделать периодическими вызовами из основной программы, при этом можно использовать CanTransfer для отслеживания занятости CAN на передачу.

Как добавить поддержку CAN в свой проект, процесс по шагам.

1. Добавляем в проект модуль at91lib\peripherals\can\can.c. Я повыкидывал из can.c весь мусорный код (относящийся к другому чипу, у которого два интерфейса CAN), чтобы было понятнее, как все работает.

2. Добавляем в файл at91lib\board\board.h определения ножек для входа и выхода CAN (в этом примере используются только ножка приема и ножка передачи):

Ненужные определения ножек PIN_CAN_TRANSCEIVER_RS, PIN_CAN_TRANSCEIVER_RXEN и использующий их код я удалил.

3. Добавляем в начало программы (до основного цикла main) код инициализации CAN (в этом примере выбрана скорость 125 кбод):

4. Пишем процедуру для опроса интерфейса CAN (её вызовы тупо вставляем в главный цикл main):

Немного комментариев по коду. Процедура, настраивающая почтовый ящик перед передачей — CAN_InitMailboxRegisters. Она требует в качестве параметра структуру CanTransfer с установленными параметрами. В общем, нам это код уже не нужен, так как ящики у нас и так уже настроены на прием (нужно только вписать в регистры ящика новые данные и запустить передачу). Процедура CAN_Write делает запуск передачи. Так как мне было банально лень переписывать, то я оставил мусорный код инициализации canTransferTX, вызов CAN_InitMailboxRegisters и CAN_Write. Когда-нибудь и это тоже пойдет под нож.

Видео:Экспресс диагностика CAN шины на автомобиле. №21Скачать

Экспресс диагностика CAN шины на автомобиле. №21

Это все! Проект настроен на прием и передачу данных по CAN.

Здесь приведен пример принципиальной схемы физического подключения интерфейса CAN микроконтроллера ARM AT91SAM7X256 к линии передачи. Здесь линия передачи/приема CAN гальванически развязана от микроконтроллера с помощью DC-DC преобразователя AM1L-0505SH30-NZ (он питает драйвер CAN PCA82C250) и изолятора сигналов ADUM3201BRZ (через этот изолятор сигналы CAN_RxD и CAN_TxD подключаются на ножки микроконтроллера 46 и 47 соответственно).

Микроконтроллер в схеме шины can

Для проверки, как работает прием, нужно подключить интерфейс CAN к чему-нибудь, что передает пакеты CAN. Я использовал интерфейс USB-CAN компании Systec Electronic (USB-CANmodul GW-002), Германия. Установка драйверов в систему Windows никаких проблем не вызывает, подключается к компьютеру стандартным шнуром USB.

Микроконтроллер в схеме шины can

Для подключения нужен шнур DB9 мама (втыкается в USB-CAN адаптер Systec Electronic) — DB9 папа (подключается к разъему, соединенному с драйвером CAN PCA82C250). Параллельно сигналам CANL и CANH обязательно должен стоять резистор 120..150 Ом. Вот цоколевка шнура (линия состоит только двух проводов CANL и CANH, даже земли нет):

DB9 мама DB9 папа
2 CANL 1 CANL
7 CANH 2 CANH

На разъеме адаптера USB-CAN используются только ножки 2 и 7. Полная цоколевка коннектора DB9 папа адаптера USB-CAN USB-CANmodul GW-002 показана на рисунке (вид снаружи на штырьки адаптера).

Микроконтроллер в схеме шины can

[Программа PCANView]

Для работы с адаптером USB-CANmodul GW-002 имеется готовая тестовая программа PCANView, позволяющая передавать и принимать данные.

Видео:CAN шина👏 Как это работаетСкачать

CAN шина👏 Как это работает

Сразу после запуска программа PCANView просит выбрать адаптер USB-CAN USB-CANmodul, с которым будет осуществляться работа (Device-Nr.:), скорость работы CAN (Baudrate:) и номер канала (для двухканального адаптера). В большинстве случаев здесь надо указать только Baudrate (выбрать из выпадающего списка).

Микроконтроллер в схеме шины can

Следующее окно (Connect to net) позволяет выбрать фильтр для принимаемых сообщений (Message filter), где указывается режим адресации — стандартный или расширенный, и можно задать диапазон для приема. Можно просто нажать кнопку OK, тогда будет выбран стандартный режим адресации, и будут приниматься все сообщения без ограничений.

Читайте также: Сброс ошибки давления в шинах джили атлас

Микроконтроллер в схеме шины can

После нажатия на OK запустится основное окно программы.

Микроконтроллер в схеме шины can

Главное окно программы содержит два поля — верхнее (для приема сообщений) и нижнее (для отправки сообщений). Если Вы запустили программу на ARM AT91SAM7X256 и подключили её к адаптеру USB-CANmodul, то в верхнем окне сразу увидите скачущие циферки данных — это то, что передает ARM. В таблице есть следующие столбцы:

Message показывает адрес ящика, которому пришло сообщение, равно CAN_MB_MID передающих ящиков 2..7 ARM (задается макросом CANID_TX).
Length показывает длину пакета данных в ящике (в нашем примере всегда 8 байт).
Data тут прыгают данные, которые генерят вызовы rand() в CANpoll программы ARM
Period измеренная длительность между принятыми пакетами CAN в миллисекундах
Count счетчик принятых пакетов
RTR-Per. не разобрался, что это такое
RTR-Cnt. не разобрался, что это такое

Для того, чтобы что-нибудь передать нашей программе в ARM, нужно в меню выбрать Transmit -> New. Появится нехитрое окошко, в котором нужно заполнить параметры для передаваемого пакета.

Микроконтроллер в схеме шины can

Видео:Простая проверка CAN шины. Сканер не видит автомобиль через OBD2. Как правильно выбрать изоленту.Скачать

Простая проверка CAN шины. Сканер не видит автомобиль через OBD2. Как правильно выбрать изоленту.

В поле ID (Hex): заполняется адрес ящика, на который будет отослан пакет. Здесь вводится шестнадцатеричное число, значение которого должно совпадать с значением, которое записано в регистры CAN_MB_MID принимающих ящиков 0 и 1 ARM (задается макросом CANID_RX, я выбрал адрес 000h). В поле Period задается период в миллисекундах, с которым будут автоматически отправляться сообщения — если оставить 0, то отправка будет срабатывать при нажатии кнопки Пробел в нижнем поле программы PCANView (в этом случае в столбце Period нижнего поля окна программы PCANView будет стоять Wait). В поле Data (1..8): можно вписать значения байт, которые будут передаваться. Если поставить галочку Extended Frame, то будет использоваться не стандартный режим адресации, а расширенный (я эту галку не ставил, так как в моем примере используется стандартный режим). Галочка Remote Request относится к отправке фрейма remote, когда получатель данных запрашивает их у отправителя (это специальная фича протокола CAN).

Вот пример вывода тестовой программы ARM в консоль DBGU — после того, как ей передаст данные программа PCANView:

Микроконтроллер в схеме шины can

[Встраивание обмена по CAN в пользовательскую программу]

Для того, чтобы написать собственную программу на компьютере, которая сможет передавать и принимать данные по шине CAN через USB-CANmodul GW-002, компания Systec Electronic предоставила библиотеку USBCAN32.DLL с подробным описанием её функций и примерами кода (см. документацию в архиве по Ссылке [3]).

[UPD140207 — поле MDLC в регистрах почтового ящика CAN_MSRx и CAN_MCRx]

Аббревиатура MDLC расшифровывается как Mailbox Data Length Code (код длины сообщения). Это поле четырехбитное, и оно присутствует в регистрах CAN_MCRx (используется при передаче) и CAN_MSRx (используется при приеме). Это поле удобно использовать для передачи дополнительной информации, например для передачи кода команды. Однако эта дополнительная возможность работает только в том случае, когда с обоих сторон обмена по шине CAN (со стороны отправителя и получателя) стоят микроконтроллеры AT91SAM7.

4 битами можно закодировать 16 вариантов команд (от 0 до 15), и это весьма полезная возможность, учитывая маленький объем данных полезных данных почтового ящика. Однако помните, что значение MDLC меньше 8 обрезает количество передаваемых данных в ящике. Так например, если указать MDLC=0, то все 8 байт в почтовом ящике придут нулевые. Если указать MDLC=1, то будут переданы данные только в 0 байте (байты 1..7 придут нулевые), если MDLC=2, то только в 0 и 1 байте (байты 2..7 придут нулевые) и так далее. При значении MDLC больше 7 будут приходить данные всех 8 байт ящика.

1. Controller Area Network site:ru.wikipedia.org . Что такое CAN шина? site:equs.ru .
2. USB-CANmodul1 site:www.systec-electronic.com .
3. Исправленный проект basic-can-project — там максимально все упрощено. В архиве проекта имеется документация по адаптеру USB-CANmodul GW-002, установке драйверов, программе PCANView и функциям библиотеки USBCAN32.DLL (файл doc\USB-CAN\L-487e_13.pdf).
4. Оригинальный пример basic-can-project от Atmel.
5. Visual Studio C#: работа с USB-CAN адаптером SYSTEC.
6. AT91SAM7X: контроллер CAN.

Комментарии

при частоте 10kHz, вероятно, происходит переполнение поля BRP, что приводит к установке «левого» значения поля, решение я вижу одно — понижать частоту master clock. для частоты 800kHz нужно просто подправить функцию-калькулятор, задав TimeQuantum=8.
и ещё, судя по картинке, в USB-CANModule можно задать произвольную частоту, рассчитав регистры
BTR0 = (SJW & 3)

Видео:поиск нерабочей can шины, часть дваСкачать

поиск нерабочей can шины, часть два

microsin: спасибо за комментарий. Подозреваю, что Вы правы — можно самому разобраться в кишочках CAN и настроить его на любую нужную скорость. Я пока не копал так глубоко, а всего лишь использовал готовый софт Atmel (из примеров IAR). Статья и была про это — как воспользоваться готовеньким, а не про то, как раскочегарить CAN на полную мощность.

  • Свежие записи
    • Нужно ли менять пружины при замене амортизаторов
    • Скрипят амортизаторы на машине что делать
    • Из чего состоит стойка амортизатора передняя
    • Чем стянуть пружину амортизатора без стяжек
    • Для чего нужны амортизаторы в автомобиле


    💥 Видео

    Кан шина, что это? Поймет школьник! принцип работыСкачать

    Кан шина, что это? Поймет школьник! принцип работы

    Как проверить CAN шину Используем симулятор ElectudeСкачать

    Как проверить CAN шину  Используем симулятор Electude

    Трансиверы CAN шины TJA1050, MCP2551 как альтернатива RS485Скачать

    Трансиверы CAN шины TJA1050, MCP2551 как альтернатива RS485

    Контролька на Arduino, с функциями осциллографа, поиска CAN шины, частотомера, вольтметра, прозвонкиСкачать

    Контролька на Arduino, с функциями осциллографа, поиска CAN шины, частотомера, вольтметра, прозвонки

    Металлизация переходных отверстий в реальной работе. Разработка индикатора CAN шины на STM32F103.Скачать

    Металлизация переходных отверстий в реальной работе. Разработка индикатора CAN шины на STM32F103.

    Как работает LIN шина автомобиля. K-Line L-Line шины данных. Лин шина автомобиля. Lin-bus networkСкачать

    Как работает LIN шина автомобиля. K-Line L-Line шины данных. Лин шина автомобиля. Lin-bus network

    STM32 CAN шина. Часть 1. Настройка и странности HALСкачать

    STM32 CAN шина. Часть 1. Настройка и странности HAL

    Универсальная плата CAN шиныСкачать

    Универсальная плата CAN шины

    Arduino CAN Sender ( Ардуино отправка пакетов в КАН шину)Скачать

    Arduino CAN Sender ( Ардуино отправка пакетов в КАН шину)

    Подробно про CAN шинуСкачать

    Подробно про CAN шину

    Логический LIN пробник, цифровой тестер лин, к лайн шины автомобиля. На Ардуино, OLED I2C, TJA 1020Скачать

    Логический LIN пробник, цифровой тестер лин, к лайн шины автомобиля. На Ардуино, OLED  I2C, TJA 1020

    Arduino CAN Monitor (простейший монитор шины CAN)Скачать

    Arduino CAN Monitor (простейший монитор шины CAN)

    Установка бесконтактного считывателя CAN-шины Eurosens InCANСкачать

    Установка бесконтактного считывателя CAN-шины Eurosens InCAN

    Демонстрация управления системой с использованием шины CANСкачать

    Демонстрация управления системой с использованием шины CAN
Поделиться или сохранить к себе:
Технарь знаток