STM32F413VGTx CAN1-CAN2-CAN3的初始化与使用例程

(一)配置流程

(1)启用CAN控制器接口时钟
          RCC_APB1PeriphClockCmd (RCC_APB1Periph_CAN1,使);for CAN1 and 
          rcc_apb1peripclockcmd (rcc_apb1perip_can2, ENABLE);对于CAN2
                    如果你只使用CAN2,必须使能CAN1时钟。
(2)CAN引脚配置
                    1使用以下函数使能CAN gpio时钟:rcc_ahb1peripclockcmd (rcc_ahb1peri_gpiox, Enable);
                    2使用以下功能启用引脚复用 GPIO_PinAFConfig (GPIOx GPIO_PinSourcex GPIO_AF_CANx);
                    3配置这些CAN引脚GPIO_Init ();
      
(3)初始化和配置CAN使用
                    CAN_Init()和
          CAN_FilterInit()
                 
(4)使用CAN_Transmit()函数发送所需的CAN帧。
           
(5)使用CAN_TransmitStatus()函数检查CAN帧的传输。
                 
(6)使用CAN_CancelTransmit()函数取消CAN帧的传输。
              
(7)接收一个CAN帧使用CAN_Receive()函数。
           
(8)使用CAN_FIFORelease()函数释放接收FIFOs。
                 
(9)返回等待接收的帧数量使用
          CAN_MessagePending()函数 .            
                     
(10)控制CAN事件可以使用以下两种方法之一:
(++)使用CAN_GetFlagStatus()函数检查CAN标志。
(++)初始化阶段通过CAN_ITConfig()添加中断事件,用CAN_GetITStatus()函数检查事件是否已经发生。在检查一个标志之后,你应该使用CAN_ClearFlag()来清除它。。在检查一个中断事件之后应该使用CAN_ClearITPendingBit()函数清除它。

(二)程序代码

//CAN1初始化 
//tsjw:重新同步跳跃时间单元.范围:CAN_SJW_1tq~ CAN_SJW_4tq
//tbs2:时间段2的时间单元.   范围:CAN_BS2_1tq~CAN_BS2_8tq;
//tbs1:时间段1的时间单元.   范围:CAN_BS1_1tq ~CAN_BS1_16tq
//brp :波特率分频器.范围:1~1024;  tq=(brp)*tpclk1
//波特率=Fpclk1/((tbs1+tbs2+1)*brp);
//mode:CAN_Mode_Normal,普通模式;CAN_Mode_LoopBack,回环模式;
//Fpclk1的时钟在初始化的时候设置为50M
//则波特率为:50M/((1+7+12)*10)=250Kbps
//返回值:无;
/************************BMS用*********************/
void CAN1_Config_Init(void)

    GPIO_InitTypeDef                 GPIO_InitStructure; 
    CAN_InitTypeDef            CAN_InitStructure;
    CAN_FilterInitTypeDef      CAN_FilterInitStructure;
    NVIC_InitTypeDef                 NVIC_InitStructure;
    
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //使GPIOA时钟                                                           
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟    
    

    
    //引脚复用映射配置
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_CAN1); //GPIOA11复用为CAN1
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_CAN1); //GPIOA12复用为CAN1
    
    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_50MHz;//100MHz
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
    
    GPIO_Init(GPIOA, &GPIO_InitStructure);            //初始化IO
    
    //CAN单元设置
    CAN_InitStructure.CAN_TTCM=DISABLE;            //非时间触发通信模式  
    CAN_InitStructure.CAN_ABOM=ENABLE;            //软件自动离线管理     
    CAN_InitStructure.CAN_AWUM=DISABLE;            //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
    CAN_InitStructure.CAN_NART=DISABLE;            //使能报文自动传送 
    CAN_InitStructure.CAN_RFLM=DISABLE;             //报文不锁定,新的覆盖旧的  
    CAN_InitStructure.CAN_TXFP=DISABLE;            //优先级由报文标识符决定 
    CAN_InitStructure.CAN_Mode= CAN_Mode_Normal;            //模式设置: mode:0,普通模式;1,回环模式; 
    //设置波特率250kbps
    CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;                //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位  CAN_SJW_1tq     CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
    CAN_InitStructure.CAN_BS1=CAN_BS1_12tq;             //Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq
    CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;                //Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~    CAN_BS2_8tq
    CAN_InitStructure.CAN_Prescaler=CAN1_PRESCALER;        //分频系数(Fdiv)为brp+1    
    
    CAN_Init(CAN1, &CAN_InitStructure);            //初始化CAN1 

    //滤波器配置 只接收0x56F4
    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=(bms_filter>>13)&0x0007;   // 取15~13  3位
    CAN_FilterInitStructure.CAN_FilterIdLow=((bms_filter<<3)&0xFFFF)|CAN_ID_EXT;// 取12~0  13位
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0007; //32位MASK//0~15 左移3位变为 3~18 0x0FFFF<<3 = 0x7FFF8
    CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xFFF8|CAN_ID_EXT;
    */
    CAN_FilterInitStructure.CAN_FilterIdHigh        =0;      
    CAN_FilterInitStructure.CAN_FilterIdLow            =0;    
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0;     
    CAN_FilterInitStructure.CAN_FilterMaskIdLow    =0;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0
    CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;//激活过滤器0
    
    CAN_FilterInit(CAN1,&CAN_FilterInitStructure);            //滤波器初始化
    
    //CAN1 NVIC 中断配置
    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);
    
    CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);                //FIFO0消息挂号中断允许.            
}   


