GD32C103的CAN使用问题

[复制链接]
3032|8
 楼主| zhangyh89 发表于 2021-11-19 15:57 | 显示全部楼层 |阅读模式
CAN, TE, pi, IO, ni
本帖最后由 zhangyh89 于 2021-11-20 15:54 编辑

最近在使用GD32C103的CAN功能,发现用一般的USB转CAN给GD32发指令的话USB转can的上位机经常提示有总线错误,如果发送数据过快还会出现USB转CAN离线的状态,USB转CAN需要重新启动才能继续发数据,但是两个不同类型的USB转CAN护发数据的就不会有问题,试过降低波特率加终端电阻都是会出现这些现象,不知道是不是GD32代码了CAN初始化的问题,还是硬件电路有问题。是否与SJW,BS1,BS2的设置有关,我设置波特率使用的GD32C103库函数自动计算的。


最终解决了,就是采样点的问题,用波特率计算器计算得出的结果进行配置后,can接收完全没有问题了,不过can-fd相关部分还是用的官方库函数的自动计算,can-fd模式下接收还是会偶尔会出现接收错误,这个错误不知道是不是由于使用的can接口芯片不支持超过1M波特率导致,暂时还没验证。附件内为波特兰率计算器
  1. typedef enum
  2. {
  3.         CAN_BDR_100K = 0,
  4.         CAN_BDR_125K ,
  5.         CAN_BDR_250K ,
  6.         CAN_BDR_500K ,
  7.         CAN_BDR_1000K
  8. }can_bdr_enum;
  1. void can0_gpio_config(void)
  2. {
  3.     /* enable CAN clock */
  4.     rcu_periph_clock_enable(RCU_CAN0);

  5.     rcu_periph_clock_enable(RCU_GPIOA);
  6.         rcu_periph_clock_enable(RCU_GPIOB);
  7.     rcu_periph_clock_enable(RCU_AF);
  8.         
  9.     gpio_pin_remap_config(GPIO_CAN0_PARTIAL_REMAP,ENABLE);
  10.         //gpio_pin_remap_config(GPIO_CAN0_FULL_REMAP,ENABLE);
  11.         
  12.     /* configure CAN0 GPIO */
  13.     gpio_init(GPIOB,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_8);
  14.     gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_9);
  15.         /* 终端电阻控制引脚*/
  16.     gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_10);
  17. }
  1. void can0_init(can_bdr_enum bdr,int baudrate_fd)
  2. {
  3.         can_parameter_struct CAN_InitStructure;
  4.     can_fd_tdc_struct can_fd_tdc_parameter;
  5.     can_fdframe_struct can_fd_parameter;         

  6.         rcu_periph_clock_enable(RCU_CAN0);
  7.         can_deinit(CAN0);
  8.         
  9.     can_struct_para_init(CAN_TX_MESSAGE_STRUCT, &g_transmit_message);
  10.     can_struct_para_init(CAN_RX_MESSAGE_STRUCT, &g_receive_message);
  11.         
  12.         can0_gpio_config();        
  13.         
  14.         if(bdr >= CAN_BDR_1000K)
  15.                   bdr = CAN_BDR_1000K;
  16.         
  17.         CAN_InitStructure.working_mode= CAN_NORMAL_MODE;
  18.         CAN_InitStructure.resync_jump_width= CAN_BT_SJW_1TQ;
  19.         CAN_InitStructure.time_segment_1= CAN_BAUDRATE_LIST[bdr].time_segment_1;//CAN_BT_BS1_12TQ;
  20.         CAN_InitStructure.time_segment_2= CAN_BAUDRATE_LIST[bdr].time_segment_2;//CAN_BT_BS2_7TQ;
  21.         CAN_InitStructure.time_triggered= DISABLE;
  22.         CAN_InitStructure.auto_bus_off_recovery= ENABLE;
  23.         CAN_InitStructure.auto_wake_up= ENABLE;
  24.         CAN_InitStructure.auto_retrans= ENABLE;
  25.         CAN_InitStructure.rec_fifo_overwrite= DISABLE;
  26.         CAN_InitStructure.trans_fifo_order= ENABLE;
  27.         CAN_InitStructure.prescaler= CAN_BAUDRATE_LIST[bdr].prescaler;//3;//CAN0总线的时钟 60M/((1+12+7)*3) = 1000k
  28.         can_init(CAN0, &CAN_InitStructure);

  29.     if(baudrate_fd != 0)
  30.     {
  31.         g_canfd_open = 1;
  32.         can_struct_para_init(CAN_FD_FRAME_STRUCT, &can_fd_parameter);
  33.         can_fd_parameter.fd_frame = ENABLE;
  34.         can_fd_parameter.excp_event_detect = ENABLE;
  35.         can_fd_parameter.delay_compensation = ENABLE;
  36.         can_fd_tdc_parameter.tdc_filter = 0x04;
  37.         can_fd_tdc_parameter.tdc_mode = CAN_TDCMOD_CALC_AND_OFFSET;
  38.         can_fd_tdc_parameter.tdc_offset = 0x04;
  39.         can_fd_parameter.p_delay_compensation = &can_fd_tdc_parameter;
  40.         can_fd_parameter.iso_bosch = CAN_FDMOD_ISO;
  41.         can_fd_parameter.esi_mode = CAN_ESIMOD_HARDWARE;
  42.         can_fd_init(CAN0, &can_fd_parameter);
  43.         can_fd_frequency_set(CAN0, baudrate_fd);   
  44.     }        
  45.         
  46.     //can1_filter_start_bank(14);
  47.     can_filter_mask_mode_init(0x001, 0x7FF, CAN_STANDARD_FIFO0, 0);
  48.         can_filter_mask_mode_init(0x0FF, 0x7FF, CAN_STANDARD_FIFO0, 1);
  49.     /* configure CAN0 NVIC */
  50.     nvic_irq_enable(CAN0_RX0_IRQn, 0, 0);
  51.         nvic_irq_enable(CAN0_TX_IRQn, 0, 0);

  52.     /* enable can receive FIFO0 not empty interrupt */
  53.     can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0);
  54.         can_interrupt_enable(CAN0, CAN_INT_TME);
  55. }
