硬汉嵌入式论坛

 找回密码
 立即注册
查看: 380|回复: 18
收起左侧

[CAN/FDCAN] CANFD加速-如何配置

[复制链接]

1

主题

0

回帖

3

积分

新手上路

积分
3
发表于 2024-3-22 10:09:53 | 显示全部楼层 |阅读模式
测试发现使用CANFD的时候,有CANFD和CANFD加速两种

使用STM32H7,1M仲裁4M数据的方式,连接ZLG的CANFD卡测试
问题:
(1)无法发出CANFD加速,只能发出CANFD;
(2)ZLG的CANFD卡,发出CANFD加速报文,会报错;
2024-03-22_100815.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
发表于 2024-3-22 11:26:15 | 显示全部楼层
可能是你PHY芯片的问题,以我们TOOL为例,支持数据段5Mbps,仲裁段1Mbps

论坛有原理图可以下载,使用我们的这款PHY试试。




回复

使用道具 举报

0

主题

2

回帖

2

积分

新手上路

积分
2
发表于 2024-3-22 11:37:33 | 显示全部楼层
CAN FD与CAN FD加速的区别在于是否使能BRS,如果没有使能BRS就只能配置成1M+1M,使能BRS之后数据域才能配置超过1M,你现在这种情况应该就是BRS没有配置
回复

使用道具 举报

8

主题

157

回帖

181

积分

初级会员

积分
181
发表于 2024-3-22 14:39:50 | 显示全部楼层
配置波特率的时候,三种选项,你选FD加速的即可。
回复

使用道具 举报

0

主题

9

回帖

9

积分

新手上路

积分
9
发表于 7 天前 | 显示全部楼层
我也遇到和楼主同样的问题,和周立功用  "CANFD加速 " 通讯错误,请问楼主具体是怎么解决的?  
回复

使用道具 举报

0

主题

9

回帖

9

积分

新手上路

积分
9
发表于 7 天前 | 显示全部楼层
用的STM32H750VBT6 芯片,已经设置了:
CanHandle.Init.FrameFormat =FDCAN_FRAME_FD_BRS;     //CANFD加速  

HAL_FDCAN_ConfigTxDelayCompensation(&CanHandle, CanHandle.Init.DataPrescaler *         CanHandle.Init.DataTimeSeg1  ,0);       
HAL_FDCAN_EnableTxDelayCompensation(&CanHandle);       

还有哪些地方需要设置吗?请高人指点,万分感谢!
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
发表于 7 天前 | 显示全部楼层
Z先生 发表于 2024-4-22 15:48
用的STM32H750VBT6 芯片,已经设置了:
CanHandle.Init.FrameFormat =FDCAN_FRAME_FD_BRS;     //CANFD加 ...

终端电阻都带上测试下。
回复

使用道具 举报

0

主题

9

回帖

9

积分

新手上路

积分
9
发表于 7 天前 | 显示全部楼层
CANFD 模式下8M都能正常通讯,终端电阻也没问题, PHY 也没问题(最高可以支持12M),就是  “CANFD加速”   模式有问题,我怀疑就是哪里没设置对,查了半个月了,就没解决,碰巧这里发现了个和我一样的问题,请大神指导!
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
发表于 7 天前 | 显示全部楼层
Z先生 发表于 2024-4-22 16:19
CANFD 模式下8M都能正常通讯,终端电阻也没问题, PHY 也没问题(最高可以支持12M),就是  “CANFD加速”  ...

你当前用那款PHY,方便的话,CAN原理图和CANFD配置代码帖子下。
回复

使用道具 举报

0

主题

9

回帖

9

积分

新手上路

积分
9
发表于 7 天前 | 显示全部楼层
d:\can.png
回复

使用道具 举报

0

主题

9

回帖

9

积分

新手上路