void CAN2_Config_Init_1(void)

    GPIO_InitTypeDef         GPIO_InitStructure; 
    CAN_InitTypeDef            CAN_InitStructure;
    CAN_FilterInitTypeDef      CAN_FilterInitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

     
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1 | RCC_APB1Periph_CAN2, ENABLE);//使能CAN1、2时钟         
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);  
    
    //引脚复用映射配置
    GPIO_PinAFConfig(GPIOB,GPIO_PinSource12,GPIO_AF_CAN2); //GPIOB12复用为CAN2
    GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_CAN2); //GPIOB13复用为CAN2
    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);            //初始化IO

    //CAN单元设置
        //CAN单元设置
    CAN_InitStructure.CAN_TTCM=DISABLE;            //非时间触发通信模式  
    CAN_InitStructure.CAN_ABOM=ENABLE;            //软件自动离线管理     
    CAN_InitStructure.CAN_AWUM=DISABLE;            //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
    CAN_InitStructure.CAN_NART=DISABLE;            //使能报文自动传送 
    CAN_InitStructure.CAN_RFLM=DISABLE;             //报文不锁定,新的覆盖旧的  
    CAN_InitStructure.CAN_TXFP=DISABLE;            //优先级由报文标识符决定 
    CAN_InitStructure.CAN_Mode= CAN_Mode_Normal;            //模式设置: mode:0,普通模式;1,回环模式; 
    //设置波特率250kbps
    CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;                //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位  CAN_SJW_1tq     CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
    CAN_InitStructure.CAN_BS1=CAN_BS1_12tq;             //Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq
    CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;                //Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~    CAN_BS2_8tq
    CAN_InitStructure.CAN_Prescaler=CAN2_PRESCALER;        //分频系数(Fdiv)为brp+1    
    
    CAN_Init(CAN2, &CAN_InitStructure);            //初始化CAN2
    

    CAN_FilterInitStructure.CAN_FilterNumber=14;
  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=CAN_Filter_FIFO0;
  CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; 
  CAN_FilterInit(CAN2,&CAN_FilterInitStructure);
  CAN_FilterInit(CAN1,&CAN_FilterInitStructure);
  CAN_ITConfig(CAN2,CAN_IT_FMP0,ENABLE);
    
    //CAN2 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     // 主优先级为1
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;            // 次优先级为0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
}   

void CAN3_Config_Init(void)

        GPIO_InitTypeDef         GPIO_InitStructure; 
        CAN_InitTypeDef         CAN_InitStructure;
        CAN_FilterInitTypeDef     CAN_FilterInitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);                                                              
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN3, ENABLE);//使能CAN3时钟  

        //引脚复用映射配置
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource8,GPIO_AF11_CAN3); //GPIOB3复用为CAN3
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource15,GPIO_AF11_CAN3); //GPIOB4复用为CAN3

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_15;
        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);          //初始化IO

        //CAN单元设置
        CAN_InitStructure.CAN_TTCM=DISABLE;         //非时间触发通信模式  
        CAN_InitStructure.CAN_ABOM=ENABLE;         //软件自动离线管理   
        CAN_InitStructure.CAN_AWUM=DISABLE;         //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)
        CAN_InitStructure.CAN_NART=ENABLE;         //使能报文自动传送 
        CAN_InitStructure.CAN_RFLM=DISABLE;         //报文不锁定,新的覆盖旧的    
        CAN_InitStructure.CAN_TXFP=DISABLE;         //优先级由报文标识符决定 
        CAN_InitStructure.CAN_Mode= CAN_Mode_Normal;             //模式设置: mode:0,普通模式;1,回环模式; 
        //设置波特率250kbps
        CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;                //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位  CAN_SJW_1tq     CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
        CAN_InitStructure.CAN_BS1=CAN_BS1_12tq;             //Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq
        CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;                //Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~    CAN_BS2_8tq
        CAN_InitStructure.CAN_Prescaler=CAN3_PRESCALER;        //分频系数(Fdiv)为brp+1    
        CAN_Init(CAN3, &CAN_InitStructure);            //初始化CAN3

        //暂时不过滤
        CAN_FilterInitStructure.CAN_FilterNumber=3; //过滤器0
        CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;     //屏蔽位模式
        CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;  //32位宽 
        CAN_FilterInitStructure.CAN_FilterIdHigh        =0;      
        CAN_FilterInitStructure.CAN_FilterIdLow            =0;    
        CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0;     
        CAN_FilterInitStructure.CAN_FilterMaskIdLow    =0;
        CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO1;//过滤器3关联到FIFO1
        CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;//激活过滤器3
        CAN_FilterInit(CAN3,&CAN_FilterInitStructure);          //滤波器初始化

        //CAN3 NVIC 配置
        NVIC_InitStructure.NVIC_IRQChannel = CAN3_RX1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;     // 主优先级为1
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;            // 次优先级为0
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);

        CAN_ITConfig(CAN3,CAN_IT_FMP1,ENABLE);              //FIFO0消息挂号中断允许.             
}     

(三)使用时注意事项

can1和can3使用时无特殊注意事项,但是CAN2在使用初始化时需要注意与CAN1的不同之处!
  

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值