无标题.png

STM32CANBaudRate.zip

5.07 MB, 下载次数: 231

autodash 发表于 2021-11-19 16:39 | 显示全部楼层
你把采样点放在75%试试
dxfshsh 发表于 2021-11-19 17:57 | 显示全部楼层
不推荐使用自动波特率分配,其适配性,不可能做的很好,当您用到CANFD时,更是这样,您需要自己设计一个更加合理的分配方案。
imdx 发表于 2021-11-19 21:34 | 显示全部楼层
GD32E103那个自动计算波特率的函数有bug,不要用。不知道现在GD32C103的库改了没。
 楼主| zhangyh89 发表于 2021-11-19 23:43 | 显示全部楼层
imdx 发表于 2021-11-19 21:34
GD32E103那个自动计算波特率的函数有bug,不要用。不知道现在GD32C103的库改了没。 ...

请问有没有可以参靠的常用波特率设置代码,尝试更改BS1,BS2,还有分频,但是设完后完全无法通讯,估计还是设置有问题
 楼主| zhangyh89 发表于 2021-11-20 00:48 | 显示全部楼层
现确定了是自动波特率设置的bs1 bs2 swj有问题,改完后好多了不会出现任何错误了
  1. void can0_gpio_config(void)
  2. {
  3.     /* enable CAN clock */
  4.     rcu_periph_clock_enable(RCU_CAN0);

  5.     rcu_periph_clock_enable(RCU_GPIOA);
  6.         rcu_periph_clock_enable(RCU_GPIOB);
  7.     rcu_periph_clock_enable(RCU_AF);
  8.        
  9.     gpio_pin_remap_config(GPIO_CAN0_PARTIAL_REMAP,ENABLE);
  10.         //gpio_pin_remap_config(GPIO_CAN0_FULL_REMAP,ENABLE);
  11.        
  12.     /* configure CAN0 GPIO */
  13.     gpio_init(GPIOB,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_8);
  14.     gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_9);
  15.         /* 终端电阻控制引脚*/
  16.     gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_10);
  17. }

  18. void CAN_Configuration(void)
  19. {
  20.         can_parameter_struct CAN_InitStructure;
  21. //        can_filter_parameter_struct CAN_FilterInitStructure;
  22.         rcu_periph_clock_enable(RCU_CAN0);
  23.         can_deinit(CAN0);
  24.        
  25.         can0_gpio_config();       
  26.        
  27.         CAN_InitStructure.working_mode= CAN_NORMAL_MODE;
  28.         CAN_InitStructure.resync_jump_width= CAN_BT_SJW_1TQ;
  29.         CAN_InitStructure.time_segment_1= CAN_BT_BS1_12TQ;
  30.         CAN_InitStructure.time_segment_2= CAN_BT_BS2_7TQ;
  31.         CAN_InitStructure.time_triggered= DISABLE;
  32.         CAN_InitStructure.auto_bus_off_recovery= ENABLE;
  33.         CAN_InitStructure.auto_wake_up= ENABLE;
  34.         CAN_InitStructure.auto_retrans= ENABLE;
  35.         CAN_InitStructure.rec_fifo_overwrite= DISABLE;
  36.         CAN_InitStructure.trans_fifo_order= ENABLE;
  37.         CAN_InitStructure.prescaler=3;//CAN0总线的时钟 60M/((1+12+7)*3) = 1000k
  38.         can_init(CAN0, &CAN_InitStructure);

  39.     can1_filter_start_bank(14);
  40.     can_filter_mask_mode_init(0, 0, CAN_STANDARD_FIFO0, 0);
  41.     /* configure CAN0 NVIC */
  42.     nvic_irq_enable(CAN0_RX0_IRQn, 0, 0);
  43.     /* enable can receive FIFO0 not empty interrupt */
  44.     can_interrupt_enable(CAN0, CAN_INTEN_RFNEIE0);
  45. }
full_stack 发表于 2021-11-20 13:45 | 显示全部楼层
采样率保持一致,
full_stack 发表于 2021-11-20 13:46 | 显示全部楼层
这个问题,出现的原因就是不同CAN控制器,采样率不一样,采样点尽量接近。
autodash 发表于 2021-11-20 18:13 | 显示全部楼层
GD的demo代码的采样率就是随意来的,去看看nxp,freescale 车规芯片的采样率,那才是正确的。 采样率跟波特率和线长是有很大关系的。 如果你只是在桌面上测测,随便设定就行。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

13

主题

34

帖子

0

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