wsl11111 发表于 2022-4-29 16:15

GD32E503的双CAN

最近在调试gd32e503的双can,can0已调通,CAN1不知道为什么一直不通,求帮忙给看一下,用的是GD32E503CET6,48pin,PB6和PB5引脚映射的CAN1.代码如下
void Config_Can1_init( void )
{
    can_parameter_struct can_parameter;       
    can_filter_parameter_struct can_filter;
    /* enable CAN clock */
    rcu_periph_clock_enable(RCU_CAN0);
    rcu_periph_clock_enable(RCU_CAN1);   
    /* configure CAN1 GPIO */
    gpio_init(CAN1_RX_PORT,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,CAN1_RX_PIN);
    gpio_init(CAN1_TX_PORT,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,CAN1_TX_PIN);   
    gpio_pin_remap_config(GPIO_CAN1_REMAP,ENABLE);                  
    can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);
    /* initialize CAN register */
    can_deinit(CAN1);
    /* initialize CAN parameters */
    can_parameter.working_mode = CAN_LOOPBACK_MODE;
    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.resync_jump_width = CAN_BT_SJW_1TQ;/* configure CAN0 baud rate 1Mbps */
    can_parameter.time_segment_1 = CAN_BT_BS1_5TQ;
    can_parameter.time_segment_2 = CAN_BT_BS2_4TQ;
    can_parameter.prescaler = 9;
    /* initialize CAN */
    can_init(CAN1, &can_parameter);   
    /* initialize filter */
    can_struct_para_init(CAN_INIT_STRUCT, &can_filter);
    can_filter.filter_list_high = 0x00;
    can_filter.filter_list_low = 0x00;
    can_filter.filter_mask_high = 0x00;
    can_filter.filter_mask_low = 0x00;
    can_filter.filter_fifo_number = CAN_FIFO1;
    can_filter.filter_number = 16;
    can_filter.filter_mode = CAN_FILTERMODE_MASK;
    can_filter.filter_bits = CAN_FILTERBITS_32BIT;
    can_filter.filter_enable = ENABLE;
    can_filter_init(CAN1,&can_filter);               
    /* configure CAN1 NVIC */
    nvic_irq_enable(CAN1_RX0_IRQn, 0, 1);
    /* enable can receive FIFO1 not empty interrupt */
    can_interrupt_enable(CAN1, CAN_INTEN_RFNEIE1);                       
}
void CAN1_RX0_IRQHandler(void)
{
    /* check the receive message */
   can_message_receive(CAN1, CAN_FIFO1, &gcan1_receive_message);
   printf("\r\n can1 receive data:%02x %02x",gcan1_receive_message.rx_data,gcan1_receive_message.rx_data);
}


急,有人帮忙看看吗?官方的例程都是can0的,can1的例程根本找不到

starsuper123 发表于 2022-4-29 16:55

你can1的接收中断应该是CAN1_RX1_IRQn这个,还有你没分配滤波器,用这个函数can1_filter_start_bank(uint8_t start_bank),哦,接收服务函数记得改一下

wsl11111 发表于 2022-4-29 17:42

