Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум разработчиков электроники ELECTRONIX.ru _ ARM, 32bit _ STM32 CAN фильтр.

Автор: Jenya7 Dec 27 2017, 10:35

Решил использовать CAN в проекте. Так то все понятно но фильтрация приходящих сообщений вызывает затруднения.
Если я хочу получать RxMessage.StdId = 0x100 - 0x1FF - какой фильтр мне нужно применить?

Автор: novikovfb Dec 27 2017, 10:48

Цитата(Jenya7 @ Dec 27 2017, 14:35) *
Решил использовать CAN в проекте. Так то все понятно но фильтрация приходящих сообщений вызывает затруднения.
Если я хочу получать RxMessage.StdId = 0x100 - 0x1FF - какой фильтр мне нужно применить?

фильтр 0x100, маска 0x700. Маска указывает, какие биты проверять, фильтр - чему они должны быть равны.

Автор: Jenya7 Dec 27 2017, 11:40

Цитата(novikovfb @ Dec 27 2017, 15:48) *
фильтр 0x100, маска 0x700. Маска указывает, какие биты проверять, фильтр - чему они должны быть равны.

то есть все что в фильтре нули то пропускается и то что в маске единицы то тоже пропускается?
а для стандартного ИД мне достаточно лоу? хай не трогать?
Код
  //CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
  CAN_FilterInitStructure.CAN_FilterIdLow = 0x0100;
  //CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0700;


а. я понял.
MASK = 0 and ID =0 - бит проходит
MASK = 1 and ID =0 - бит блокируется

получается должно быть так
Код
  //CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
  CAN_FilterInitStructure.CAN_FilterIdLow = 0x01FF;
  //CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFE00;



нет. вот так.
Код
  //CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
  CAN_FilterInitStructure.CAN_FilterIdLow = 0x0100;
  //CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFEFF;

Автор: novikovfb Dec 27 2017, 11:50

Цитата(Jenya7 @ Dec 27 2017, 15:40) *
то есть все что в фильтре нули то пропускается и то что в маске единицы то тоже пропускается?
а для стандартного ИД мне достаточно лоу? хай не трогать?
...
нет. вот так.
Код
  //CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
  CAN_FilterInitStructure.CAN_FilterIdLow = 0x0100;
  //CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFEFF;

Что в маске единицы - в фильтре и сообщении должно совпасть. Что в маске нули - в сообщении может быть любым.
Вышеприведенный фильтр, если и будет работать (некоторые контроллеры требуют 0 в фильтре там, где в маске 0), то будет брать только сообщения 0x000 и 0x100, потому как маска требует совпадения всех битов кроме 0x100.

Автор: Jenya7 Dec 27 2017, 11:56

Цитата(novikovfb @ Dec 27 2017, 17:50) *
Что в маске единицы - в фильтре и сообщении должно совпасть. Что в маске нули - в сообщении может быть любым.
Вышеприведенный фильтр, если и будет работать (некоторые контроллеры требуют 0 в фильтре там, где в маске 0), то будет брать только сообщения 0x000 и 0x100, потому как маска требует совпадения всех битов кроме 0x100.

нашел такой пример
Цитата
Example 2. we wish to accept only frames with IDs of 00001560 to 0000156F

set filter to 00001560

set mask to 1FFFFFF0

то есть по анологии получается так?
Код
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
  CAN_FilterInitStructure.CAN_FilterIdLow = 0x0100;
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x1FFF;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFF00;

Автор: Jenya7 Sep 28 2018, 07:36

Цитата(novikovfb @ Dec 27 2017, 17:50) *
Что в маске единицы - в фильтре и сообщении должно совпасть. Что в маске нули - в сообщении может быть любым.
Вышеприведенный фильтр, если и будет работать (некоторые контроллеры требуют 0 в фильтре там, где в маске 0), то будет брать только сообщения 0x000 и 0x100, потому как маска требует совпадения всех битов кроме 0x100.


настроил
Код
CAN_FilterInitStructure.CAN_FilterNumber = 0;
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
    CAN_FilterInitStructure.CAN_FilterIdLow = 0x0064;    
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x00FF;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);
мастер посылает
Код
TxMessage.ExtId = (opcode << 8) | 0х64;
однако слейв не принимает. без маски и фильтра принимает.


Автор: yes Sep 28 2018, 10:40

запрограммировано на фильтрацию 28-битных ID (то есть extended ID)
попробуйте попередавать для начала extID с таким ID с мастера

затем смотреть в сторону
CAN_FILTERSCALE_16BIT

там по-моему сразу два фильтра надо программировать - уже не помню

Автор: Jenya7 Sep 28 2018, 11:04

Цитата(yes @ Sep 28 2018, 16:40) *
запрограммировано на фильтрацию 28-битных ID (то есть extended ID)
попробуйте попередавать для начала extID с таким ID с мастера

затем смотреть в сторону
CAN_FILTERSCALE_16BIT

там по-моему сразу два фильтра надо программировать - уже не помню


так у меня и есть extended ID. я передаю 0х64 и это ID у меня определено на слейве а 0хFF - только его сравнивать, остальные биты don't care.

Автор: yes Sep 28 2018, 13:12

> Если я хочу получать RxMessage.StdId = 0x100 - 0x1FF

> и есть extended ID
?

с фильтрами никаких проблем не было - должно работать
для порядка, можно пройтись циклом по всем и запретить - так во всех экзамплах делают, по-моему

upd: в некоторых камнях есть два контроллера CAN - мастер и слейв, чтобы фильтры в слейве работали, мастер тоже нужно включить (я с этим не сталкивался, но где-то видел)

Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)