ESP32-C3 CAN接口的使用指南
esp32-C3 CAN接口使用
功能概述
ESP32-C3具有1个CAN控制器支持以下特性:
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其他位与验证代码相同即可接收)
单过滤器模式
单过滤器模式可过滤:

双过滤器模式
双过滤器模式可过滤:

关键函数说明
配置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: ");
else
printf("Send : ");
if (msg->extd)
printf("Extended ");
else
printf("Standard ");
if (msg->rtr)
printf("Remote Frame, ");
else
printf("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");
}
else
printf("\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)); //运行10s
twai_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 Driver
ESP_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: ");
else
printf("Send : ");
if (msg->extd)
printf("Extended ");
else
printf("Standard ");
if (msg->rtr)
printf("Remote Frame, ");
else
printf("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");
}
else
printf("\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)); //运行10s
twai_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 Driver
ESP_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: ");
else
printf("Send : ");
if (msg->extd)
printf("Extended ");
else
printf("Standard ");
if (msg->rtr)
printf("Remote Frame, ");
else
printf("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");
}
else
printf("\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的扩展帧。