STM32F107之CAN配置

STM32F107属于STMF10x系列的互联型产品,所以配有2个CAN模块即CAN1和CAN2。CAN模块正常工作模式和测试模式,且测试模式又分为环回模式、静默模式和环回静默模式,但一般都使用正常工作模式,所以在此仅介绍正常工作模式相关配置。

一、来说说CAN模块的配置步骤:

1、初始化CAN相关GPIO口;

2、初始化CAN控制器;

3、初始化CAN过滤器;

4、初始化CAN中断;

5、添加CAN中断接收函数;

二、CAN1部分具体代码如下(库函数版本为V3.50):

1、初始化CAN1相关GPIO口:

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PORTA时钟                 
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟    

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽
    GPIO_Init(GPIOA, &GPIO_InitStructure);            //初始化IO

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;    //上拉输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);  

 

2、初始化CAN1控制器:   

    CAN_DeInit(CAN1); //默认初始化配置
    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=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;                //SJW = 1tq
    CAN_InitStructure.CAN_BS1=CAN_BS1_3tq;             //Tbs1 = 3tq
    CAN_InitStructure.CAN_BS2=CAN_BS2_5tq;                //Tbs2 = 5tq
    CAN_InitStructure.CAN_Prescaler=8; //分频系数8,即波特率为36M/((1+3+5)*8)= 500k,其中36M为PCLK1    
    CAN_Init(CAN1, &CAN_InitStructure);            //初始化CAN1 

3、初始化CAN1过滤器:   

    CAN_FilterInitStructure.CAN_FilterNumber=0;    //过滤器0,选择范围0 - 13
    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);            //滤波器初始化

4、初始化CAN1中断:   

    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);

5、添加CAN1中断接收函数:

void CAN1_RX0_IRQHandler(void)
{
      CanRxMsg RxMessage;
      CAN_Receive(CAN1, CAN_Filter_FIFO0, &RxMessage);
      /*此处可添加接收消息处理逻辑*/
}

三、CAN2部分的具体代码:

    CAN2与CAN1大同小异,相关配置步骤也是一样,指示具体配置参数有所差别,这里只列出不同之处:

1、初始化CAN2相关GPIO口: 与CAN1配置类似

2、初始化CAN2控制器:与CAN1配置相同

3、初始化CAN2过滤器:

    CAN_FilterInitStructure.CAN_FilterNumber=14;    //过滤器14,选择范围14 - 27
    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_SlaveStartBank(14);//配置CAN2起始过滤器为14,此配置只当芯片有CAN2模块时才需要

    CAN_FilterInit(&CAN_FilterInitStructure);            //滤波器初始化,通过库函数可得知这里实际是配置CAN1相关寄存器,因CAN2不能直接访问SRAM,所以利用CAN1的寄存器来间接访问。

4、初始化CAN2中断:   

    CAN_ITConfig(CAN2,CAN_IT_FMP0,ENABLE);                //FIFO0消息挂号中断允许.            
    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);

5、添加CAN2中断接收函数;

void CAN2_RX0_IRQHandler(void)
{
      CanRxMsg RxMessage;
      CAN_Receive(CAN2, CAN_Filter_FIFO0, &RxMessage);
      /*此处可添加接收消息处理逻辑*/
}

到此代码部分已差不多,但以上内容均指示说明了一个大概过程与配置,具体为何这样配置需配合官方文档和其它相关资料分析。

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(STM32)