GD32E503的双CAN

[复制链接]
 楼主| wsl11111 发表于 2022-4-29 16:15 | 显示全部楼层 |阅读模式
最近在调试gd32e503的双can,can0已调通,CAN1不知道为什么一直不通,求帮忙给看一下,用的是GD32E503CET6,48pin,PB6和PB5引脚映射的CAN1.代码如下
  1. void Config_Can1_init( void )
  2. {
  3.     can_parameter_struct can_parameter;       
  4.     can_filter_parameter_struct can_filter;
  5.     /* enable CAN clock */
  6.     rcu_periph_clock_enable(RCU_CAN0);
  7.     rcu_periph_clock_enable(RCU_CAN1);   
  8.     /* configure CAN1 GPIO */
  9.     gpio_init(CAN1_RX_PORT,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,CAN1_RX_PIN);
  10.     gpio_init(CAN1_TX_PORT,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,CAN1_TX_PIN);   
  11.     gpio_pin_remap_config(GPIO_CAN1_REMAP,ENABLE);                  
  12.     can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);
  13.     /* initialize CAN register */
  14.     can_deinit(CAN1);
  15.     /* initialize CAN parameters */
  16.     can_parameter.working_mode = CAN_LOOPBACK_MODE;
  17.     can_parameter.time_triggered = DISABLE;
  18.     can_parameter.auto_bus_off_recovery = DISABLE;
  19.     can_parameter.auto_wake_up = DISABLE;
  20.     can_parameter.auto_retrans = DISABLE;
  21.     can_parameter.rec_fifo_overwrite = DISABLE;
  22.     can_parameter.trans_fifo_order = DISABLE;   
  23.     can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;/* configure CAN0 baud rate 1Mbps */
  24.     can_parameter.time_segment_1 = CAN_BT_BS1_5TQ;
  25.     can_parameter.time_segment_2 = CAN_BT_BS2_4TQ;
  26.     can_parameter.prescaler = 9;
  27.     /* initialize CAN */
  28.     can_init(CAN1, &can_parameter);   
  29.     /* initialize filter */
  30.     can_struct_para_init(CAN_INIT_STRUCT, &can_filter);
  31.     can_filter.filter_list_high = 0x00;
  32.     can_filter.filter_list_low = 0x00;
  33.     can_filter.filter_mask_high = 0x00;
  34.     can_filter.filter_mask_low = 0x00;
  35.     can_filter.filter_fifo_number = CAN_FIFO1;
  36.     can_filter.filter_number = 16;
  37.     can_filter.filter_mode = CAN_FILTERMODE_MASK;
  38.     can_filter.filter_bits = CAN_FILTERBITS_32BIT;
  39.     can_filter.filter_enable = ENABLE;
  40.     can_filter_init(CAN1,&can_filter);               
  41.     /* configure CAN1 NVIC */
  42.     nvic_irq_enable(CAN1_RX0_IRQn, 0, 1);
  43.     /* enable can receive FIFO1 not empty interrupt */
  44.     can_interrupt_enable(CAN1, CAN_INTEN_RFNEIE1);                       
  45. }
  46. void CAN1_RX0_IRQHandler(void)
  47. {
  48.     /* check the receive message */
  49.    can_message_receive(CAN1, CAN_FIFO1, &gcan1_receive_message);
  50.    printf("\r\n can1 receive data:%02x %02x",gcan1_receive_message.rx_data[0],gcan1_receive_message.rx_data[1]);
  51. }



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

评论

