你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32G0B1CC单片机多个从板使用CAN链接,CAN接收帧和发送帧丢失的问题。

[复制链接]
1LT1 提问时间:2024-9-11 18:04 / 未解决

请教一下,我用3块以上的STM32G0B1CC单片机支持的CAN从板,使用电脑发送广播帧给到每一块从板,让每一块从板回复一帧响应帧给电脑端,在这期间就会出现从板接收帧丢失和从板接收后发送帧丢失的情况,相同发送速度单块板的情况就不会丢帧。(附上CAN的配置代码)

/*=============================================================================================
** @Name      : void HAL_FDCAN_RxFifo0Callback(void)
** @Input     : void
** @Output    : void
** @Function  : CAN接收中断处理函数
** @The notes : 底层CAN中断调用
**===========================================================================================*/
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{

    u8 i = 0;
    if ((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != 0)//fifo有新数据
    {
        HAL_FDCAN_GetRxMessage(&hfdcan1, FDCAN_RX_FIFO0, &RxHeader, canRxData);
        CANWriteRcvCyBuf(eCAN0, &RxHeader);
        for(i = 0; i < 8; i++)
        {
            canRxData[i] = 0;
        }
    }
}/*=============================================================================================
** @Name      : u8 BSPCANInit(e_CANNUM canNum, u8 osc, u16 rate)
** @Input     : canNum:CAN通道号 osc:晶振频率 rate:CAN波特率
** @Output    : 初始化结果 TRUE:成功 FALSE:失败
** @Function  : CAN驱动模块初始化
** @The notes : BSP调用
**===========================================================================================*/
u8 BSPCANInit(e_CANNUM canNum, u8 osc, u16 rate)
{

    GPIO_InitTypeDef GPIO_InitStruct = {0};
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
    FDCAN_FilterTypeDef sFilterConfig;

    if(canNum >= eCANNUM)
    {
        return(FALSE);
    }

    //模块未使能不进行初始化
    if(((eCAN0 == canNum) && (1 != gBSPFunCfg.Bits.CAN0En))
            || ((eCAN1 == canNum) && (1 != gBSPFunCfg.Bits.CAN1En)))
    {
        return(FALSE);
    }

    switch(canNum)
    {
    case eCAN0:
        hfdcan1.Instance = FDCAN1;
        hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV1;
        hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
        hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
        hfdcan1.Init.AutoRetransmission = ENABLE;
        hfdcan1.Init.TransmitPause = ENABLE;
        hfdcan1.Init.ProtocolException = DISABLE;
        hfdcan1.Init.DataPrescaler = 8;
        hfdcan1.Init.DataSyncJumpWidth = 1;
        hfdcan1.Init.DataTimeSeg1 = 10;
        hfdcan1.Init.DataTimeSeg2 = 5;
        hfdcan1.Init.StdFiltersNbr = 28;
        hfdcan1.Init.ExtFiltersNbr = 8;
        hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;

        if(rate == 125)
        {
            hfdcan1.Init.NominalPrescaler = 64;         //8:1000k    16:500k    32:250k   64:125k
            hfdcan1.Init.NominalSyncJumpWidth = 1;
            hfdcan1.Init.NominalTimeSeg1 = 4;
            hfdcan1.Init.NominalTimeSeg2 = 3;
        }
        else if(rate == 250)
        {
            hfdcan1.Init.NominalPrescaler = 32;         //8:1000k    16:500k    32:250k   64:125k
            hfdcan1.Init.NominalSyncJumpWidth = 1;
            hfdcan1.Init.NominalTimeSeg1 = 4;
            hfdcan1.Init.NominalTimeSeg2 = 3;
        }
        else if(rate == 500)
        {
            hfdcan1.Init.NominalPrescaler = 16;         //8:1000k    16:500k    32:250k   64:125k
            hfdcan1.Init.NominalSyncJumpWidth = 1;
            hfdcan1.Init.NominalTimeSeg1 = 4;
            hfdcan1.Init.NominalTimeSeg2 = 3;
        }
        else if(rate == 1000)
        {
            hfdcan1.Init.NominalPrescaler = 8;          //8:1000k    16:500k    32:250k   64:125k
            hfdcan1.Init.NominalSyncJumpWidth = 1;
            hfdcan1.Init.NominalTimeSeg1 = 4;
            hfdcan1.Init.NominalTimeSeg2 = 3;
        }
        else
        {
            hfdcan1.Init.NominalPrescaler = 16;         //8:1000k    16:500k    32:250k   64:125k
            hfdcan1.Init.NominalSyncJumpWidth = 1;
            hfdcan1.Init.NominalTimeSeg1 = 4;
            hfdcan1.Init.NominalTimeSeg2 = 3;
        }

        PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
        PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_PCLK1;
        HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
        /* Peripheral clock enable */
        __HAL_RCC_FDCAN_CLK_ENABLE();

        __HAL_RCC_GPIOD_CLK_ENABLE();
        /**FDCAN1 GPIO Configuration
                        PD0     ------> FDCAN1_RX
                        PD1     ------> FDCAN1_TX
         */
        GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF3_FDCAN1;
        HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

        HAL_NVIC_SetPriority(TIM16_FDCAN_IT0_IRQn, 0, 0);
        HAL_NVIC_EnableIRQ(TIM16_FDCAN_IT0_IRQn);

        HAL_FDCAN_Init(&hfdcan1);

        sFilterConfig.IdType = FDCAN_EXTENDED_ID;   //  配置为过滤扩展帧
        sFilterConfig.FilterIndex = 0;              //  过滤器的索引号
        sFilterConfig.FilterType = FDCAN_FILTER_RANGE_NO_EIDM;  //  过滤方式为范围,即从FilterID1~FilterID2之间的ID
        sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
        sFilterConfig.FilterID1 = 0x00000000;
        sFilterConfig.FilterID2 = 0x1fffffff;       //  扩展帧为29位ID,即0x1fffffff,配置为接收所有帧
        HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig);

        HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_ACCEPT_IN_RX_FIFO0, FDCAN_ACCEPT_IN_RX_FIFO0, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE);
        HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0);

        /* Start the FDCAN module */
        HAL_FDCAN_Start(&hfdcan1);
        break;

    case eCAN1:

        break;

    default:

        break;
    }
    return(TRUE);
}

