求助啊,被STM32的CAN折磨的疯了

最近几天都在调试自己做的小型开发板,但是在CAN的这一块就是调试不过去,在初始化的时候就过不去了,程序如下:
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;

  /* Configure CAN1 pin: RX */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_RX;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(GPIO_CAN, &GPIO_InitStructure);

  /* Configure CAN1 pin: TX */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_TX;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIO_CAN, &GPIO_InitStructure);

  GPIO_PinRemapConfig(GPIO_Remap_CAN , ENABLE);

    /* Configure CAN2 pin: RX */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_RX_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(GPIO_CAN_2, &GPIO_InitStructure);

  /* Configure CAN2 pin: TX */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_TX_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIO_CAN_2, &GPIO_InitStructure);

  GPIO_PinRemapConfig(GPIO_Remap_CAN_2 , ENABLE);
}


void CAN_Config(CAN_TypeDef* CANx, uint8_t CAN_FilterNumber)
{
  /* CAN register init */
  CAN_DeInit(CANx);
  CAN_StructInit(&CAN_InitStructure);

  /* CAN cell init */
  CAN_InitStructure.CAN_TTCM = DISABLE;
  CAN_InitStructure.CAN_ABOM = DISABLE;
  CAN_InitStructure.CAN_AWUM = DISABLE;
  CAN_InitStructure.CAN_NART = DISABLE;
  CAN_InitStructure.CAN_RFLM = DISABLE;
  CAN_InitStructure.CAN_TXFP = DISABLE;
  CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
  CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
  CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
  CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
  CAN_InitStructure.CAN_Prescaler = 4;//2
  CAN_Init(CANx, &CAN_InitStructure);

/* CAN filter init */
  CAN_FilterInitStructure.CAN_FilterNumber=CAN_FilterNumber;
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
  CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
  CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=(CANx == CAN1? 0:1);
  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
  CAN_FilterInit(CANx, &CAN_FilterInitStructure);

   /* transmit */
  TxMessage.StdId = 0x321;
  TxMessage.ExtId = 0x01;
  TxMessage.RTR = CAN_RTR_DATA;
  TxMessage.IDE = CAN_ID_STD;
  TxMessage.DLC = 1;

}


  CANx->MCR &= ~MCR_SLEEP;

  /* Request initialisation */
  CANx->MCR |= MCR_INRQ ;

  /* Wait the acknowledge */
  while (((CANx->MSR & MSR_INAK) != MSR_INAK) && (wait_ack != INAK_TimeOut))
  {
    wait_ack++;
  }

  /* ...and check acknowledged */
  if ((CANx->MSR & MSR_INAK) != MSR_INAK)
  {
    InitStatus = CANINITFAILED;
  }
  else 
  {
    /* Set the time triggered communication mode */
    if (CAN_InitStruct->CAN_TTCM == ENABLE)
    {
      CANx->MCR |= MCR_TTCM;
    }
    else
    {
      CANx->MCR &= ~MCR_TTCM;
    }

    /* Set the automatic bus-off management */
    if (CAN_InitStruct->CAN_ABOM == ENABLE)
    {
      CANx->MCR |= MCR_ABOM;
    }
    else
    {
      CANx->MCR &= ~MCR_ABOM;
    }

    /* Set the automatic wake-up mode */
    if (CAN_InitStruct->CAN_AWUM == ENABLE)
    {
      CANx->MCR |= MCR_AWUM;
    }
    else
    {
      CANx->MCR &= ~MCR_AWUM;
    }

    /* Set the no automatic retransmission */
    if (CAN_InitStruct->CAN_NART == ENABLE)
    {
      CANx->MCR |= MCR_NART;
    }
    else
    {
      CANx->MCR &= ~MCR_NART;
    }

    /* Set the receive FIFO locked mode */
    if (CAN_InitStruct->CAN_RFLM == ENABLE)
    {
      CANx->MCR |= MCR_RFLM;
    }
    else
    {
      CANx->MCR &= ~MCR_RFLM;
    }

    /* Set the transmit FIFO priority */
    if (CAN_InitStruct->CAN_TXFP == ENABLE)
    {
      CANx->MCR |= MCR_TXFP;
    }
    else
    {
      CANx->MCR &= ~MCR_TXFP;
    }

    /* Set the bit timing register */
    CANx->BTR = (uint32_t)((uint32_t)CAN_InitStruct->CAN_Mode << 30) | ((uint32_t)CAN_InitStruct->CAN_SJW << 24) |
               ((uint32_t)CAN_InitStruct->CAN_BS1 << 16) | ((uint32_t)CAN_InitStruct->CAN_BS2 << 20) |
               ((uint32_t)CAN_InitStruct->CAN_Prescaler - 1);

    /* Request leave initialisation */
    CANx->MCR &= ~MCR_INRQ;

   /* Wait the acknowledge */
   wait_ack = 0x00;

   while (((CANx->MSR & MSR_INAK) == MSR_INAK) && (wait_ack != INAK_TimeOut))
   {
     wait_ack++;
   }

    /* ...and check acknowledged */
    if ((CANx->MSR & MSR_INAK) == MSR_INAK)
    {
      InitStatus = CANINITFAILED;
    }
    else
    {
      InitStatus = CANINITOK ;
    }
  }

  /* At this step, return the status of initialization */
  return InitStatus;



就是死在了   while (((CANx->MSR & MSR_INAK) == MSR_INAK) && (wait_ack != INAK_TimeOut))
   {
     wait_ack++;
   }手册说是到这个地方是硬件自动对CAN_MSR_INAK位自动清零,但是就是一直没出现,希望各位大神赐教啊!!!!!

 

总算是解决了,在CAN这一块卡了半个月,从头地仔细看了一遍STM32的CAN,检测硬件电路的设计,缺少帮忙真的很无助,总算黄天不负有心人,弄出来了,在此总结一下,感谢帮助过的各位。
    CAN1在STM上有两个可以重映射的IO口PD0,PD1和PB8,PB9,因此在对他们进行重映射时有十分注意,必须要在一下每个地方修改:
CAN1的重映射:
  #define RCC_APB2Periph_GPIO_CAN    RCC_APB2Periph_GPIOB                 //端口修改
  #define GPIO_Remap_CAN             GPIO_Remap1_CAN1                      //若是映射到PD口则是GPIO_Remap2_CAN1
  #define GPIO_CAN                   GPIOB                                  //端口修改
  #define GPIO_Pin_CAN_RX            GPIO_Pin_8                             //Rx修改
  #define GPIO_Pin_CAN_TX            GPIO_Pin_9                             //Tx修改
我就是在第二个地方失误了,重映射的时候没改,蛋疼了半个月,希望后来者能够避免此错误。

猜你喜欢

转载自blog.csdn.net/qinrenzhi/article/details/82562267