starsuper123 发表于 2022-4-29 16:55
你can1的接收中断应该是CAN1_RX1_IRQn这个,还有你没分配滤波器,用这个函数can1_filter_start_bank(uint8_ ...

分配can1的滤波器,内个函数在初始化can0时候调用了。我在can1配置滤波器结构体里选择了15号滤波器,然后改成rx1_irqn后也接收不到数据。

wsl11111 发表于 2022-5-5 10:35

别沉啊,大家帮忙看看,困扰好久了,是在找不出来问题

sagade 发表于 2022-5-6 12:58

楼上老哥说了是要开CAN1_RX1_IRQn中断,然后中断服务函数也要改成CAN1_RX1_IRQHandler。GD32F4是可以的,E5的CAN看着差不多的。
can1_filter_start_bank貌似不设置也行,默认CAN1的过滤器是从15开始的。

wsl11111 发表于 2022-5-6 15:20

sagade 发表于 2022-5-6 12:58
楼上老哥说了是要开CAN1_RX1_IRQn中断,然后中断服务函数也要改成CAN1_RX1_IRQHandler。GD32F4是可以的,E5 ...

中断是修改成can1_rx1_irqn的中断了,但是还是不行。老哥,f4的例程能参考一下吗?

sagade 发表于 2022-5-6 16:00

void CAN_Init(void)
{
        can_parameter_struct can_parameter;
        can_filter_parameter_struct can_filter;
       
        /* enable CAN clock */
        rcu_periph_clock_enable(RCU_CAN0);
#if CONFIG_CAN1_EN
    rcu_periph_clock_enable(RCU_CAN1);
#endif
        rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_GPIOB);

        /* configure CAN1 GPIO */
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11);
    gpio_af_set(GPIOA, GPIO_AF_9, GPIO_PIN_11);
   
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12);
    gpio_af_set(GPIOA, GPIO_AF_9, GPIO_PIN_12);

    /* initialize CAN register */
    can_deinit(CAN0);
#if CONFIG_CAN1_EN
        /* configure CAN1 GPIO */
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5);
    gpio_af_set(GPIOB, GPIO_AF_9, GPIO_PIN_5);
   
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
    gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6);
    gpio_af_set(GPIOB, GPIO_AF_9, GPIO_PIN_6);

    /* initialize CAN register */
    can_deinit(CAN1);
#endif

        can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);
    can_struct_para_init(CAN_INIT_STRUCT, &can_filter);
       
    /* initialize CAN parameters */
    can_parameter.time_triggered = DISABLE;
    can_parameter.auto_bus_off_recovery = DISABLE;
    can_parameter.auto_wake_up = DISABLE;
    can_parameter.no_auto_retrans = DISABLE;
    can_parameter.rec_fifo_overwrite = DISABLE;
    can_parameter.trans_fifo_order = DISABLE;
    can_parameter.working_mode = CAN_NORMAL_MODE;
    can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
    can_parameter.time_segment_1 = CAN_BT_BS1_3TQ;
    can_parameter.time_segment_2 = CAN_BT_BS2_3TQ;
        /* 1MBps */
#if CAN_BAUDRATE == 1000
    can_parameter.prescaler = 6;
    /* 500KBps */
#elif CAN_BAUDRATE == 500
    can_parameter.prescaler = 10;
    /* 250KBps */
#elif CAN_BAUDRATE == 250
    can_parameter.prescaler = 20;
    /* 125KBps */
#elif CAN_BAUDRATE == 125
    can_parameter.prescaler = 40;
    /* 100KBps */
#elifCAN_BAUDRATE == 100
    can_parameter.prescaler = 50;
    /* 50KBps */
#elifCAN_BAUDRATE == 50
    can_parameter.prescaler = 100;
    /* 20KBps */
#elifCAN_BAUDRATE == 20
    can_parameter.prescaler = 250;
#else
        #error "please select list can baudrate in private defines in main.c "
#endif

        can_init(CAN0, &can_parameter);
#if CONFIG_CAN1_EN
        /* initialize CAN */
    can_init(CAN1, &can_parameter);
#endif   
        //can1_filter_start_bank(14);
    /* initialize filter */
    can_filter.filter_number = 0;        //CAN0:0->13;CAN1:14->27
    can_filter.filter_mode = CAN_FILTERMODE_MASK;
    can_filter.filter_bits = CAN_FILTERBITS_32BIT;
    can_filter.filter_list_high = 0x0000;//0x3000;
    can_filter.filter_list_low = 0x0000;
    can_filter.filter_mask_high = 0x0000;//0x3000;
    can_filter.filter_mask_low = 0x0000;
    can_filter.filter_fifo_number = CAN_FIFO0;
    can_filter.filter_enable = ENABLE;
    can_filter_init(&can_filter);

