GD32C103/GD32C113 CANFD

CANFD介绍

FD全称是 Flexible Data-Rate,顾名思义,表示CAN-FD 的帧报文具有数据场波特率可变的特性,即仲裁场合数据控制场使用标准的通信波特率,而到数据场就会切换为更高的通信波特率,车端常用的为2Mbit/s和5Mbit/s,从而达到提高通信速率的目的

CAN
在这里插入图片描述
CAN FD
在这里插入图片描述

GD32C103/GD32C113介绍

GD32C113是GD32C103的升级版,带两路CANFD

在这里插入图片描述

在这里插入图片描述

GD32C113 CAN引脚

can0

在这里插入图片描述

在这里插入图片描述

can0

在这里插入图片描述

在这里插入图片描述

示例

extern can_trasnmit_message_struct g_transmit_message;
extern can_receive_message_struct g_receive_message;
extern FlagStatus can0_receive_flag;
extern FlagStatus can1_receive_flag;

can_parameter_struct can_parameter;
can_fdframe_struct can_fd_parameter;
can_fd_tdc_struct can_fd_tdc_parameter;

启用时钟

// 启用GPIO时钟
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOB);

// 启用CAN时钟
rcu_periph_clock_enable(RCU_CAN0);
rcu_periph_clock_enable(RCU_CAN1);

// 根据实际配置复用时钟
// rcu_periph_clock_enable(RCU_AF);

初始化CAN FD

/* configure CAN0 GPIO */
gpio_init(GPIOA, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_0);		// rx
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);		// tx
	
/* configure CAN1 GPIO */
gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_12);		// rx
gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13);		// tx
	
// 根据实际配置复用CAN GPIO
// gpio_pin_remap_config(GPIO_CAN0_FULL_REMAP, ENABLE);
// gpio_pin_remap_config(GPIO_CAN1_REMAP, ENABLE);
	
// 复位can配置
can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);
can_deinit(CAN0);
can_deinit(CAN1);	
	

can_parameter.time_triggered = DISABLE;
can_parameter.auto_bus_off_recovery = DISABLE;
can_parameter.auto_wake_up = DISABLE;
can_parameter.auto_retrans = DISABLE;
can_parameter.rec_fifo_overwrite = DISABLE;
can_parameter.trans_fifo_order = DISABLE;
can_parameter.working_mode = CAN_NORMAL_MODE;
    
/* configure CAN0/1 baud rate 1MBps, sample point at 80% */
can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
can_parameter.time_segment_1 = CAN_BT_BS1_7TQ;
can_parameter.time_segment_2 = CAN_BT_BS2_2TQ;
can_parameter.prescaler = 6;

// 初始化CAN
can_init(CAN0, &can_parameter);
can_init(CAN1, &can_parameter);
		
		
// 配置CANFD
can_struct_para_init(CAN_FD_FRAME_STRUCT, &can_fd_parameter);
can_fd_parameter.fd_frame = ENABLE;
can_fd_parameter.excp_event_detect = ENABLE;
can_fd_parameter.delay_compensation = ENABLE;
can_fd_tdc_parameter.tdc_filter = 0x04;
can_fd_tdc_parameter.tdc_mode = CAN_TDCMOD_CALC_AND_OFFSET;
can_fd_tdc_parameter.tdc_offset = 0x04;
can_fd_parameter.p_delay_compensation = &can_fd_tdc_parameter;
can_fd_parameter.iso_bosch = CAN_FDMOD_ISO;
can_fd_parameter.esi_mode = CAN_ESIMOD_HARDWARE;
/* FD mode data baudrate 2Mbps, sample piont at 80% */
can_fd_parameter.data_resync_jump_width = CAN_BT_SJW_1TQ;
can_fd_parameter.data_time_segment_1 = CAN_BT_BS1_3TQ;
can_fd_parameter.data_time_segment_2 = CAN_BT_BS2_1TQ;
/* CAN-FD data segement prescaler should be the same as non-data segement prescaler */
can_fd_parameter.data_prescaler = 6;
can_fd_init(CAN0, &can_fd_parameter);
can_fd_init(CAN1, &can_fd_parameter);
		
		
		
/* initialize filter */
can1_filter_start_bank(14);

can_filter_mask_mode_init(DEV_CAN0_ID, DEV_CAN0_MASK, CAN_EXTENDED_FIFO0, 0);
can_filter_mask_mode_init(DEV_CAN1_ID, DEV_CAN1_MASK, CAN_EXTENDED_FIFO0, 15);
		
// 启用CAN接收中断
nvic_irq_enable(CAN0_RX0_IRQn, 0, 0);
nvic_irq_enable(CAN1_RX0_IRQn, 1, 0);
		
/* enable can receive FIFO0 not empty interrupt */
can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0);
can_interrupt_enable(CAN1, CAN_INTEN_RFNEIE0);
		