积分
9
发表于 7 天前 | 显示全部楼层
void CAN1_Init(uint8_t *Rx_Buff, u8 Mode, uint32_t tsjw, uint32_t d_tbs1, uint32_t d_tbs2, uint16_t d_brp,uint32_t n_tbs1, uint32_t n_tbs2,uint16_t n_brp,u8 ReSend,u8  cfg_class_canFD_1)  
{
          HAL_FDCAN_DeInit(&Can1Handle);   
       
        FDCAN_ClkCalUnitTypeDef FDCAN1_ClkCalUnit;
        //CAN1_RxMsg.data = Rx_Buff;
       
        Can1Handle.Instance = FDCAN1;
        Can1Handle.State = HAL_FDCAN_STATE_RESET;
       
        if(cfg_class_canFD_1==1)  //CANFD
        {
            Can1Handle.Init.FrameFormat =FDCAN_FRAME_FD_NO_BRS;     //CANFD
      HAL_FDCAN_DisableTxDelayCompensation(&Can1Handle);               
        }               
        else if(cfg_class_canFD_1==2)  //CANFD加速
        {
                  Can1Handle.Init.FrameFormat =FDCAN_FRAME_FD_BRS;     //CANFD加速  
        }
        else if(cfg_class_canFD_1==3)  //CAN2.0
        {
                  Can1Handle.Init.FrameFormat =FDCAN_FRAME_CLASSIC;     //传统模式  
                  HAL_FDCAN_DisableTxDelayCompensation(&Can1Handle);               
        }
       
        if(Mode==0x00)
            Can1Handle.Init.Mode = FDCAN_MODE_NORMAL;
        else if(Mode==0x01)
                  Can1Handle.Init.Mode = FDCAN_MODE_BUS_MONITORING;
       
        if(ReSend==0)
           Can1Handle.Init.AutoRetransmission = DISABLE ;//ENABLE;     //关闭自动重传!传统模式下一定要关闭!!!
        else if(ReSend==1)
           Can1Handle.Init.AutoRetransmission = ENABLE ;//ENABLE;     //关闭自动重传!传统模式下一定要关闭!!!
       
        Can1Handle.Init.TransmitPause = DISABLE;         //关闭传输暂停
        Can1Handle.Init.ProtocolException = ENABLE;      //关闭协议异常处理
       
        Can1Handle.Init.NominalPrescaler = n_brp;          //分频系数
        Can1Handle.Init.NominalSyncJumpWidth = n_tbs2;     // tsjw;      //重新同步跳跃宽度
        Can1Handle.Init.NominalTimeSeg1 = n_tbs1;          //tsg1范围:2~256
        Can1Handle.Init.NominalTimeSeg2 = n_tbs2;           //tsg2范围:2~128
       
        Can1Handle.Init.DataPrescaler = d_brp;
        Can1Handle.Init.DataSyncJumpWidth =d_tbs2   ;//0x4;   
        Can1Handle.Init.DataTimeSeg1 = d_tbs1; /* DataTimeSeg1 = Propagation_segment + Phase_segment_1 */  //0x05
        Can1Handle.Init.DataTimeSeg2 = d_tbs2;                                                             //0x04
       
                Can1Handle.Init.MessageRAMOffset = 0;                           //信息RAM偏移
        Can1Handle.Init.StdFiltersNbr = 1;                              //标准信息ID滤波器编号   原来=1
        Can1Handle.Init.ExtFiltersNbr = 1;                              //扩展信息ID滤波器编号    原来=1
        Can1Handle.Init.RxFifo0ElmtsNbr = 12;                            //接收FIFO0元素编号      原来=12
        Can1Handle.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_64;           //接收FIFO0元素大小:8字节
        Can1Handle.Init.RxFifo1ElmtsNbr = 0;                            //接收FIFO1元素编号    2
        Can1Handle.Init.RxBuffersNbr = 0;  
               Can1Handle.Init.RxBufferSize=FDCAN_DATA_BYTES_64;
        Can1Handle.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_64;  
       
        Can1Handle.Init.TxEventsNbr = 0;                                //发送事件编号
        Can1Handle.Init.TxBuffersNbr = 0;                               //发送缓冲编号
        Can1Handle.Init.TxFifoQueueElmtsNbr =16;                        //发送FIFO序列元素编号   正确的=16
        Can1Handle.Init.TxFifoQueueMode =FDCAN_TX_FIFO_OPERATION ;// FDCAN_TX_QUEUE_OPERATION ;//FDCAN_TX_FIFO_OPERATION;      //发送FIFO序列模式
        Can1Handle.Init.TxElmtSize = FDCAN_DATA_BYTES_64;                //发送大小:8字节
        HAL_FDCAN_Init(&Can1Handle);
               
        //配置CAN滤波器
         sFilterConfig11.IdType = FDCAN_STANDARD_ID;                //标准ID  ;  FDCAN_STANDARD_ID;     
        sFilterConfig11.FilterIndex = 0;                           //滤波器索引  0
        sFilterConfig11.FilterType = FDCAN_FILTER_RANGE;  //FDCAN_FILTER_DUAL;  FDCAN_FILTER_MASK;            //滤波器类型
        sFilterConfig11.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;    //过滤器0关联到FIFO0  
        sFilterConfig11.FilterID1 = 0x000;
        sFilterConfig11.FilterID2 = 0x7FF; /* For acceptance, MessageID and FilterID1 must match exactly */
        HAL_FDCAN_ConfigFilter(&Can1Handle, &sFilterConfig11);
       
        //------------------------------------------------
                sFilterConfig12.IdType = FDCAN_EXTENDED_ID;              //扩展帧
        sFilterConfig12.FilterIndex = 0;   
        sFilterConfig12.FilterType = FDCAN_FILTER_RANGE;  //FDCAN_FILTER_DUAL;  FDCAN_FILTER_MASK;            //滤波器类型
        sFilterConfig12.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;    //过滤器0关联到FIFO0  
        sFilterConfig12.FilterID1 = 0x00000000;
        sFilterConfig12.FilterID2 = 0x1FFFFFFF; /* For acceptance, MessageID and FilterID1 must match exactly */
        HAL_FDCAN_ConfigFilter(&Can1Handle, &sFilterConfig12);
       
        //-----------------------------------------------
        FDCAN1_ClkCalUnit.ClockCalibration=DISABLE;                                                //?????????
        FDCAN1_ClkCalUnit.ClockDivider=FDCAN_CLOCK_DIV1;                                //4??,??50Mhz?fdca_tq_ck
        HAL_FDCAN_ConfigClockCalibration(&Can1Handle,&FDCAN1_ClkCalUnit);        //????

        HAL_FDCAN_ActivateNotification(&Can1Handle,FDCAN_IT_RX_FIFO0_NEW_MESSAGE,0);
       
        if(cfg_class_canFD_1==2)  //CANFD加速
        {                                                                                                                     
                     HAL_FDCAN_ConfigTxDelayCompensation(&Can1Handle, Can1Handle.Init.DataPrescaler *  Can1Handle.Init.DataTimeSeg1  ,0);       
                     HAL_FDCAN_EnableTxDelayCompensation(&Can1Handle);               
        }       

        //启动FDCAN模块
        HAL_FDCAN_Start(&Can1Handle);
}
回复

