打印
[STM32H7]

STM32H753 FDCAN当普通CAN使用,发送数据异常

[复制链接]
1003|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zsy3830|  楼主 | 2022-4-18 11:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
AN, ST, dc
FDCAN初始化:

            __HAL_RCC_FDCAN_CLK_ENABLE(); //使能 FDCAN 时钟
            __HAL_RCC_GPIOB_CLK_ENABLE(); //开启 GPIOB 时钟   

            //FDCAN1 时钟源配置为 PLL1Q
            FDCAN1_PeriphClk.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
            FDCAN1_PeriphClk.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL;
            HAL_RCCEx_PeriphCLKConfig(&FDCAN1_PeriphClk);

            GPIO_Initure.Pin        = GPIO_PIN_8|GPIO_PIN_9;    //PB8,9
            GPIO_Initure.Mode       = GPIO_MODE_AF_PP;          //推挽复用
            GPIO_Initure.Pull       = GPIO_PULLUP;              //上拉
            GPIO_Initure.Speed      = GPIO_SPEED_FREQ_HIGH;     //高速
            GPIO_Initure.Alternate  = GPIO_AF9_FDCAN1;          //复用为 CAN1
            HAL_GPIO_Init(GPIOB, &GPIO_Initure);                //初始化   

            HAL_FDCAN_DeInit(&FDCAN1_Handler);                  //先清除以前的设置

            FDCAN1_Handler.Instance = FDCAN1;               
            FDCAN1_Handler.Init.FrameFormat         = FDCAN_FRAME_CLASSIC;  //传统模式
            FDCAN1_Handler.Init.Mode                = FDCAN_MODE_NORMAL;    //正常模式
            FDCAN1_Handler.Init.AutoRetransmission  = DISABLE;              //关闭自动重传!
            FDCAN1_Handler.Init.TransmitPause       = DISABLE;              //关闭传输暂停
            FDCAN1_Handler.Init.ProtocolException   = DISABLE;              //关闭协议异常处理
            FDCAN1_Handler.Init.NominalPrescaler    = FDCAN_CLOCK_DIV10;     //分频系数

             FDCAN1_Handler.Init.NominalSyncJumpWidth= 0x08;                //重新同步跳跃宽度
             FDCAN1_Handler.Init.NominalTimeSeg1     = 0x1f;                //tsg1 范围:2~256
             FDCAN1_Handler.Init.NominalTimeSeg2     = 0x08;                //tsg2 范围:2~128

            FDCAN1_Handler.Init.MessageRAMOffset    = 0;                    //信息 RAM 偏移
            FDCAN1_Handler.Init.StdFiltersNbr       = 1;                    //标准信息 ID 滤波器编号
            FDCAN1_Handler.Init.ExtFiltersNbr       = 0;                    //扩展信息 ID 滤波器编号
            FDCAN1_Handler.Init.RxFifo0ElmtsNbr     = 1;                   //接收 FIFO0 元素编号
            FDCAN1_Handler.Init.RxFifo0ElmtSize     = FDCAN_DATA_BYTES_8;   //接收 FIFO0 8 字节
            FDCAN1_Handler.Init.RxBuffersNbr        = 0;                   //接收缓冲编号

            FDCAN1_Handler.Init.TxEventsNbr         = 0;                    //发送事件编号
            FDCAN1_Handler.Init.TxBuffersNbr        = 1;                   //发送缓冲编号
            FDCAN1_Handler.Init.TxFifoQueueElmtsNbr = 0;                    //发送 FIFO 序列元素编号
            FDCAN1_Handler.Init.TxFifoQueueMode     = FDCAN_TX_FIFO_OPERATION;
            FDCAN1_Handler.Init.TxElmtSize          = FDCAN_DATA_BYTES_8;   //发送大小:8 字节

            if(HAL_FDCAN_Init(&FDCAN1_Handler) != HAL_OK)                               //初始化 FDCAN   
            {
                while(1);
            }

            //设置滤波器
            FDCAN1_RXFilter.IdType      = FDCAN_EXTENDED_ID;        //扩展 ID
            FDCAN1_RXFilter.FilterIndex = 0;                        //滤波器索引
            FDCAN1_RXFilter.FilterType  = FDCAN_FILTER_MASK;        //滤波器类型
            FDCAN1_RXFilter.FilterConfig= FDCAN_FILTER_TO_RXFIFO0;  //过滤器 0 关联到 FIFO0
            FDCAN1_RXFilter.FilterID1   = 0x0000;                   //32 位 ID
            FDCAN1_RXFilter.FilterID2   = 0x0000;                   //传统模式的话,这里是 32 位掩码
            HAL_FDCAN_ConfigFilter(&FDCAN1_Handler,&FDCAN1_RXFilter); //滤波器初始化

            HAL_FDCAN_ActivateNotification(&FDCAN1_Handler,FDCAN_IT_RX_FIFO0_NEW_MESSAGE,0);   
            HAL_FDCAN_Start(&FDCAN1_Handler);                       //开启 FDCAN            
            HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn,1,2);
            HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn);   


