Exemplo n.º 1
0
//============================================================================
//函数名称: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;  //设置为接受缓冲区,用于接受数据    
}
Exemplo n.º 3
0
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);
        }
    }
}
Exemplo n.º 4
0
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);
}
Exemplo n.º 5
0
// -------------------------------------------------------------
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);
  }
  
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
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);
  }
}
Exemplo n.º 8
0
//============================================================================
//函数名称: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;
}
Exemplo n.º 9
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;
}