打印

GD32E503的双CAN

[复制链接]
2999|26
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
最近在调试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[0],gcan1_receive_message.rx_data[1]);
}



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

使用特权

评论回复
评论
wsl11111 2022-4-29 16:17 回复TA
在用回环模式进行调试,一直收不到数据,can0接受用的FIFO0,过滤器0,can0中断可以正常接收。can1用的FIFO1,过滤器16,收不到数据 
沙发
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 | 只看该作者
别沉啊,大家帮忙看看,困扰好久了,是在找不出来问题

使用特权

评论回复
5
sagade| | 2022-5-6 12:58 | 只看该作者
楼上老哥说了是要开CAN1_RX1_IRQn中断,然后中断服务函数也要改成CAN1_RX1_IRQHandler。GD32F4是可以的,E5的CAN看着差不多的。
can1_filter_start_bank貌似不设置也行,默认CAN1的过滤器是从15开始的。

使用特权

评论回复
6
wsl11111|  楼主 | 2022-5-6 15:20 | 只看该作者
sagade 发表于 2022-5-6 12:58
楼上老哥说了是要开CAN1_RX1_IRQn中断,然后中断服务函数也要改成CAN1_RX1_IRQHandler。GD32F4是可以的,E5 ...

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

使用特权

评论回复
7
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 */
#elif  CAN_BAUDRATE == 100
    can_parameter.prescaler = 50;
    /* 50KBps */
#elif  CAN_BAUDRATE == 50
    can_parameter.prescaler = 100;
    /* 20KBps */
#elif  CAN_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);

}

使用特权

评论回复
8
sagade| | 2022-5-6 16:06 | 只看该作者
接收时看下FIFO1里面是否有数据,我原先是中断服务函数写成CAN1_RX0_IRQHandler了,导致FIFO1是有数据的,但是不进CAN1_RX0_IRQHandler,改成CAN1_RX1_IRQHandler就可以了

使用特权

评论回复
9
wsl11111|  楼主 | 2022-5-7 13:56 | 只看该作者
老哥,按照你说的我查了一下问题。发现can1发送都是正常,邮箱里的数据和发送完成后的标志都有。但是接收fifo一直没有反应。后来发现can1分配14号滤波器后,使能以后看CAN_FW寄存器里只有can0使能的0号滤波器,而没有14号滤波器。照片在下面

image.jpg (435.22 KB )

image.jpg

使用特权

评论回复
10
wsl11111|  楼主 | 2022-5-7 13:56 | 只看该作者
sagade 发表于 2022-5-6 16:06
接收时看下FIFO1里面是否有数据,我原先是中断服务函数写成CAN1_RX0_IRQHandler了,导致FIFO1是有数据的, ...

老哥我回复到下面了

使用特权

评论回复
11
wsl11111|  楼主 | 2022-5-7 13:58 | 只看该作者
清晰的图片

A8E256EA-A60D-40C2-8619-CA9B01AE3D18.jpeg (505.68 KB )

A8E256EA-A60D-40C2-8619-CA9B01AE3D18.jpeg

使用特权

评论回复
12
wsl11111|  楼主 | 2022-5-7 14:40 | 只看该作者
终于找到问题了。太坑了,所有接收的滤波器都归can0,配置can1的滤波器时也需要输入can0的地址才可以。can_filter_init(CAN0,&can_filter)

使用特权

评论回复
13
duzhiqiang521| | 2022-5-7 15:15 | 只看该作者
wsl11111 发表于 2022-5-7 14:40
终于找到问题了。太坑了,所有接收的滤波器都归can0,配置can1的滤波器时也需要输入can0的地址才可以。can_ ...

恭喜解决问题,不容易!

使用特权

评论回复
14
sagade| | 2022-5-7 15:38 | 只看该作者
恭喜解决问题,原来E5的can_filter_init和F4有点不一样,需要指定CAN0或者CAN2,没有CAN1
\param[in]  can_periph
      \arg        CANx(x=0,2),the CAN2 only for GD32E50X_CL and GD32E508

使用特权

评论回复
15
wsl11111|  楼主 | 2022-5-9 14:02 | 只看该作者
sagade 发表于 2022-5-7 15:38
恭喜解决问题,原来E5的can_filter_init和F4有点不一样,需要指定CAN0或者CAN2,没有CAN1
\param  can_peri ...

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

使用特权

评论回复
16
lv19920909| | 2022-5-11 14:23 | 只看该作者
老哥,我这调试503 CAN得时候总是过不了 能分享一下代码吗

使用特权

评论回复
17
tail066| | 2022-5-11 21:37 | 只看该作者
调试出个好底子,受益无穷

使用特权

评论回复
18
wsl11111|  楼主 | 2022-5-13 15:18 | 只看该作者
lv19920909 发表于 2022-5-11 14:23
老哥,我这调试503 CAN得时候总是过不了 能分享一下代码吗

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

使用特权

评论回复
19
lv19920909| | 2022-5-13 15:41 | 只看该作者
我也是调双CAN   CAN1 也是根据您上面得代码调试得,也没通过。方便得话能发我一个完成的吗?84960909@qq.com 有偿也可以得

使用特权

评论回复
20
wsl11111|  楼主 | 2022-5-22 20:34 | 只看该作者
lv19920909 发表于 2022-5-13 15:41
我也是调双CAN   CAN1 也是根据您上面得代码调试得,也没通过。方便得话能发我一个完成的吗? 有偿也可以得 ...

不好意思兄弟兄弟,刚看到给你发过去了

使用特权

评论回复
评论
dc717019803 2024-6-27 17:25 回复TA
也正在踩这个坑,能方便转发一份吗,2210117311@qq.com 
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

14

帖子

0

粉丝