要使用 PSoC 6 (CY8CPROTO-062S2-4343W) 的 CAN-FD 控制器发送和接收 64 字节扩展标识符(29 位)数据帧,需修改配置以支持扩展帧、FD 模式和大数据量。以下是关键步骤和示例代码:
关键配置步骤
启用 FD 模式和扩展标识符:
- 设置
isCANFD = true 和 isExtendedId = true
- 配置
dataLength = CY_CANFD_DLC_64BYTES(对应 DLC=15)
调整 FIFO 深度和缓冲区大小:
- 发送/接收 FIFO 元素数量设为 16
- 每个元素分配 64 字节缓冲区
配置波特率:
- 仲裁段(Nominal)波特率:1 Mbps
- 数据段(Data)波特率:2 Mbps(需硬件支持)
完整消息过滤掩码:
- 掩码设置为
0x1FFFFFFF(匹配所有 29 位标识符)
修改后的代码示例
#include "cy_canfd.h"
#define TX_MAILBOX_INDEX 0
#define RX_FIFO_INDEX 0
#define MAX_DATA_SIZE 64 // 64字节数据
#define DLC_64_BYTES 15 // CANFD DLC=15 对应64字节
#define CANFD_EXTENDED_ID 0x18EEFF00 // 29位扩展ID示例
// CANFD上下文和配置结构
cy_stc_canfd_context_t canfdContext;
const cy_stc_canfd_baudrate_t baudrateCfg = {
.prescaler = 5,
.timeSegment1 = 14,
.timeSegment2 = 5,
.syncJumpWidth = 4,
.nominalBitRate = 1000000, // 1 Mbps (仲裁段)
.dataBitRate = 2000000, // 2 Mbps (数据段)
.bitRateSwitching = true // 启用比特率切换
};
const cy_stc_canfd_mbx_config_t txMailboxCfg = {
.isExtendedId = true, // 使用29位扩展ID
.isRemote = false,
.id = CANFD_EXTENDED_ID, // 扩展ID值
.dataLength = DLC_64_BYTES, // DLC=15 (64字节)
.txBuffer = NULL
};
const cy_stc_canfd_mbx_config_t rxFIFOCfg = {
.isExtendedId = true,
.isRemote = false,
.id = CANFD_EXTENDED_ID,
.mask = 0x1FFFFFFF, // 完整29位掩码
.dataLength = DLC_64_BYTES, // 接收64字节
.rxBuffer = NULL
};
const cy_stc_canfd_queue_config_t rxQueueCfg = {
.mbxConfig = &rxFIFOCfg,
.numberOfFIFOElements = 16, // FIFO深度=16
.rxQueue = NULL
};
void init_canfd(void) {
// 初始化CANFD控制器
Cy_CANFD_Init(CANFD, &canfdConfig, &baudrateCfg, &canfdContext);
// 配置发送邮箱
Cy_CANFD_ConfigureTxMailbox(CANFD, TX_MAILBOX_INDEX, &txMailboxCfg, &canfdContext);
// 配置接收FIFO
Cy_CANFD_ConfigureRxQueue(CANFD, RX_FIFO_INDEX, &rxQueueCfg, &canfdContext);
// 启动CANFD
Cy_CANFD_Enable(CANFD);
}
void send_64byte_frame(void) {
uint8_t txData[MAX_DATA_SIZE] = {0};
// 填充64字节数据...
Cy_CANFD_TransmitMsgBuffer(&canfdContext, TX_MAILBOX_INDEX, DLC_64_BYTES, txData);
}
void receive_64byte_frame(void) {
cy_stc_canfd_rx_message_t rxMsg;
if (CY_CANFD_RX_NOT_EMPTY == Cy_CANFD_ReceiveFromQueue(&canfdContext, RX_FIFO_INDEX, &rxMsg)) {
// 检查DLC是否为64字节
if (rxMsg.dlc == DLC_64_BYTES) {
uint8_t *data = rxMsg.msg;
// 处理64字节数据...
}
}
}
验证步骤
硬件连接:
- 两个 EVK 的 CANH-CANH、CANL-CANL 直连
- 总线两端加 120Ω 终端电阻
配置匹配性检查:
- 双方波特率(Nominal/Data)必须一致
- 扩展 ID 和掩码需匹配通信对象
调试建议:
- 检查
Cy_CANFD_TransmitMsgBuffer() 返回值是否为 CY_CANFD_SUCCESS
- 确认接收端 FIFO 状态:
Cy_CANFD_GetRxQueueStatus()
- 使用逻辑分析仪抓取 CAN 总线波形
常见问题解决
- 只能接收 15 字节:
- 检查发送/接收配置中的
dataLength 是否设为 DLC_64_BYTES(15)
- 确认
bitRateSwitching 已启用(FD 模式必需)
- 无法收到帧:
- 验证 ID 掩码
0x1FFFFFFF(允许所有扩展帧)
- 检查硬件波特率误差(建议 < 1%)
⚠️ 注意:确保 PSoC 6 的 CAN-FD 时钟配置支持目标波特率(参考 Technical Reference Manual)。
通过以上配置,两个 EVK 即可可靠传输 64 字节扩展帧。