-
GD32F205的CAN1接口引脚问题
我在使用GD32F205RET6器件实现CAN0和CAN1两个接口,实现接收中断,初始化如下: void CAN_init(void) { can_parameter_struct can_init_struct; can_filter_parameter_struct can_filter_struct; /************************** 1. 使能相关时钟 **************************/ // 使能GPIOA、GPIOB、AFIO时钟(复用功能依赖AFIO) rcu_periph_clock_enable(RCU_GPIOA); rcu_periph_clock_enable(RCU_GPIOB); rcu_periph_clock_enable(RCU_AF); // 使能CAN0和CAN1时钟(CAN1依赖CAN0时钟,手册3.17节) rcu_periph_clock_enable(RCU_CAN0); rcu_periph_clock_enable(RCU_CAN1); /************************** 2. 配置GPIO引脚 **************************/ // CAN0: PA11 (CAN0_RX), PA12 (CAN0_TX) - 默认引脚配置 // 注意:RX引脚应该配置为内部上拉输入,而不是浮空输入 gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12); // TX: 复用推挽输出 gpio_init(GPIOA, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_11); // RX: 内部上拉输入 // 4. 禁用USBFS(避免与CAN0复用冲突,文档表2-5:PA11=CAN0_RX/USBFS_DM) // usbfs_deinit(); // 如果需要重映射,取消下面的注释 // gpio_pin_remap_config(GPIO_CAN0_FULL_REMAP, ENABLE); // CAN1: PB12 (CAN1_RX), PB13 (CAN1_TX) - 默认引脚配置 gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13); // TX: 复用推挽输出 gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_12); // RX: 内部上拉输入 // 4. 禁用SPI1/I2C1(避免与CAN1复用冲突,文档表2-5:PB12=CAN1_RX/SPI1_NSS) spi_disable(SPI1); i2c_deinit(I2C1); // 如果需要重映射,取消下面的注释 // gpio_pin_remap_config(GPIO_CAN1_REMAP, ENABLE); /************************** 3. 复位CAN控制器 **************************/ can_deinit(CAN0); can_deinit(CAN1); /************************** 4. 配置CAN0(主控制器) **************************/ can_struct_para_init(CAN_INIT_STRUCT, &can_init_struct); // 工作模式:正常模式,自动重传,FIFO锁定(满后丢弃新帧) can_init_struct.auto_bus_off_recovery = ENABLE; can_init_struct.working_mode = CAN_NORMAL_MODE; can_init_struct.auto_bus_off_recovery = ENABLE; can_init_struct.time_triggered = DISABLE; can_init_struct.auto_bus_off_recovery = ENABLE; can_init_struct.auto_wake_up = DISABLE; can_init_struct.auto_retrans = ENABLE; // 使能自动重传 can_init_struct.rec_fifo_overwrite = ENABLE; // 允许FIFO覆盖 can_init_struct.trans_fifo_order = DISABLE; // 波特率配置:系统时钟120MHz → APB1分频2 → APB1时钟60MHz(手册5.3.2节) // 波特率=60MHz / [(BRP+1)*(1+TS1+TS2)] = 1Mbps → (BRP+1)*(1+TS1+TS2)=60 // 选择:BRP=4(0x04),TS1=10(0x0A,对应11TQ),TS2=1(0x01,对应2TQ) can_init_struct.resync_jump_width = CAN_BT_SJW_1TQ;// can_init_struct.time_segment_1 = CAN_BT_BS1_9TQ; // can_init_struct.time_segment_2 = CAN_BT_BS2_2TQ; // can_init_struct.prescaler = 5; // can_init(CAN0, &can_init_struct); /************************** 5. 配置CAN1(扩展控制器) **************************/ // CAN1复用CAN0的波特率配置(手册26.4节:CAN1无独立BRP寄存器) can_struct_para_init(CAN_INIT_STRUCT, &can_init_struct); can_init_struct.working_mode = CAN_NORMAL_MODE; can_init_struct.auto_bus_off_recovery = ENABLE; can_init_struct.time_triggered = DISABLE; can_init_struct.auto_bus_off_recovery = ENABLE; can_init_struct.auto_wake_up = DISABLE; //gai can_init_struct.auto_retrans = ENABLE; // 使能自动重传 can_init_struct.rec_fifo_overwrite = ENABLE; // 允许FIFO覆盖 can_init_struct.trans_fifo_order = DISABLE; can_init(CAN1, &can_init_struct); // can_working_mode_set(CAN1, CAN_NORMAL_MODE); /************************** 6. 配置过滤器(手册26.3.5节) **************************/ // 过滤器组0 → 分配给CAN0,映射到FIFO0,接收所有ID //can_filter_struct_init(&can_filter_struct); can_struct_para_init(CAN_FILTER_STRUCT, &can_filter_struct); can_filter_struct.filter_mode = CAN_FILTERMODE_MASK; can_filter_struct.filter_bits = CAN_FILTERBITS_32BIT; can_filter_struct.filter_list_high = 0x0000; can_filter_struct.filter_list_low = 0x0000; can_filter_struct.filter_mask_high = 0x0000; can_filter_struct.filter_mask_low = 0x0000; can_filter_struct.filter_number = 0; can_filter_struct.filter_enable = ENABLE; can_filter_struct.filter_fifo_number = CAN_FIFO0; can_filter_struct.filter_enable = ENABLE; can_filter_init(&can_filter_struct); // 过滤器组14 → 分配给CAN1,映射到FIFO1,接收所有ID(手册26.3.5节:14~27组归CAN1) can1_filter_start_bank(14); can_struct_para_init(CAN_FILTER_STRUCT, &can_filter_struct); can_filter_struct.filter_mode = CAN_FILTERMODE_MASK; can_filter_struct.filter_bits = CAN_FILTERBITS_32BIT; can_filter_struct.filter_list_high = 0x0000; can_filter_struct.filter_list_low = 0x0000; can_filter_struct.filter_mask_high = 0x0000; can_filter_struct.filter_mask_low = 0x0000; can_filter_struct.filter_number = 14; can_filter_struct.filter_enable = ENABLE; can_filter_struct.filter_fifo_number = CAN_FIFO1; can_filter_struct.filter_enable = ENABLE; can_filter_init(&can_filter_struct); /************************** 7. 使能接收FIFO不空中断(手册26.3.9节) **************************/ // CAN0 FIFO0非空中断 can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0); // CAN1 FIFO1非空中断(依赖CAN0的INTEN寄存器) can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE1); /************************** 8. 配置NVIC中断优先级 **************************/ nvic_irq_enable(CAN0_RX0_IRQn, 0, 1); // 优先级0,子优先级1 nvic_irq_enable(CAN1_RX1_IRQn, 1, 0); // 优先级0,子优先级0 } 结果是:CAN0正常,CAN1采用CAN0的FIFO1接收,时钟接收不到数据。现在的问题是 (1)CAN1的RX引脚是PB12,TX引脚是PB13有没有错,DataBook上是这样的,如果采用引脚映射CAN1_RX 可以是PB5,CAN1_TX可以是PB6; (2)CAN1是否真的不是独立的,而是依赖CAN0的FIFO1来接收数据,并由CAN0的FIFO1不空中断产生中断; (3)CAN1的接收过滤器与CAN0的过滤器是同一个模块,仅仅是CAN0采用0-13,CAN1采用14-27吗?
267浏览量 1回复量 关注量

问答