Exemplo n.º 1
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.º 2
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;
}
/*
 * 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;
}