tolstiybh 0 17 февраля, 2017 Опубликовано 17 февраля, 2017 · Жалоба Народ всем привет. Использую STM32F091. Необходимо фильтровать CAN сообщения на аппаратном уровне, чтобы успешно приходили CAN сообщения определенного ID, например, 0x434, 0x3b3, 0x171, 0x42f, 0x041. Как это сделать? Пробовал различные варианты по инициализации CAN_FilterIdHigh, CAN_FilterIdLow, CAN_FilterMaskIdHigh, CAN_FilterMaskIdLow, но все равно пропускается большой поток ненужных сообщений. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DmitryG 0 18 февраля, 2017 Опубликовано 18 февраля, 2017 (изменено) · Жалоба Народ всем привет. Использую 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; Изменено 18 февраля, 2017 пользователем DmitryG Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tolstiybh 0 18 февраля, 2017 Опубликовано 18 февраля, 2017 · Жалоба Как Вы указали в приведенном примере, я уже делал, но пропуски ненужных сообщений все равно были. И так на 0 фильтр 4 идентификатора и и на 1 фильтр 4 идентификатора. Толку никакого. Может нужно что-то дополнительно прописывать, чтобы проходили только нужные сообщения? Мне нужно только 10 сообщений, т.е. 3 фильтра. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pvo125 0 19 февраля, 2017 Опубликовано 19 февраля, 2017 · Жалоба Выбираете 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tolstiybh 0 20 февраля, 2017 Опубликовано 20 февраля, 2017 · Жалоба Всем привет. Вот я так делаю: 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 0 20 февраля, 2017 Опубликовано 20 февраля, 2017 (изменено) · Жалоба 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 в режиме списка идентификаторов. Изменено 20 февраля, 2017 пользователем pvo125 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tolstiybh 0 20 февраля, 2017 Опубликовано 20 февраля, 2017 · Жалоба Все заработало. Спасибо. Использую вариант с IDlist, а не mask. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться