Перейти к содержанию
    

Адресация и фильтрация CAN сообщений на STM32F4

Добрый день!

 

У меня CAN-шиной соединены 4 устройства STM32F4. Каждое из них подсоединено к компьютеру по USART для возможности вывода на экран входящих и исходящих сообщений. При отправке данных от одного устройства к конкретному другому, сообщение всё равно отображают все 4 устройства. Объясните, пожалуйста, каким образом правильно настроить адресацию и фильтрацию сообщений на STM32F4.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если не ошибаюсь, то в стандарте Can нет такого понятия, как адрес устройства. Есть понятие - идентификатор посылки.

В системе, где несколько устройств, и каждое из устройств может отправить посылку любому другому, целесообразно, чтобы в идентификаторе содержалась след информация:

Идентификатор получателя, идентификатор отправителя, тип посылки.

Соответственно фильтры настраиваются на идентификаторы посылок.

Например так:

// --------------------------------------------	// Настройки модуля фильтрации
setmask(CAN1->FMR, CAN_FMR_FINIT);			// To Initialization mode for the filter
// --------------------------------------------	// Настройки банка 0
clrmask(CAN1->FA1R, CAN_FA1R_FACT0);		// Deactivation
clrmask(CAN1->FM1R, CAN_FM1R_FBM0);			// Mask mode
clrmask(CAN1->FS1R, CAN_FS1R_FSC0);			// 16-bit scale
clrmask(CAN1->FFA1R, CAN_FFA1R_FFA0);		// Assign to FIFO 0
CAN1->sFilterRegister[0].FR1 = ((int32u)0x1FF8 << 16) + ((int32u)Dev2_to_Dev1 << 5);
CAN1->sFilterRegister[0].FR2 = ((int32u)0x1FF8 << 16) + ((int32u)Dev3_to_Dev1 << 5);
setmask(CAN1->FA1R, CAN_FA1R_FACT0);		// Activation

clrmask(CAN1->FMR, CAN_FMR_FINIT);			// From Initialization mode for the filter

Вроде бы работало, детали уже увы не помню, надо заглядывать в документацию.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

.

 

 

Хорошо. Я вас понял.

 

Главный вопрос в инициализации у меня относительно строк CAN_FilterIdHigh, CAN_FilterIdLow, CAN_FilterMaskIdHigh, CAN_FilterMaskIdLow. Я не очень понимаю, что конкретно в них писать. В них нужно писать диапазон Id? Если да, то зачем нужны какие-то скобки?

 

 

  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 = 0x0000;

  CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;

  CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
  CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
  CAN_FilterInit(&CAN_FilterInitStructure);

Изменено пользователем IgorKossak
бездумное цитирование, [codebox] для длинного кода, [code] - для короткого!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Главный вопрос в инициализации у меня относительно строк CAN_FilterIdHigh, CAN_FilterIdLow, CAN_FilterMaskIdHigh, CAN_FilterMaskIdLow.

Термины, которые Вы используете, видимо из кода HAL от CMSIS или CubeM. Тут я Вам не советчик. Единственное, что могу добавить, фильтр можно настроить на полное совпадение с конкретным идентификатором, так и установить маску, когда под один фильтр может попадать целая группа идентификаторов.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не скажу конкретно про ваш STM, но в CAN-модуле с которым я работал для фильтрации сообщений было правило

если ((CAN_ID & FILTR_MASK) == FILTR_ID) сообщение принимается, иначе игнорируется.

Поэтому UserManual в руки и читать мат.часть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хорошо. Я вас понял.

 

Главный вопрос в инициализации у меня относительно строк CAN_FilterIdHigh, CAN_FilterIdLow, CAN_FilterMaskIdHigh, CAN_FilterMaskIdLow. Я не очень понимаю, что конкретно в них писать. В них нужно писать диапазон Id? Если да, то зачем нужны какие-то скобки?

 

Вы начните с чтения мануала на процессор. Там довольно подробно расписана фильтрация, какие режимы есть и что надо писать в регистры. Дальше если вы хотите использовать Cube / HAL, то уже смотрите, что их функции пишут в эти регистры и таким образом понимаете, что вам надо в них передавать

 

