STM32
直播中

吴湛

9年用户 833经验值
擅长:417804
私信 关注
[问答]

STM32F407的CAN2为什么要开启CAN1时钟才能使用呢

为什么STM32F407的CAN1可以单独使用?而CAN2要开启CAN1时钟才能使用呢?

回帖(1)

陈磊

2021-10-21 16:44:23
  注意CAN1可以单独使用,CAN2要开启CAN1时钟才能使用。
  u8 CAN1_Mode_Init(u8 mode)
  {
  GPIO_InitTypeDef GPIO_InitStructure;
  CAN_InitTypeDef CAN_InitStructure;
  CAN_FilterInitTypeDef CAN_FilterInitStructure;
  #if CAN1_RX0_INT_ENABLE
  NVIC_InitTypeDef NVIC_InitStructure;
  #endif
  //使能相关时钟
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能PORTA时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟
  //初始化GPIO
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11| GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化PA11,PA12
  //引脚复用映射配置
  GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_CAN1); //GPIOA11复用为CAN1
  GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_CAN1); //GPIOA12复用为CAN1
  //CAN单元设置
  CAN_InitStructure.CAN_TTCM=DISABLE; //非时间触发通信模式
  CAN_InitStructure.CAN_ABOM=DISABLE; //软件自动离线管理
  CAN_InitStructure.CAN_AWUM=DISABLE;//睡眠模式通过软件唤醒(清除CAN-》MCR的SLEEP位)
  CAN_InitStructure.CAN_NART=ENABLE; //禁止报文自动传送
  CAN_InitStructure.CAN_RFLM=DISABLE; //报文不锁定,新的覆盖旧的
  CAN_InitStructure.CAN_TXFP=DISABLE; //优先级由报文标识符决�
  /***************************************************************************************/
  //配置can工作模式
  CAN_InitStructure.CAN_Mode= mode; //模式设置
  CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tq
  CAN_InitStructure.CAN_BS1=CAN_BS1_7tq; //时间段1的时间单元。 Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
  CAN_InitStructure.CAN_BS2=CAN_BS2_6tq; //时间段2的时间单元。 Tbs2范围CAN_BS2_1tq ~ CAN_BS2_8tq
  CAN_InitStructure.CAN_Prescaler=6; //分频系数(Fdiv)为brp+1
  /***************************************************************************************/
  CAN_Init(CAN1, &CAN_InitStructure); // 初始化CAN1
  //配置过滤器
  CAN_FilterInitStructure.CAN_FilterNumber=0; //过滤器0
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位
  CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;32位ID
  CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK
  CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0
  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0
  CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化
  #if CAN1_RX0_INT_ENABLE
  CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许。
  NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 主优先级为1
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 次优先级为0
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  #endif
  return 0;
  }
  #if CAN1_RX0_INT_ENABLE //使能RX0中断
  //中断服务函数
  void CAN1_RX0_IRQHandler(void)
  {
  CanRxMsg RxMessage;
  CAN_Receive(CAN1, 0, &RxMessage);
  }
  #endif
  u8 CAN1_Send_Msg(u8* msg,u8 len)
  {
  u8 mbox;
  u16 i=0;
  CanTxMsg TxMessage;
  TxMessage.StdId=0x12; // 标准标识符为0
  TxMessage.ExtId=0x12; // 设置扩展标示符(29位)
  TxMessage.IDE=0; // 使用扩展标识符
  TxMessage.RTR=0; // 消息类型为数据帧,一帧8位
  TxMessage.DLC=len; // 发送两帧信息
  for(i=0;i《len;i++)
  TxMessage.Data[i]=msg[i]; // 第一帧信息
  mbox= CAN_Transmit(CAN1, &TxMessage);
  i=0;
  while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i《0XFFF))i++; //等待发送结束
  if(i》=0XFFF)return 1;
  return 0;
  }
  u8 CAN2_Mode_Init(u8 mode)
  {
  GPIO_InitTypeDef GPIO_InitStructure;
  CAN_InitTypeDef CAN_InitStructure;
  CAN_FilterInitTypeDef CAN_FilterInitStructure;
  #if CAN2_RX0_INT_ENABLE
  NVIC_InitTypeDef NVIC_InitStructure;
  #endif
  //ʹÄÜÏà¹ØÊ±ÖÓ
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//ʹÄÜPORTAʱÖÓ
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1|RCC_APB1Periph_CAN2, ENABLE); //ʹÓÃCAN2µÄʱºòҲҪʹÄÜCAN1ʱÖÓ
  //³õʼ»¯GPIO
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12| GPIO_Pin_13;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//¸´Óù¦ÄÜ
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//ÍÆÍìÊä³ö
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//ÉÏÀ­
  GPIO_Init(GPIOB, &GPIO_InitStructure);//³õʼ»¯PA11,PA12
  //Òý½Å¸´ÓÃÓ³ÉäÅäÖÃ
  GPIO_PinAFConfig(GPIOB,GPIO_PinSource12,GPIO_AF_CAN2); //GPIOA11¸´ÓÃΪCAN1
  GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_CAN2); //GPIOA12¸´ÓÃΪCAN1
  // CAN_DeInit(CAN2);
  // CAN_StructInit(&CAN_InitStructure);
  //CANµ¥ÔªÉèÖÃ
  CAN_InitStructure.CAN_TTCM=DISABLE; //·Çʱ¼ä´¥·¢Í¨ÐÅģʽ
  CAN_InitStructure.CAN_ABOM=DISABLE; //Èí¼þ×Ô¶¯ÀëÏß¹ÜÀí
  CAN_InitStructure.CAN_AWUM=DISABLE;//˯Ãßģʽͨ¹ýÈí¼þ»½ÐÑ(Çå³ýCAN-》MCRµÄSLEEPλ)
  CAN_InitStructure.CAN_NART=ENABLE; //½ûÖ¹±¨ÎÄ×Ô¶¯´«ËÍ
  CAN_InitStructure.CAN_RFLM=DISABLE; //±¨ÎIJ»Ëø¶¨,еĸ²¸Ç¾ÉµÄ
  CAN_InitStructure.CAN_TXFP=DISABLE; //ÓÅÏȼ¶Óɱ¨Îıêʶ·û¾ö¶¨
  /***************************************************************************************/
  //ÅäÖÃcan¹¤×÷ģʽ
  CAN_InitStructure.CAN_Mode= mode; //ģʽÉèÖÃ
  CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //ÖØÐÂͬ²½ÌøÔ¾¿í¶È(Tsjw)Ϊtsjw+1¸öʱ¼äµ¥Î» CAN_SJW_1tq~CAN_SJW_4tq
  CAN_InitStructure.CAN_BS1=CAN_BS1_7tq; //ʱ¼ä¶Î1µÄʱ¼äµ¥Ôª。 Tbs1·¶Î§CAN_BS1_1tq ~CAN_BS1_16tq
  CAN_InitStructure.CAN_BS2=CAN_BS2_6tq; //ʱ¼ä¶Î2µÄʱ¼äµ¥Ôª。 Tbs2·¶Î§CAN_BS2_1tq ~ CAN_BS2_8tq
  CAN_InitStructure.CAN_Prescaler=6; //·ÖƵϵÊý(Fdiv)Ϊbrp+1 42 /(1+7+6) *6 =0.5M
  /***************************************************************************************/
  CAN_Init(CAN2, &CAN_InitStructure); // ³õʼ»¯CAN2
  //ÅäÖùýÂËÆ÷
  CAN_FilterInitStructure.CAN_FilterNumber=14; //¹ýÂËÆ÷0
  CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
  CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32λ
  CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;32λID
  CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
  CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32λMASK
  CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
  CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//¹ýÂËÆ÷0¹ØÁªµ½FIFO0
  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //¼¤»î¹ýÂËÆ÷0
  CAN_FilterInit(&CAN_FilterInitStructure);//Â˲¨Æ÷³õʼ»¯
  #if CAN2_RX0_INT_ENABLE
  /* OPEN Reception IT */
  CAN_ITConfig(CAN2, CAN_IT_TME, ENABLE);
  CAN_ITConfig(CAN2, CAN_IT_FMP1, ENABLE);
  CAN_ITConfig(CAN2, CAN_IT_EWG, ENABLE);
  CAN_ITConfig(CAN2, CAN_IT_EPV, ENABLE);
  CAN_ITConfig(CAN2, CAN_IT_BOF, ENABLE);
  CAN_ITConfig(CAN2, CAN_IT_LEC, ENABLE);
  CAN_ITConfig(CAN2, CAN_IT_ERR, ENABLE);
  /* receive */
  NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  NVIC_InitStructure.NVIC_IRQChannel = CAN2_SCE_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  BSP_IntVectSet(BSP_INT_ID_CAN2_RX1,CAN2_RX1_IRQHandler);
  BSP_IntEn(BSP_INT_ID_CAN2_RX1);
  BSP_IntVectSet(BSP_INT_ID_CAN2_SCE,CAN2_SCE_IRQHandler);
  BSP_IntEn(BSP_INT_ID_CAN2_SCE);
  BSP_IntVectSet(BSP_INT_ID_CAN2_TX,CAN2_TX_IRQHandler);
  BSP_IntEn(BSP_INT_ID_CAN2_TX);
  #endif
  return 0;
  }
  #if CAN2_RX0_INT_ENABLE //ʹÄÜRX0ÖжÏ
  //ÖжϷþÎñº¯Êý
  void CAN2_RX0_IRQHandler(void)
  {
  CanRxMsg RxMessage;
  CAN_Receive(CAN2, 0, &RxMessage);
  uart1SendChars((u8 *)&RxMessage,sizeof(RxMessage));
  }
  #endif
  u8 CAN2_Send_Msg(u8* msg,u8 len)
  {
  u8 mbox;
  u16 i=0;
  CanTxMsg TxMessage;
  TxMessage.StdId=0x12; // ±ê×¼±êʶ·ûΪ0
  TxMessage.ExtId=0x12; // ÉèÖÃÀ©Õ¹±êʾ·û£¨29룩
  TxMessage.IDE=0; // ʹÓÃÀ©Õ¹±êʶ·û
  TxMessage.RTR=0; // ÏûÏ¢ÀàÐÍΪÊý¾ÝÖ¡£¬Ò»Ö¡8λ
  TxMessage.DLC=len; // ·¢ËÍÁ½Ö¡ÐÅÏ¢
  for(i=0;i《len;i++)
  TxMessage.Data[i]=msg[i]; // µÚÒ»Ö¡ÐÅÏ¢
  mbox= CAN_Transmit(CAN2, &TxMessage);
  i=0;
  while((CAN_TransmitStatus(CAN2, mbox)==CAN_TxStatus_Failed)&&(i《0XFFF))i++; //µÈ´ý·¢ËͽáÊø
  if(i》=0XFFF)return 1;
  return 0;
  }
  void CAN2_SCE_IRQHandler(void)
  {
  if(CAN_GetITStatus(CAN2,CAN_IT_EWG))
  {
  CAN_ClearITPendingBit(CAN2,CAN_IT_EWG);
  // DEBUG_PRINTF(“EWGrn”);
  }
  if(CAN_GetITStatus(CAN2,CAN_IT_EPV))
  {
  CAN_ClearITPendingBit(CAN2,CAN_IT_EPV);
  // DEBUG_PRINTF(“EPVrn”);
  }
  if(CAN_GetITStatus(CAN2,CAN_IT_BOF))
  {
  CAN_ClearITPendingBit(CAN2,CAN_IT_BOF);
  // DEBUG_PRINTF(“BOFrn”);
  }
  //CAN2-》MCR
  if(CAN_GetITStatus(CAN2,CAN_IT_LEC))
  {
  CAN_ClearITPendingBit(CAN2,CAN_IT_LEC);
  // DEBUG_PRINTF(“LECrn”);
  }
  if(CAN_GetITStatus(CAN2,CAN_IT_ERR))
  {
  CAN_ClearITPendingBit(CAN2,CAN_IT_ERR);
  // DEBUG_PRINTF(“ERRrn”);
  }
  }
举报

更多回帖

发帖
×
20
完善资料,
赚取积分