Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F091 CAN filters init
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
max_mart
Народ всем привет.

Использую STM32F091. Необходимо фильтровать CAN сообщения на аппаратном уровне, чтобы успешно приходили CAN сообщения определенного ID, например, 0x434, 0x3b3, 0x171, 0x42f, 0x041.

Как это сделать?

Пробовал различные варианты по инициализации CAN_FilterIdHigh, CAN_FilterIdLow, CAN_FilterMaskIdHigh, CAN_FilterMaskIdLow, но все равно пропускается большой поток ненужных сообщений.
DmitryG
Цитата(max_mart @ Feb 17 2017, 20:39) *
Народ всем привет.

Использую STM32F091. Необходимо фильтровать CAN сообщения на аппаратном уровне, чтобы успешно приходили CAN сообщения определенного ID, например, 0x434, 0x3b3, 0x171, 0x42f, 0x041.

Как это сделать?

Пробовал различные варианты по инициализации CAN_FilterIdHigh, CAN_FilterIdLow, CAN_FilterMaskIdHigh, CAN_FilterMaskIdLow, но все равно пропускается большой поток ненужных сообщений.


На STM32F4 у меня пропускает сообщения от устройств с айдишниками от 100 до 199.

CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;

CAN_FilterInitStructure.CAN_FilterIdHigh = 0x100 << 5;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x199 << 5;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x700 << 5;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0;
max_mart
Как Вы указали в приведенном примере, я уже делал, но пропуски ненужных сообщений все равно были. И так на 0 фильтр 4 идентификатора и и на 1 фильтр 4 идентификатора. Толку никакого.
Может нужно что-то дополнительно прописывать, чтобы проходили только нужные сообщения?

Мне нужно только 10 сообщений, т.е. 3 фильтра.
pvo125
Выбираете 11 битный идентификатор. Далее в режиме ID List чтоб только полное совпадение ID пропускалось фильтром. Далее 16 битный режим фильтров. Получится на один банк например первый настроить 4 фильтра ( для сообщений 0x434 0x3b3 0x171 0x42f) для пятого ID нужно будет задействовать второй банк. Далее пример с записью в регистры CAN. Если на SPL будете делать все равно отладчиком надо сравнить значения самих фильтров со значением ниже. Как мапятся показано ниже
STDID[10:3] STDID[2:0] RTR IDE EXID[17:15]
Код
CAN1->FM1R |= CAN_FM1R_FBM1;           //Filters bank 1  mode ID List
CAN1->FS1R&=~CAN_FS1R_FSC1          // Filters bank 1  scale 16 bits    
CAN1->FFA1R|=CAN_FFA1R_FFA1;         // Filters bank 1   FIFO1        

    4        3         4        RTR    IDE    EXTID
1 0 0 | 0 0 1 1 | 0 1 0 0 |   0   |   0   |   000     
1 0 0  0 | 01 1   0|1 0 0     0|       0      000        =       0x 8680                
    
    3            b       3        RTR   IDE   EXTID
0 1 1 |1  0 1 1 | 0  0 1 1 |   0  |   0   |  000    
0 1 1  1| 0 1 1   0 |0 1 1     0  |   0       000       =          0x7660          

CAN1->sFilterRegister[1].FR1=0x76608680; //Filters bank 1 fmi=00 ID=0x434 IDE=0 RTR=0   data_frame ( 11 bit ID  )
                                             //Filters bank 1 fmi=01 ID=0x3b3 IDE=0 RTR=0     data_frame
   1            7         1       RTR     IDE     EXTID
0 0 1| 0  1 1 1 | 0  0  0 1 |   0   |   0   | 000     
0 0 1  0 |1 1 1   0 |0  0 1      0  |   0      000            =       0x 2E20

    4             2        f      RTR    IDE   EXTID
1 0 0| 0  0 1 0 | 1  1 1 1 |   0  |   0   |  000    
1 0 0  0 |0 1 0   1| 1 1 1      0 |   0       000      =    0x85E0


CAN1->sFilterRegister[1].FR2=0x85E0 2E20;    //Filters bank 1 fmi=02 ID=0x171 IDE=0 RTR=0    data_frame
                                                    //Filters bank 1 fmi=03 ID=0x42f  IDE=0 RTR=0   data_frame

max_mart
Всем привет. Вот я так делаю:
CODE
void setup_can_filter(void)
{
CAN_FilterInitTypeDef CAN_FilterInitStructure;
/* CAN filter init 0*/
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = (0x332<<5);//|(1<<4);
CAN_FilterInitStructure.CAN_FilterIdLow = (0x331<<5);//|(0<<4);
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = (0x3B3<<5);//|(1<<4);
CAN_FilterInitStructure.CAN_FilterMaskIdLow = (0x430<<5);//|(0<<4);
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
/* CAN filter init 1*/
CAN_FilterInitStructure.CAN_FilterNumber = 1;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = (0x171<<5);//|(1<<4);
CAN_FilterInitStructure.CAN_FilterIdLow = (0x0415<<5);//|(0<<4);
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = (0x0434<<5);//|(1<<4);
CAN_FilterInitStructure.CAN_FilterMaskIdLow = (0x042F<<5);//|(0<<4);
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
}

void setup_can(CAN_InitTypeDef *can, int baud)
{
CAN_StructInit(can);

CAN_DeInit(CAN);

CAN_StructInit(can);
/* CAN cell init */
can->CAN_TTCM = DISABLE;
can->CAN_ABOM = ENABLE;
can->CAN_AWUM = DISABLE;
can->CAN_NART = DISABLE; /* orig: DISABLE Transmit only once */
can->CAN_RFLM = DISABLE;
can->CAN_TXFP = DISABLE;
can->CAN_Mode = CAN_Mode_Normal;
can->CAN_SJW = CAN_SJW_1tq;
can->CAN_BS1 = CAN_BS1_13tq;
can->CAN_BS2 = CAN_BS2_2tq;

switch(baud)
{
case 1000000:
can->CAN_Prescaler = 3;
break;

case 500000:
/* CAN Baudrate = 100KBps (tested OK on real car) */
// на самом деле не 100К, а 500К (копипастеры ...)
can->CAN_Prescaler = 6;
break;

case 250000:
/* CAN Baudrate = 250KBps */
can->CAN_Prescaler = 12;
break;

case 125000:
/* CAN Baudrate = 125KBps */
can->CAN_Prescaler = 24;
break;

case 100000:
/* CAN Baudrate = 100KBps (tested OK on real car) */
can->CAN_Prescaler = 30;
break;

case 50000:
/* CAN Baudrate = 50KBps */
can->CAN_Prescaler = 60;
break;
}
setup_can_filter();
CAN_Init(CAN, can);
CAN_ITConfig(CAN, CAN_IT_FMP0, ENABLE);
}


Все равно не работает. НЕ нужные сообщения проходят. Что может быть не так?
pvo125
Цитата
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;

Не знаю в какой режим Вы пытаетесь настроить фильтры но строчка выше говорит что в режиме Id Mask. Т е пропускать все сообщения если они по маске проходят а нужно в режиме списка идентификаторов ID List.В SPL есть такой параметр CAN_FilterMode_IdList
может быть надо так писать
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdList;
Не уверен на SPL инициализацию не делал. Главное отладчиком посмотрите чтобы в регистре CAN1_FB1M были установлены биты FBM0 FBM1 которые и показывают что банки 0 и 1 в режиме списка идентификаторов.
max_mart
Все заработало. Спасибо. Использую вариант с IDlist, а не mask.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.