OpenEdv-开源电子网

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

阿波罗STM32F429无法实现双CAN通讯呀,我用CUBEMX配置之后CAN1能够发送但是CAN2发送就会出错

[复制链接]

1

主题

2

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2023-10-8
在线时间
4 小时
发表于 2023-10-8 19:34:00 | 显示全部楼层 |阅读模式
4金钱
这个是我配置之后的代码(HAL库),有些地方我改了我注释里面标注出来了。
/* USER CODE BEGIN 0 */
CAN_TxHeaderTypeDef     TxMessage;      //发送消息
CAN_RxHeaderTypeDef     RxMessage;      //接收消息
uint8_t aRxData[8];
/* USER CODE END 0 */

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 = 5;
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan1.Init.TimeSeg1 = CAN_BS1_5TQ;
  hcan1.Init.TimeSeg2 = CAN_BS2_3TQ;
  hcan1.Init.TimeTriggeredMode = DISABLE;
  hcan1.Init.AutoBusOff = DISABLE;
  hcan1.Init.AutoWakeUp = DISABLE;
  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 = 5;
  hcan2.Init.Mode = CAN_MODE_NORMAL;
  hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan2.Init.TimeSeg1 = CAN_BS1_5TQ;
  hcan2.Init.TimeSeg2 = CAN_BS2_3TQ;
  hcan2.Init.TimeTriggeredMode = DISABLE;
  hcan2.Init.AutoBusOff = DISABLE;
  hcan2.Init.AutoWakeUp = DISABLE;
  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)
{
   //HAL_RCC_CAN1_CLK_ENABLED=0; //原本没有这句话的,但是调试的时候我发现先初始化CAN1再初始化CAN2的时候不太对,这里还是先还原注释掉

  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();
    }
        printf("\r\n %d \r\n ",HAL_RCC_CAN1_CLK_ENABLED);//我这里调试用的,原本配置出来没有这句话的

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**CAN1 GPIO Configuration
    PA11     ------> CAN1_RX
    PA12     ------> CAN1_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* CAN1 interrupt Init */
    HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
//    HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 0, 0);
//    HAL_NVIC_EnableIRQ(CAN1_RX1_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();
    }
               
                printf("\r\n %d \r\n ",HAL_RCC_CAN1_CLK_ENABLED);//我这里调试用的,原本配置出来没有这句话的

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**CAN2 GPIO Configuration
    PB12     ------> CAN2_RX
    PB13     ------> CAN2_TX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
                //GPIO_InitStruct.Pull = GPIO_NOPULL;
                //GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;//原本配置的时候是NOPULL,但是我看了好多例子都是PULLUP
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF9_CAN2;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* CAN2 interrupt Init */
    HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn);
//    HAL_NVIC_SetPriority(CAN2_RX1_IRQn, 0, 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)
{
   //HAL_RCC_CAN1_CLK_ENABLED=1;//原本没有这句话的,自己调试的时候加上的

  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
    PA11     ------> CAN1_RX
    PA12     ------> CAN1_TX
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);

    /* CAN1 interrupt Deinit */
    HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);
    HAL_NVIC_DisableIRQ(CAN1_RX1_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
    PB12     ------> CAN2_RX
    PB13     ------> CAN2_TX
    */
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12|GPIO_PIN_13);

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

  /* USER CODE END CAN2_MspDeInit 1 */
  }
}

/* USER CODE BEGIN 1 */
//过滤器我是自己配置的
static void CAN1_Filter_Config(void)
{
    CAN_FilterTypeDef  CAN_FilterInitStructure;

    /*CAN筛选器初始化*/
    CAN_FilterInitStructure.FilterBank=0;                                                //筛选器组0
    CAN_FilterInitStructure.FilterMode=CAN_FILTERMODE_IDMASK;        //工作在掩码模式
    CAN_FilterInitStructure.FilterScale=CAN_FILTERSCALE_16BIT;        //筛选器位宽为单个32位。
    CAN_FilterInitStructure.FilterIdLow= ((0x601&0xFF)|(0x602&0xFF)|(0x603&0xFF)|(0x604&0xFF)|(0x605&0xFF)|(0x606&0xFF)|(0x607&0xFF)|(0x200&0xFF)|(0x201&0xFF)); //要筛选的ID低位
    CAN_FilterInitStructure.FilterMaskIdLow= 0xFFFF;                        //筛选器低16位每位必须匹配
    CAN_FilterInitStructure.FilterFIFOAssignment=CAN_FILTER_FIFO0 ;        //筛选器被关联到FIFO0
    CAN_FilterInitStructure.FilterActivation=ENABLE;                        //使能筛选器
          CAN_FilterInitStructure.SlaveStartFilterBank=14;                       
    HAL_CAN_ConfigFilter(&hcan1,&CAN_FilterInitStructure);
}