#if CONFIG_CAN1_EN       
        can_filter.filter_fifo_number = CAN_FIFO1;
        can_filter.filter_number = 15;
        can_filter_init(&can_filter);
#endif   
}开中断是写在别的地方
nvic_irq_enable(CAN1_RX1_IRQn,0,0);
can_interrupt_enable(CAN1, CAN_INT_RFNE1);然后是中断服务函数

void CAN1_RX1_IRQHandler(void)
{
        can_receive_message_struct receive_message;
        can_message_receive(CAN1, CAN_FIFO1, &receive_message);

}

sagade 发表于 2022-5-6 16:06

接收时看下FIFO1里面是否有数据,我原先是中断服务函数写成CAN1_RX0_IRQHandler了,导致FIFO1是有数据的,但是不进CAN1_RX0_IRQHandler,改成CAN1_RX1_IRQHandler就可以了

wsl11111 发表于 2022-5-7 13:56

老哥,按照你说的我查了一下问题。发现can1发送都是正常,邮箱里的数据和发送完成后的标志都有。但是接收fifo一直没有反应。后来发现can1分配14号滤波器后,使能以后看CAN_FW寄存器里只有can0使能的0号滤波器,而没有14号滤波器。照片在下面

wsl11111 发表于 2022-5-7 13:56

sagade 发表于 2022-5-6 16:06
接收时看下FIFO1里面是否有数据,我原先是中断服务函数写成CAN1_RX0_IRQHandler了,导致FIFO1是有数据的, ...

老哥我回复到下面了

wsl11111 发表于 2022-5-7 13:58

清晰的图片

wsl11111 发表于 2022-5-7 14:40

终于找到问题了。太坑了,所有接收的滤波器都归can0,配置can1的滤波器时也需要输入can0的地址才可以。can_filter_init(CAN0,&can_filter)

duzhiqiang521 发表于 2022-5-7 15:15

wsl11111 发表于 2022-5-7 14:40
终于找到问题了。太坑了,所有接收的滤波器都归can0,配置can1的滤波器时也需要输入can0的地址才可以。can_ ...

恭喜解决问题,不容易!

sagade 发表于 2022-5-7 15:38

恭喜解决问题,原来E5的can_filter_init和F4有点不一样,需要指定CAN0或者CAN2,没有CAN1
\paramcan_periph
      \arg      CANx(x=0,2),the CAN2 only for GD32E50X_CL and GD32E508

wsl11111 发表于 2022-5-9 14:02

sagade 发表于 2022-5-7 15:38
恭喜解决问题,原来E5的can_filter_init和F4有点不一样,需要指定CAN0或者CAN2,没有CAN1
\paramcan_peri ...

是的,没有仔细看这个函数的入口参数。感谢老哥的帮助

lv19920909 发表于 2022-5-11 14:23

老哥,我这调试503 CAN得时候总是过不了 能分享一下代码吗

tail066 发表于 2022-5-11 21:37

调试出个好底子,受益无穷

wsl11111 发表于 2022-5-13 15:18

lv19920909 发表于 2022-5-11 14:23
老哥,我这调试503 CAN得时候总是过不了 能分享一下代码吗

我这上面分享的是CAN1的代码,你调的哪个can

lv19920909 发表于 2022-5-13 15:41

我也是调双CAN   CAN1 也是根据您上面得代码调试得,也没通过。方便得话能发我一个完成的吗?84960909@qq.com 有偿也可以得

wsl11111 发表于 2022-5-22 20:34

lv19920909 发表于 2022-5-13 15:41
我也是调双CAN   CAN1 也是根据您上面得代码调试得,也没通过。方便得话能发我一个完成的吗? 有偿也可以得 ...

不好意思兄弟兄弟,刚看到给你发过去了
页: [1] 2
查看完整版本: GD32E503的双CAN