//============================================================================ //函数名称:CANEnableRXBuff //函数返回:无 //参数说明: CANChannel:CAN模块号 // iMB:缓冲区号 // id:id号 //功能概要:使能接收缓冲区 //============================================================================ void CANEnableRXBuff(uint8 CANChannel,uint16 iMB, uint32 id) { uint32 id2; uint32 cs = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_RX_EMPTY); CAN_MemMapPtr CANBaseAdd; if(CANChannel == 0) CANBaseAdd = CAN0_BASE_PTR; else if(CANChannel == 1) CANBaseAdd = CAN1_BASE_PTR; //将MB配置为非激活状态 CANBaseAdd->MB[iMB].CS = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_RX_INACTIVE); //取出29位单独的ID id2 = id & ~(CAN_MSG_IDE_MASK | CAN_MSG_TYPE_MASK); if(id & CAN_MSG_IDE_MASK)//扩展帧 { CANBaseAdd->MB[iMB].ID = id2; cs |= FLEXCAN_MB_CS_IDE;//置位IDE位 } else//标准帧 { CANBaseAdd->MB[iMB].ID = id2<<FLEXCAN_MB_ID_STD_BIT_NO; } //激活接收缓冲区,code写0100 CANBaseAdd->MB[iMB].CS = cs; }
/* * LPLD_CAN_Enable_RX_Buf * 该函数用于使能Flex_CAN模块的接收缓冲区 * 参数: * canx--设置CAN总线通道 * |__CAN0 --CAN0号模块 * |__CAN1 --CAN1号模块 * mbx--对应的邮箱号 * |__MB_NUM_0 --邮箱0 * |__... --... * |__MB_NUM_15 --邮箱15 * id--接收缓冲的ID,用于和接收到的ID进行匹配。 * 输出: * 无 * */ void LPLD_CAN_Enable_RX_Buf(CANx canx, uint16 mbx, uint32 id) { uint32 idemp; //获得当前缓冲区的CODE值0X0100 uint32 cs = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_RX_EMPTY); CAN_MemMapPtr canptr = CANx_Ptr[canx]; //将MB配置为非激活状态 canptr->MB[mbx].CS = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_RX_INACTIVE); //取出29位单独的ID idemp = id & 0x1FFFFFFF; //设置ID用于接收的数据帧和邮箱的ID进行匹配 if(id & CAN_MSG_IDE_MASK)//扩展帧 { canptr->MB[mbx].ID = idemp; cs |= FLEXCAN_MB_CS_IDE;//置位IDE位,设置为扩展帧 } else//标准帧 { //将ID左移18位存储在标准帧的ID位置 canptr->MB[mbx].ID = (idemp << FLEXCAN_MB_ID_STD_BIT_NO); //取标准帧的ID号 } //激活接收缓冲区,code写0100 canptr->MB[mbx].CS = cs; //设置为接受缓冲区,用于接受数据 }
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); } } }
uint32_t FlexCAN::setNumTxBoxes (uint32_t txboxes) { uint8_t c; uint32_t oldIde; if (txboxes > NUM_MAILBOXES - 1) txboxes = NUM_MAILBOXES - 1; if (txboxes < 1) txboxes = 1; numTxMailboxes = txboxes; // Inialize Rx boxen for (c = 0; c < NUM_MAILBOXES - numTxMailboxes; c++) { // preserve the existing filter ide setting oldIde = FLEXCANb_MBn_CS(flexcanBase, c) & FLEXCAN_MB_CS_IDE; FLEXCANb_MBn_CS(flexcanBase, c) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_RX_EMPTY) | oldIde; } // Initialize Tx boxen for (c = NUM_MAILBOXES - numTxMailboxes; c < NUM_MAILBOXES; c++) { FLEXCANb_MBn_CS(flexcanBase, c) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_INACTIVE); } return (numTxMailboxes); }
// ------------------------------------------------------------- void FlexCAN::setMask(const CAN_filter_t &mask) { // enter freeze mode FLEXCAN0_MCR |= (FLEXCAN_MCR_HALT); while(!(FLEXCAN0_MCR & FLEXCAN_MCR_FRZ_ACK)); FLEXCAN0_RXMGMASK = 0; //enable reception of all messages that fit the mask if (mask.ext) { FLEXCAN0_RXFGMASK = ((mask.rtr?1:0) << 31) | ((mask.ext?1:0) << 30) | ((mask.id & FLEXCAN_MB_ID_EXT_MASK) << 1); } else { FLEXCAN0_RXFGMASK = ((mask.rtr?1:0) << 31) | ((mask.ext?1:0) << 30) | (FLEXCAN_MB_ID_IDSTD(mask.id) << 1); } // start the CAN FLEXCAN0_MCR &= ~(FLEXCAN_MCR_HALT); // wait till exit of freeze mode while(FLEXCAN0_MCR & FLEXCAN_MCR_FRZ_ACK); // wait till ready while(FLEXCAN0_MCR & FLEXCAN_MCR_NOT_RDY); //set tx buffers to inactive for (int i = txb; i < txb + txBuffers; i++) { FLEXCAN0_MBn_CS(i) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_INACTIVE); } }
int FlexCAN::write (const CAN_message_t &msg) { uint32_t index; // find an available buffer int buffer = -1; for (index = NUM_MAILBOXES - numTxMailboxes - 1; index < NUM_MAILBOXES; index++) { if ((FLEXCANb_MBn_CS(flexcanBase, index) & FLEXCAN_MB_CS_CODE_MASK) == FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_INACTIVE)) { buffer = index; break;// found one } } if (buffer > -1) { dbg_println ("Writing a frame directly."); writeTxRegisters (msg, buffer); return 1; } else { // no mailboxes available. Try to buffer it if (addToRingBuffer (txRing, msg) == true) { return 1; } } // could not send the frame! return 0; }
// ------------------------------------------------------------- void CAN_K2X::begin(uint32_t bitrate) { // segment timings from freescale loopback test if ( 250000 == bitrate ) { FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(1) | FLEXCAN_CTRL_PSEG1(3) | FLEXCAN_CTRL_PSEG2(3) | FLEXCAN_CTRL_PRESDIV(15)); } else if ( 500000 == bitrate ) { FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(1) | FLEXCAN_CTRL_PSEG1(3) | FLEXCAN_CTRL_PSEG2(3) | FLEXCAN_CTRL_PRESDIV(7)); } else if ( 1000000 == bitrate ) { FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(3) | FLEXCAN_CTRL_RJW(0) | FLEXCAN_CTRL_PSEG1(0) | FLEXCAN_CTRL_PSEG2(1) | FLEXCAN_CTRL_PRESDIV(5)); } else // 125000 { FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(2) | FLEXCAN_CTRL_PSEG1(3) | FLEXCAN_CTRL_PSEG2(3) | FLEXCAN_CTRL_PRESDIV(31)); } FLEXCAN0_RXMGMASK = 0; //enable reception of all messages that fit the mask // if (mask.extended) // { // FLEXCAN0_RXFGMASK = ((mask.rtr ? 1 : 0) << 31) | ((mask.extended ? 1 : 0) << 30) | ((mask.id & FLEXCAN_MB_ID_EXT_MASK) << 1); // } // else // { // FLEXCAN0_RXFGMASK = ((mask.rtr ? 1 : 0) << 31) | ((mask.extended ? 1 : 0) << 30) | (FLEXCAN_MB_ID_IDSTD(mask.id) << 1); // } FLEXCAN0_RXFGMASK = 0; // start the CAN FLEXCAN0_MCR &= ~(FLEXCAN_MCR_HALT); // wait till exit of freeze mode while (FLEXCAN0_MCR & FLEXCAN_MCR_FRZ_ACK); // wait till ready while (FLEXCAN0_MCR & FLEXCAN_MCR_NOT_RDY); //set tx buffers to inactive for (int i = txb; i < txb + txBuffers; i++) { FLEXCAN0_MBn_CS(i) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_INACTIVE); } }
//============================================================================ //函数名称: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; }
// ------------------------------------------------------------- void FlexCAN::begin(uint8_t _baud) { // soft reset can bus reset(); // segment splits and clock divisor based on baud rate switch (_baud){ case (CAN_5KBPS): FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(3) | FLEXCAN_CTRL_PSEG1(7) | FLEXCAN_CTRL_PSEG2(3) | FLEXCAN_CTRL_PRESDIV(199)); // 5000 baud Prescaler -> 199 Tq -> 16 break; case (CAN_10KBPS): FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(3) | FLEXCAN_CTRL_PSEG1(7) | FLEXCAN_CTRL_PSEG2(3) | FLEXCAN_CTRL_PRESDIV(99)); // 10000 baud Prescaler -> 99 Tq -> 16 break; case (CAN_20KBPS): FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(3) | FLEXCAN_CTRL_PSEG1(7) | FLEXCAN_CTRL_PSEG2(3) | FLEXCAN_CTRL_PRESDIV(49)); // 20000 baud Prescaler -> 49 Tq -> 16 break; case (CAN_25KBPS): FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(3) | FLEXCAN_CTRL_PSEG1(7) | FLEXCAN_CTRL_PSEG2(3) | FLEXCAN_CTRL_PRESDIV(39)); // 25000 baud Prescaler -> 39 Tq -> 16 break; case (CAN_31K25BPS): FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(3) | FLEXCAN_CTRL_PSEG1(7) | FLEXCAN_CTRL_PSEG2(3) | FLEXCAN_CTRL_PRESDIV(31)); // 31250 baud Prescaler -> 31 Tq -> 16 break; case (CAN_33KBPS): FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(3) | FLEXCAN_CTRL_PSEG1(7) | FLEXCAN_CTRL_PSEG2(3) | FLEXCAN_CTRL_PRESDIV(29)); // 33333 baud Prescaler -> 29 Tq -> 16 break; case (CAN_40KBPS): FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(3) | FLEXCAN_CTRL_PSEG1(7) | FLEXCAN_CTRL_PSEG2(3) | FLEXCAN_CTRL_PRESDIV(24)); // 40000 baud Prescaler -> 24 Tq -> 16 break; case (CAN_50KBPS): FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(3) | FLEXCAN_CTRL_PSEG1(7) | FLEXCAN_CTRL_PSEG2(3) | FLEXCAN_CTRL_PRESDIV(19)); // 50000 baud Prescaler -> 19 Tq -> 16 break; case (CAN_80KBPS): FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(1) | FLEXCAN_CTRL_PSEG1(3) | FLEXCAN_CTRL_PSEG2(1) | FLEXCAN_CTRL_PRESDIV(19)); // 80000 baud Prescaler -> 19 !!Tq -> 10!! break; case (CAN_83K3BPS): FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(3) | FLEXCAN_CTRL_PSEG1(7) | FLEXCAN_CTRL_PSEG2(3) | FLEXCAN_CTRL_PRESDIV(11)); // 83333 baud Prescaler -> 11 Tq -> 16 break; case (CAN_95KBPS): FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(2) | FLEXCAN_CTRL_PSEG1(4) | FLEXCAN_CTRL_PSEG2(2) | FLEXCAN_CTRL_PRESDIV(13)); // 95000 baud Prescaler -> 13 !!Tq -> 12!! break; case (CAN_100KBPS): FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(3) | FLEXCAN_CTRL_PSEG1(7) | FLEXCAN_CTRL_PSEG2(3) | FLEXCAN_CTRL_PRESDIV(9)); // 100000 baud Prescaler -> 9 Tq -> 16 break; case (CAN_125KBPS): FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(3) | FLEXCAN_CTRL_PSEG1(7) | FLEXCAN_CTRL_PSEG2(3) | FLEXCAN_CTRL_PRESDIV(7)); // 125000 baud Prescaler -> 7 Tq -> 16 break; case (CAN_200KBPS): FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(3) | FLEXCAN_CTRL_PSEG1(7) | FLEXCAN_CTRL_PSEG2(3) | FLEXCAN_CTRL_PRESDIV(4)); // 200000 baud Prescaler -> 4 Tq -> 16 break; case (CAN_250KBPS): FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(3) | FLEXCAN_CTRL_PSEG1(7) | FLEXCAN_CTRL_PSEG2(3) | FLEXCAN_CTRL_PRESDIV(3)); // 250000 baud Prescaler -> 3 Tq -> 16 break; case (CAN_500KBPS): FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(3) | FLEXCAN_CTRL_PSEG1(7) | FLEXCAN_CTRL_PSEG2(3) | FLEXCAN_CTRL_PRESDIV(1)); // 500000 baud Prescaler -> 1 Tq -> 16 break; case (CAN_666KBPS): FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(2) | FLEXCAN_CTRL_PSEG1(4) | FLEXCAN_CTRL_PSEG2(2) | FLEXCAN_CTRL_PRESDIV(1)); // 666666 baud Prescaler -> 1 !!Tq -> 12!! break; case (CAN_1000KBPS): FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(3) | FLEXCAN_CTRL_PSEG1(7) | FLEXCAN_CTRL_PSEG2(3) | FLEXCAN_CTRL_PRESDIV(0)); // 100000 baud Prescaler -> 0 Tq -> 16 break; default: // 125000 FLEXCAN0_CTRL1 = (FLEXCAN_CTRL_PROPSEG(2) | FLEXCAN_CTRL_RJW(2) | FLEXCAN_CTRL_PSEG1(7) | FLEXCAN_CTRL_PSEG2(3) | FLEXCAN_CTRL_PRESDIV(7)); // 125000 baud Prescaler -> 7 Tq -> 16 break; } //enable reception of all messages FLEXCAN0_RXMGMASK = 0; FLEXCAN0_RXFGMASK = ((defaultMask.rtr?1:0) << 31) | ((defaultMask.ext?1:0) << 30) | (FLEXCAN_MB_ID_IDSTD(defaultMask.id) << 1); // start the CAN FLEXCAN0_MCR &= ~(FLEXCAN_MCR_HALT); // wait till exit of freeze mode while(FLEXCAN0_MCR & FLEXCAN_MCR_FRZ_ACK); // wait till ready while(FLEXCAN0_MCR & FLEXCAN_MCR_NOT_RDY); //set tx buffers to inactive for (int i = txb; i < txb + txBuffers; i++) { FLEXCAN0_MBn_CS(i) = FLEXCAN_MB_CS_CODE(FLEXCAN_MB_CODE_TX_INACTIVE); } }
/* * 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; }