/*********************************************************************************************** 功能:CAN 发送一则消息 形参:CAN_Type: CAN结构 @arg CAN0 : CAN0模块 @arg CAN1 : CAN1模块 TxMessage : 发送消息结构 返回:0 详解:0 ************************************************************************************************/ uint8_t CAN_Transmit(CAN_Type* CANx, CAN_TxMsgTypeDef* TxMessage) { uint32_t temp_id = 0; uint16_t i,j; uint32_t word[2] = {0}; //参数检查 assert_param(IS_CAN_MB_NUM(TxMessage->MBIndex)); assert_param(IS_CAN_RTR(TxMessage->RTR)); assert_param(IS_CAN_IDE(TxMessage->IDE)); assert_param(IS_CAN_ALL_PERIPH(CANx)); assert_param(IS_CAN_DLC(TxMessage->DLC)); assert_param(IS_CAN_IDE(TxMessage->IDE )); //转换数据格式 for(i=0;i<TxMessage->DLC;i++) { if(i < 4) { word[0] |= ((TxMessage->Data[i])<<((3-i)*8)); } else { word[1] |= ((TxMessage->Data[i])<<((7-i)*8)); } } //拓展帧还是普通帧 (TxMessage->IDE == CAN_IDE_Extended)?(temp_id = ((1<<29)|TxMessage->Id)):(temp_id = ((1<<29)|(TxMessage->Id << 18))); //传输处理 CANx->MB[TxMessage->MBIndex].CS = CAN_CS_CODE(8); // 写非激活代码 CANx->MB[TxMessage->MBIndex].ID = temp_id; CANx->MB[TxMessage->MBIndex].WORD0 = word[0]; CANx->MB[TxMessage->MBIndex].WORD1 = word[1]; for(i = 0;i < 50;i++); //延时处理,让硬件准备好 if(TxMessage->IDE == 1) { CANx->MB[TxMessage->MBIndex].CS = CAN_CS_CODE(12)|CAN_CS_IDE_MASK|CAN_CS_DLC(TxMessage->DLC)|CAN_CS_SRR_MASK; } else { CANx->MB[TxMessage->MBIndex].CS = CAN_CS_CODE(12)|CAN_CS_DLC(TxMessage->DLC); } //远程帧还是数据帧 (TxMessage->RTR == CAN_RTR_Remote)?(CANx->MB[TxMessage->MBIndex].CS |= CAN_CS_RTR_MASK):(CANx->MB[TxMessage->MBIndex].CS &= ~CAN_CS_RTR_MASK); j=0; //等待数据发送完成或则超时 while(!(CANx->IFLAG1 & (1<<TxMessage->MBIndex))) { if((j++)>0x1000) return FALSE; } //清报文缓冲区中断标志 CANx->IFLAG1 = (1<<TxMessage->MBIndex); //必须清除 return TRUE; }
void CAN_Init(void) { SIM_SCGC6|=SIM_SCGC6_FLEXCAN0_MASK; PORTA_PCR13=PORT_PCR_MUX(0x02); PORTA_PCR12=PORT_PCR_MUX(0x02); CAN0_MCR|=CAN_MCR_FRZ_MASK; CAN0_MCR&=~CAN_MCR_MDIS_MASK; while(CAN0_MCR&CAN_MCR_LPMACK_MASK); CAN0_MCR|=CAN_MCR_SOFTRST_MASK; while(CAN0_MCR&CAN_MCR_SOFTRST_MASK); while(!(CAN0_MCR&CAN_MCR_FRZACK_MASK)); CAN0_MCR|=CAN_MCR_SRXDIS_MASK; CAN0_MCR|=CAN_MCR_RFEN_MASK; CAN0_CTRL1=CAN_CTRL1_PROPSEG(2)|CAN_CTRL1_RJW(1)|CAN_CTRL1_PSEG1(7)|CAN_CTRL1_PSEG2(3)|CAN_CTRL1_PRESDIV(1); // 500KBPS // CAN0_CTRL1=CAN_CTRL1_PROPSEG(2)|CAN_CTRL1_RJW(1)|CAN_CTRL1_PSEG1(7)|CAN_CTRL1_PSEG2(3)|CAN_CTRL1_PRESDIV(9); // 100KBPS CAN0_CTRL1&=~CAN_CTRL1_LPB_MASK; CAN0_RXIMR0=CAN_RXIMR_MI(0x1FFFFFFF); CAN0_RXMGMASK=0; CAN0_RXFGMASK=0; CAN0_MCR&=~CAN_MCR_HALT_MASK; while(CAN0_MCR&CAN_MCR_FRZACK_MASK); while(CAN0_MCR&CAN_MCR_NOTRDY_MASK); CAN0_CS(txb)=CAN_CS_CODE(0/*INACTIVE*/); }
/*********************************************************************************************** 功能:CAN 使能邮箱接收功能 形参:CAN_Type: CAN结构 @arg CAN0 : CAN0模块 @arg CAN1 : CAN1模块 RxMessage : 接收消息结构 返回:0 详解:0 ************************************************************************************************/ void CAN_EnableReceiveMB(CAN_Type* CANx,CAN_RxMsgTypeDef* RxMessage) { //参数检查 assert_param(IS_CAN_ALL_PERIPH(CANx)); assert_param(IS_CAN_MB_NUM(RxMessage->MBIndex)); //不激活邮箱 CANx->MB[RxMessage->MBIndex].CS = CAN_CS_CODE(0); //写入ID //拓展帧还是普通帧 if(RxMessage->IDE == CAN_IDE_Extended) { CANx->MB[RxMessage->MBIndex].ID = RxMessage->Id; CANx->MB[RxMessage->MBIndex].CS = (0|CAN_CS_CODE(4)|CAN_CS_IDE_MASK); // 激活这个 MB 作为接受数据 } else { CANx->MB[RxMessage->MBIndex].ID = RxMessage->Id<<18; CANx->MB[RxMessage->MBIndex].CS = CAN_CS_CODE(4); } }