На основе примера 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 шина- введениеСкачать
Читайте также: Размер шин для картинга
В примере 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Скачать
Читайте также: Сколько качать шины ваз 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.
Здесь приведен пример принципиальной схемы физического подключения интерфейса CAN микроконтроллера ARM AT91SAM7X256 к линии передачи. Здесь линия передачи/приема CAN гальванически развязана от микроконтроллера с помощью DC-DC преобразователя AM1L-0505SH30-NZ (он питает драйвер CAN PCA82C250) и изолятора сигналов ADUM3201BRZ (через этот изолятор сигналы CAN_RxD и CAN_TxD подключаются на ножки микроконтроллера 46 и 47 соответственно).
Для проверки, как работает прием, нужно подключить интерфейс CAN к чему-нибудь, что передает пакеты CAN. Я использовал интерфейс USB-CAN компании Systec Electronic (USB-CANmodul GW-002), Германия. Установка драйверов в систему Windows никаких проблем не вызывает, подключается к компьютеру стандартным шнуром USB.
Для подключения нужен шнур 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 показана на рисунке (вид снаружи на штырьки адаптера).
[Программа PCANView]
Для работы с адаптером USB-CANmodul GW-002 имеется готовая тестовая программа PCANView, позволяющая передавать и принимать данные.
Видео:CAN шина👏 Как это работаетСкачать
Сразу после запуска программа PCANView просит выбрать адаптер USB-CAN USB-CANmodul, с которым будет осуществляться работа (Device-Nr.:), скорость работы CAN (Baudrate:) и номер канала (для двухканального адаптера). В большинстве случаев здесь надо указать только Baudrate (выбрать из выпадающего списка).
Следующее окно (Connect to net) позволяет выбрать фильтр для принимаемых сообщений (Message filter), где указывается режим адресации — стандартный или расширенный, и можно задать диапазон для приема. Можно просто нажать кнопку OK, тогда будет выбран стандартный режим адресации, и будут приниматься все сообщения без ограничений.
Читайте также: Сброс ошибки давления в шинах джили атлас
После нажатия на OK запустится основное окно программы.
Главное окно программы содержит два поля — верхнее (для приема сообщений) и нижнее (для отправки сообщений). Если Вы запустили программу на 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 шины. Сканер не видит автомобиль через 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 через 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 шины, часть дваСкачать
microsin: спасибо за комментарий. Подозреваю, что Вы правы — можно самому разобраться в кишочках CAN и настроить его на любую нужную скорость. Я пока не копал так глубоко, а всего лишь использовал готовый софт Atmel (из примеров IAR). Статья и была про это — как воспользоваться готовеньким, а не про то, как раскочегарить CAN на полную мощность.
- Свежие записи
- Нужно ли менять пружины при замене амортизаторов
- Скрипят амортизаторы на машине что делать
- Из чего состоит стойка амортизатора передняя
- Чем стянуть пружину амортизатора без стяжек
- Для чего нужны амортизаторы в автомобиле
💥 Видео
Кан шина, что это? Поймет школьник! принцип работыСкачать
Как проверить CAN шину Используем симулятор ElectudeСкачать
Трансиверы CAN шины TJA1050, MCP2551 как альтернатива RS485Скачать
Контролька на Arduino, с функциями осциллографа, поиска CAN шины, частотомера, вольтметра, прозвонкиСкачать
Металлизация переходных отверстий в реальной работе. Разработка индикатора CAN шины на STM32F103.Скачать
Как работает LIN шина автомобиля. K-Line L-Line шины данных. Лин шина автомобиля. Lin-bus networkСкачать
STM32 CAN шина. Часть 1. Настройка и странности HALСкачать
Универсальная плата CAN шиныСкачать
Arduino CAN Sender ( Ардуино отправка пакетов в КАН шину)Скачать
Подробно про CAN шинуСкачать
Логический LIN пробник, цифровой тестер лин, к лайн шины автомобиля. На Ардуино, OLED I2C, TJA 1020Скачать
Arduino CAN Monitor (простейший монитор шины CAN)Скачать
Установка бесконтактного считывателя CAN-шины Eurosens InCANСкачать
Демонстрация управления системой с использованием шины CANСкачать