esp32-C3 CAN接口使用

news/2024/5/17 16:42:52/文章来源:https://blog.csdn.net/ai_ljh/article/details/126860984

esp32-C3 CAN接口使用

  • 功能概述
  • CAN协议关注点
  • 接收过滤器
    • 单过滤器模式
    • 双过滤器模式
  • 关键函数说明
    • 配置和安装驱动
    • 获取TWAI状态信息
    • 发送/接收消息
  • 使用示例
    • CAN控制器自回环测试
    • CAN收发带过滤测试

功能概述

ESP32-C3具有1个CAN控制器支持以下特性:

  • 兼容ISO 11898-1协议(CAN2.0)
  • 支持标准帧(11bit ID)和扩展帧(29bit ID)格式
  • Bit速率从1Kbit/s-1Mbit/s
  • 工作模式:
    • 正常模式
    • 只听模式(不影响总线)
    • 无响应模式(传输期间无需ACK,可方便自检)
  • 64Byte大小的接收BUF
  • 支持接收单/双过滤
  • 支持错误处理

CAN协议关注点

数据帧或远程帧通过仲裁域抢占CAN总线,协议开始为11bit的ID号,其高位在前低位在后,0表示显性位,1表示隐性位,当多个设备同时发送消息时,ID中的显性位0会覆盖隐性位1,因此ID号越小的设备优先级约高,会优先抢占总线。
在这里插入图片描述
比如ID为3、2、1的设备优先级从高到底为:1(0001B)、2(0010B)、3(0011)。
SSR:一直为1(隐性)
RTR:0(显性)-数据帧 1(隐性)-远程帧
IDE:0(显性)-标准帧 1(隐性)-扩展帧
ACK:发送端输出1(隐性),接收端响应0(显性),发送端到响应0(显性),则发送表示成功。
参考文章:https://blog.csdn.net/qq_38880380/article/details/84573821 讲的更加详细。

接收过滤器

ESP32-c3接收过滤器如下图所示,配置包含1个验证代码寄存器和1个验证掩码寄存器,分别为32bit。
在这里插入图片描述
基本过滤原理是: 过滤出与验证代码相同的消息,但不关注验证掩码为1的消息bit位。
例如验证标准帧11位ID:
验证代码: 000 0001 1010
验证掩码: 000 0000 0011
最终过滤: 000 0000 10xx (ID最低2位掩码为1,不关注,只要ID其他位与验证代码相同即可接收)

单过滤器模式

单过滤器模式可过滤:

  • 标准帧的11位ID、RTR位、数据字节1和数据字节2
  • 或扩展帧的29位ID和RTR位
    在这里插入图片描述

双过滤器模式

双过滤器模式可过滤:

  • 标准帧的11位ID、RTR位、数据字节1(仅filter1)
  • 或扩展帧29位ID中的高16位
    在这里插入图片描述

关键函数说明

配置CONFIG_TWAI_ISR_IN_IRAM,并在安装TWAI驱动时设置标志TWAI_ALERT_AND_LOG ,可放置TWAI中断服务程序在内部RAM中。

配置和安装驱动