can_struct_para_init(CAN_TX_MESSAGE_STRUCT, &g_transmit_message);
g_transmit_message.tx_sfid = 0x00;
g_transmit_message.tx_efid = 0x00;
g_transmit_message.tx_ft = CAN_FT_DATA;
g_transmit_message.tx_ff = CAN_FF_EXTENDED;
g_transmit_message.tx_dlen = 8;
		
// 设置CAN FD长度
g_transmit_message.tx_dlen = 12;
g_transmit_message.fd_flag = 1;
g_transmit_message.fd_brs = 1;
g_transmit_message.fd_esi = 0;
		
		
/* initialize receive message */
can_struct_para_init(CAN_RX_MESSAGE_STRUCT, &g_receive_message);

发送can fd

g_transmit_message.tx_efid = DEV_CAN1_ID;
g_transmit_message.tx_data[0] = 0x00;
g_transmit_message.tx_data[1] = 0xA1;
g_transmit_message.tx_data[2] = 0xA2;
g_transmit_message.tx_data[3] = 0xA3;
g_transmit_message.tx_data[4] = 0xA4;
g_transmit_message.tx_data[5] = 0xA1;
g_transmit_message.tx_data[6] = 0xA2;
g_transmit_message.tx_data[7] = 0xA3;
g_transmit_message.tx_data[8] = 0xA4;
g_transmit_message.tx_data[9] = 0xA1;
g_transmit_message.tx_data[10] = 0X12;
g_transmit_message.tx_data[11] = 0X03;
				