/*=============================================================================================
** @Name      : u8 BSPCANSendMsg(e_CANNUM canNum, t_CANMSG *msg)
** @Input     : canNum:通道号 *msg:发送信息结构体
** @Output    : 发送结果:TRUE-成功 FALSE-失败
** @Function  : CAN发送信息(直接发送)
** @The notes : 用户调用(尽量少用,会丢帧)
**===========================================================================================*/
u8 BSPCANSendMsg(e_CANNUM canNum, t_CANMSG *msg)
{

    FDCAN_TxHeaderTypeDef TxHeader;
    u8 data[8] = {0};

    TxHeader.Identifier = msg->ID;
    TxHeader.IdType = FDCAN_EXTENDED_ID;
    TxHeader.TxFrameType = FDCAN_DATA_FRAME;
    TxHeader.DataLength = msg->Len;
    TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
    TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
    TxHeader.FDFormat = FDCAN_CLASSIC_CAN;
    TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
    TxHeader.MessageMarker = 0x00;
    data[0] = msg->Data[0];//缓冲区
    data[1] = msg->Data[1];
    data[2] = msg->Data[2];
    data[3] = msg->Data[3];
    data[4] = msg->Data[4];
    data[5] = msg->Data[5];
    data[6] = msg->Data[6];
    data[7] = msg->Data[7];

    HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, data);

    return(TRUE);
}
收藏 评论7 发布时间:2024-9-11 18:04

举报

7个回答
xmshao 回答时间:5 天前

1LT1 发表于 2024-9-12 16:15
测试了一下,A1~A4四块从板,A1从板延时10ms发送响应帧累加到A4从板40ms发送,错开时间发送,查询帧周期 ...

多测试下,看看到底跟板本身有关系,还是说只是跟板回复的先后有关,慢慢找原因。

xmshao 回答时间:5 天前

1LT1 发表于 2024-9-12 14:48</p>
<p>尝试过了,500k的波特率情况下总线占用率在20%以内,并且还进行过5ms-50ms发送查询帧的测试,从控板 ...

[md]有点奇怪。

感觉你硬件上好像也没啥问题。

这将从板的发回复间隔拉大点,稍微夸张点无妨,比方20ms,甚至更多,再行验证下。

xmshao 回答时间:5 天前
会不会是代码处理方面的问题?软件处理不及时,导致接收溢出或发送缓冲区未及时清空?


对于从板,可以让他们在不同时间段回复,避免同时发送导致总线负荷过高。
butterflyspring 回答时间:5 天前
[color=var(--md-box-samantha-normal-text-color) !important]在 CAN 总线系统中,通常需要在总线的两端各连接一个 120 欧姆的终端电阻,以减少信号反射,确保信号的完整性和稳定性。对于 FDCAN 总线,如果是一个简单的点对点连接或者短距离的连接,可能不严格要求 120 欧姆的匹配电阻也能正常工作。但在较长的总线长度、多个节点连接或者对信号质量要求较高的应用场景中,120 欧姆的匹配电阻就非常必要了。

[color=var(--md-box-samantha-normal-text-color) !important]总之,是否需要 120 欧姆匹配电阻取决于具体的 FDCAN 总线应用环境和要求

1LT1 回答时间:5 天前

butterflyspring 发表于 2024-9-12 09:36
在 CAN 总线系统中,通常需要在总线的两端各连接一个 120 欧姆的终端电阻,以减少信号反射,确保信号的完整 ...

总线两端都加了一个120欧姆的电阻,can的波形也打了,差分信号也很标准😕

1LT1 回答时间:5 天前

xmshao 发表于 2024-9-12 14:31
会不会是代码处理方面的问题?软件处理不及时,导致接收溢出或发送缓冲区未及时清空?</p>
<p>

尝试过了,500k的波特率情况下总线占用率在20%以内,并且还进行过5ms-50ms发送查询帧的测试,从控板同样会出现接收丢帧;还测试过查询帧发出后,从板1会延时1ms回复、从板2会延时2ms回复、从板3会延时3ms回复这样,没有改善效果,该丢还是丢

因为这个现象导致我的boot程序升级多块从板app程序的功能出现数据传输丢帧的故障,我用nxp的k128mcu就不会出现这样的问题

1LT1 回答时间:5 天前
xmshao 发表于 2024-9-12 15:38
[md]有点奇怪。

感觉你硬件上好像也没啥问题。

测试了一下,A1~A4四块从板,A1从板延时10ms发送响应帧累加到A4从板40ms发送,错开时间发送,查询帧周期为50ms,实验结果只有A1满帧回复
测试1.png
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版