在用回环模式进行调试,一直收不到数据,can0接受用的FIFO0,过滤器0,can0中断可以正常接收。can1用的FIFO1,过滤器16,收不到数据  发表于 2022-4-29 16:17
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 | 显示全部楼层
  1. void CAN_Init(void)
  2. {
  3.         can_parameter_struct can_parameter;
  4.         can_filter_parameter_struct can_filter;
  5.        
  6.         /* enable CAN clock */
  7.         rcu_periph_clock_enable(RCU_CAN0);
  8. #if CONFIG_CAN1_EN
  9.     rcu_periph_clock_enable(RCU_CAN1);
  10. #endif
  11.         rcu_periph_clock_enable(RCU_GPIOA);
  12.     rcu_periph_clock_enable(RCU_GPIOB);

  13.         /* configure CAN1 GPIO */
  14.     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_11);
  15.     gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_11);
  16.     gpio_af_set(GPIOA, GPIO_AF_9, GPIO_PIN_11);
  17.    
  18.     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
  19.     gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_12);
  20.     gpio_af_set(GPIOA, GPIO_AF_9, GPIO_PIN_12);

  21.     /* initialize CAN register */
  22.     can_deinit(CAN0);
  23. #if CONFIG_CAN1_EN
  24.         /* configure CAN1 GPIO */
  25.     gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_5);
  26.     gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_5);
  27.     gpio_af_set(GPIOB, GPIO_AF_9, GPIO_PIN_5);
  28.    
  29.     gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
  30.     gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_6);
  31.     gpio_af_set(GPIOB, GPIO_AF_9, GPIO_PIN_6);

  32.     /* initialize CAN register */
  33.     can_deinit(CAN1);
  34. #endif

  35.         can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);
  36.     can_struct_para_init(CAN_INIT_STRUCT, &can_filter);
  37.        
  38.     /* initialize CAN parameters */
  39.     can_parameter.time_triggered = DISABLE;
  40.     can_parameter.auto_bus_off_recovery = DISABLE;
  41.     can_parameter.auto_wake_up = DISABLE;
  42.     can_parameter.no_auto_retrans = DISABLE;
  43.     can_parameter.rec_fifo_overwrite = DISABLE;
  44.     can_parameter.trans_fifo_order = DISABLE;
  45.     can_parameter.working_mode = CAN_NORMAL_MODE;
  46.     can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
  47.     can_parameter.time_segment_1 = CAN_BT_BS1_3TQ;
  48.     can_parameter.time_segment_2 = CAN_BT_BS2_3TQ;
  49.         /* 1MBps */
  50. #if CAN_BAUDRATE == 1000
  51.     can_parameter.prescaler = 6;
  52.     /* 500KBps */
  53. #elif CAN_BAUDRATE == 500
  54.     can_parameter.prescaler = 10;
  55.     /* 250KBps */
  56. #elif CAN_BAUDRATE == 250
  57.     can_parameter.prescaler = 20;
  58.     /* 125KBps */
  59. #elif CAN_BAUDRATE == 125
  60.     can_parameter.prescaler = 40;
  61.     /* 100KBps */
  62. #elif  CAN_BAUDRATE == 100
  63.     can_parameter.prescaler = 50;
  64.     /* 50KBps */
  65. #elif  CAN_BAUDRATE == 50
  66.     can_parameter.prescaler = 100;
  67.     /* 20KBps */
  68. #elif  CAN_BAUDRATE == 20
  69.     can_parameter.prescaler = 250;
  70. #else
  71.         #error "please select list can baudrate in private defines in main.c "
  72. #endif

  73.         can_init(CAN0, &can_parameter);
  74. #if CONFIG_CAN1_EN
  75.         /* initialize CAN */
  76.     can_init(CAN1, &can_parameter);
  77. #endif   
  78.         //can1_filter_start_bank(14);
  79.     /* initialize filter */
  80.     can_filter.filter_number = 0;        //CAN0:0->13;CAN1:14->27
  81.     can_filter.filter_mode = CAN_FILTERMODE_MASK;
  82.     can_filter.filter_bits = CAN_FILTERBITS_32BIT;
  83.     can_filter.filter_list_high = 0x0000;//0x3000;
  84.     can_filter.filter_list_low = 0x0000;
  85.     can_filter.filter_mask_high = 0x0000;//0x3000;
  86.     can_filter.filter_mask_low = 0x0000;
  87.     can_filter.filter_fifo_number = CAN_FIFO0;
  88.     can_filter.filter_enable = ENABLE;
  89.     can_filter_init(&can_filter);

  90. #if CONFIG_CAN1_EN       
  91.         can_filter.filter_fifo_number = CAN_FIFO1;
  92.         can_filter.filter_number = 15;
  93.         can_filter_init(&can_filter);
  94. #endif   
  95. }
开中断是写在别的地方
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 | 显示全部楼层
微信截图_20220506160316.png 接收时看下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号滤波器。照片在下面
image.jpg
 楼主| wsl11111 发表于 2022-5-7 13:56 来自手机 | 显示全部楼层
sagade 发表于 2022-5-6 16:06
接收时看下FIFO1里面是否有数据,我原先是中断服务函数写成CAN1_RX0_IRQHandler了,导致FIFO1是有数据的, ...

老哥我回复到下面了
 楼主| wsl11111 发表于 2022-5-7 13:58 来自手机 | 显示全部楼层
清晰的图片
A8E256EA-A60D-40C2-8619-CA9B01AE3D18.jpeg
 楼主| 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
\param[in]  can_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
\param  can_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 也是根据您上面得代码调试得,也没通过。方便得话能发我一个完成的吗? 有偿也可以得 ...

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

评论

也正在踩这个坑,能方便转发一份吗,2210117311@qq.com  发表于 2024-6-27 17:25
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

14

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部