void FlexCAN::writeTxRegisters (const CAN_message_t &msg, uint8_t buffer) { // transmit the frame FLEXCANb_MBn_CS(flexcanBase, buffer) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_INACTIVE); if (msg.flags.extended) { FLEXCANb_MBn_ID(flexcanBase, buffer) = (msg.id & FLEXCAN_MB_ID_EXT_MASK); } else { FLEXCANb_MBn_ID(flexcanBase, buffer) = FLEXCAN_MB_ID_IDSTD(msg.id); } FLEXCANb_MBn_WORD0(flexcanBase, buffer) = (msg.buf[0]<<24)|(msg.buf[1]<<16)|(msg.buf[2]<<8)|msg.buf[3]; FLEXCANb_MBn_WORD1(flexcanBase, buffer) = (msg.buf[4]<<24)|(msg.buf[5]<<16)|(msg.buf[6]<<8)|msg.buf[7]; if (msg.flags.extended) { if (msg.flags.remote) { FLEXCANb_MBn_CS(flexcanBase, buffer) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_ONCE) | FLEXCAN_MB_CS_LENGTH(msg.len) | FLEXCAN_MB_CS_SRR | FLEXCAN_MB_CS_IDE | FLEXCAN_MB_CS_RTR; } else { FLEXCANb_MBn_CS(flexcanBase, buffer) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_ONCE) | FLEXCAN_MB_CS_LENGTH(msg.len) | FLEXCAN_MB_CS_SRR | FLEXCAN_MB_CS_IDE; } } else { if (msg.flags.remote) { FLEXCANb_MBn_CS(flexcanBase, buffer) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_ONCE) | FLEXCAN_MB_CS_LENGTH(msg.len) | FLEXCAN_MB_CS_RTR; } else { FLEXCANb_MBn_CS(flexcanBase, buffer) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_ONCE) | FLEXCAN_MB_CS_LENGTH(msg.len); } } }
//============================================================================ //函数名称:CANSendData //函数返回:0:成功,1:失败 //参数说明: // CANChannel:模块号 // iMB:缓冲区号 // id: ID号 // length:数据长度 // Data[8]:发送数据缓冲区 //功能概要:发送数据 //============================================================================ uint8 CANSendData(uint8 CANChannel,uint16 iMB, uint32 id,uint8 length,uint8 Data[]) { int16 i,wno,bno; uint32 word[2] = {0}; CAN_MemMapPtr CANBaseAdd; if(CANChannel == 0) CANBaseAdd = CAN0_BASE_PTR; else if(CANChannel == 1) CANBaseAdd = CAN1_BASE_PTR; //缓冲区和数据长度设置错误 if(iMB >= NUMBER_OF_MB || length >8) return 1; //超出范围 //转换8个字节转换成32位的word存储 wno = (length-1)>>2;//是否超过4字节 bno = (length-1)%4; // if(wno > 0) //长度大于4(即发送数据超过4字节) { word[0] = ( (Data[0]<<24) | (Data[1]<<16) | (Data[2]<< 8) | Data[3] ); } for(i=0;i<=bno;i++) word[wno] |= Data[(wno<<2)+i] << (24-(i<<3)); /////////////////////////////////////////////////////// // ID 格式 // B31 30 29 28 27 26 ... 11 10 9 8 7 6 5 4 3 2 1 0 // | | | | // | | |------------------------------------| // | | |--> 29 位 ID // | | // | |--> RTR 1: 远程帧, 0: 数据帧 // | // |-------> IDE 1 : 扩展ID, 0: 标准ID /////////////////////////////////////////////////////// //通过id判断帧类型——扩展帧 wno = (id & CAN_MSG_IDE_MASK)>>CAN_MSG_IDE_BIT_NO; //IDE //通过id判断帧类型——远程帧 bno = (id & CAN_MSG_TYPE_MASK)>>CAN_MSG_TYPE_BIT_NO;//RTR //获得ID位数 i = wno? 0: FLEXCAN_MB_ID_STD_BIT_NO; //以下四步骤为发送过程 CANBaseAdd->MB[iMB].CS = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_INACTIVE)//缓冲区写激活代码 | (wno<<FLEXCAN_MB_CS_IDE_BIT_NO)//缓冲区写IDE位 | (bno<<FLEXCAN_MB_CS_RTR_BIT_NO)//缓冲区写RTR位 | FLEXCAN_MB_CS_LENGTH(length); //缓冲区写数据长度 //缓冲区写ID CANBaseAdd->MB[iMB].ID = (1 << FLEXCAN_MB_ID_PRIO_BIT_NO) | ((id & ~(CAN_MSG_IDE_MASK|CAN_MSG_TYPE_MASK))<<i); //缓冲区写内容 CANBaseAdd->MB[iMB].WORD0 = word[0]; CANBaseAdd->MB[iMB].WORD1 = word[1]; //延迟 for(i = 0;i < 100;i++); //通过制定的发送代码开始发送 CANBaseAdd->MB[iMB].CS = (CANBaseAdd->MB[iMB].CS & ~(FLEXCAN_MB_CS_CODE_MASK)) | FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_ONCE)//写激活代码 | FLEXCAN_MB_CS_LENGTH(length);//缓冲区写数据长度 //限时等待发送完成(如果使用中断则限时等待语句可删除) i=0; while(!(CANBaseAdd->IFLAG1 & (1<<iMB))) { if((i++)>0x1000) return 1; } //清报文缓冲区中断标志 CANBaseAdd->IFLAG1 = (1<<iMB); return 0; }
/* * LPLD_CAN_SendData * 该函数用于Flex_CAN模块向总线发送数据 * 参数: * canx--设置CAN总线通道 * |__CAN0 -CAN0号模块 * |__CAN1 -CAN1号模块 * mbx--对应的邮箱号 * |__MB_NUM_0 --邮箱0 * |__... --... * |__MB_NUM_15 --邮箱15 * id--目标位置的id号 * len--发送数据的字节数,最大8个字节 * *data--发送数据的缓冲区 * 输出: * 0:配置出现错误 * 1:配置成功 */ uint8 LPLD_CAN_SendData(CANx canx, uint16 mbx, uint32 id, uint8 len, uint8 *data) { int16 i,j,k; uint32 word[2] = {0}; CAN_MemMapPtr canptr = CANx_Ptr[canx]; //判断缓冲区和数据长度设置错误 if(mbx >= MB_MAX_NO || len > MB_MAX_DATA) return 0; //超出范围 //将8个字节转换成32位的word存储 //首先判断当前数据包含字节数 j = (len-1)/4; //是否超过4字节 k = (len-1)%4; // if(j > 0) //长度大于4(即发送数据超过4字节) { word[0] = ((data[0]<<24) | (data[1]<<16) | (data[2]<< 8) | data[3] ); } for(i = 0; i <= k ; i++) { word[j] |= data[(j<<2)+i] << (24-(i<<3)); } //通过id判断帧类型——扩展帧 j = (id & CAN_MSG_IDE_MASK)>>CAN_MSG_IDE_BIT_NO; //IDE //通过id判断帧类型——远程帧 k = (id & CAN_MSG_TYPE_MASK)>>CAN_MSG_TYPE_BIT_NO;//RTR //获得ID位数 i = j? 0: FLEXCAN_MB_ID_STD_BIT_NO; if(canptr->IFLAG1 & (1<<mbx)) canptr->IFLAG1 = (1<<mbx); //以下四步骤为发送过程 //先缓冲区写激活码 canptr->MB[mbx].CS = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_INACTIVE); //向缓冲区写目标ID canptr->MB[mbx].ID = (1 << FLEXCAN_MB_ID_PRIO_BIT_NO) | ((id & ~(CAN_MSG_IDE_MASK|CAN_MSG_TYPE_MASK))<<i); //向缓冲区写数据 canptr->MB[mbx].WORD0 = word[0]; canptr->MB[mbx].WORD1 = word[1]; //通过制定的发送代码开始发送 canptr->MB[mbx].CS = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_ONCE)//写激活代码 | (j<<FLEXCAN_MB_CS_IDE_BIT_NO) //缓冲区写IDE位 | (k<<FLEXCAN_MB_CS_RTR_BIT_NO) //缓冲区写RTR位 | FLEXCAN_MB_CS_LENGTH(len); //缓冲区写数据长度 for(i = 0;i <1000;i++); //等待缓冲区装载完成 //限时等待发送完成(如果使用中断则限时等待语句可删除) i=0; while(!(canptr->IFLAG1 & (1<<mbx))) { if((i++)>0x1000) return 0; } //清报文缓冲区中断标志 canptr->IFLAG1 = (1<<mbx); return 1; }