/******************** (C) COPYRIGHT 2011 嵌入式开发工作室 ******************** * 文件名 :bsp_can.c * 描述 : * * 实验平台: * 硬件连接: * * 作者 : * 时间 :2022-10-12 * 版本 :V1.0 **********************************************************************************/ #include #include #include "can.h" #include "stm32f10x_can.h" #include "misc.h" #include "Sys.h" #include "bsp_can.h" #include "canbusdrv.h" #include "REV_CarMessage.h" #include "Sleep.h" #include "SecTimer.h" #define DEBUG_BSP_CAN 1 #if DEBUG_BSP_CAN > 0 #define CAN_PRINT DEPRINT #define CAN_PRINT_ARRAY DEPRINT_ARRAY #else #define CAN_PRINT(...) ; #define CAN_PRINT_ARRAY(...) ; #endif u8 CAN_Mode_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure; #if CAN_RX0_INT_ENABLE NVIC_InitTypeDef NVIC_InitStructure; #endif RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);//使能PORTD时钟,使能功能复用时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟 CAN_OperatingModeRequest(CAN1, CAN_OperatingMode_Initialization); 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);//初始化IO // GPIO_PinRemapConfig(GPIO_Remap2_CAN1,ENABLE); //GPIO_PinRemapConfig(GPIO_Remap1_CAN1,ENABLE); //CAN单元设置 CAN_InitStructure.CAN_TTCM=DISABLE; //非时间触发通信模式 // CAN_InitStructure.CAN_ABOM=ENABLE; // 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; //模式设置: mode:0,普通模式;1,回环模式; // //设置波特率 #if 0 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_8tq; //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=9; //分频系数(Fdiv)为brp+1 // #else /* 250k采样点在87.5%为好,下面设置正好是87.5%*/ 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_13tq; //Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;//Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~ CAN_BS2_8tq CAN_InitStructure.CAN_Prescaler=9; //分频系数(Fdiv)为brp+1 // #endif CAN_Init(CAN1, &CAN_InitStructure); // 初始化CAN1 CAN = 36000000 / 9 / (1 + 7 + 8); 250k 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 CAN_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 CAN_ITConfig(CAN1,CAN_IT_TME,ENABLE);//FIFO0消息挂号中断允许. // CAN_ClearITPendingBit(CAN1, CAN_IT_EPV); // CAN_ClearITPendingBit(CAN1, CAN_IT_BOF); CAN_ITConfig(CAN1,CAN_IT_EPV,ENABLE); /* Error passive Interrupt */ CAN_ITConfig(CAN1,CAN_IT_BOF,ENABLE); /* Error bus off Interrupt */ CAN_ITConfig(CAN1,CAN_IT_ERR,ENABLE); /* Error bus off Interrupt */ CAN_OperatingModeRequest(CAN1, CAN_OperatingMode_Normal); NVIC_InitStructure.NVIC_IRQChannel = CAN1_TX_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 主优先级为1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 次优先级为0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = CAN1_SCE_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 主优先级为1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 次优先级为0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); printf("can 1 open!\n"); return 0; } void CAN1_TX_IRQHandler(void) { unsigned char ret; ret = CAN_TransmitStatus(CAN1, 0); if (ret != CAN_TxStatus_Pending) { bsp_can_msg_sent_hook(0, 0, ret == CAN_TxStatus_Ok); } ret = CAN_TransmitStatus(CAN1, 1); if (ret != CAN_TxStatus_Pending) { bsp_can_msg_sent_hook(0, 1, ret == CAN_TxStatus_Ok); } ret = CAN_TransmitStatus(CAN1, 2); if (ret != CAN_TxStatus_Pending) { bsp_can_msg_sent_hook(0, 2, ret == CAN_TxStatus_Ok); } CAN_ClearITPendingBit(CAN1, CAN_IT_TME); } void CAN1_SCE_IRQHandler(void) { if (CAN_GetITStatus(CAN1, CAN_IT_EPV) == SET) { if (CAN_GetFlagStatus(CAN1, CAN_FLAG_EPV) == SET) { can_bus_err_passive_hook(0); // printf("!!!CAN1 ERR passive\n"); //CAN_ClearFlag(CAN1, CAN_FLAG_EPV); } else { // printf("!!!CAN1 ERR active\n"); } CAN_ClearITPendingBit(CAN1, CAN_IT_EPV); } if (CAN_GetITStatus(CAN1, CAN_IT_BOF) == SET) { if (CAN_GetFlagStatus(CAN1, CAN_FLAG_BOF) == SET) { can_bus_off_hook(0); // printf("!!!CAN1 BUS OFF\n"); //CAN_ClearFlag(CAN1, CAN_FLAG_BOF); } else { // printf("!!!CAN1 BUS ON\n"); } CAN_ClearITPendingBit(CAN1, CAN_IT_BOF); } } void CAN2_SCE_IRQHandler(void) { if (CAN_GetITStatus(CAN2, CAN_IT_EPV) == SET) { if (CAN_GetFlagStatus(CAN2, CAN_FLAG_EPV) == SET) { can_bus_err_passive_hook(1); // printf("!!!CAN2 ERR passive\n"); CAN_ClearFlag(CAN2, CAN_FLAG_EPV); } else { // printf("!!!CAN2 ERR active\n"); } CAN_ClearITPendingBit(CAN2, CAN_IT_EPV); } if (CAN_GetITStatus(CAN2, CAN_IT_BOF) == SET) { if (CAN_GetFlagStatus(CAN2, CAN_FLAG_BOF) == SET) { Sleep_Parame.BufFlag = 1; Sleep_Parame.BusoffCnt++; SecStop(&SecTimer[BusoffCnt_Free_SecTimerNUM]); can_bus_off_hook(1); // printf("!!!CAN2 BUS OFF\n"); CAN_ClearFlag(CAN2, CAN_FLAG_BOF); } else { Sleep_Parame.BusoffCnt=0; // printf("!!!CAN2 BUS ON\n"); } CAN_ClearITPendingBit(CAN2, CAN_IT_BOF); } } #if CAN_RX0_INT_ENABLE //使能RX0中断 //中断服务函数 void CAN1_RX0_IRQHandler(void) { CanRxMsg RxMessage; // int i=0; // CAN_Receive(CAN1, 0, &RxMessage); // Can_Send_Msg(RxMessage.Data,8); CAN_Receive(CAN1,CAN_FIFO0,&RxMessage); bsp_can_msg_receive_hook(0, (CanTxMsg *)&RxMessage); /* 注意这里CanRxMsg 和 CanTxMsg 格式不同,但是能兼容*/ } #endif ///////////////////////////////////////////////////CAN2//////////////////////////////////////////////////// void CAN2_TX_IRQHandler(void) { unsigned char ret; ret = CAN_TransmitStatus(CAN2, 0); if (ret != CAN_TxStatus_Pending) { bsp_can_msg_sent_hook(1, 0, ret == CAN_TxStatus_Ok); } ret = CAN_TransmitStatus(CAN2, 1); if (ret != CAN_TxStatus_Pending) { bsp_can_msg_sent_hook(1, 1, ret == CAN_TxStatus_Ok); } ret = CAN_TransmitStatus(CAN2, 2); if (ret != CAN_TxStatus_Pending) { bsp_can_msg_sent_hook(1, 2, ret == CAN_TxStatus_Ok); } CAN_ClearITPendingBit(CAN2, CAN_IT_TME); } u8 CAN2_Mode_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure; #if CAN_RX2_INT_ENABLE NVIC_InitTypeDef NVIC_InitStructure; #endif SYS_ENTER_CRITICAL(); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);//使能PORTB时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);//使能CAN2时钟 CAN_OperatingModeRequest(CAN2, CAN_OperatingMode_Initialization); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽 GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化IO GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入 GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化IO // GPIO_PinRemapConfig(GPIO_Remap_CAN2,ENABLE); //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=ENABLE; //优先级由报文标识符决定 // CAN_InitStructure.CAN_Mode= CAN_Mode_Normal; //模式设置: mode:0,普通模式;1,回环模式; // //设置波特率 #if 0 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_4tq; //Tbs1=tbs1+1个时间单位CAN_BS1_1tq ~CAN_BS1_16tq CAN_InitStructure.CAN_BS2=CAN_BS2_3tq; //Tbs2=tbs2+1个时间单位CAN_BS2_1tq ~ CAN_BS2_8tq CAN_InitStructure.CAN_Prescaler=9; //分频系数(Fdiv)为brp+1 // #else /* 500kpbs 采样点应该在80%多一点为好 */ CAN_InitStructure.CAN_SJW=CAN_SJW_2tq; CAN_InitStructure.CAN_BS1=CAN_BS1_9tq; CAN_InitStructure.CAN_BS2=CAN_BS2_2tq; CAN_InitStructure.CAN_Prescaler=6; // 83.3%采样点 // #endif CAN_Init(CAN2, &CAN_InitStructure); // 初始化CAN2 //#ifdef _Filter if(Sleep_Parame.False_sleep_State) { 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_FIFO1;//过滤器0关联到FIFO0 CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;//激活过滤器0 CAN_FilterInit(&CAN_FilterInitStructure); //滤波器初始化 } //#else else { CAN_Filter_register(Standard_frame,Evcan_HandleTable); } //#endif #if CAN_RX2_INT_ENABLE CAN_ITConfig(CAN2,CAN_IT_FMP1,ENABLE);//FIFO0消息挂号中断允许. NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 主优先级为1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 次优先级为0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #endif CAN_ITConfig(CAN2,CAN_IT_TME,ENABLE);//FIFO0消息挂号中断允许. // CAN_ClearITPendingBit(CAN1, CAN_IT_EPV); // CAN_ClearITPendingBit(CAN1, CAN_IT_BOF); CAN_ITConfig(CAN2,CAN_IT_EPV,ENABLE); /* Error passive Interrupt */ CAN_ITConfig(CAN2,CAN_IT_BOF,ENABLE); /* Error bus off Interrupt */ CAN_ITConfig(CAN2,CAN_IT_ERR,ENABLE); /* Error bus off Interrupt */ CAN_OperatingModeRequest(CAN2, CAN_OperatingMode_Normal); NVIC_InitStructure.NVIC_IRQChannel = CAN2_TX_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 主优先级为1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 次优先级为0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = CAN2_SCE_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 主优先级为1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 次优先级为0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); SYS_EXIT_CRITICAL(); printf("can 2 open!\n"); return 0; } ///////////////////////////////////////////////////CAN2//////////////////////////////////////////////////// #if CAN_RX2_INT_ENABLE //使能RX2中断 //中断服务函数 void CAN2_RX1_IRQHandler(void) { CanRxMsg RxMessage2; // CAN_Receive(CAN2, CAN_FIFO0, &RxMessage); Sleep_Parame.Bus_Packet_Free = 1; SecStop(&SecTimer[Bus_Packet_Free_SecTimerNUM]); for (uint8_t fifoMsgNum = 0; fifoMsgNum < 3; fifoMsgNum ++) { if (CAN_MessagePending(CAN2, CAN_FIFO1)) { CAN_Receive(CAN2, CAN_FIFO1, &RxMessage2); if (RxMessage2.RTR == CAN_RTR_DATA) { bsp_can_msg_receive_hook(1, (CanTxMsg *)&RxMessage2); /* 注意这里CanRxMsg 和 CanTxMsg 格式不同,但是能兼容*/ UdsApi_MsgQueueIn(RxMessage2); } } else { break; } } // Can2_Send_Msg(RxMessage2.Data,8); } #endif /** * @brief: 接口的配置信息 * * @param channel: can 通道号, 不大于MCU_CAN_CHANNEL_NUM * @param pt_bsp_cfg[IN]: 总线自动配置 * * @return: * 返回结果: true - open 成功 false - open 失败 */ bool bsp_can_open(unsigned char channel, const bsp_can_cfg_t * pt_bsp_cfg) { if (channel == 0) { CAN_Mode_Init(); } else { CAN2_Mode_Init(); } return true; } /** * @brief: 关闭接口 * * @return: * 返回结果: true - open 成功 false - open 失败 */ bool bsp_can_close(unsigned char channel) { if (channel == 0) { CAN_OperatingModeRequest(CAN1, CAN_OperatingMode_Initialization); CAN_DeInit(CAN1); } else { CAN_OperatingModeRequest(CAN2, CAN_OperatingMode_Initialization); CAN_DeInit(CAN2); } return true; } unsigned char bsp_can_msg_send(unsigned char channel, const can_frame_t * pt_fram) { u8 mbox; mbox= CAN_Transmit((channel == 0)?CAN1:CAN2, (can_frame_t *)pt_fram); if (mbox == CAN_TxStatus_NoMailBox) { mbox = BSP_CAN_SEND_FAIL; } return mbox; }