Я честно говоря с HAL еще не сталкивался, но из опыта работы с CMSIS - его дока очень слабая, без мануала на проц не обойтись. Может быть в HAL это поправили.

 

И опять же из опыта работы с CMSIS - для CAN от него толку ноль. Он слишком уж тонкая обертка над железом и вообще нет никаких плюшек по сравнению с прямой работой с регистрами CAN-модуля процессора.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поэтому UserManual в руки и читать мат.часть.

Тем более что там пять строчек кода.

Вам надо тупо настроить 1 раз регистры (зачем вызывать для этого какие-то левые п/п, один бог знает) и всё. Далее вы просто обрабатываете сообщения поступающие в ваш ящик в прерывании.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тем более что там пять строчек кода.

Вам надо тупо настроить 1 раз регистры (зачем вызывать для этого какие-то левые п/п, один бог знает) и всё. Далее вы просто обрабатываете сообщения поступающие в ваш ящик в прерывании.

 

Как настроить регистры, более или менее понятно. Я бы задал вопрос под другим углом: Каким образом сделать так, что бы каждый из нескольких идентичных каналов, с процессором прошитым одинаковой прошивкой определил для себя заданный диапазон идентификаторов, несовпадающий с другими каналами (топология один мастер - четыре слейва. Ранее это делалось на SPI и оно естественным образом рулилось сигналами NSS но захотелось лишнего геморроя - решил попробовать CAN... ) Вводить в схему перемычки или дип переключатели категорически не хочется, иметь различную версию прошивки для каждого канала - тем более...

Изменено пользователем nanorobot

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ранее это делалось на SPI и оно естественным образом рулилось сигналами NSS но захотелось лишнего геморроя - решил попробовать CAN... ) Вводить в схему перемычки или дип переключатели категорически не хочется, иметь различную версию прошивки для каждого канала - тем более...

Ну если Вы раньше каким-то образом определяли кто будет мастером на SPI, то в чём проблема так же назначить мастера и теперь?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну если Вы раньше каким-то образом определяли кто будет мастером на SPI, то в чём проблема так же назначить мастера и теперь?

Проблема не в том, кого назначить мастером. Проблема в том чтоб каждый из четырех слейвов имел уникальный диапазон идентификаторов. Все слейвы изначально неотличимы один от другого. То есть требуется некая процедура инициализации - назначение каждому слейву своего диапазона идентификаторов. Ничего изящного в голову не приходит.

Изменено пользователем nanorobot

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А мастер почему простаивает, пусть он распределит. Не?

Все слейвы изначально неотличимы один от другого. На любое сообщение от мастера либо все среагируют одинаково, либо все проигнорируют, в зависимости от изначально установленных фильтров. Как в такой ситуации мастер что либо может распределить?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все слейвы изначально неотличимы один от другого. На любое сообщение от мастера либо все среагируют одинаково, либо все проигнорируют, в зависимости от изначально установленных фильтров. Как в такой ситуации мастер что либо может распределить?

О, это в чём-то похоже на IrLAP (IrDA): мастер выдаёт запрос и ведомые, услышавшие и не заригистрированные, во временных слотах, естественно с коллизиями, откликаются; ну и потом, естественно разрешение коллизий.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все слейвы изначально неотличимы один от другого. На любое сообщение от мастера либо все среагируют одинаково, либо все проигнорируют, в зависимости от изначально установленных фильтров. Как в такой ситуации мастер что либо может распределить?

Естественно - не реагировать одинаково. Назначить каждому слэйву уникальный ID. На этапе производства (сер.номер) или динамически после вкл. Ну или использовать уникальный номер уже имеющийся в МК или каком-либо чипе схемы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ранее это делалось на SPI и оно естественным образом рулилось сигналами NSS но захотелось лишнего геморроя - решил попробовать CAN... )

 

Линии NSS от мастера остались в системе? Если да, то кто мешает по их состоянию в программе задавать шаблон идентификаторов. Ногодрыг мастером GPIO NSS и вот каждый Слейв знает свой шаблон, анализируя свою GPIO NSS.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...