STM32F107之CAN配置

STM32F107属于STMF10x系列的互联型产品,所以配有2个CAN模块即CAN1和CAN2。CAN模块正常工作模式和测试模式,且测试模式又分为环回模式、静默模式和环回静默模式,但一般都使用正常工作模式,所以在此仅介绍正常工作模式相关配置。
一、来说说CAN模块的配置步骤:
1、初始化CAN相关GPIO口;
【STM32F107之CAN配置】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); //初始化IOGPIO_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; //激活过滤器0CAN_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; //激活过滤器0CAN_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); /*此处可添加接收消息处理逻辑*/ }

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










    推荐阅读