can_message_transmit(CAN0, &g_transmit_message);
can_message_transmit(CAN1, &g_transmit_message);
<think>我们正在讨论GD32C103微控制器的CANFD功能。虽然用户提供的引用[1]和[2]分别涉及Keepalived配置和ESP32-C3的安全功能,但这些内容与当前问题无关。因此,我们将忽略这些引用,专注于GD32C103CANFD。 根据用户上一次的问题(关于CAN总线的消极错误段)以及当前明确提及的“GD32C103 CANFD功能问题或配置指南”,我将提供关于GD32C103CANFD配置和使用指南。 GD32C103是兆易创新(GigaDevice)推出的一款基于Arm Cortex-M4内核的微控制器,支持CANFD(Controller Area Network Flexible Data-rate)协议。CANFD是对传统CAN协议的扩展,支持更高的数据速率(最高可达5Mbps)和更大的数据负载(最多64字节)。 以下为GD32C103CANFD配置指南: ### 1. **CANFD模式基本配置步骤** - **使能时钟**:首先需要使能CANFD外设的时钟。 - **配置GPIO**:将用于CANFD通信的TX和RX引脚配置为复用功能(AF)。 - **初始化CANFD**:设置工作模式(正常模式或回环测试模式)、波特率、数据段波特率等。 - **配置过滤器**:设置接收过滤器,以决定接收哪些消息。 - **配置中断**(可选):如果需要使用中断处理接收或发送完成,则配置中断。 - **启动CANFD**:使能CANFD外设。 ### 2. **关键寄存器配置** - **CANFD_CTL寄存器**:控制CANFD的工作模式(如测试模式、自动重传等)。 - **CANFD_BT寄存器**:配置位时序,包括同步段、传播段、相位段1和2以及分频因子。 - **CANFD_DBT寄存器**:配置数据段的位时序(数据段波特率通常高于仲裁段)。 - **CANFD_TXQ和CANFD_RXQ寄存器**:配置发送队列和接收FIFO。 ### 3. **CANFD波特率计算** 波特率计算公式为: $$ \text{BaudRate} = \frac{\text{PCLK}}{\text{BRP} \times (\text{TS1} + \text{TS2} + 1)} $$ 其中: - `PCLK`:CANFD外设的时钟频率。 - `BRP`:波特率分频因子(1~1024)。 - `TS1`:时间段1(包括传播段和相位段1,范围为1~32)。 - `TS2`:时间段2(相位段2,范围为1~32)。 例如,若PCLK=120MHz,目标波特率为1Mbps,则: $$ \text{BRP} \times (\text{TS1} + \text{TS2} + 1) = \frac{120\text{MHz}}{1\text{Mbps}} = 120 $$ 可以设置BRP=10,TS1=10,TS2=9,则总和为10+9+1=20,实际波特率为120MHz/(10*20)=600Kbps(需调整)。 数据段波特率(如5Mbps)使用类似公式,但通过`CANFD_DBT`寄存器单独配置。 ### 4. **CANFD发送和接收流程** - **发送消息**: 1. 检查发送邮箱是否空闲。 2. 设置标识符(ID)、数据长度(DLC,0~64字节)和数据。 3. 请求发送(置位相应的发送请求位)。 - **接收消息**: 1. 检查接收FIFO是否有数据(通过状态寄存器或中断)。 2. 从接收FIFO读取标识符、DLC和数据。 3. 释放接收FIFO条目。 ### 5. **代码示例(基于GD32标准库)** ```c #include "gd32c10x.h" void canfd_config(void) { // 使能时钟 rcu_periph_clock_enable(RCU_CAN0); // CAN0时钟 rcu_periph_clock_enable(RCU_GPIOA); // GPIOA时钟 // 配置PA11为CAN0_RX,PA12为CAN0_TX gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12); gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_11); // CANFD初始化结构体 canfd_parameter_struct canfd_init_para; canfd_struct_para_init(CANFD_INIT_STRUCT, &canfd_init_para); // 工作模式:正常模式 canfd_init_para.working_mode = CANFD_NORMAL_MODE; // 自动重传 canfd_init_para.auto_retrans = ENABLE; // 波特率:仲裁段1Mbps,数据段5Mbps canfd_init_para.prescaler = 10; // BRP=10 canfd_init_para.time_segment_1 = 10; // TS1=10 canfd_init_para.time_segment_2 = 9; // TS2=9 canfd_init_para.sync_jump_width = 1; // SJW=1 canfd_init_para.data_prescaler = 2; // 数据段BRP=2 canfd_init_para.data_time_segment_1 = 5; // 数据段TS1=5 canfd_init_para.data_time_segment_2 = 4; // 数据段TS2=4 canfd_init_para.data_sync_jump_width = 1; // 数据段SJW=1 canfd_init_para.fd_frame = ENABLE; // 启用CANFDcanfd_init_para.fd_bsm = ENABLE; // 启用比特率切换(CANFD帧中切换波特率) // 初始化CANFD canfd_init(CAN0, &canfd_init_para); // 配置过滤器(接收所有消息) canfd_filter_parameter_struct canfd_filter; canfd_struct_para_init(CANFD_FILTER_STRUCT, &canfd_filter); canfd_filter.filter_number = 0; // 过滤器0 canfd_filter.filter_mode = CANFD_FILTERMODE_MASK; canfd_filter.filter_bits = CANFD_FILTERBITS_32BIT; canfd_filter.filter_list_high = 0x0000; canfd_filter.filter_list_low = 0x0000; canfd_filter.filter_mask_high = 0x0000; canfd_filter.filter_mask_low = 0x0000; canfd_filter.filter_fifo_number = CANFD_FIFO0; // 使用FIFO0 canfd_filter.filter_enable = ENABLE; canfd_filter(CAN0, &canfd_filter); // 使能CANFD canfd_enable(CAN0); } ``` ### 6. **常见问题与调试** - **无法进入正常工作模式**:检查时钟配置、GPIO复用设置和波特率计算。 - **无法接收消息**:确认过滤器配置是否正确,以及是否启用了接收中断(如有使用)。 - **数据段波特率不匹配**:确保通信双方的数据段波特率设置一致。 ### 7. **参考资源** - GD32C103用户手册(重点关注CANFD章节)[^3]。 - GD32C10x标准外设库示例代码(`GD32C10x_Firmware_Library_Vx.x.x\Examples\CANFD`)。 §§相关问题§§ 1. GD32C103CANFD与传统CAN有何区别? 2. 如何配置GD32C103CANFD过滤器以实现选择性接收? 3. CANFD在数据段波特率高于仲裁段时如何保证稳定性? 4. GD32C103CANFD是否支持远程帧? 5. 如何诊断GD32C103 CANFD通信中的错误? [^3]: GD32C103 User Manual, GigaDevice Semiconductor Inc.</think>### GD32C103 CANFD 功能配置指南 GD32C103 是兆易创新(GigaDevice)推出的基于 Arm Cortex-M4 内核的微控制器,支持 **CANFD(Controller Area Network Flexible Data-Rate)** 协议,兼容传统 CAN 2.0B 的同时,提供更高的数据速率(最高 5Mbps)和更大的数据负载(最多 64 字节)。以下是关键功能说明和配置指南: --- #### **一、CANFD 核心特性** 1. **协议兼容性**: - 支持 ISO 11898-1:2015 CANFD 标准。 - 兼容传统 CAN 2.0B 帧格式。 2. **数据传输能力**: - 仲裁段波特率:最高 1Mbps(与传统 CAN 相同)。 - **数据段波特率**:最高 5Mbps(通过 `CANFD_DBT` 寄存器配置)。 - **数据长度**:支持 0-64 字节负载(传统 CAN 仅 8 字节)。 3. **硬件资源**: - 独立发送/接收 FIFO(深度可配置)。 - 集成 28 个可编程过滤器(支持范围、掩码、列表模式)。 4. **错误处理**: - 内置错误计数器(TEC/REC)。 - 支持被动错误状态和总线关闭恢复机制。 --- #### **二、配置步骤与代码示例** ##### **1. 时钟与 GPIO 初始化** ```c // 使能 CANFD 外设时钟 rcu_periph_clock_enable(RCU_CAN0); // 配置 CANFD_RX (PA11) 和 CANFD_TX (PA12) gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12); // TX gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_11); // RX gpio_pin_remap_config(GPIO_CAN0_FULL_REMAP, ENABLE); // 复用功能重映射 ``` ##### **2. CANFD 工作模式设置** ```c can_fd_init_parameter_struct can_fd_init; can_struct_para_init(CAN_INIT_STRUCT, &can_fd_init); // 基本参数 can_fd_init.working_mode = CAN_MODE_NORMAL; // 正常模式 can_fd_init.auto_retrans = DISABLE; // 禁用自动重传 can_fd_init.fd_frame = ENABLE; // 启用 CANFD 帧 can_fd_init.fd_bsm = ENABLE; // 启用比特率切换 // 仲裁段波特率 = PCLK / (BRP * (TS1 + TS2 + 1)) can_fd_init.prescaler = 10; // 分频系数 BRP=10 can_fd_init.time_segment_1 = 13; // TS1=13 can_fd_init.time_segment_2 = 2; // TS2=2 can_fd_init.sync_jump_width = 1; // SJW=1 // 数据段波特率(5Mbps 配置) can_fd_init.data_prescaler = 2; // 数据段分频系数 can_fd_init.data_time_segment_1 = 5; can_fd_init.data_time_segment_2 = 2; can_fd_init.data_sync_jump_width = 1; can_init(CAN0, &can_fd_init); // 应用配置 ``` ##### **3. 过滤器配置(接收指定 ID 帧)** ```c can_filter_parameter_struct can_filter; can_filter.filter_number = 0; // 过滤器0 can_filter.filter_mode = CAN_FILTERMODE_MASK; // 掩码模式 can_filter.filter_bits = CAN_FILTERBITS_32BIT; // 32 位标识符 can_filter.filter_list_high = 0x456 << 21; // 目标 ID: 0x456 can_filter.filter_mask_high = 0xFFF << 21; // 掩码: 检查全部12位ID can_filter.filter_enable = ENABLE; // 启用过滤器 can_filter_init(&can_filter); ``` ##### **4. 发送 CANFD 帧(64 字节负载)** ```c can_fd_tx_message_struct tx_msg; tx_msg.tx_efid = ENABLE; // 扩展帧 tx_msg.tx_ft = CAN_FT_DATA; // 数据帧 tx_msg.tx_ff = CAN_FF_EXTENDED;// 扩展帧格式 tx_msg.tx_dlen = 64; // 数据长度=64 字节 tx_msg.tx_fid = 0x456; // 帧 ID=0x456 // 填充数据 uint8_t data[64] = {...}; memcpy(tx_msg.tx_data, data, 64); // 发送到发送邮箱0 can_message_transmit(CAN0, CAN_MAILBOX0, &tx_msg); ``` ##### **5. 接收中断处理** ```c // 启用接收中断 nvic_irq_enable(CAN0_RX0_IRQn, 0, 0); can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0); // 使能 FIFO0 非空中断 // 中断服务函数 void CAN0_RX0_IRQHandler(void) { if (can_interrupt_flag_get(CAN0, CAN_INT_FLAG_RFF0)) { can_fd_rx_message_struct rx_msg; can_message_receive(CAN0, CAN_FIFO0, &rx_msg); // 从 FIFO0 读取 // 处理数据: rx_msg.rx_data[0..rx_msg.rx_dlen-1] } } ``` --- #### **三、调试与常见问题** 1. **波特率不匹配**: - 确保仲裁段/数据段的 `TS1`、`TS2`、`BRP` 计算正确: $$ \text{BaudRate} = \frac{\text{PCLK}}{\text{BRP} \times (\text{TS1} + \text{TS2} + 1)} $$ - 使用逻辑分析仪捕获总线波形验证时序。 2. **帧接收失败**: - 检查过滤器配置是否覆盖目标 ID。 - 确认发送方数据段波特率 ≤ 5Mbps(GD32C103 上限)。 3. **错误状态恢复**: - 若进入总线关闭状态(`CAN_ESR_BOFF` 置位),需执行: ```c can_software_reset(CAN0); // 软件复位 CAN 外设 can_init(CAN0, &can_fd_init); // 重新初始化 ``` --- #### **四、参考资源** 1. GD32C103 用户手册(CANFD 章节)[^1]。 2. GD32C10x 标准外设库示例代码(`GD32C10x_Firmware_Library_V2.x.x\Examples\CAN`)[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值