使用道具 举报

0

主题

9

回帖

9

积分

新手上路

积分
9
发表于 7 天前 | 显示全部楼层
原理图和初始化代码如上,目前在 CAN2.0  和  CANFD 模式下都能正常和周立功通讯,和研华的CAN2.0和CANFD也能正常通讯,CANFD从1M到8M都没问题, 但设置为  CANFD加速 ,周立功那边就报错了
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
发表于 7 天前 | 显示全部楼层
Z先生 发表于 2024-4-22 19:40
原理图和初始化代码如上,目前在 CAN2.0  和  CANFD 模式下都能正常和周立功通讯,和研华的CAN2.0和CANFD也 ...

原理图没贴上,要专门上传下。
回复

使用道具 举报

0

主题

9

回帖

9

积分

新手上路

积分
9
发表于 7 天前 | 显示全部楼层
eric2013 发表于 2024-4-22 20:21
原理图没贴上,要专门上传下。

CAN的原理图
can.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
发表于 6 天前 | 显示全部楼层

看着都没什么问题,加速模式情况下

配置为500K+1M的方式,是不是正常的。
回复

使用道具 举报

0

主题

9

回帖

9

积分

新手上路

积分
9
发表于 6 天前 | 显示全部楼层
eric2013 发表于 2024-4-23 07:58
看着都没什么问题,加速模式情况下

配置为500K+1M的方式,是不是正常的。

各种波特率的组合都试过了,can2.0  和 CANFD 都能正常通讯,就是不能用 加速模式,如果确认程序没问题,那只能从硬件找原因了
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
发表于 5 天前 | 显示全部楼层
Z先生 发表于 2024-4-23 09:09
各种波特率的组合都试过了,can2.0  和 CANFD 都能正常通讯,就是不能用 加速模式,如果确认程序没问题, ...