static void CAN2_Filter_Config(void)
//过滤器我是自己配置的
{
    CAN_FilterTypeDef  CAN_FilterInitStructure;

    /*CAN筛选器初始化*/
    CAN_FilterInitStructure.FilterBank=14;                                                //筛选器组14
    CAN_FilterInitStructure.FilterMode=CAN_FILTERMODE_IDMASK;        //工作在掩码模式
    CAN_FilterInitStructure.FilterScale=CAN_FILTERSCALE_16BIT;        //筛选器位宽为单个32位。
    CAN_FilterInitStructure.FilterIdLow= ((0x01&0xFF)|(0x02&0xFF)|(0x03&0xFF)|(0x04&0xFF)|(0x05&0xFF)|(0x06&0xFF)|(0x07&0xFF)); //要筛选的ID低位
    CAN_FilterInitStructure.FilterMaskIdLow= 0xFFFF;                        //筛选器低16位每位必须匹配
    CAN_FilterInitStructure.FilterFIFOAssignment=CAN_FILTER_FIFO0 ;        //筛选器被关联到FIFO0
    CAN_FilterInitStructure.FilterActivation=ENABLE;                        //使能筛选器
          CAN_FilterInitStructure.SlaveStartFilterBank=14;                       
    HAL_CAN_ConfigFilter(&hcan2,&CAN_FilterInitStructure);
}

//CAN口接收数据初始化配置
//接收配置也是我自己写的
void CAN_RxInitConfig(void)
{
    RxMessage.StdId=0x581|0x582|0x583|0x584|0x585|0x586|0x587|0x200|0x201|0x001|0x002|0x003|0x004|0x005|0x006|0x007;
          //RxMessage.StdId=0x00;
    RxMessage.IDE=CAN_ID_STD;
    RxMessage.RTR=CAN_RTR_DATA;
    RxMessage.DLC=8;
}


/*******************************************************************************
* Function Name  : HAL_CAN_RxFifo0MsgPendingCallback
* Description    : 消息接收回调函数
* Input          : hcan
* Output         : None
* Return         : None
****************************************************************************** */
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
//    uint8_t  i;

    if(HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxMessage, aRxData) == HAL_OK)
    {
        printf("\nGet Rx Message Success!!\n");
//        for(int i=0; i<8; i++)
//        {
//            printf("%d ", aRxData[i]);
//        }
    }
                else if(HAL_CAN_GetRxMessage(&hcan2, CAN_RX_FIFO0, &RxMessage, aRxData) == HAL_OK)
    {
        printf("\nGet Rx Message Success!!\n");
//        for(int i=0; i<8; i++)
//        {
//            printf("%d ", aRxData[i]);
//        }
    }
               
}

/*
* 函数名:CAN_Config
* 描述  :完整配置CAN的功能
* 输入  :无
* 输出  : 无
* 调用  :外部调用
*/
void CAN_Config(void)
{
        MX_CAN1_Init();
  //MX_CAN2_Init();
        CAN1_Filter_Config();
        HAL_CAN_Start(&hcan1);
        HAL_CAN_ActivateNotification(&hcan1,CAN_IT_RX_FIFO0_MSG_PENDING);
        MX_CAN2_Init();
        CAN2_Filter_Config();
  //CAN_RxInitConfig();
  //HAL_CAN_Start(&hcan1);
        HAL_CAN_Start(&hcan2);
  //HAL_CAN_ActivateNotification(&hcan1,CAN_IT_RX_FIFO0_MSG_PENDING);
        HAL_CAN_ActivateNotification(&hcan2,CAN_IT_RX_FIFO0_MSG_PENDING);
//  HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxMessage, aRxData);
//  printf("\r\n Init \r\n");
}

//can发送一组数据(固定格式:ID为0x001,标准帧,数据帧)
//CAN1发送没有报错
void CAN1_Send_MsgEncoder1(uint8_t *temp)
{
    static CAN_TxHeaderTypeDef TxMessage;
    uint32_t *pTxMailbox;
    TxMessage.StdId=0x001;        //标准标识符
    TxMessage.IDE=CAN_ID_STD;    //使用标准帧
    TxMessage.RTR=CAN_RTR_DATA;  //数据帧
    TxMessage.DLC=8;
    int a=HAL_CAN_AddTxMessage(&hcan1,&TxMessage,temp,pTxMailbox);
    if(a!=HAL_OK)
    {

        printf("txmessage failed!%d\r\n",a);
    }
    HAL_Delay(1);
}

//can发送一组数据(固定格式:ID为0x001,标准帧,数据帧)
//CAN2发送报错,a=1
void CAN2_Send_MsgEncoder1(uint8_t *temp)
{
    static CAN_TxHeaderTypeDef TxMessage;
    uint32_t *pTxMailbox;
    TxMessage.StdId=0x001;        //标准标识符
    TxMessage.IDE=CAN_ID_STD;    //使用标准帧
    TxMessage.RTR=CAN_RTR_DATA;  //数据帧
    TxMessage.DLC=8;
    int a=HAL_CAN_AddTxMessage(&hcan2,&TxMessage,temp,pTxMailbox);
    if(a!=HAL_OK)
    {

        printf("txmessage failed!%d\r\n",a);
    }
    HAL_Delay(1);
}


P.S.希望大佬有程序的能发出来学习学习,我搞了一下午了实在不知道为啥出错,在A盘资料里面也没找到双CAN 的例子,看了之前15和16年的帖子感觉我自己配置的没啥问题,希望各位路过的能帮帮忙!!

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

使用道具 举报

6

主题

52

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
215
金钱
215
注册时间
2023-9-1
在线时间
24 小时
发表于 2023-10-10 09:18:00 | 显示全部楼层
看不懂,帮你顶一个!
学习至上
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-23 07:36

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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