(一)配置流程
(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的不同之处! ??
|