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

stm32f107VC 双CAN+双FIFO,CAN1收发正常,CAN2收发都没反应

[复制链接]
二少 提问时间:2021-12-23 10:41 / 已解决
CAN_HandleTypeDef hcan1;
CAN_HandleTypeDef hcan2;

/* CAN1 init function */
void MX_CAN1_Init(void)
{

/* USER CODE BEGIN CAN1_Init 0 */

/* USER CODE END CAN1_Init 0 */

/* USER CODE BEGIN CAN1_Init 1 */

/* USER CODE END CAN1_Init 1 */
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 9;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_13TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = ENABLE;
hcan1.Init.AutoWakeUp = ENABLE;
hcan1.Init.AutoRetransmission = DISABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN1_Init 2 */

/* USER CODE END CAN1_Init 2 */

}
/* CAN2 init function */
void MX_CAN2_Init(void)
{

/* USER CODE BEGIN CAN2_Init 0 */

/* USER CODE END CAN2_Init 0 */

/* USER CODE BEGIN CAN2_Init 1 */

/* USER CODE END CAN2_Init 1 */
hcan2.Instance = CAN2;
hcan2.Init.Prescaler = 9;
hcan2.Init.Mode = CAN_MODE_NORMAL;
hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan2.Init.TimeSeg1 = CAN_BS1_13TQ;
hcan2.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan2.Init.TimeTriggeredMode = DISABLE;
hcan2.Init.AutoBusOff = ENABLE;
hcan2.Init.AutoWakeUp = ENABLE;
hcan2.Init.AutoRetransmission = DISABLE;
hcan2.Init.ReceiveFifoLocked = DISABLE;
hcan2.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN2_Init 2 */

/* USER CODE END CAN2_Init 2 */

}

static uint32_t HAL_RCC_CAN1_CLK_ENABLED=0;

void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{

GPIO_InitTypeDef GPIO_InitStruct = {0};
if(canHandle->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspInit 0 */

/* USER CODE END CAN1_MspInit 0 */
/* CAN1 clock enable */
HAL_RCC_CAN1_CLK_ENABLED++;
if(HAL_RCC_CAN1_CLK_ENABLED==1){
__HAL_RCC_CAN1_CLK_ENABLE();
}

__HAL_RCC_GPIOD_CLK_ENABLE();
/**CAN1 GPIO Configuration
PD0     ------> CAN1_RX
PD1     ------> CAN1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

__HAL_AFIO_REMAP_CAN1_3();

/* CAN1 interrupt Init */
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 6, 0);
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
/* USER CODE BEGIN CAN1_MspInit 1 */

/* USER CODE END CAN1_MspInit 1 */
}
else if(canHandle->Instance==CAN2)
{
/* USER CODE BEGIN CAN2_MspInit 0 */

/* USER CODE END CAN2_MspInit 0 */
/* CAN2 clock enable */
__HAL_RCC_CAN2_CLK_ENABLE();
HAL_RCC_CAN1_CLK_ENABLED++;
if(HAL_RCC_CAN1_CLK_ENABLED==1){
__HAL_RCC_CAN1_CLK_ENABLE();
}

__HAL_RCC_GPIOB_CLK_ENABLE();
/**CAN2 GPIO Configuration
PB5     ------> CAN2_RX
PB6     ------> CAN2_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

__HAL_AFIO_REMAP_CAN2_ENABLE();

/* CAN2 interrupt Init */
HAL_NVIC_SetPriority(CAN2_RX1_IRQn, 6, 0);
HAL_NVIC_EnableIRQ(CAN2_RX1_IRQn);
/* USER CODE BEGIN CAN2_MspInit 1 */

/* USER CODE END CAN2_MspInit 1 */
}
}

void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{

if(canHandle->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspDeInit 0 */

/* USER CODE END CAN1_MspDeInit 0 */
/* Peripheral clock disable */
HAL_RCC_CAN1_CLK_ENABLED--;
if(HAL_RCC_CAN1_CLK_ENABLED==0){
__HAL_RCC_CAN1_CLK_DISABLE();
}

/**CAN1 GPIO Configuration
PD0     ------> CAN1_RX
PD1     ------> CAN1_TX
*/
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_0|GPIO_PIN_1);

/* CAN1 interrupt Deinit */
HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);
/* USER CODE BEGIN CAN1_MspDeInit 1 */

