#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. я использовал в своей программе только одну переменную, поэтому за раз использовалась только одна.