Мне нужно настроить фильтры CAN таким образом, чтобы пропускались только идентификаторы 0x80 и идентификаторы между 0x200 и 0x300, все остальные не разрешены для передачи

#c #filtering #stm32 #can-bus

Вопрос:

Я пробовал таким образом, но проблема в том, что только 200-300 могут пройти, но 80 часов не пройдено. если я использую if-else, то только 80 часов проходит не 200-300 часов. Итак, проблема в том, что я могу пройти 80 часов или 200-300 часов. Не одновременно 80ч и 200-300ч.

 #define Filter_ID1  0x80

#define Filter_ID2  0x200


#if Filter_ID1

sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;

sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;

sFilterConfig.FilterBank = 0;

sFilterConfig.FilterIdHigh=0x80<<5;

sFilterConfig.FilterMaskIdHigh=0xff<<5;

sFilterConfig.FilterIdLow = 0x0000;

sFilterConfig.FilterMaskIdLow = 0x0000;

sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;

sFilterConfig.FilterActivation = ENABLE;

#endif


#if Filter_ID2

sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;

sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;

sFilterConfig.FilterBank = 1;

sFilterConfig.FilterIdHigh=0x200<<5;

sFilterConfig.FilterMaskIdHigh=0x300<<5;

sFilterConfig.FilterIdLow = 0x0000;

sFilterConfig.FilterMaskIdLow = 0x0000;

sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;

sFilterConfig.FilterActivation = ENABLE;

#endif

 

Комментарии:

1. Вы, кажется, путаете маску и значения. Если разрешено что-либо между 0x200 и 0x300, то вы вообще не можете смотреть на эту часть идентификатора. Как правило, это дерьмо с маской принятия было настолько утомительным, чтобы все исправить, что обычно приносило больше вреда, чем пользы… Я бы настоятельно рекомендовал вместо этого использовать современный контроллер CAN с почтовыми ящиками. Хотя, я думаю, это может исключить STM32.

2. @Lundin, что привело вас к такому выводу? st.com/content/ccc/resource/training/technical/product_training/…

3. @0___________ Значит, они наконец-то заменили «bxCAN»? Как раз вовремя. По иронии судьбы, в других частях ST уже давно есть почтовые ящики, такие как SPC56. Хотя, по-моему, этот в основном был разработан компанией Freescale…

Ответ №1:

Вам необходимо настроить два банка фильтров:

Для диапазона [0x200, 0x300) (исключено 0x300) вам необходим режим маски идентификатора. В этом случае:

  • Маска (FxR2) = 0x300 (проверьте биты 8 и 9, игнорируйте другие)
  • Идентификатор (FxR1) = 0x200 (биты 8 и 9 должны быть 0b10)

Для 0x80 вам нужен режим списка идентификаторов. Для 32-разрядного списка банк фильтров содержит 2 элемента. Чтобы принять только 0x80, вам нужно заполнить их одним и тем же значением (0x80 дважды).

  • Идентификатор (FxR1) = 0x80
  • Идентификатор (FxR2) = 0x80

Одновременно может быть активировано несколько банков фильтров.

FiRx является ли соглашение об именовании, используемое справочным руководством, где i = 0..27 (номер банка фильтров) и x = 1,2 (номер регистра). Я не знаю, как их называет библиотека, которой вы пользуетесь.

Конечно, значения, которые я упомянул, являются всего лишь логическими значениями. Вам нужно переместить/изменить их, чтобы они соответствовали вашим регистрам HW. Я не уверен, что сдвиг влево на 5 правильный. Мне кажется << 3 , это правильное значение. См. раздел Конфигурация масштаба банка фильтров — организация регистрации в справочном руководстве

Комментарии:

1. я понимаю вашу точку зрения, и она полностью соответствует основам. Но теперь я обнаружил, что у меня есть проблема с внедрением нескольких банков фильтров. Можете ли вы привести мне пример кода, в котором используется несколько банков фильтров?

2. Я думаю, что никаких дополнительных усилий не требуется, просто активируйте их оба одновременно. Но я все еще думаю, что в ваших назначениях регистра конфигурации могут быть ошибки. Их имена несколько сбивают с толку, и они напрямую не совпадают с именами регистров HW. Вам необходимо обратиться к документации библиотеки.

3. спасибо за вашу помощь. Наконец-то это работает. я использовал два фильтра. переменная конфигурации должна быть равна двум для двух банков. sFilterConfig1 и sFilterConfig2. я использовал в своей программе только одну переменную, поэтому за раз использовалась только одна.