/* USER CODE END CAN1_MspDeInit 1 */
}
else if(canHandle->Instance==CAN2)
{
/* USER CODE BEGIN CAN2_MspDeInit 0 */

/* USER CODE END CAN2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_CAN2_CLK_DISABLE();
HAL_RCC_CAN1_CLK_ENABLED--;
if(HAL_RCC_CAN1_CLK_ENABLED==0){
__HAL_RCC_CAN1_CLK_DISABLE();
}

/**CAN2 GPIO Configuration
PB5     ------> CAN2_RX
PB6     ------> CAN2_TX
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_5|GPIO_PIN_6);

/* CAN2 interrupt Deinit */
HAL_NVIC_DisableIRQ(CAN2_RX1_IRQn);
/* USER CODE BEGIN CAN2_MspDeInit 1 */

/* USER CODE END CAN2_MspDeInit 1 */
}
}



//CAN1 初始化
void bsp_can1_init(void)
{
/*过滤器 CAN1过滤器范围0-13 ,CAN2过滤器范围14-27*/
CAN_FilterTypeDef  sFilterConfig;
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;

if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
{
/* Filter configuration Error */
Error_Handler();
}

//        FilterConfig_Scale32_Null(&hcan1,0);//不过滤
//        FilterConfig_Scale32_IdMask_StandardIdOnly(&hcan1,1,(uint16_t *)StdIdArray);//单标准ID
//        Filter_Scale32_IdMask_ExtendIdOnly(&hcan1,2,(uint32_t *)ExtIdArray);//单扩展ID
//        Filter_Scale32_IdMask_StandardId_ExtendId_Mix(&hcan1,3,(uint16_t *)StdIdArray,(uint32_t *)ExtIdArray);//标准ID + 扩展ID

/*波特率重新调整*/
CAN_Baud_Process(250,&hcan1);
/* Start the CAN peripheral */
if (HAL_CAN_Start(&hcan1) != HAL_OK)
{
/* Start Error */
Error_Handler();
}

/* Activate CAN RX notification */
if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
{
/* Notification Error */
Error_Handler();
}

//        /* Activate CAN BUSOFF notification ###################################*/
//        if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_BUSOFF) != HAL_OK)
//  {
//    /* Notification Error */
//    Error_Handler();
//  }

//  /* Activate CAN TX notification */
//  if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_TX_MAILBOX_EMPTY) != HAL_OK)
//  {
//    /* Notification Error */
//    Error_Handler();
//  }

}

//CAN2 初始化
void bsp_can2_init(void)
{
/*过滤器 CAN1过滤器范围0-13 ,CAN2过滤器范围14-27*/
CAN_FilterTypeDef  sFilterConfig;
sFilterConfig.FilterBank = 14;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO1;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;

if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
{
/* Filter configuration Error */
Error_Handler();
}               
//        FilterConfig_Scale32_Null(&hcan2,14);//不过滤
//        FilterConfig_Scale32_IdMask_StandardIdOnly(&hcan1,15,(uint16_t *)StdIdArray);//单标准ID
//        Filter_Scale32_IdMask_ExtendIdOnly(&hcan1,16,(uint32_t *)ExtIdArray);//单扩展ID
//        Filter_Scale32_IdMask_StandardId_ExtendId_Mix(&hcan1,17,(uint16_t *)StdIdArray,(uint32_t *)ExtIdArray);//标准ID + 扩展ID

/*波特率重新调整*/
CAN_Baud_Process(250,&hcan2);
/* Start the CAN peripheral */
if (HAL_CAN_Start(&hcan2) != HAL_OK)
{
/* Start Error */
Error_Handler();
}

/* Activate CAN RX notification */
if (HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO1_MSG_PENDING) != HAL_OK)
{
/* Notification Error */
Error_Handler();
}

//        /* Activate CAN BUSOFF notification ###################################*/
//        if (HAL_CAN_ActivateNotification(&hcan2, CAN_IT_BUSOFF) != HAL_OK)
//  {
//    /* Notification Error */
//    Error_Handler();
//  }

//  /* Activate CAN TX notification */
//  if (HAL_CAN_ActivateNotification(&hcan2, CAN_IT_TX_MAILBOX_EMPTY) != HAL_OK)
//  {
//    /* Notification Error */
//    Error_Handler();
//  }

}

