一、注意點
兩個CAN接口同時工作主要是初始化的時候必須一起使能時鐘
二、代碼分享
u8 can_init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
{
u16 std_id_1 =0x123;
u16 std_id_2 =0x123;
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_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能PORTA時鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1時鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, 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_InitStructure.GPIO_Pin = GPIO_Pin_5| GPIO_Pin_6;
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);//初始化PA12,PA13
//引腳複用映射配置
GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_CAN1); //GPIOA11複用爲CAN1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_CAN1); //GPIOA12複用爲CAN1
GPIO_PinAFConfig(GPIOB,GPIO_PinSource5,GPIO_AF_CAN2); //GPIOA11複用爲CAN2
GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_CAN2); //GPIOA12複用爲CAN2
//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_InitStructure.CAN_Mode= mode; //模式設置
CAN_InitStructure.CAN_SJW=tsjw; //重新同步跳躍寬度(Tsjw)爲tsjw+1個時間單位 CAN_SJW_1tq~CAN_SJW_4tq
CAN_InitStructure.CAN_BS1=tbs1; //Tbs1範圍CAN_BS1_1tq ~CAN_BS1_16tq
CAN_InitStructure.CAN_BS2=tbs2;//Tbs2範圍CAN_BS2_1tq ~ CAN_BS2_8tq
CAN_InitStructure.CAN_Prescaler=brp; //分頻係數(Fdiv)爲brp+1
CAN_Init(CAN1, &CAN_InitStructure); // 初始化CAN1
CAN_Init(CAN2, &CAN_InitStructure); // 初始化CAN2
//配置過濾器
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);//濾波器初始化
/*---------------------------------------------------------------------------------------------------------------------------------*/
CAN_FilterInitStructure.CAN_FilterNumber=14; //過濾器14
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); //CAN2
#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
#if CAN2_RX0_INT_ENABLE
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);
#endif
return 0;
}