考虑换个PHY芯片试试。
回复

使用道具 举报

0

主题

9

回帖

9

积分

新手上路

积分
9
发表于 5 天前 | 显示全部楼层
eric2013 发表于 2024-4-24 07:15
考虑换个PHY芯片试试。

有没有可能和时钟源有关系?我的配置如下,麻烦帮我看看
/*******************************************************************************
* Function Name  : SystemClock_Init
* Description    : STM32H7时钟配置,系统时钟400MHz
* Input          : None
* Output         : None
* Return         : None
* Note                         : Fvco=Fs*(plln/pllm),VCO时钟频率
                                   Fsys=Fvco/pllp, MCU系统时钟频率,这里为400MHz
                                   Fusb=Fvco/pllq, USB,SDIO,RNG时钟频率,必须为48MHz
                                   PLLN:主PLL倍频系数(PLL倍频),取值范围:4~512
                                   PLLM:主PLL和音频PLL分频系数(PLL之前的分频),取值范围:2~63
                                   PLLP:系统时钟的主PLL分频系数(PLL之后的分频),取值范围:2~128.(且必须是2的倍数)
                                   PLLQ:USB/SDIO/随机数产生器等的主PLL分频系数(PLL之后的分频),取值范围:1~128
                                   Fs:晶振输入(4-26MHz)(HSE)
*******************************************************************************/
void SystemClock_Init_CAN200M(uint8_t Fosc)
{
        RCC_ClkInitTypeDef RCC_ClkInitStruct={0};
        RCC_OscInitTypeDef RCC_OscInitStruct={0};
        HAL_StatusTypeDef ret = HAL_OK;

        /*!< Supply configuration update enable */
        MODIFY_REG(PWR->CR3, PWR_CR3_SCUEN, 0);

        /* The voltage scaling allows optimizing the power consumption when the device is
         clocked below the maximum system frequency, to update the voltage scaling value
         regarding system frequency refer to product datasheet.  */
        __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

        while ((PWR->D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY) {}

        /* Enable HSE Oscillator and activate PLL with HSE as source */
        RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
        RCC_OscInitStruct.HSEState = RCC_HSE_ON;
        RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
        RCC_OscInitStruct.CSIState = RCC_CSI_OFF;
        RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
        RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

        if(Fosc == 25)   //25MHz
        {
                RCC_OscInitStruct.PLL.PLLM = 5;
                RCC_OscInitStruct.PLL.PLLN = 160;
        }
        else if(Fosc == 8)  //8MHz
        {
                RCC_OscInitStruct.PLL.PLLM = 2;
                RCC_OscInitStruct.PLL.PLLN = 200;
        }
        RCC_OscInitStruct.PLL.PLLP = 2;
        RCC_OscInitStruct.PLL.PLLR = 2;
        RCC_OscInitStruct.PLL.PLLQ = 10;     //800M分频  原来是4=200M  改为5 =160M      10=80M

        RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
        RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
        ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
        if(ret != HAL_OK)
        {
                while(1) { ; }
        }

        /* Select PLL as system clock source and configure  bus clocks dividers */
        RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1        | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2  | RCC_CLOCKTYPE_D3PCLK1);
        RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
        RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
        RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
        RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;  
        RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
        RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
        RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
        ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
        if(ret != HAL_OK)
        {
                while(1) { ; }
        }
       
        /*activate CSI clock mondatory for I/O Compensation Cell*/  
        __HAL_RCC_CSI_ENABLE() ;

        /* Enable SYSCFG clock mondatory for I/O Compensation Cell */
        __HAL_RCC_SYSCFG_CLK_ENABLE() ;

        /* Enables the I/O Compensation Cell */   
        HAL_EnableCompensationCell();
}


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106685
QQ
发表于 4 天前 | 显示全部楼层
Z先生 发表于 2024-4-24 22:15
有没有可能和时钟源有关系?我的配置如下,麻烦帮我看看
/******************************************* ...

这个时钟配置不全,主要是CAN的时钟配置。可以配置CAN的时钟为20,40,80M看下。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-29 14:52 , Processed in 0.273986 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表