/**

* @brief  Rx FIFO 0 full callback.
* @param  hcan pointer to a CAN_HandleTypeDef structure that contains
* the configuration information for the specified CAN.

  * @retval None
    */
    void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
    {
    //CAN1 -FIFO0 接收处理
    if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &bsp_can1.RxMessage, bsp_can1.RxData) != HAL_OK) {
    Error_Handler();
    }

    uint32_t r_std_id = bsp_can1.RxMessage.StdId;
    uint32_t r_ext_id = bsp_can1.RxMessage.ExtId;
    printf("CAN1->0x%03X, 0x%08X, %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X\r\n",
    r_std_id, r_ext_id,
    bsp_can1.RxData[0], bsp_can1.RxData[1], bsp_can1.RxData[2], bsp_can1.RxData[3],
    bsp_can1.RxData[4], bsp_can1.RxData[5], bsp_can1.RxData[6], bsp_can1.RxData[7]);

    bsp_can1.RxMessage.StdId = 0;
    bsp_can1.RxMessage.ExtId = 0;
  }

  /**

  * @brief  Rx FIFO 1 message pending callback.
  * @param  hcan pointer to a CAN_HandleTypeDef structure that contains
  * the configuration information for the specified CAN.

    * @retval None
      */
      void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)
      {
      //CAN2 -FIFO1 接收处理
      if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO1, &bsp_can2.RxMessage, bsp_can2.RxData) != HAL_OK) {
      Error_Handler();
      }

      uint32_t r_std_id = bsp_can2.RxMessage.StdId;
      uint32_t r_ext_id = bsp_can2.RxMessage.ExtId;
      printf("CAN2->0x%03X, 0x%08X, %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X\r\n",
      r_std_id, r_ext_id,
      bsp_can2.RxData[0], bsp_can2.RxData[1], bsp_can2.RxData[2], bsp_can2.RxData[3],
      bsp_can2.RxData[4], bsp_can2.RxData[5], bsp_can2.RxData[6], bsp_can2.RxData[7]);

      bsp_can2.RxMessage.StdId = 0;
      bsp_can2.RxMessage.ExtId = 0;
    /* NOTE : This function Should not be modified, when the callback is needed,
    the HAL_CAN_RxFifo1MsgPendingCallback could be implemented in the
    user file
    */
    }



    /**

    * @brief  CAN1 发送数据
    * @param  StdId 标准ID,不使用则传0
    * @param  ExtId 扩展ID,不使用则传0
    * @param  pData 发送数据
    * @param  Len         发送长度
      */
      uint8_t CAN1_SendNormalData(uint16_t StdId,uint32_t ExtId, uint16_t Len)
      {
      HAL_StatusTypeDef   HAL_RetVal;
      uint8_t  FreeTxNum = 0;
      bsp_can1.TxMessage.StdId = StdId;
      bsp_can1.TxMessage.ExtId = ExtId;
      if(ExtId)bsp_can1.TxMessage.IDE = CAN_ID_EXT;
      else bsp_can1.TxMessage.IDE = CAN_ID_STD;
      bsp_can1.TxMessage.TransmitGlobalTime = DISABLE;
      bsp_can1.TxMessage.RTR = CAN_RTR_DATA;//使用标准帧

      if(Len > 8 || !Len)return 1;
      bsp_can1.TxMessage.DLC = Len;
      FreeTxNum = HAL_CAN_GetTxMailboxesFreeLevel(&hcan1);
      while(0 == FreeTxNum)
      {
              osDelay(1);
              FreeTxNum = HAL_CAN_GetTxMailboxesFreeLevel(&hcan1);
              if(0 == FreeTxNum)
              {
                      return 2;
              }
      }
      HAL_RetVal = HAL_CAN_AddTxMessage(&hcan1, &bsp_can1.TxMessage, bsp_can1.TxData, &bsp_can1.TxMailbox);
      if(HAL_RetVal != HAL_OK)
      {
                      return 2;
      }
      return 0;
    }

    /*** @brief  CAN2 发送数据
    * @param  StdId 标准ID,不使用则传0
    * @param  ExtId 扩展ID,不使用则传0
    * @param  pData 发送数据
    * @param  Len         发送长度
      */
      uint8_t CAN2_SendNormalData(uint16_t StdId,uint32_t ExtId, uint16_t Len)
      {
      HAL_StatusTypeDef   HAL_RetVal;
      uint8_t  FreeTxNum = 0;
      bsp_can2.TxMessage.StdId = StdId;
      bsp_can2.TxMessage.ExtId = ExtId;
      if(ExtId)bsp_can2.TxMessage.IDE = CAN_ID_EXT;
      else bsp_can2.TxMessage.IDE = CAN_ID_STD;
      bsp_can2.TxMessage.TransmitGlobalTime = DISABLE;
      bsp_can2.TxMessage.RTR = CAN_RTR_DATA;//使用标准帧

      if(Len > 8 || !Len)return 1;
      bsp_can2.TxMessage.DLC = Len;
      FreeTxNum = HAL_CAN_GetTxMailboxesFreeLevel(&hcan2);
      while(0 == FreeTxNum)
      {
      osDelay(1);
      FreeTxNum = HAL_CAN_GetTxMailboxesFreeLevel(&hcan2);
      if(0 == FreeTxNum)
      {
      return 2;
      }
      }
      HAL_RetVal = HAL_CAN_AddTxMessage(&hcan2, &bsp_can2.TxMessage, bsp_can2.TxData, &bsp_can2.TxMailbox);
      if(HAL_RetVal != HAL_OK)
      {
      return 2;
      }
      return 0;
      }



    主函数:


    void myTask02_Fun(void *argument)
    {
    /* USER CODE BEGIN myTask02_Fun */
    /* Infinite loop */
    for(;;)
    {
    //printf("test...\r\n");
    FAN_PR_4_Toggle();

            ++bsp_can1.TxData[0];
            CAN1_SendNormalData(0x11,0x0,4);

            ++bsp_can2.TxData[0];
            CAN2_SendNormalData(0x22,0x0,8);        
    osDelay(1000);
    }
    /* USER CODE END myTask02_Fun */
    }