发送函数:

/*=============================================================================================
** @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 FDCAN_TxHeader;
    u8 i = 0;
    u8 TxData[8] = {0};

    for(i = 0;i < 8; i++)
        {
                TxData = msg->Data;
        }

    FDCAN_TxHeader.Identifier          = msg->ID;              //32 位 ID
    FDCAN_TxHeader.IdType              = FDCAN_EXTENDED_ID;    //扩展 ID
    FDCAN_TxHeader.TxFrameType         = FDCAN_DATA_FRAME;     //数据帧
    FDCAN_TxHeader.DataLength          = FDCAN_DLC_BYTES_8;             //数据长度
    FDCAN_TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
    FDCAN_TxHeader.BitRateSwitch       = FDCAN_BRS_OFF;        //关闭速率切换
    FDCAN_TxHeader.FDFormat            = FDCAN_CLASSIC_CAN;    //传统的 CAN 模式
    FDCAN_TxHeader.TxEventFifoControl  = FDCAN_NO_TX_EVENTS;   //无发送事件
    FDCAN_TxHeader.MessageMarker       = 0;

    if(eCAN0 == canNum)
    {
        //HAL_FDCAN_AddMessageToTxFifoQ(&FDCAN1_Handler, &FDCAN_TxHeader, TxData);
        HAL_FDCAN_AddMessageToTxBuffer(&FDCAN1_Handler, &FDCAN_TxHeader, TxData, FDCAN_TX_BUFFER0);

        /* Send calibration confirmation message */
        HAL_FDCAN_EnableTxBufferRequest(&FDCAN1_Handler, FDCAN_TX_BUFFER0);
    }
    else
    {
         HAL_FDCAN_AddMessageToTxFifoQ(&FDCAN2_Handler, &FDCAN_TxHeader, TxData);
    }

        return(TRUE);
}


连续发送16帧数据之后,不再发送,一直出现该EEOR里面
    /* Check that the selected buffer has an allocated area into the RAM */
    if (POSITION_VAL(BufferIndex) >= ((hfdcan->Instance->TXBC & FDCAN_TXBC_NDTB) >> FDCAN_TXBC_NDTB_Pos))
    {
      /* Update error code */
      hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;

      return HAL_ERROR;
    }


问题已经找了好多天了,项目处于延迟状态,那位大神帮忙看看是什么问题,第一次用ST的单片机,没什么经验,求助各位同行了,谢谢


我的时钟初始化(16M的外置晶振)是这样的,也是用户的也是HAL的库

        /* Configure the MPU attributes */
        MPU_Config();

        /* Enable the CPU Cache */
        CPU_CACHE_Enable();

  /* STM32H7xx HAL library initialization:
       - Systick timer is configured by default as source of time base, but user
         can eventually implement his proper time base source (a general purpose
         timer for example or other time source), keeping in mind that Time base
         duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
         handled in milliseconds basis.
       - Set NVIC Group Priority to 4
       - Low Level Initialization
     */
    HAL_Init();


