STM32F407 CAN1 CAN2

注意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   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   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("EWG\r\n");
    }

    if(CAN_GetITStatus(CAN2,CAN_IT_EPV))
    {
        CAN_ClearITPendingBit(CAN2,CAN_IT_EPV);
    //    DEBUG_PRINTF("EPV\r\n");
    }

    if(CAN_GetITStatus(CAN2,CAN_IT_BOF))
    {
        CAN_ClearITPendingBit(CAN2,CAN_IT_BOF);
     //   DEBUG_PRINTF("BOF\r\n");
    }
    //CAN2->MCR

    if(CAN_GetITStatus(CAN2,CAN_IT_LEC))
    {
        CAN_ClearITPendingBit(CAN2,CAN_IT_LEC);
     //   DEBUG_PRINTF("LEC\r\n");
    }

    if(CAN_GetITStatus(CAN2,CAN_IT_ERR))
    {
        CAN_ClearITPendingBit(CAN2,CAN_IT_ERR);
      //  DEBUG_PRINTF("ERR\r\n");
    }
   
}

 

 

你可能感兴趣的:(STM32)