STM32 带双 CAN - 配置滤波器

STM32 with dual CAN - configure filters

提问人:brigadir 提问时间:10/1/2023 更新时间:10/5/2023 访问量:86

问:

尝试在具有 2 个 CAN 总线的STM32F105上设置过滤器时寻求解决奇怪问题的帮助 - 16 位列表模式下的过滤器仅适用于前 2 个 bank。但同样的配置适用于具有单个CAN总线的STM32F103。

代码如下:

bool CanSetFilter(CAN_HandleTypeDef *can, uint8_t bank, uint16_t id1, uint16_t id2, uint16_t id3, uint16_t id4) {
  return CanSetFilterList16bit(can, bank, (uint32_t(id1)<<21) | (uint32_t(id2)<<5), (uint32_t(id3)<<21) | (uint32_t(id4)<<5), CAN_FILTERMODE_IDLIST, CAN_FILTERSCALE_16BIT, CAN_FILTER_FIFO0);
}

bool CanSetFilterList16bit(CAN_HandleTypeDef *can, uint8_t bank_num, uint32_t filter_id, uint32_t mask, uint32_t filter_mode, uint32_t filter_scale, uint32_t fifo) {
  CAN_FilterTypeDef sFilterConfig;
  sFilterConfig.FilterBank = bank_num;
  sFilterConfig.FilterMode = filter_mode;
  sFilterConfig.FilterScale = filter_scale;
  sFilterConfig.FilterFIFOAssignment = fifo;
  sFilterConfig.FilterActivation = ENABLE;
  sFilterConfig.FilterIdHigh = filter_id&0xFFFF;
  sFilterConfig.FilterIdLow = filter_id>>16;
  sFilterConfig.FilterMaskIdHigh = mask&0xFFFF;
  sFilterConfig.FilterMaskIdLow = mask>>16;
  bool result = (HAL_CAN_ConfigFilter(can, &sFilterConfig ) == HAL_OK);
  return result;
}

// and apply filters:
uint16_t canFilterIds[] = {
    0x076, 0x077, 0x07D, 0x167, 
    0x171, 0x204, 0x213, 0x217, 
    0x230, 0x3B3, 0x42F, 0x43E, // < this goes to bank 3 and doesn't work in result
};

const int canFiltersCount = sizeof(canFilterIds) / sizeof(canFilterIds[0]);
int filter = 0;
for (int i=0; (i<canFiltersCount) && (filter<28); filter++) {
    uint32_t f1 = (i<canFiltersCount) ? canFilterIds[i++] : canFilterIds[i];
    uint32_t f2 = (i<canFiltersCount) ? canFilterIds[i++] : canFilterIds[i];
    uint32_t f3 = (i<canFiltersCount) ? canFilterIds[i++] : canFilterIds[i];
    uint32_t f4 = (i<canFiltersCount) ? canFilterIds[i++] : canFilterIds[i];
    CanSetFilter(&hcan1, filter, f1, f2, f3, f4);
}

我看到在调试模式下,所有三个调用都成功了。以下是相应的结果:CanSetFilter(...)CAN_FilterTypeDefenter image description here

enter image description here

enter image description here

我不知道问题出在哪里,所以如果有人有工作的例子或遇到过这个问题,请期待。

滤波器 STM32 CAN总线 HAL

评论

0赞 Lundin 10/2/2023
由于这显然是 C++,如果库是针对 C 的,可能会出现各种意外的打嗝。强烈建议使用 C,这是一种选择吗?
0赞 brigadir 10/3/2023
在这种情况下,我依赖 HAL。在调试时,我看到所有值都按预期传递给 HAL。应该是低层的东西,STM32F105与 F103 不同
0赞 Lundin 10/3/2023
C++ 无法处理硬件寄存器,如果它们按照通常的做法设计,使用联合类型双关语。因此,如果您的代码使用硬件寄存器映射,则不应使用 C++。没有指定访问寄存器时会发生什么。

答:

0赞 brigadir 10/5/2023 #1

好的,问题出在CAN 2的过滤器初始化上。应该禁用我设置的过滤器。它会导致不正确的行为。当我把它改成它时,效果很好。 这是 CAN2 总线的过滤器初始化代码,它禁用了对其的过滤,但保持过滤器为 CAN1 工作,也许对某人有所帮助。sFilterConfig.FilterBank = 27;sFilterConfig.FilterBank = 0;

CAN_FilterTypeDef sFilterConfig;
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterActivation = CAN_FILTER_DISABLE;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO1;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 28;
HAL_result = HAL_CAN_ConfigFilter(&hcan2, &sFilterConfig);

受到此处讨论的启发:https://community.st.com/t5/stm32-mcus-products/how-to-configure-can-filters-to-use-can1-and-can2-parallelly/td-p/56553