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的扩展帧。