注意CAN1可以单独使用,CAN2要开启CAN1时钟才能使用。
u8 CAN1_Mode_Init(u8 mode)
{
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_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, 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_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_CAN1); //GPIOA11复用为CAN1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_CAN1); //GPIOA12复用为CAN1
//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工作模式
CAN_InitStructure.CAN_Mode= mode; //模式设置
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tq
CAN_InitStructure.CAN_BS1=CAN_BS1_7tq; //时间段1的时间单元. Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
CAN_InitStructure.CAN_BS2=CAN_BS2_6tq; //时间段2的时间单元. Tbs2范围CAN_BS2_1tq ~ CAN_BS2_8tq
CAN_InitStructure.CAN_Prescaler=6; //分频系数(Fdiv)为brp+1
/***************************************************************************************/
CAN_Init(CAN1, &CAN_InitStructure); // 初始化CAN1
//配置过滤器
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);//滤波器初始化
#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
return 0;
}
#if CAN1_RX0_INT_ENABLE //使能RX0中断
//中断服务函数
void CAN1_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
CAN_Receive(CAN1, 0, &RxMessage);
}
#endif
u8 CAN1_Send_Msg(u8* msg,u8 len)
{
u8 mbox;
u16 i=0;
CanTxMsg TxMessage;
TxMessage.StdId=0x12; // 标准标识符为0
TxMessage.ExtId=0x12; // 设置扩展标示符(29位)
TxMessage.IDE=0; // 使用扩展标识符
TxMessage.RTR=0; // 消息类型为数据帧,一帧8位
TxMessage.DLC=len; // 发送两帧信息
for(i=0;i
mbox= CAN_Transmit(CAN1, &TxMessage);
i=0;
while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF))i++; //等待发送结束
if(i>=0XFFF)return 1;
return 0;
}
u8 CAN2_Mode_Init(u8 mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
#if CAN2_RX0_INT_ENABLE
NVIC_InitTypeDef NVIC_InitStructure;
#endif
//ʹÄÜÏà¹ØʱÖÓ
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//ʹÄÜPORTAʱÖÓ
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1|RCC_APB1Periph_CAN2, ENABLE); //ʹÓÃCAN2µÄʱºòҲҪʹÄÜCAN1ʱÖÓ
//³õʼ»¯GPIO
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);//³õʼ»¯PA11,PA12
//Òý½Å¸´ÓÃÓ³ÉäÅäÖÃ
GPIO_PinAFConfig(GPIOB,GPIO_PinSource12,GPIO_AF_CAN2); //GPIOA11¸´ÓÃΪCAN1
GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_CAN2); //GPIOA12¸´ÓÃΪCAN1
// CAN_DeInit(CAN2);
// 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=ENABLE; //½ûÖ¹±¨ÎÄ×Ô¶¯´«ËÍ
CAN_InitStructure.CAN_RFLM=DISABLE; //±¨ÎIJ»Ëø¶¨,еĸ²¸Ç¾ÉµÄ
CAN_InitStructure.CAN_TXFP=DISABLE; //ÓÅÏȼ¶Óɱ¨Îıêʶ·û¾ö¶¨
/***************************************************************************************/
//ÅäÖÃcan¹¤×÷ģʽ
CAN_InitStructure.CAN_Mode= mode; //ģʽÉèÖÃ
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //ÖØÐÂͬ²½ÌøÔ¾¿í¶È(Tsjw)Ϊtsjw+1¸öʱ¼äµ¥Î» CAN_SJW_1tq~CAN_SJW_4tq
CAN_InitStructure.CAN_BS1=CAN_BS1_7tq; //ʱ¼ä¶Î1µÄʱ¼äµ¥Ôª. Tbs1·¶Î§CAN_BS1_1tq ~CAN_BS1_16tq
CAN_InitStructure.CAN_BS2=CAN_BS2_6tq; //ʱ¼ä¶Î2µÄʱ¼äµ¥Ôª. Tbs2·¶Î§CAN_BS2_1tq ~ CAN_BS2_8tq
CAN_InitStructure.CAN_Prescaler=6; //·ÖƵϵÊý(Fdiv)Ϊbrp+1 42 /(1+7+6) *6 =0.5M
/***************************************************************************************/
CAN_Init(CAN2, &CAN_InitStructure); // ³õʼ»¯CAN2
//ÅäÖùýÂËÆ÷
CAN_FilterInitStructure.CAN_FilterNumber=14; //¹ýÂËÆ÷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);//Â˲¨Æ÷³õʼ»¯
#if CAN2_RX0_INT_ENABLE
/* OPEN Reception IT */
CAN_ITConfig(CAN2, CAN_IT_TME, ENABLE);
CAN_ITConfig(CAN2, CAN_IT_FMP1, ENABLE);
CAN_ITConfig(CAN2, CAN_IT_EWG, ENABLE);
CAN_ITConfig(CAN2, CAN_IT_EPV, ENABLE);
CAN_ITConfig(CAN2, CAN_IT_BOF, ENABLE);
CAN_ITConfig(CAN2, CAN_IT_LEC, ENABLE);
CAN_ITConfig(CAN2, CAN_IT_ERR, ENABLE);
/* receive */
NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = CAN2_SCE_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
BSP_IntVectSet(BSP_INT_ID_CAN2_RX1,CAN2_RX1_IRQHandler);
BSP_IntEn(BSP_INT_ID_CAN2_RX1);
BSP_IntVectSet(BSP_INT_ID_CAN2_SCE,CAN2_SCE_IRQHandler);
BSP_IntEn(BSP_INT_ID_CAN2_SCE);
BSP_IntVectSet(BSP_INT_ID_CAN2_TX,CAN2_TX_IRQHandler);
BSP_IntEn(BSP_INT_ID_CAN2_TX);
#endif
return 0;
}
#if CAN2_RX0_INT_ENABLE //ʹÄÜRX0ÖжÏ
//ÖжϷþÎñº¯Êý
void CAN2_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
CAN_Receive(CAN2, 0, &RxMessage);
uart1SendChars((u8 *)&RxMessage,sizeof(RxMessage));
}
#endif
u8 CAN2_Send_Msg(u8* msg,u8 len)
{
u8 mbox;
u16 i=0;
CanTxMsg TxMessage;
TxMessage.StdId=0x12; // ±ê×¼±êʶ·ûΪ0
TxMessage.ExtId=0x12; // ÉèÖÃÀ©Õ¹±êʾ·û£¨29룩
TxMessage.IDE=0; // ʹÓÃÀ©Õ¹±êʶ·û
TxMessage.RTR=0; // ÏûÏ¢ÀàÐÍΪÊý¾ÝÖ¡£¬Ò»Ö¡8λ
TxMessage.DLC=len; // ·¢ËÍÁ½Ö¡ÐÅÏ¢
for(i=0;i
mbox= CAN_Transmit(CAN2, &TxMessage);
i=0;
while((CAN_TransmitStatus(CAN2, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF))i++; //µÈ´ý·¢ËͽáÊø
if(i>=0XFFF)return 1;
return 0;
}
void CAN2_SCE_IRQHandler(void)
{
if(CAN_GetITStatus(CAN2,CAN_IT_EWG))
{
CAN_ClearITPendingBit(CAN2,CAN_IT_EWG);
// DEBUG_PRINTF("EWG\r\n");
}
if(CAN_GetITStatus(CAN2,CAN_IT_EPV))
{
CAN_ClearITPendingBit(CAN2,CAN_IT_EPV);
// DEBUG_PRINTF("EPV\r\n");
}
if(CAN_GetITStatus(CAN2,CAN_IT_BOF))
{
CAN_ClearITPendingBit(CAN2,CAN_IT_BOF);
// DEBUG_PRINTF("BOF\r\n");
}
//CAN2->MCR
if(CAN_GetITStatus(CAN2,CAN_IT_LEC))
{
CAN_ClearITPendingBit(CAN2,CAN_IT_LEC);
// DEBUG_PRINTF("LEC\r\n");
}
if(CAN_GetITStatus(CAN2,CAN_IT_ERR))
{
CAN_ClearITPendingBit(CAN2,CAN_IT_ERR);
// DEBUG_PRINTF("ERR\r\n");
}
}