//    /*!< Supply configuration update enable */
//    HAL_PWREx_ConfigSupply(PWR_DIRECT_SMPS_SUPPLY);
//
//    /* 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(!__HAL_PWR_GET_FLAG(PWR_FLAG_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;

    RCC_OscInitStruct.PLL.PLLM = 2;
    RCC_OscInitStruct.PLL.PLLN = 50;
    RCC_OscInitStruct.PLL.PLLFRACN = 0;
    RCC_OscInitStruct.PLL.PLLP = 2;
    RCC_OscInitStruct.PLL.PLLR = 2;
    RCC_OscInitStruct.PLL.PLLQ = 10;

    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_4);
    if(ret != HAL_OK)
    {
        while(1) { ; }
    }

    /*
    Note : The activation of the I/O Compensation Cell is recommended with communication  interfaces
    (GPIO, SPI, FMC, QSPI ...)  when  operating at  high frequencies(please refer to product datasheet)      
    The I/O Compensation Cell activation  procedure requires :
    - The activation of the CSI clock
    - The activation of the SYSCFG clock
    - Enabling the I/O Compensation Cell : setting bit[0] of register SYSCFG_CCCSR
    */

    /*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();   

    SystemCoreClockUpdate();

使用特权

评论回复
沙发
kiwis66| | 2022-4-22 14:19 | 只看该作者
刚接触CAN
又来个FDCAN

使用特权

评论回复
板凳
tail066| | 2022-4-24 16:54 | 只看该作者
这样估计够呛能解决,楼主还是仿真吧,

使用特权

评论回复
地板
Jacquetry| | 2022-10-5 21:28 | 只看该作者
感觉悬了

使用特权

评论回复
5
Bblythe| | 2022-10-8 07:06 | 只看该作者

防止因瞬间大电流引起的电源电压下降

使用特权

评论回复
6
Pulitzer| | 2022-10-8 10:05 | 只看该作者

与15号引脚连接的C1称为旁路电容

使用特权

评论回复
7
Uriah| | 2022-10-8 17:06 | 只看该作者

通常选择0.01μF~0.1μF的陶瓷电容作为旁路电容。

使用特权

评论回复
8
Bblythe| | 2023-7-1 07:06 | 只看该作者

I2C1的时钟可以自行选择HSI或者SYSCLK

使用特权

评论回复
9
童雨竹| | 2023-7-1 09:02 | 只看该作者

I2C1工作时钟源选择;I2C1模块工作时钟的开启使能。

使用特权

评论回复
10
Pulitzer| | 2023-7-1 10:05 | 只看该作者

STM32芯片中有多个工作时钟源的外设很常见

使用特权

评论回复
11
公羊子丹| | 2023-7-1 11:08 | 只看该作者

控制模块的时钟仍然由外设时钟PCLK提供

使用特权

评论回复
12
公羊子丹| | 2023-7-1 12:01 | 只看该作者

CPU借助于APB总线访问相关寄存器达到对I2C1工作模块的控制

使用特权

评论回复
13
Wordsworth| | 2023-7-1 13:04 | 只看该作者

ART2固定使用PCLK时钟,只有开启和关闭的问题,不存在其它时钟源选择

使用特权

评论回复
14
Clyde011| | 2023-7-1 14:07 | 只看该作者

一部分是I2C1的工作模块,另外一部分是其控制模块

使用特权

评论回复
15
万图| | 2023-7-1 16:03 | 只看该作者

USART1可以有多个时钟源

使用特权

评论回复
16
Uriah| | 2023-7-1 17:06 | 只看该作者

STM32CUBEMX配置生成初始化代码

使用特权

评论回复
17
帛灿灿| | 2023-7-1 19:02 | 只看该作者

通过访问寄存器来控制I2C1工作时钟的开启。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

14

帖子

0

粉丝