STM8A CAN-фильтрация в стандартной периферийной библиотеке - PullRequest
0 голосов
/ 19 февраля 2020

Я работаю с STM8AF5286UDY и пытаюсь настроить интерфейс CAN. Для программирования я использую стандартную периферийную библиотеку. На данный момент мой интерфейс CAN работает нормально. Единственное, что не работает, это фильтрация.

Я использую расширенные идентификаторы и хочу получить все идентификаторы от 0x18FEC100 до 0x18FEC999. Мой код выглядит следующим образом:

/* CAN filter init */

 CAN_FilterNumber = CAN_FilterNumber_0;

 CAN_FilterActivation = ENABLE;

 CAN_FilterMode = CAN_FilterMode_IdMask;

 CAN_FilterScale = CAN_FilterScale_32Bit;

 CAN_FilterID1=0x18FEC101;

 CAN_FilterID2=0;

 CAN_FilterID3=0;

 CAN_FilterID4=0;

 CAN_FilterIDMask1=0x1FFFF000;

 CAN_FilterIDMask2=0;

 CAN_FilterIDMask3=0;

 CAN_FilterIDMask4=0;  

 CAN_FilterInit(CAN_FilterNumber, CAN_FilterActivation, CAN_FilterMode, 
         CAN_FilterScale,CAN_FilterID1, CAN_FilterID2, CAN_FilterID3,
         CAN_FilterID4,CAN_FilterIDMask1, CAN_FilterIDMask2, 
         CAN_FilterIDMask3, CAN_FilterIDMask4);

Буду признателен за любую помощь! Спасибо!

РЕДАКТИРОВАТЬ: В моем исходном коде я забыл включить IDE и RTR при адресации. Также в библиотеке каждый адрес и маска является 8-битным значением. Поэтому я изменил свой код следующим образом:

/* CAN filter init */
  CAN_FilterNumber = CAN_FilterNumber_2;
  CAN_FilterActivation = ENABLE;
  CAN_FilterMode = CAN_FilterMode_IdMask; 
  CAN_FilterScale = CAN_FilterScale_32Bit; 
  CAN_FilterID1=0xc7;  
  CAN_FilterID2=0xed;
  CAN_FilterID3=0x02;
  CAN_FilterID4=0x02;
  CAN_FilterIDMask1=0xFF; 
  CAN_FilterIDMask2=0xE7; 
  CAN_FilterIDMask3=0xE0;
  CAN_FilterIDMask4=0x00; 
  CAN_FilterInit(CAN_FilterNumber, CAN_FilterActivation, CAN_FilterMode, 
                 CAN_FilterScale,CAN_FilterID1, CAN_FilterID2, CAN_FilterID3,
                 CAN_FilterID4,CAN_FilterIDMask1, CAN_FilterIDMask2, 
                 CAN_FilterIDMask3, CAN_FilterIDMask4);

Этот фильтр работает для первых 16-разрядных, поэтому при использовании 0x18FEC101 он фильтрует 0x18FE. Каким-то образом это не работает для других 16-разрядных.

В библиотеке следующий код используется для записи адресов и масок в банке фильтров на 32-разрядных:

else if (CAN_FilterScale == CAN_FilterScale_32Bit)
    {
      CAN->Page.Filter.FR01 = CAN_FilterID1;
      CAN->Page.Filter.FR02 = CAN_FilterID2;
      CAN->Page.Filter.FR03 = CAN_FilterID3;
      CAN->Page.Filter.FR04 = CAN_FilterID4;
      CAN->Page.Filter.FR05 = CAN_FilterIDMask1;
      CAN->Page.Filter.FR06 = CAN_FilterIDMask2;
      CAN->Page.Filter.FR07 = CAN_FilterIDMask3;
      CAN->Page.Filter.FR08 = CAN_FilterIDMask4;
    }

Есть какие-нибудь идеи, в чем может быть моя ошибка? Спасибо!

Ответы [ 2 ]

0 голосов
/ 20 февраля 2020

Код, который я разместил (отредактированная версия), работает сейчас. Оказывается, у меня была проблема с вычислением адресов вручную.

Спасибо @ Тагли.

0 голосов
/ 19 февраля 2020

Маска фильтрации работает побитно. Таким образом, вы не можете создать фильтр для приема значений в диапазоне от 0x18FEC100 до 0x18FEC999. Вам нужно думать двоично.

В регистрах маски фильтра 1 означает «должен совпадать», а 0 означает «не важно».

ID = 0x18FEC101 и Mask = 0x1FFFF000 означает, что он будет принимать значения в диапазоне от 0x18FEC000 - 0x18FECFFF, так как фильтр не будет заботиться о младших 12 битах.

Однако , процесс еще больше усложняется расположением битов аппаратных регистров. Имейте в виду, что биты RTR & IDE также включены в регистры фильтра. Я не знаю, справится ли стандартная периферийная библиотека с этим, но, вероятно, нет. Возможно, вам нужно вручную расположить биты, чтобы определить правильные значения регистра. В справочном руководстве ( RM0016 ) см. Рисунок 148 .

...