【ESP32 Arduino】【CAN通信】使用【ESP32CAN库】,对于CAN的消息进行滤波的程序

本文详细介绍了ESP32CAN模块的滤波逻辑,并提供了示例代码进行说明。作者通过研究SJA1000数据手册和应用笔记,理解了CAN滤波器的工作原理,并设置了单模式滤波器,明确了验收代码和验收屏蔽寄存器的配置方法,以过滤特定ID的消息。在初始化CAN模块后,程序能够接收并打印符合滤波条件的CAN帧信息。

ESP32CAN的Examples对于esp32can_filter的程序注释非常少,非常的不明确,所以我广泛查找了各种资料,包括ESP IDF的和ST32的,终于搞懂了它的滤波逻辑,这里贴出我的程序,里面有详细的注释说明它的滤波逻辑

#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif

#include <ESP32CAN.h>
#include <CAN_config.h>
#include <Arduino.h>
#include <HuskyCANBoard2.h>

CAN_device_t CAN_cfg;               // CAN Config
const int rx_queue_size = 10;       // Receive Queue size

void setup() {
    Serial.begin(115200);
    Serial.println("Filter Demo - ESP32-Arduino-CAN");
    CAN_cfg.speed = CAN_SPEED_1000KBPS;//注意这里的通信速率,挂载在一条总线上的所有的设备必须一致,我开始一致没调出来就是因为这里设置错误了
    CAN_cfg.tx_pin_id = CAN_TX;
    CAN_cfg.rx_pin_id = CAN_RX;
    CAN_cfg.rx_queue = xQueueCreate(rx_queue_size, sizeof(CAN_frame_t));

    // Set CAN Filter
    // See in the SJA1000 Datasheet chapter "6.4.15 Acceptance filter"
    // and the APPLICATION NOTE AN97076 chapter "4.1.2 Acceptance Filter"
    // for PeliCAN Mode
    CAN_filter_t p_filter;//创建一个滤波器对象
    p_filter.FM = Single_Mode;//设置单滤波模式

    p_filter.ACR0 = 0x00;//验收代码寄存器 这个代表你想要过滤出的ID号
    p_filter.ACR1 = 0x20;//因为标准帧ID号的长度为11位,而这里的16进制有16位,所以你想要过滤出的ID号的值必须左移5位才是
    p_filter.ACR2 = 0x00;//16位的两个16进制数,以这里为例,我想要过滤出的ID号为1,所以1左移5位的10进制数为32,也就是0x20,所以这
    p_filter.ACR3 = 0x00;//里的ACR0为0x00,ACR1为0x20,再举个例子,比如我想过滤出ID号为1000的消息,则1000左移5位为的
    //10进制数3200016进制数为0x7D00,所以这里的ACR0为0x7D ACR1为0x00,

    p_filter.AMR0 = 0x00;//验收屏蔽寄存器 这里的 1 代表可以与上面规定的不同的位,0 代表必须严格相同的位
    p_filter.AMR1 = 0x0F;//这里我想严格的过滤出ID号为1的消息,所以这里的AMR0为0x00,代表前8位必须完全相同,
    p_filter.AMR2 = 0xFF;//AMR1为0x0F代表高4位必须完全相同,后四位无所谓,而AMR2和AMR3都为0xFF则表示后面的都可以不一样,也可以一样,不做要求
    p_filter.AMR3 = 0xFF;
    ESP32Can.CANConfigFilter(&p_filter);

    // Init CAN Module
    ESP32Can.CANInit();
}

void loop() {

    CAN_frame_t rx_frame;

    unsigned long currentMillis = millis();

    // Receive next CAN frame from queue
    if (xQueueReceive(CAN_cfg.rx_queue, &rx_frame, 3 * portTICK_PERIOD_MS) == pdTRUE) {

        if (rx_frame.FIR.B.FF == CAN_frame_std) {
            printf("New standard frame");
        } else {
            printf("New extended frame");
        }

        if (rx_frame.FIR.B.RTR == CAN_RTR) {
            printf(" RTR from 0x%08X, DLC %d\r\n", rx_frame.MsgID, rx_frame.FIR.B.DLC);
        } else {
            printf(" from 0x%08X, DLC %d, Data ", rx_frame.MsgID, rx_frame.FIR.B.DLC);
            for (int i = 0; i < rx_frame.FIR.B.DLC; i++) {
                printf("0x%02X ", rx_frame.data.u8[i]);
            }
            printf("\n");
        }
    }
}


评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Black__Jacket

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值