/******************************************/
/*
经过调试发现CAN2发送的数据都卡在发送邮箱里面;
配置过滤器的时候,使用CAN1句柄,也是接收不到数据。
通过查看寄存器,发送错误寄存器ESR的LEC值一直是101 (显性位错),在发送是TEC的值是变化的,接收数据时REC的值也是变化的。
现在不知道如何处理,就只有CAN2有这问题,CAN1的收发是完全没问题的。
*/

收藏 评论5 发布时间:2021-12-23 10:41

举报

5个回答
二少 回答时间:2021-12-29 11:31:45

xmshao 发表于 2021-12-24 15:23
CAN1 can2用法是一样的。</p>
<p>干脆就只对CAN2进行验证测试,先基于回环模式进行测试,这样可以先排除硬 ...

[md]调试到最好发现是硬件问题。换了块TJA1050就正常啦

xmshao 回答时间:2021-12-23 11:07:09
你注意过滤器这个地方,过滤器统一由CAN1管控的,所以即使在配置CAN2所用的滤波期时,还是得使用CAN1,CubeMx生成的代码在这个地方可能有bug。就是下面HAL_CAN_ConfigFilter()这个地方,你确认下。

void bsp_can2_init(void){CAN_FilterTypeDef  sFilterConfig;sFilterConfig.FilterBank = 14;sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;sFilterConfig.FilterIdHigh = 0x0000;sFilterConfig.FilterIdLow = 0x0000;sFilterConfig.FilterMaskIdHigh = 0x0000;sFilterConfig.FilterMaskIdLow = 0x0000;sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO1;sFilterConfig.FilterActivation = ENABLE;sFilterConfig.SlaveStartFilterBank = 14;if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)

。。。。。。
二少 回答时间:2021-12-23 14:59:13
xmshao 发表于 2021-12-23 11:07
你注意过滤器这个地方,过滤器统一由CAN1管控的,所以即使在配置CAN2所用的滤波期时,还是得使用CAN1,Cube ...

使用CAN1句柄去配置CAN2的过滤器也是不行。。还是发不了数据 和 接收不到数据
xmshao 回答时间:2021-12-24 15:23:01

二少 发表于 2021-12-23 14:59
使用CAN1句柄去配置CAN2的过滤器也是不行。。还是发不了数据 和 接收不到数据 ...

CAN1 can2用法是一样的。

干脆就只对CAN2进行验证测试,先基于回环模式进行测试,这样可以先排除硬件方面的原因。注意滤波器设置那里照样使用CAN1.

xmshao 回答时间:2022-1-24 10:39:54

二少 发表于 2021-12-29 11:31
调试到最好发现是硬件问题。换了块TJA1050就正常啦

OK,

谢谢反馈!

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版