OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5014|回复: 4

STM32H753的FDCAN1不能正常手法数据

[复制链接]

4

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2014-7-21
在线时间
10 小时
发表于 2022-4-18 16:57:45 | 显示全部楼层 |阅读模式
1金钱
RCC时钟配置:
  /* 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_LDO_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 = 100;
    RCC_OscInitStruct.PLL.PLLFRACN = 0;
    RCC_OscInitStruct.PLL.PLLP = 2;
    RCC_OscInitStruct.PLL.PLLR = 2;
    RCC_OscInitStruct.PLL.PLLQ = 20;

    RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
    RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
    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();  



CAN初始化:
              __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    = 0x01;     //分频系数

            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       = 2;                    //扩展信息 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);  


发送函数:

    FDCAN_TxHeader.Identifier          = 0x000123;              //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;

   HAL_FDCAN_AddMessageToTxFifoQ(&FDCAN1_Handler, &FDCAN_TxHeader, TxData);



问题:
程序跑起来之后,CAN发送接口连续发送16帧数据就不再发送,一直处于the Tx FIFO/Queue is full 状态
,那位大神指点一下,谢谢

  if (hfdcan->State == HAL_FDCAN_STATE_BUSY)
  {
    /* Check that the Tx FIFO/Queue has an allocated area into the RAM */
    if ((hfdcan->Instance->TXBC & FDCAN_TXBC_TFQS) == 0U)
    {
      /* Update error code */
      hfdcan->ErrorCode |= HAL_FDCAN_ERROR_PARAM;

      return HAL_ERROR;
    }

    /* Check that the Tx FIFO/Queue is not full */
    if ((hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFQF) != 0U)
    {
      /* Update error code */
      hfdcan->ErrorCode |= HAL_FDCAN_ERROR_FIFO_FULL;
      wathfdcan = hfdcan;
      return HAL_ERROR;                                                             /*程序一直在这里反复执行*/
    }
    else
    {
      /* Retrieve the Tx FIFO PutIndex */
      PutIndex = ((hfdcan->Instance->TXFQS & FDCAN_TXFQS_TFQPI) >> FDCAN_TXFQS_TFQPI_Pos);

      /* Add the message to the Tx FIFO/Queue */
      FDCAN_CopyMessageToRAM(hfdcan, pTxHeader, pTxData, PutIndex);

      /* Activate the corresponding transmission request */
      hfdcan->Instance->TXBAR = ((uint32_t)1 << PutIndex);

      /* Store the Latest Tx FIFO/Queue Request Buffer Index */
      hfdcan->LatestTxFifoQRequest = ((uint32_t)1 << PutIndex);
    }

    /* Return function status */
    return HAL_OK;
  }

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

465

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1732
金钱
1732
注册时间
2021-4-11
在线时间
320 小时
发表于 2022-4-18 17:47:44 | 显示全部楼层
帮顶               
回复

使用道具 举报

10

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
122
金钱
122
注册时间
2014-11-15
在线时间
17 小时
发表于 2022-4-25 11:03:40 | 显示全部楼层
楼主解决了吗,我也遇到了
回复

使用道具 举报

4

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
58
金钱
58
注册时间
2014-7-21
在线时间
10 小时
 楼主| 发表于 2022-4-25 13:55:35 | 显示全部楼层
SKYZHC 发表于 2022-4-25 11:03
楼主解决了吗,我也遇到了

没有哦,可以交流一下
回复

使用道具 举报

0

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
182
金钱
182
注册时间
2021-2-3
在线时间
48 小时
发表于 2022-4-28 09:00:58 | 显示全部楼层
zsy3830 发表于 2022-4-25 13:55
没有哦,可以交流一下

是不是工作电压不足,很多的芯片都是需要5V供电
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-25 21:32

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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