CAN-шина и stm32 — часть вторая — фильтры и два CAN
Первая часть закончилась на том, что я обещал рассказать про настройку фильтров и работу двух CAN-интерфейсов на одном камне. Начнём с фильтров.
Фильтры
Как уже говорилось ранее, у каждого CAN-интерфейса есть 14 фильтров. Фильтры так же называются фильтрами-банками или просто банками. Каждый фильтр имеет порядковый номер (счёт идёт он нуля), и представляет из себя два 32-х битных регистра (далее буду называть их «регистры фильтра», первый и второй). Каждый фильтр имеет свои «регистры фильтра».
В двух словах, фильтр работает так: в первый «регистр фильтра» мы прописываем некий идентификатор пакета, а во второй некую маску, в результате чего CAN будет принимать только некоторый диапазон кадров, а все остальные отбрасывать. Это первый способ. Второй способ: в один или оба «регистра фильтра» мы прописываем конкретные идентификаторы кадров, которые хотим получать — всё остальное будет отброшено.
Фильтр нельзя настроить как исключающий, то есть если нужно принимать все кадры кроме какого-то одного, например 0x0296, придётся настроить два фильтра, так чтобы они принимали кадры с 0x0000 по 0x0295, и с 0x0297 по 0x07FF.
Для гибкой настройки фильтрации есть четыре варианта использования «регистров фильтра» для каждого фильтра. Картинка из референс мануала иллюстрирует это…
Красными полосками я разделил варианты использования «регистров фильтра».
Первый и второй варианты подходят для фильтрации как стандартных (11 бит), так и расширенных (29 бит) идентификаторов, а третий и четвёртый только для стандартных. Теперь давайте рассмотрим всё это подробно.
Первый вариант — 32-Bit Filter — Identifier Mask
Заранее предупреждаю — будет сложно, так что приготовьтесь
В первый «регистр фильтра» (ID на картинке ) записываться идентификатор кадра, а во второй (Mask на картинке ) маска, которая будет накладываться на этот идентификатор и сравниваться с этим идентификатором. Выглядит запутано, но не пугайтесь, ниже всё разъяснится. Таким образом фильтр будет содержать определённый диапазон идентификаторов, которые будут приняты (не отброшены).
Поскольку наш CAN-интерфейс принимает все кадры, а потом уже аппаратно отбрасывает те, которые не соответствуют настройкам фильтра, то далее по тексту под словом «принимать» я буду подразумевать, что кадр не был отброшен.
Для примера будем настраивать фильтр №0.
Указываем режим работы фильтра…
Режим идентификатора и маски. Обращаю ваше внимание на этот параметр, если записать сюда другой макрос (CAN_FILTERMODE_IDLIST), тогда фильтр будет работать по другому. Поскольку эти макросы схожие, будьте внимательны.
Указываем масштаб (размерность) фильтра…
32 бита, говорит о том, что фильтроваться могут либо стандартные (11 бит) идентификаторы, либо расширенные (29 бит).
Видео:STM32 CAN шина. Часть 2. Фильтрация и демонстрация работыСкачать
Далее, в прошлой части мы писали такой код…
Это два «регистра фильтра», каждый из которых условно разделён на старшую и младшую часть. Везде записаны нули чтоб принимать все кадры.
Сейчас мы настроим фильтр для работы с идентификаторами стандартных кадров, то есть с 11-битными идентификаторами.
Не смотря на то, что размерность фильтра у нас указана 32 бита (CAN_FILTERSCALE_32BIT), мы можем настраивать фильтр для работы и со стандартными (11 бит), и с расширенными (29 бит) идентификаторами. Если бы мы указали размерность фильтра 16 бит (CAN_FILTERSCALE_16BIT), тогда фильтр работал бы только со стандартными кадрами, об этом речь пойдёт ниже.
Предположим что мы хотим принимать идентификаторы с 0x0100 по 0x0107, тогда в старшую часть первого «регистра фильтра» записываем начальный идентификатор, со сдвигом…
В младшую часть пишем нули.
Сдвиг делается потому, что идентификатор у нас 11-ти битный, и согласно рисунку для него выделена старшая часть, старшей части «регистра фильтра». Такое вот получилось «масло масляное».
Mapping показывает что здесь должен лежать стандартный идентификатор — STDID — восемь бит в первом октете (слева) и три во втором.
В бинарном формате число 0x0100 выглядит так — 0000000100000000, а поскольку количество стандартных идентификаторов не может превышать 0x07FF (0000011111111111), то первые пять нулей никому не нужны, поэтому «выкидываются на мороз».
В целом, все эти картинки с распределением ноликов и единичек вам не так уж и нужны, однако для общего развития и упрощения понимания будут полезны.
Переходим к старшей части второго «регистра фильтра». Сюда мы записываем (опять же со сдвигом) число 0x07F8…
Читайте также: Шины для тойота королла 2017
Вот это поворот, скажет неискушенный читатель, наверное автор что-то перепутал. Но нет, всё правильно, и сейчас будем с этим разбираться.
В младшую часть второго «регистра фильтра» мы опять записали нолик, а число 0x07F8 (0000011111111000) легло у нас в старшую часть второго «регистра фильтра» вот так…
Первые (слева) пять ноликов опять же выкинуты, по описанным выше причинам.
Таким образом, число 0x07F8 у нас является маской. Немного забегая вперёд, скажу что это число нужно подбирать самостоятельно, экспериментальным путём. Теперь давайте разбираться как это работает.
Теперь смотрите что получается. Когда прилетает какой-то идентификатор, он попадает в систему фильтрации, и происходит следующее: между прилетевшим идентификатором и маской выполняется побитовая операция «И» (она же AND, она же &), и далее этот результат сравнивается с тем, что записано в «первом регистре» фильтра, в нашем случае это число 0x0100. Если результат совпадает, тогда идентификатор (кадр с этим идентификатором) принимается, если нет — отбрасывается.
Чтоб внести ясность можно описать этот механизм простой программой…
Видео:MCP2515, контроллер CAN шины с интерфейсом SPIСкачать
ID — это то, что мы записали в первый «регистр фильтра».
Mask — маска, записанная во второй «регистр фильтра».
Цикл for имитирует прилетающие идентификаторы, от 0 до 0x07FF (0x0800 — 1, максимальное кол-во стандартных идентификаторов) . В условии if на прилетевший идентификатор накладывается маска, и если полученный результат равен 0x0100, прилетевший идентификатор будет принят CAN’ом (выведен на печать).
Результатом работы программы будет вот такой вывод…
Идентификаторы с 0x0100 по 0x0107, которые мы планировали принимать.
По ссылке можно качнуть программу, которая выводит значения в HEX и бинарном формате…
С её помощью можно методом «тыка» подбирать маску. Программа написана для Линукса, но должна скомпилиться и для Windows. Либо просто перенесите её на stm.
Если мы изменим в маске последнюю цифру с 0x07F8 на 0x07FC, то наш CAN будет принимать идентификаторы с 0x0100 по 0x0103…
Совсем не обязательно настраивать фильтр так, чтобы принимаемые идентификаторы были последовательны в порядке возрастания, можно делать как угодно, всё зависит от ID и Mask. Например если в ID записать 0x0200, а маску 0x03FD, тогда будут приниматься идентификаторы 0x0200, 0x0202, 0x0600 и 0x0602…
Чтобы понять как подбирать маску взгляните на последнюю картинку. Если бит в маске равен единице значит и соответствующий бит в прилетевшем идентификаторе тоже должен быть равен единице. Если же бит в маске равен нулю, тогда не важно чему равен соответствующий бит в прилетевшем идентификаторе.
Первый бит в маске (слева направо) равен нулю, соответственно не важно чему равен первый бит у идентификаторов, которые будут приняты, может быть ноль или единица. Второй бит в маске равен единице, поэтому принимаются только те идентификаторы, у которых второй бит равен единице. Десятый бит в маске равен нулю, значит не важно чему равен этот бит у идентификаторов, которые будут приняты.
Для закрепления понимания давайте сделаем маску, у которой все биты кроме трёх последних будут равны единице…
Вуаля. Теперь мы принимаем идентификаторы в диапазоне с 0x0200 по 0x0207. Обратите внимание, что маска такая же как и для идентификаторов с 0x0100 по 0x0107. Это ничего не значит, просто к слову.
В общем думаю более менее всё понятно. Берёте какой-нибудь идентификатор, придумываете маску, скармливаете это программе и смотрите какие идентификаторы будут приняты.
Теперь давайте мысленно вернёмся к началу статьи, вспомним что мы хотели принимать идентификаторы с 0x0100 по 0x0107, и закончим настройку фильтра №0.
В результате у нас получится следующий код…
Последний параметр просто включает фильтр, а вот про предпоследний нужно сказать пару слов. Как вы помните у CAN’а есть два приёмных буфера CAN_RX_FIFO0 и CAN_RX_FIFO1. В данном случае мы указали CAN_RX_FIFO0, это означает что все принятые кадры прошедшие через фильтр №0 попадут CAN_RX_FIFO0. Отсюда вытекает, что настроив несколько фильтров, мы можем указать в какой именно буфер будут сваливаться принятые кадры. Теперь давайте настроим ещё один фильтр.
Читайте также: Маркировка даты выпуска шины toyo
Видео:Вебинар: Как найти любые данные из CAN-шины любого автомобиля?Скачать
Возьмём последний пример и будем принимать идентификаторы с 0x0200 по 0x0207 через фильтр №1…
Указываем только номер фильтра и прописываем значения в «регистры фильтра». Все остальные настройки будут автоматически взяты из настроек фильтра №0.
Таким образом инициализация CAN’а и фильтров будет выглядеть так…
Если мы хотим помещать кадры прошедшие через фильтр №1 в буфер CAN_RX_FIFO1, тогда это нужно указать. И вообще, если работаете с разными буферами, то не лишним будет указывать это везде чтоб не запутаться, хуже не будет.
Таким образом кадры с 0x0100 по 0x0107 будут падать в буфер CAN_RX_FIFO0, а кадры с 0x0200 по 0x0207 в буфер CAN_RX_FIFO1.
Далее если есть необходимость вы можете настроить ещё сколько нужно фильтров — максимальный №13.
Режим фильтра (CAN_FILTERMODE_IDMASK) и размерность (CAN_FILTERSCALE_32BIT) тоже можно настраивать для каждого фильтра отдельно, но об этом позже.
Теперь рассмотрим фильтрование 29-ти битных идентификаторов. Вы же помните, что мы всё ещё разбираем первый вариант использования «регистров фильтра», который подразумевает фильтрование 11-ти и 29-ти битных идентификаторов
Поскольку настройки режима и размерности фильтра здесь те же самые, что и в предыдущих примерах, мы настроим только номер фильтра и «регистры фильтра», ну и укажем буфер CAN_RX_FIFO1 (можно CAN_RX_FIFO0, как хотите). Разумеется, если вы настраиваете только один фильтр, тогда нужно прописать все значения. При этом совсем не важно какой номер фильтра вы укажите, можно любой с 0 до 13.
Настроим фильтр №2, а принимать будем кадры с идентификаторами в диапазоне от 0x00010000 до 0x00010007…
Здесь у нас «регистры фильтра» используются полностью, тоже делается сдвиг, чтоб биты встали в нужные места, и ещё в младшие части добавляется | 0x04.
ID и Mask лягут в области STID и EXID…
… а в бит IDE будет записана единичка с помощью | 0x04 (00000100). Это сообщит системе, что фильтр настроен на работу с расширенным идентификатором. То есть всегда, когда настраиваем фильтр на работу с расширенным кадром, добавляем | 0x04.
Бит RTR не трогаем, однако если захотим настроить фильтр на работу с Remote Frame, тогда в него надо записать единицу. Это касается и стандартных, и расширенных кадров.
Операции с ID и маской здесь точно такие же как и в предыдущем примере, и вот такая же программка, только для 29-ти битных идентификаторов…
Дальше вы уже знаете что с этим делать.
Вы может настроить несколько фильтров для расширенных кадров, и совмещать их со стандартными, как мы это только что сделали. Сейчас наш CAN принимает стандартные идентификаторы с 0x0100 по 0x0107 и с 0x0200 по 0x0207, складывая их в CAN_RX_FIFO0, и расширенные с 0x00010000 по 0x00010007, складывая их в CAN_RX_FIFO1.
На этом первый вариант закончен, самое трудное позади, дальше будет легко.
Второй вариант — 32-Bit Filters — Identifier List
Видео:Подробно про CAN шинуСкачать
Здесь всё просто, фильтр можно настроить на приём только одного или двух конкретных идентификатора, они просто записываются в первый и второй «регистры фильтра», так же со сдвигом. Единственное важное отличие от предыдущего варианта, это режим фильтра, тут он будет CAN_FILTERMODE_IDLIST.
Фильтр №3 будет принимать два стандартных идентификатора — 0x06D9 и 0x04C6…
А фильтр №4 будет принимать два расширенных идентификатора — 0x000006D9 и 0x000004C6…
Если нужно принимать только один идентификатор, тогда во второй «регистр фильтра» нужно прописать то же, что и в первом…
Получится что CAN будет два раза фильтровать одно и то же, но другого варианта видимо нет, так как если записать туда просто нули, будет приниматься идентификатор 0x0000.
Третий вариант — 16-Bit Filters — Identifier Mask
Читайте также: Шины в краснодаре по халве
Этот вариант, как и первый, работает с маской, но может фильтровать только стандартные (11 бит) кадры. Достоинство этого варианта перед первым в том, что один фильтр можно настроить на два диапазона идентификаторов. Это достигается за счёт использования «регистров фильтра» полностью, а не только старшие части.
Будем принимать кадры в диапазонах с 0x0320 по 0x0323, и с 0x0480 по 0x0487.
Режим фильтра на работу с маской…
Важное отличие от предыдущих примеров — размерность фильтра указываем 16 бит…
В старшую и младшую часть первого «регистра фильтра» записываем начальные ID первого и второго диапазона…
А в старшую и младшую часть второго «регистра фильтра» записываем соответствующие маски…
Если нужно принимать только один диапазон, тогда вместо второго идентификатора и маски нужно прописать то же что и для первого…
Опять же, получится что CAN будет выполнять лишнюю работу, но если записать туда нули, тогда будут приниматься вообще все стандартные кадры.
Четвёртый вариант — 16-Bit Filters — Identifier List
Этот вариант похож на второй, только опять же, мы можем фильтровать не два конкретных идентификатора, четыре. И как вы уже наверно догадались, они могут быть только стандартными.
Будем принимать идентификаторы 0x0690, 0x0693, 0x0696 и 0x0699.
Настраиваем фильтр №6, и меняем режим на CAN_FILTERMODE_IDLIST…
Видео:CanHacker из 2CAN модуля своими руками КанХакер подробно в деталяхСкачать
Опять же, если вместо какого-то идентификатора вписать 0x0000, то будет приниматься кадр 0x0000.
С последним вариантом, равно как и с разбором фильтров, покончено.
В довершение осталось сказать что фильтр настроенный как CAN_FILTERSCALE_32BIT имеет более высокий приоритет чем CAN_FILTERSCALE_16BIT.
То есть если мы настроим два фильтра вот так…
… все кадры будут складываться в буфер 1.
Так же и номера фильтров имеют приоритет. Чем меньше номер фильтра, тем выше у него приоритет. В примере ниже, все кадры будут складываться опять же в буфер 1.
А если поменять номера фильтров, то в буфер 0. Всё.
Два CAN’а на одном камне
Единственной особенностью CAN2 является то, что он не может работать при отключённом CAN1, во всём остальном настройки CAN2 такие же как у CAN1, кроме номеров фильтров. Чтоб CAN2 заработал, достаточно просто активировать CAN1 и настроить у него хотя бы один фильтр.
То есть инициализация обоих CAN’ов будет такая…
Для CAN1 фильтры с 0 по 13, для CAN2 фильтры с 14 по 27. У CAN2 есть дополнительный параметр — sFilterConfig.SlaveStartFilterBank = 14 , сообщающий системе с какого номера начинаются фильтры CAN2. Добавляются фильтры так же как описано выше.
Разумеется CAN’ы можно настраивать на разные скорости. Собственно не знаю что ещё сказать.
Не смотря на то, что в мануалах CAN2 называют Slave, это полностью самостоятельный интерфейс, просто он не может работать без включённого CAN1, так как именно CAN1 включает всю систему буферов, фильтров, почтовых ящиков, и т.д. Видимо это какая-то особенность проектирования камня. Наверно сначала не планировали два CAN’а делать, а потом передумали и приладили
Если CAN1 не используется и к нему не подключён трансивер, тогда ножку RX нужно подтянуть к плюсу, можно внутреннюю подтяжку пользовать.
Если CAN1 не используется, тогда его запускать не нужно.
CAN_IT_RX_FIFO0_MSG_PENDING — это может быть CAN_IT_RX_FIFO1_MSG_PENDING, зависит от того какой буфер вы указали в настройках фильтра (CAN_RX_FIFO0 или CAN_RX_FIFO1).
Колбек для приёма, если у обоих CAN’ов задействован буфер CAN_RX_FIFO0…
Если для обоих CAN’ов задействован буфер CAN_RX_FIFO1…
Обратите внимание, что в названии функции . RxFifo0… поменялось на . RxFifo1.
Если для разных CAN’ов настроены разные буферы…
Если CAN1 не используется, тогда для него ничего писать не нужно.
Видео:Блокировка can-шины в фаре Toyota/Lexus. Шок для опытных установщиков. Зачем думать и читать схемыСкачать
Статью писал долго, с перерывами, так что если что упустил/забыл — пишите в чат.
Это всё, всем спасибо
- Свежие записи
- Нужно ли менять пружины при замене амортизаторов
- Скрипят амортизаторы на машине что делать
- Из чего состоит стойка амортизатора передняя
- Чем стянуть пружину амортизатора без стяжек
- Для чего нужны амортизаторы в автомобиле
💥 Видео
Экспресс диагностика CAN шины на автомобиле. №21Скачать
Mercedes w210 замена кан шины и фильтр на АКППСкачать
Can FilterСкачать
STM32 CAN шина. Часть 1. Настройка и странности HALСкачать
лекция 403 CAN шина- введениеСкачать
CAN шина👏 Как это работаетСкачать
CAN-шина, простой поиск данных в кан шине автомобиля. Как расшифровать и найти данные в кан шине?Скачать
CAN шина на осциллографе FINIRSI ADS1013DСкачать
Универсальная плата CAN шиныСкачать
CAN Эмулятор скорости из модуля CAN StarLine Stm32f103c8t6 Подмотчик скорости по кан шине (без схем)Скачать
Анализ CAN-шины Гранта. CAN-hacker.Скачать
Mercedes Benz E 211 CAN filterСкачать
STM32 настройка CANСкачать
Lexus LX570 CAN шина, включение фар по CANСкачать