#include "driver/twai.h"//安装CAN驱动
esp_err_t twai_driver_install(const twai_general_config_t *g_config, //基本配置const twai_timing_config_t *t_config, //时序配置const twai_filter_config_t *f_config)//过滤器配置
//启动CAN驱动
esp_err_t twai_start(void)
//停用CAN驱动
esp_err_t twai_stop(void)
//卸载CAN驱动
esp_err_t twai_driver_uninstall(void)

结构体说明:

//CAN接口基本配置
twai_general_config_t g_config = {.mode = TWAI_MODE_NORMAL , //TWAI_MODE_NORMAL / TWAI_MODE_NO_ACK / TWAI_MODE_LISTEN_ONLY.tx_io = 2, //IO号.rx_io = 3, //IO号.clkout_io = TWAI_IO_UNUSED, //io号,不用为-1.bus_off_io = TWAI_IO_UNUSED,//io号,不用为-1.tx_queue_len = 5, //发送队列长度,0-禁用发送队列.rx_queue_len = 5,//接收队列长度.alerts_enabled = TWAI_ALERT_NONE,  //警告标志 TWAI_ALERT_ALL 可开启所有警告.clkout_divider = 0,//1 to 14 , 0-不用.intr_flags = ESP_INTR_FLAG_LEVEL1}//中断优先级//CAN接口时序配置官方提供了1K to 1Mbps的常用配置
twai_timing_config_t t_config = TWAI_TIMING_CONFIG_1MBITS(); //TWAI_TIMING_CONFIG_500KBITS()//过滤器配置
twai_filter_config_t f_config = {.acceptance_code = 0, //验证代码.acceptance_mask = 0xFFFFFFFF, //验证掩码 0xFFFFFFFF表示全部接收.single_filter = true}//true:单过滤器模式 false:双过滤器模式

获取TWAI状态信息

//获取twai状态
esp_err_t twai_get_status_info(twai_status_info_t *status_info)
//返回值:ESP_OK: 成功;ESP_ERR_INVALID_ARG: 参数无效;ESP_ERR_INVALID_STATE:驱动未安装//状态信息
twai_status_info_t status_info={.state=,//TWAI_STATE_STOPPED / TWAI_STATE_RUNNING / TWAI_STATE_BUS_OFF / TWAI_STATE_RECOVERING.msgs_to_tx=,//发送队列消息数       .msgs_to_rx=,//接收队列消息数    .tx_error_counter=, //发送错误计数.rx_error_counter=, //接收错误计数.tx_failed_count=,  //发送失败计数.rx_missed_count=,  //因接收队列满丢失的消息数.rx_overrun_count=, //因接收buf(64Byte)满而丢失的消息数.arb_lost_count=,   //仲裁失败计数.bus_error_count=};//总线错误计数

发送/接收消息

//发送消息到发送队列排队,如发送队列为空则立即发送,为满则等待ticks_to_wait时间
esp_err_t twai_transmit(const twai_message_t *message, //消息包TickType_t ticks_to_wait)//超时时间
/***********************************************
* 	返回值:
*	ESP_OK:发送成功
*	ESP_ERR_INVALID_ARG:参数无效
*	ESP_ERR_TIMEOUT:等待TX队列时超时
*	ESP_FAIL:TX队列已禁用,且当前正在传输另一条消息
*	ESP_ERR_INVALID_STATE:CAN驱动程序未运行或未安装
*	ESP_ERR_NOT_SUPPORTED:只听模式不支持发送
*************************************************///从接收队列接收1个消息,若队列为空,则阻塞
esp_err_t twai_receive(twai_message_t *message, //消息包TickType_t ticks_to_wait)//超时
/***********************************************
* 	返回值:
*	ESP_OK:接收成功
*	ESP_ERR_INVALID_ARG:参数无效
*	ESP_ERR_TIMEOUT:等待队列时超时
*	ESP_FAIL:TX队列已禁用,且当前正在传输另一条消息
*	ESP_ERR_INVALID_STATE:CAN驱动程序未运行或未安装
*	ESP_ERR_NOT_SUPPORTED:只听模式不支持发送
*************************************************///发送/接收消息帧结构
twai_message_t send_message1 = {.extd = 1,//0-标准帧; 1-扩展帧.rtr = 0,//0-数据帧; 1-远程帧.ss = 1, //0-错误重发; 1-单次发送(仲裁或丢失时消息不会被重发),对接收消息无效.self = 0,//0-不接收自己发送的消息,1-接收自己发送的消息,对接收消息无效.dlc_non_comp = 0,// 0-数据长度不大于8(ISO 11898-1); 1-数据长度大于8(非标);.identifier = ID0, //11/29位ID.data_length_code = 0, //DLC数据长度4bit位宽.data = {0, 0 , 0 , 0 ,0 ,0 ,0 ,0}};//发送数据,对远程帧无效

使用示例

CAN控制器自回环测试

硬件需将2-3脚回环或连接CAN接口转换芯片,程序运行10s,分别发送标准帧、远程帧、扩展帧,并接收打印帧内容。
需注意自回环测试需要配置:twai_general_config_t->mode = TWAI_MODE_NO_ACK;twai_message_t ->self = 1;

#include <stdio.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_err.h"
#include "esp_log.h"
#include "driver/twai.h"#define EXAMPLE_TAG "TWAI Self Test"
#define SENDMSG 0
#define RECEIVEMSG 1
/* --------------------------- Tasks and Functions -------------------------- */void printf_msg(int flag, twai_message_t *msg) // flag:0-send 1-receive
{int j;if (flag)printf("Receive: ");elseprintf("Send   : ");if (msg->extd)printf("Extended ");elseprintf("Standard ");if (msg->rtr)printf("Remote Frame, ");elseprintf("Data  Frame,  ");printf("ID: %d    ", msg->identifier);if (msg->rtr == 0){for (j = 0; j < msg->data_length_code; j++){printf("D%d: %d\t", j, msg->data[j]);}printf("\n");}elseprintf("\n");
}static void twai_transmit_task(void *arg)
{int i;twai_message_t s1 = {.extd = 0,                         // 0-标准帧; 1-扩展帧.rtr = 0,                          // 0-数据帧; 1-远程帧.ss = 1,                           // 0-错误重发; 1-单次发送(仲裁或丢失时消息不会被重发),对接收消息无效.self = 1,                         // 0-不接收自己发送的消息,1-接收自己发送的消息,对接收消息无效.dlc_non_comp = 0,                 // 0-数据长度不大于8(ISO 11898-1); 1-数据长度大于8(非标);.identifier = 60,                  // 11/29位ID.data_length_code = 4,             // DLC数据长度4bit位宽.data = {0, 0, 0, 0, 0, 0, 0, 0}}; //发送数据,对远程帧无效vTaskDelay(pdMS_TO_TICKS(1000));for (i = 0; i < 3; i++) //发送3个标准数据帧{s1.data[0] = i;ESP_ERROR_CHECK(twai_transmit(&s1, portMAX_DELAY));printf_msg(SENDMSG, &s1);}s1.rtr = 1;s1.data_length_code = 6;vTaskDelay(pdMS_TO_TICKS(1000));for (i = 0; i < 1; i++) //发送1个标准远程帧{ESP_ERROR_CHECK(twai_transmit(&s1, portMAX_DELAY));printf_msg(SENDMSG, &s1);}s1.extd = 1;s1.rtr = 0;s1.data_length_code = 5;vTaskDelay(pdMS_TO_TICKS(1000));for (i = 0; i < 3; i++) //发送3个扩展数据帧{s1.data[0] = i;ESP_ERROR_CHECK(twai_transmit(&s1, portMAX_DELAY));printf_msg(SENDMSG, &s1);}s1.rtr = 1;s1.data_length_code = 3;vTaskDelay(pdMS_TO_TICKS(1000));for (i = 0; i < 1; i++) //发送1个扩展远程帧{ESP_ERROR_CHECK(twai_transmit(&s1, portMAX_DELAY));printf_msg(SENDMSG, &s1);}vTaskDelete(NULL);
}static void twai_receive_task(void *arg)
{twai_message_t r1;for (int i = 0; i < 8; i++) //发送1个扩展远程帧{ESP_ERROR_CHECK(twai_receive(&r1, portMAX_DELAY));printf_msg(RECEIVEMSG, &r1);}vTaskDelete(NULL);
}void app_main(void)
{// CAN接口基本配置twai_general_config_t g_config = {.mode = TWAI_MODE_NO_ACK,            // TWAI_MODE_NORMAL / TWAI_MODE_NO_ACK / TWAI_MODE_LISTEN_ONLY.tx_io = 2,                          // IO号.rx_io = 3,                          // IO号.clkout_io = TWAI_IO_UNUSED,         // io号,不用为-1.bus_off_io = TWAI_IO_UNUSED,        // io号,不用为-1.tx_queue_len = 5,                   //发送队列长度,0-禁用发送队列.rx_queue_len = 5,                   //接收队列长度.alerts_enabled = TWAI_ALERT_NONE,   //警告标志 TWAI_ALERT_ALL 可开启所有警告.clkout_divider = 0,                 // 1 to 14 , 0-不用.intr_flags = ESP_INTR_FLAG_LEVEL1}; //中断优先级// CAN接口时序配置官方提供了1K to 1Mbps的常用配置twai_timing_config_t t_config = TWAI_TIMING_CONFIG_1MBITS(); // TWAI_TIMING_CONFIG_500KBITS()//过滤器配置twai_filter_config_t f_config = {.acceptance_code = 0,          //验证代码.acceptance_mask = 0xFFFFFFFF, //验证掩码 0xFFFFFFFF表示全部接收.single_filter = true};        // true:单过滤器模式 false:双过滤器模式ESP_ERROR_CHECK(twai_driver_install(&g_config, &t_config, &f_config));ESP_LOGI(EXAMPLE_TAG, "Driver installed");ESP_ERROR_CHECK(twai_start());ESP_LOGI(EXAMPLE_TAG, "Driver started");xTaskCreatePinnedToCore(twai_receive_task, "TWAI_rx", 4096, NULL, 8, NULL, tskNO_AFFINITY);xTaskCreatePinnedToCore(twai_transmit_task, "TWAI_tx", 4096, NULL, 9, NULL, tskNO_AFFINITY);vTaskDelay(pdMS_TO_TICKS(10000)); //运行10stwai_status_info_t status_info;twai_get_status_info(&status_info);while (status_info.msgs_to_tx != 0){ESP_ERROR_CHECK(twai_get_status_info(&status_info));}ESP_ERROR_CHECK(twai_stop()); // Stop the TWAI DriverESP_LOGI(EXAMPLE_TAG, "Driver stopped");ESP_ERROR_CHECK(twai_driver_uninstall());ESP_LOGI(EXAMPLE_TAG, "Driver uninstalled");
}

效果:

I (278) TWAI Self Test: Driver installed
I (278) TWAI Self Test: Driver started
Send : Standard Data Frame, ID: 60 D0: 0 D1: 0 D2: 0 D3: 0
Send : Standard Data Frame, ID: 60 D0: 1 D1: 0 D2: 0 D3: 0
Send : Standard Data Frame, ID: 60 D0: 2 D1: 0 D2: 0 D3: 0
Receive: Standard Data Frame, ID: 60 D0: 0 D1: 0 D2: 0 D3: 0
Receive: Standard Data Frame, ID: 60 D0: 1 D1: 0 D2: 0 D3: 0
Receive: Standard Data Frame, ID: 60 D0: 2 D1: 0 D2: 0 D3: 0
Send : Standard Remote Frame, ID: 60
Receive: Standard Remote Frame, ID: 60
Send : Extended Data Frame, ID: 60 D0: 0 D1: 0 D2: 0 D3: 0 D4: 0
Send : Extended Data Frame, ID: 60 D0: 1 D1: 0 D2: 0 D3: 0 D4: 0
Send : Extended Data Frame, ID: 60 D0: 2 D1: 0 D2: 0 D3: 0 D4: 0
Receive: Extended Data Frame, ID: 60 D0: 0 D1: 0 D2: 0 D3: 0 D4: 0
Receive: Extended Data Frame, ID: 60 D0: 1 D1: 0 D2: 0 D3: 0 D4: 0
Receive: Extended Data Frame, ID: 60 D0: 2 D1: 0 D2: 0 D3: 0 D4: 0
Send : Extended Remote Frame, ID: 60
Receive: Extended Remote Frame, ID: 60
I (10278) TWAI Self Test: Driver stopped
I (10278) TWAI Self Test: Driver uninstalled

CAN收发带过滤测试

收发测试至少有2个CAN终端,本次测试采用ESP32-C3作为master,ESP32作为slave,master分别发送ID号为0x55b和0x55e的消息包,slave设置过滤器,只接收ID为0x55e的扩展帧,并将数据做处理后以0xcc的ID发送到主机。
需要注意的是,正常收发数据需配置: twai_general_config_t->.mode = TWAI_MODE_NORMAL; 和 twai_message_t->self = 0; 另外使用过滤器注意移位。

主机代码:

#include <stdio.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_err.h"
#include "esp_log.h"
#include "driver/twai.h"#define EXAMPLE_TAG "TWAI master"
#define SENDMSG 0
#define RECEIVEMSG 1
/* --------------------------- Tasks and Functions -------------------------- */void printf_msg(int flag, twai_message_t *msg) // flag:0-send 1-receive
{int j;if (flag)printf("Receive: ");elseprintf("Send   : ");if (msg->extd)printf("Extended ");elseprintf("Standard ");if (msg->rtr)printf("Remote Frame, ");elseprintf("Data  Frame,  ");printf("ID: 0x%x    ", msg->identifier);if (msg->rtr == 0){for (j = 0; j < msg->data_length_code; j++){printf("D%d: %d\t", j, msg->data[j]);}printf("\n");}elseprintf("\n");
}static void twai_transmit_task(void *arg)
{int i;twai_message_t s1 = {.extd = 0,                         // 0-标准帧; 1-扩展帧.rtr = 0,                          // 0-数据帧; 1-远程帧.ss = 1,                           // 0-错误重发; 1-单次发送(仲裁或丢失时消息不会被重发),对接收消息无效.self = 0,                         // 0-不接收自己发送的消息,1-接收自己发送的消息,对接收消息无效.dlc_non_comp = 0,                 // 0-数据长度不大于8(ISO 11898-1); 1-数据长度大于8(非标);.identifier = 0x55b,                  // 11/29位ID.data_length_code = 4,             // DLC数据长度4bit位宽.data = {0, 0, 0, 0, 0, 0, 0, 0}}; //发送数据,对远程帧无效vTaskDelay(pdMS_TO_TICKS(1000));for (i = 0; i < 3; i++) //发送3个标准数据帧{s1.data[0] = i;ESP_ERROR_CHECK(twai_transmit(&s1, portMAX_DELAY));printf_msg(SENDMSG, &s1);}s1.rtr = 1;s1.data_length_code = 6;vTaskDelay(pdMS_TO_TICKS(1000));for (i = 0; i < 1; i++) //发送1个标准远程帧{ESP_ERROR_CHECK(twai_transmit(&s1, portMAX_DELAY));printf_msg(SENDMSG, &s1);}s1.extd = 1;s1.rtr = 0;s1.identifier = 0x55e;s1.data_length_code = 5;vTaskDelay(pdMS_TO_TICKS(1000));for (i = 0; i < 3; i++) //发送3个扩展数据帧{s1.data[0] = i;ESP_ERROR_CHECK(twai_transmit(&s1, portMAX_DELAY));printf_msg(SENDMSG, &s1);}s1.rtr = 1;s1.data_length_code = 3;vTaskDelay(pdMS_TO_TICKS(1000));for (i = 0; i < 1; i++) //发送1个扩展远程帧{ESP_ERROR_CHECK(twai_transmit(&s1, portMAX_DELAY));printf_msg(SENDMSG, &s1);}vTaskDelete(NULL);
}static void twai_receive_task(void *arg)
{twai_message_t r1;for (int i = 0; i < 8; i++) //发送1个扩展远程帧{ESP_ERROR_CHECK(twai_receive(&r1, portMAX_DELAY));printf_msg(RECEIVEMSG, &r1);}vTaskDelete(NULL);
}void app_main(void)
{// CAN接口基本配置twai_general_config_t g_config = {.mode = TWAI_MODE_NORMAL,            // TWAI_MODE_NORMAL / TWAI_MODE_NO_ACK / TWAI_MODE_LISTEN_ONLY.tx_io = 2,                          // IO号.rx_io = 3,                          // IO号.clkout_io = TWAI_IO_UNUSED,         // io号,不用为-1.bus_off_io = TWAI_IO_UNUSED,        // io号,不用为-1.tx_queue_len = 5,                   //发送队列长度,0-禁用发送队列.rx_queue_len = 5,                   //接收队列长度.alerts_enabled = TWAI_ALERT_NONE,   //警告标志 TWAI_ALERT_ALL 可开启所有警告.clkout_divider = 0,                 // 1 to 14 , 0-不用.intr_flags = ESP_INTR_FLAG_LEVEL1}; //中断优先级// CAN接口时序配置官方提供了1K to 1Mbps的常用配置twai_timing_config_t t_config = TWAI_TIMING_CONFIG_1MBITS(); // TWAI_TIMING_CONFIG_500KBITS()//过滤器配置twai_filter_config_t f_config = {.acceptance_code = 0,          //验证代码.acceptance_mask = 0xFFFFFFFF, //验证掩码 0xFFFFFFFF表示全部接收.single_filter = true};        // true:单过滤器模式 false:双过滤器模式ESP_ERROR_CHECK(twai_driver_install(&g_config, &t_config, &f_config));ESP_LOGI(EXAMPLE_TAG, "Driver installed");ESP_ERROR_CHECK(twai_start());ESP_LOGI(EXAMPLE_TAG, "Driver started");xTaskCreatePinnedToCore(twai_receive_task, "TWAI_rx", 4096, NULL, 8, NULL, tskNO_AFFINITY);xTaskCreatePinnedToCore(twai_transmit_task, "TWAI_tx", 4096, NULL, 9, NULL, tskNO_AFFINITY);vTaskDelay(pdMS_TO_TICKS(10000)); //运行10stwai_status_info_t status_info;twai_get_status_info(&status_info);while (status_info.msgs_to_tx != 0){ESP_ERROR_CHECK(twai_get_status_info(&status_info));}ESP_ERROR_CHECK(twai_stop()); // Stop the TWAI DriverESP_LOGI(EXAMPLE_TAG, "Driver stopped");ESP_ERROR_CHECK(twai_driver_uninstall());ESP_LOGI(EXAMPLE_TAG, "Driver uninstalled");
}

从机代码:

#include <stdio.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "esp_err.h"
#include "esp_log.h"
#include "driver/twai.h"#define EXAMPLE_TAG "TWAI slave"
#define SENDMSG 0
#define RECEIVEMSG 1
/* --------------------------- Tasks and Functions -------------------------- */void printf_msg(int flag, twai_message_t *msg) // flag:0-send 1-receive
{int j;if (flag)printf("Receive: ");elseprintf("Send   : ");if (msg->extd)printf("Extended ");elseprintf("Standard ");if (msg->rtr)printf("Remote Frame, ");elseprintf("Data  Frame,  ");printf("ID: 0x%x    ", msg->identifier);if (msg->rtr == 0){for (j = 0; j < msg->data_length_code; j++){printf("D%d: %d\t", j, msg->data[j]);}printf("\n");}elseprintf("\n");
}static void twai_receive_task(void *arg)
{int j;twai_message_t s1 = {.extd = 0,                         // 0-标准帧; 1-扩展帧.rtr = 0,                          // 0-数据帧; 1-远程帧.ss = 1,                           // 0-错误重发; 1-单次发送(仲裁或丢失时消息不会被重发),对接收消息无效.self = 0,                         // 0-不接收自己发送的消息,1-接收自己发送的消息,对接收消息无效.dlc_non_comp = 0,                 // 0-数据长度不大于8(ISO 11898-1); 1-数据长度大于8(非标);.identifier = 0xcc,                 // 11/29位ID.data_length_code = 4,             // DLC数据长度4bit位宽.data = {0, 0, 0, 0, 0, 0, 0, 0}}; //发送数据,对远程帧无效twai_message_t r1;for (int i = 0; i < 8; i++){ESP_ERROR_CHECK(twai_receive(&r1, portMAX_DELAY));printf_msg(RECEIVEMSG, &r1);s1.extd = r1.extd;s1.rtr = r1.rtr;s1.data_length_code = r1.data_length_code;if (r1.rtr == 0){for (j = 0; j < r1.data_length_code; j++)s1.data[j] = 255 - r1.data[j]; // 255减去原始数据回传}ESP_ERROR_CHECK(twai_transmit(&s1, portMAX_DELAY));}vTaskDelete(NULL);
}void app_main(void)
{// CAN接口基本配置twai_general_config_t g_config = {.mode = TWAI_MODE_NORMAL,            // TWAI_MODE_NORMAL / TWAI_MODE_NO_ACK / TWAI_MODE_LISTEN_ONLY.tx_io = 21,                          // IO号.rx_io = 22,                          // IO号.clkout_io = TWAI_IO_UNUSED,         // io号,不用为-1.bus_off_io = TWAI_IO_UNUSED,        // io号,不用为-1.tx_queue_len = 5,                   //发送队列长度,0-禁用发送队列.rx_queue_len = 5,                   //接收队列长度.alerts_enabled = TWAI_ALERT_NONE,   //警告标志 TWAI_ALERT_ALL 可开启所有警告.clkout_divider = 0,                 // 1 to 14 , 0-不用.intr_flags = ESP_INTR_FLAG_LEVEL1}; //中断优先级// CAN接口时序配置官方提供了1K to 1Mbps的常用配置twai_timing_config_t t_config = TWAI_TIMING_CONFIG_1MBITS(); // TWAI_TIMING_CONFIG_500KBITS()//过滤器配置twai_filter_config_t f_config = {.acceptance_code = 0x55e << 3, //验证代码.acceptance_mask = 0x00000007, //验证掩码 0xFFFFFFFF表示全部接收 7:不关注低3bit.single_filter = true};        // true:单过滤器模式 false:双过滤器模式ESP_ERROR_CHECK(twai_driver_install(&g_config, &t_config, &f_config));ESP_LOGI(EXAMPLE_TAG, "Driver installed");ESP_ERROR_CHECK(twai_start());ESP_LOGI(EXAMPLE_TAG, "Driver started");xTaskCreatePinnedToCore(twai_receive_task, "TWAI_rx", 4096, NULL, 8, NULL, tskNO_AFFINITY);
}

效果:
主机打印:

I (277) TWAI master: Driver installed
I (277) TWAI master: Driver started
Send : Standard Data Frame, ID: 0x55b D0: 0 D1: 0 D2: 0 D3: 0
Send : Standard Data Frame, ID: 0x55b D0: 1 D1: 0 D2: 0 D3: 0
Send : Standard Data Frame, ID: 0x55b D0: 2 D1: 0 D2: 0 D3: 0
Send : Standard Remote Frame, ID: 0x55b
Send : Extended Data Frame, ID: 0x55e D0: 0 D1: 0 D2: 0 D3: 0 D4: 0
Send : Extended Data Frame, ID: 0x55e D0: 1 D1: 0 D2: 0 D3: 0 D4: 0
Send : Extended Data Frame, ID: 0x55e D0: 2 D1: 0 D2: 0 D3: 0 D4: 0
Receive: Extended Data Frame, ID: 0xcc D0: 255 D1: 255 D2: 255 D3: 255 D4: 255
Receive: Extended Data Frame, ID: 0xcc D0: 254 D1: 255 D2: 255 D3: 255 D4: 255
Receive: Extended Data Frame, ID: 0xcc D0: 253 D1: 255 D2: 255 D3: 255 D4: 255
Send : Extended Remote Frame, ID: 0x55e
Receive: Extended Remote Frame, ID: 0xcc
I (10277) TWAI master: Driver stopped
I (10277) TWAI master: Driver uninstalled

从机打印:

I (308) TWAI slave: Driver installed
I (308) TWAI slave: Driver started
Receive: Extended Data Frame, ID: 0x55e D0: 0 D1: 0 D2: 0 D3: 0 D4: 0
Receive: Extended Data Frame, ID: 0x55e D0: 1 D1: 0 D2: 0 D3: 0 D4: 0
Receive: Extended Data Frame, ID: 0x55e D0: 2 D1: 0 D2: 0 D3: 0 D4: 0
Receive: Extended Remote Frame, ID: 0x55e

可见从机只响应了ID为0x55e的扩展帧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_15676.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

伟大的micropython smartconfig 配网它来了!!!

我这其实只是实验和搬运&#xff0c;还是感谢伟大的walkline群主&#xff0c;他弄好的&#xff0c;我只是负责搬运发布给新手看。 之前一大堆人问我配网的事儿&#xff0c;输入下wifi名称密码这么麻烦吗&#xff0c;好吧&#xff0c;有求必应&#xff0c;之前的配网是通过ap模式…

PICO高管专访:关于PICO 4硬件、内容、定价、海外布局的一切解答

PICO 4昨天正式在国内发布&#xff0c;简单来说这是一款相对均衡的VR一体机&#xff0c;在硬件素质、内容生态建设上都可圈可点&#xff0c;对于国内还未入手VR的朋友们来说是非常好的选择。相关阅读&#xff1a;《PICO 4评测&#xff1a;Pancake光学新标杆&#xff0c;VR娱乐V…

20【访问者设计模式】

文章目录二十、访问者设计模式20.1 访问者设计模式简介20.1.1 访问者设计模式概述20.1.2 访问者设计模式的UML类图20.2 访问者设计模式的实现20.3 访问者设计模式的优缺点二十、访问者设计模式 20.1 访问者设计模式简介 20.1.1 访问者设计模式概述 访问者设计模式&#xff0…

计算机网络基础 VLSM----可变长子网掩码;CIDR技术----无类域间路由;

VLSM----可变长子网掩码&#xff1a; 概述&#xff1a; 通过网络位向主机位借位的方式&#xff0c;延长子网掩码&#xff0c;从而达到将一个大网络划分为多个小网络&#xff1b;借出的位数称之为子网位&#xff0c;决定了能划分网络的个数。 优点&#xff1a; 更高效的利用…

记一次导入下载好的源码工程到本地工程异常解决方案

今天在学习okhttp相关视频时&#xff0c;安装视频的操作在自己的工程中引入三方的模块&#xff0c;但是发现引入后和预期的不一致。不一致指的是&#xff0c;视频中以module方式引入sample-okhttp并解决冲突后&#xff0c;sample-okhttp能够被android stuidio识别为applicayion…

Style样式设置器

构成Style最重要的两种元素&#xff1a; Setter类帮助我们设置控件的静态外观风格 Trigger类则帮助我们设置控件的行为风格。 Setter,设置器&#xff0c;我们给属性赋值的时候一般都采用“属 性名属性值”的形式 上面的例子中针对TextBlock的Style&#xff0c;Style中使用 若…

解决csdn强制关注博主才能阅读文章

问题 有的时候查阅资料的时候,关注博主并不是很方便,查csdn会出现下面的提示解决办法 打开控制台输入以下代码: var article_content=document.getElementById("article_content"); article_content.removeAttribute("style");var follow_text=document…

深入理解计算机系统——第七章 Linking

深入理解计算机系统——第七章 Linking7.1 Compiler Drivers7.2 Static Linking7.3 Object Files7.4 Relocatable Object Files7.5 Symbols and Symbol Tables7.6 Symbol Resolution7.6.1 How Linkers Resolve Duplicate Symbol Names7.6.2 Linking with Static Libraries7.6.3…

人体神经元结构示意图,神经细胞内部结构图

人体神经结构图&#xff1f;&#xff1f;&#xff1f;&#xff1f; 谷歌人工智能写作项目&#xff1a;神经网络伪原创 下图为神经系统的结构示意图&#xff0c;请根据图回答&#xff1a; &#xff08;1&#xff09;构成神经系统的结构、功能单位是神经元&#xff0c;图中E部分…

19【迭代器设计模式】

文章目录十九、迭代器设计模式19.1 迭代器设计模式简介19.1.1 迭代器设计模式概述19.1.2 迭代器设计模式的UML类图19.2 迭代器设计模式的实现19.3 迭代器设计模式的优缺点十九、迭代器设计模式 19.1 迭代器设计模式简介 19.1.1 迭代器设计模式概述 迭代器设计模式&#xff0…

DeFi借贷重新洗牌 透过协议变化能找到哪些新趋势?

在过去的几个月里&#xff0c;DeFi 借贷赛道产生了重大变化&#xff0c;1kx 研究员 Mikey 0x 对此场域重新进行梳理&#xff0c;BlockBeats 对其整理翻译如下&#xff1a; 本文内容将包括对新借贷协议的介绍、核心数据统计以及发展趋势&#xff0c;也许可以让我们大致把握下一…

Python3操作MongoDB数据库

Python3操作MongoDB数据库 文章目录Python3操作MongoDB数据库0. 写在前面1. 安装开源驱动库pymongo2. 参考0. 写在前面 Linux&#xff1a;Ubuntu Kylin 16.04MongoDB&#xff1a;MongoDB3.2.7Python&#xff1a;Anaconda With Python3.7 1. 安装开源驱动库pymongo pymongo驱动…

公众号题库搜题对接(免费接口)

公众号题库搜题对接(免费接口) 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 题库&#xff1a;题库后台&#xff08;点击跳转&a…

用神经网络表示与逻辑,神经网络实现逻辑运算

数据挖掘中的神经网络和模糊逻辑的概念是啥&#xff1f; 【神经网络】人工神经网络&#xff08;Artificial Neural Networks&#xff0c;简写为ANNs&#xff09;也简称为神经网络&#xff08;NNs&#xff09;或称作连接模型&#xff08;Connection Model&#xff09;&#xff…

Frp内网穿透win系统实录

文章目录前言公网服务器端配置基于Docker配置简单文件配置内网服务器端配置frpc配置安装OpenSSH服务配置连接XShell和Xftp连接前言 由于实验室的某些原因&#xff0c;分配了一台win10的服务器&#xff08;QAQ&#xff09;&#xff0c;但是由于服务器在内网&#xff0c;无法访问…

【常用排序算法】

文章目录写在最前面只想用其中的某个算法&#xff1f;类关系图工具类NumberArrayUtil用于测试排序的父类 SortTest冒泡排序堆排序插入排序归并排序快速排序选择排序希尔排序写在最前面 只想用其中的某个算法&#xff1f; 如果你只是想要对应的排序算法&#xff0c;可删除每个…

A-Level数学P4:反证法题型变革趋势

历年来&#xff0c;真题中Prove by contradiction的常见题型有三类&#xff1a; 1►Even/Odd相关证明2►Multiple of 3相关证明3►Irrational number相关证明 但是从2022年开始&#xff0c;该考点有越变越活的趋势。不再局限于书本上出现过的习题类型&#xff0c;而是进一步考察…

SpringBoot生产监控

文章目录一、健康监控简介1、介绍2、SpringBoot准备工作3、其他二、健康检测触达关键组件1、内置组件健康详情2、自定义组件健康详情3、自定义多 HealthIndicator 聚合三、对外暴露应用内部重要组件的状态1、内部状态数据暴露2、JMX MBean四、指标 Metrics 快速定位五、总结一、…

String字符串拼接原理

前言 明白什么是引用&#xff0c;什么是该引用指向的真正对象。 对于基本数据类型比较的是值&#xff0c;对于引用数据类型比较的是指向的对象的地址&#xff0c;即两者指向的是否是同一个对象。 String s "gzc";上述代码中s为变量引用&#xff0c;它存在于栈中&am…

JAVA毕设项目商店管理系统(java+VUE+Mybatis+Maven+Mysql)

JAVA毕设项目商店管理系统&#xff08;javaVUEMybatisMavenMysql&#xff09; 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技…