请选择 进入手机版 | 继续访问电脑版

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

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管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版