打印

学习STM32F217快1个月了,有点迷茫!

[复制链接]
楼主: yujie870705
手机看帖
扫描二维码
随时随地手机跟帖
81
yujie870705|  楼主 | 2011-10-11 10:34 | 只看该作者 回帖奖励 |倒序浏览
//------------------------------------------------------------------------------
// Purpose: J2178 数据包封装与解封装( defined J2178 )
// Funtion: J2178 Package resolve funtion Use in J2178 Linklayer
// Dependence: none
// Protocol: 整个J1850数据包有效数据部分被定义为3个区:
//           Header Field:帧类型,1 至 3 个字节。
//           Data Field:用户数据域,最大8个字节。
//           CRC byte:一个字节的 CRC 校验区
//           Header Field:帧类型的定义
//           帧类型区的第一字节中的 BIT4 决定了当前帧的Header Field 为几个字节,
//           BIT4为1时Header Field为1个字节,BIT4为0时Header Field为3个字节
//          当Header Field为1个字节时Header Field和紧接着Header Field的一个字节
//          会被重新定义为 Frame ID,这部分的定义在 SAE J2178 中有说明Frame ID的
//          含义主要与诊断功能和诊断系统相关,由于定义太多情参看 SAE J2178-3 中
//          的 FIGURE 3J
//          帧类型区的第2字节和第3字节代表含义为地址
//          校验方式为 CRC
//------------------------------------------------------------------------------
#ifndef CMP_J2178_C
#define CMP_J2178_C

//-- Defined of funtion --------------------------------------------------------
#include "CMP_J2178.h"

//------------------------------------------------------------------------------
// Funtion: J1850 CRC 数据校验函数
// Input: chmsg_buf - 待计算校验数据包
//        chbytes - 校验字节个数
// OutPut: none
// Return: CRC 校验值
//------------------------------------------------------------------------------
unsigned char CMP_J2178_crc( unsigned char *chmsg_buf, unsigned char chbytes )
{
    unsigned char crc_reg = 0xff, poly, i, j;
    unsigned char *byte_point;
    unsigned char bit_point;
    for( i = 0, byte_point = chmsg_buf; i < chbytes; ++i, ++byte_point )
    {
        for( j = 0, bit_point = 0x80 ; j < 8; ++j, bit_point >>= 1 )
        {
            if( bit_point & *byte_point ) // case for new bit = 1
            {
                if( crc_reg & 0x80 )
                {
                    poly = 1; // define the polynomial
                }
                else
                {
                    poly=0x1c;
                }
                crc_reg = ( ( crc_reg << 1 ) | 1 ) ^ poly;
            }
            else // case for new bit = 0
            {
                poly = 0;
                if( crc_reg & 0x80 )
                {
                    poly=0x1d;
                }
                crc_reg = ( crc_reg << 1 ) ^ poly;
            }
        }
    }
    return ~crc_reg;    // Return CRC
}

//------------------------------------------------------------------------------
//Funtion: 重组数据包至 m_PackData
//Input: TagPak - 待操作数据包
//OutPut: TagPak - 输出的原始数据包
//Return: 原始数据包长度
//------------------------------------------------------------------------------
unsigned int CMP_J2178_CreatePackage( CMP_J2178 *TagPak )
{
    unsigned char i;
    unsigned char j;
   
    TagPak->m_PackData[ 0 ] = 0;
    // Header Field 属性
    TagPak->m_PackData[ 0 ] |= TagPak->m_HeadType;
    // 帧内应答
    TagPak->m_PackData[ 0 ] |= TagPak->m_IFR;
    // 地址模式
    TagPak->m_PackData[ 0 ] |= TagPak->m_AddrMode;
    // 帧优先级 0 - 7
    TagPak->m_PackData[ 0 ] |= ( TagPak->m_Priority << 5 );
    // 帧类型
    TagPak->m_PackData[ 0 ] |= TagPak->m_FrameType;
   
    // FrameID
    if( 0 == TagPak->m_HeadType )
    {
        TagPak->m_PackData[ 1 ] = TagPak->m_FrameID;
        // 地址
        TagPak->m_PackData[ 2 ] = TagPak->m_Address;
        j = 3;
    }
    else
    {
        TagPak->m_PackData[ 1 ] = TagPak->m_FrameID;
        j = 2;
    }
   
    // 用户区
    for( i = j; i < (TagPak->m_DataLenth + j); i++ )
    {
        TagPak->m_PackData[ i ] = TagPak->m_Data[ i - j ];
    }
   
    // 总长度
    TagPak->m_PackLenth = TagPak->m_DataLenth + j + 1;
   
    // 校验
    TagPak->m_CRCCheck = CMP_J2178_crc( TagPak->m_PackData,
                                        TagPak->m_PackLenth - 1 );
   
    TagPak->m_PackData[ i ] = TagPak->m_CRCCheck;
   
    return TagPak->m_PackLenth;
}

//------------------------------------------------------------------------------
//Funtion: 解封装数据包
//Input: TagPak - 待操作数据包
//OutPut: TagPak - 待操作数据包
//Return: 用户数据域长度
//------------------------------------------------------------------------------
unsigned char CMP_J2178_SolvePackage( CMP_J2178 *TagPak )
{
    unsigned char i;
    unsigned char j;
   
    // Header Field 属性
    TagPak->m_HeadType = TagPak->m_PackData[ 0 ] & CMPJ2178_CONSOLIDATEHEAD;
    // 帧内应答
//    TagPak->m_IFR = TagPak->m_PackData[ 0 ] & CMPJ2178_IFRNOTREQUIRED;
    TagPak->m_IFR = 0;
    // 地址模式
    TagPak->m_AddrMode = TagPak->m_PackData[ 0 ] & CMPJ2178_PHYADDRRESS;
    // 帧优先级 0 - 7
    TagPak->m_Priority = (unsigned char)(( TagPak->m_PackData[ 0 ] & 0xE0 ) >> 5);
    // 帧类型
    TagPak->m_FrameType = TagPak->m_PackData[ 0 ] & 0x03;
   
   
   
    // FrameID
    if( 0 == TagPak->m_HeadType )
    {
        TagPak->m_FrameID = TagPak->m_PackData[ 1 ];
        // 地址
        TagPak->m_Address = TagPak->m_PackData[ 2 ];
        j = 3;
    }
    else
    {
        TagPak->m_FrameID = TagPak->m_PackData[ 1 ];
        j = 2;
    }
    // 总长
    TagPak->m_DataLenth = TagPak->m_PackLenth - j-1;
   
    // 用户区
    for( i = j; i < ( TagPak->m_PackLenth-1 ); i++ )
    {
        TagPak->m_Data[ i - j ] = TagPak->m_PackData[ i ];
    }
   
   
   
    // 校验
    TagPak->m_CRCCheck = TagPak->m_PackData[ i ];
    return TagPak->m_DataLenth;
}

#endif
//--------------------------------------------------------------- End of line --

使用特权

评论回复
82
yujie870705|  楼主 | 2011-10-11 10:35 | 只看该作者
//------------------------------------------------------------------------------
//  Purpose: J1850PWM-3 传输层函数
//  Funtion: 协议中并没有规定该层,但在实际的传输过程中出现了基于数据块的多包
//           交互,并且有相应的分包策略和数据包的格式自动设定过程
//  Dependent:CML_J1850PWM
//  Designer:
//  Date.Ver:
//------------------------------------------------------------------------------
#ifndef CMT_J1850PWM_C
#define CMT_J1850PWM_C

#include "CMT_J1850PWM.h"

//------------------------------------------------------------------------------
// Funtion: J1850PWM 开始建立传输 初始化协议通讯模块
// Input  : Pakpara - 数据包传输参数
//          PakTime - 传输时间参数
//          Lenth - 发送的一个数据帧长度
//          Data - 发送的一个数据帧
// Output : Ecuname - 应答的 ECU 节点地址集
// Return : 应答的 ECU 节点数量
// Info   : 本函数之外所有 J1850PWM 协议函数都必须在本函数调用后才有效
//------------------------------------------------------------------------------
char CMT_J1850PWM_StartTrans( CMLJ1850PWMpara Pakpara, CMLJ1850PWMtime PakTime,
                              unsigned char Lenth, unsigned char *Data,
                              unsigned long *Ecuname )
{
    unsigned char ECUnumb;
    unsigned char i;
    PAKSEND Paksend;
    PAKRECV Pakrecv;
        
    if( false == CML_J1850PWM_Open( Pakpara, PakTime ) )//如果打开端口失败
    {
        return false;
    }
    if( Lenth )//判断发送数据长度
    {
        Paksend.PakLenth = ( unsigned char )Lenth;//构造发送数据包
        Paksend.Pakdata = Data;
        CML_J1850PWM_Send( &Paksend );//发送
    }
    else
    {
        return false;
    }
    ECUnumb = 0;//ECU回应数量初始化
    while( 1 )//循环等待接收数据
    {
        if( (CML_J1850PWM_Recv( &Pakrecv ) != false) )//接收到有效数据
        {
            Ecuname[ ECUnumb ] = Pakrecv.PakID;//接收ECU地址到Ecuname
            ECUnumb++;
        }
        else//接收完毕则返回回应ECU数量
        {
            return ECUnumb;
        }
    }

}

//------------------------------------------------------------------------------
// Funtion: J1850PWM 停止传输
// Input  : none
// Output : none
// Return : 停止传输成功时返回 true 停止传输失败返回 false
// Info   : none
//------------------------------------------------------------------------------
char CMT_J1850PWM_StopTrans( )
{
    CML_J1850PWM_Close( );
    return true;
}

//------------------------------------------------------------------------------
// Funtion: J1850PWM 命令传输
// Input  : Paksend - 待发送数据包
//          MaxPak - 最大接收包数
// Output : Pakrecv - 待接收数据
//          PakNumb - 接收到的包数量
// Return : 应答码
// Info   : none
//------------------------------------------------------------------------------
char CMT_J1850PWM_TransCMD( PAKSEND *Paksend, PAKRECV *Pakrecv,
                           unsigned char *PakNumb, char MaxPak )
{
    unsigned char Repcode;
    unsigned char i;

    // 数据发送
    if( ( NULL != Paksend ) && ( NULL != Pakrecv ) )
    {
        CML_J1850PWM_Send( Paksend );
    }
    else
    {
        return false;
    }
   
    i = 0;
    Repcode = true;
   
    //一只等待后续帧传输完成,等待时间为一个 P2
    while( true == Repcode )
    {
        // 数据接收
        Repcode = CML_J1850PWM_Recv( &Pakrecv[ i ] );
        i++;
        if( MaxPak <= i )
        {
            break;
        }
    }
    if( i == MaxPak )
    {
        (*PakNumb) = i - 1;
    }
    else
    {
        (*PakNumb) = i;
    }
    return Repcode;
}

//------------------------------------------------------------------------------
// Funtion: J1850PWM 命令传输
// Output : RecvLenth - 接收到的数据长度
//          Recdata - 回送的数据
// Input  : Lenth - 待传输数据长度
//          data - 待传输数据
//          Userpos - 用户自定义起始区位置
//          RecvLenth - 接收的最大长度
// Return : 应答码
// Info   : 本函数仅用在对地址信息和包长度不关心的情况内,本函数可根据 Userpos
//          的值重组用户区
//------------------------------------------------------------------------------
unsigned char CMT_J1850PWM_TransCMDFix( int Lenth, unsigned char *data,
                                       int *RecvLenth, unsigned char *Recdata,
                                       char Userpos )
{
    unsigned char Repcode;
    PAKSEND Paksend;
    PAKRECV Pakrecv;
    unsigned char i, j;
    unsigned char Stemp[ 200 ];
    unsigned char Rtemp[ 400 ];
   
    // 数据发送
    if( Lenth )
    {
        Paksend.Pakdata = Stemp;
        Paksend.PakLenth = ( unsigned char )Lenth;
        Pakrecv.Pakdata = Rtemp;
        for( i = 0; i < Paksend.PakLenth; i++ )
        {
            Paksend.Pakdata[ i ] = data[ i ];
        }
        CML_J1850PWM_Send( &Paksend );
    }
    else
    {
        return false;
    }
   
    Repcode = true;
    i = 0;
    j = 0;
   
    //一只等待后续帧传输完成,等待时间为一个 P2
    while( true == Repcode )
    {
        // 数据接收
        Repcode = CML_J1850PWM_Recv( &Pakrecv );

        if( true == Repcode )
        {
            for( j = Userpos; j < Pakrecv.PakLenth; j++ )
            {
                Recdata[ i + j - Userpos ] = Pakrecv.Pakdata[ j ];
                if( (i + j) >= (*RecvLenth) )
                {
                    break;
                }
            }
            if( Pakrecv.PakLenth > Userpos )
            {
                i = i + j - Userpos;
            }
        }
    }
    if( i > Userpos )
    {
        (*RecvLenth) = i - Userpos - 1;
    }
    return Repcode;
}

//------------------------------------------------------------------------------
// Funtion: J1850PWM 设定传输参数
// Input  : Paktime - 传输时间详细参数
//          Pakpara - 传输详细参数
// Output : none
// Return : true or false
// Info   : none
//------------------------------------------------------------------------------
char CMT_J1850PWM_Setpara( CMTJ1850PWMtime Paktime, CMTJ1850PWMpara Pakpara )
{
    if( false == CML_J1850PWM_ConfTime( Paktime ) )
    {
        return false;
    }
    CML_J1850PWM_ConfPak( Pakpara );
    return true;
}

//------------------------------------------------------------------------------
// Funtion: J1850PWM 读取已设定传输参数
// Input  : Paktime - 传输时间详细参数
//          Pakpara - 传输详细参数
// Output : none
// Return : none
// Info   : none
//------------------------------------------------------------------------------
void CMT_J1850PWM_Readpara( CMTJ1850PWMtime *Paktime, CMTJ1850PWMpara *Pakpara )
{
    CML_J1850PWM_ReadPakConf( Pakpara );
    CML_J1850PWM_ReadTimeConf( Paktime );
}

//------------------------------------------------------------------------------
// Funtion: J1850PWM 选择一个 ECU 节点作为当前通讯对象节点
// Input  : EcuAddr - Ecu 节点地址
// Output : none
// Return : none
// Info   : J1850PWM 最初被设定为 点对点通讯 因此每次仅选择一个节点作为通讯对象
//------------------------------------------------------------------------------
void CMT_J1850PWM_ChooseNode( unsigned int EcuAddr )
{
    CMTJ1850PWMpara Pakpara;
    // 保存通讯时间
    CML_J1850PWM_ReadPakConf( &Pakpara );
    Pakpara.ECUID = EcuAddr;
    CML_J1850PWM_ConfPak( Pakpara );
   
}

//------------------------------------------------------------------------------
// Funtion: 设置通讯参数到初始化状态
// Input  : none
// Output : init - 启动链路参数
//          para - 数据包传输参数
//          time - 链路时间参数
// Return : none
// Info   : 初始化状态:
//    para  不需要数据包过滤
//          数据包地址 0x6AF1
//          数据包类型 0x61
//    time  帧超时等待 100MS  回复等待超时时间 1S
//------------------------------------------------------------------------------
void CMT_J1850PWM_SetDefault( CMTJ1850PWMpara *para, CMTJ1850PWMtime *time )
{
      
    if( 0 != para )
    {
        // 设置数据包参数
        para->PakType = 0x61; // 包头
        para->ECUID = 0; // 不需要数据包过滤,需要过滤时请填写 ECU 地址如:0x6BF1
        para->Address = 0x6AF1;  // 数据包地址 0x6AF1
    }
   
    if( 0 != time )
    {
        // 设置通信时间参数
        time->VehFrametime = 100;   //多帧超时等待 100MS
        time->Maxwaittime = 1000;   //回复等待超时时间 1S
    }
}

#endif
//------------------------------------------------------ End Of File -----------

使用特权

评论回复
83
sinadz| | 2011-10-11 18:39 | 只看该作者
这么都高人指点,楼主应该进步很快了:lol

使用特权

评论回复
84
xsgy123| | 2011-10-11 22:23 | 只看该作者
楼主现在估计已经到了看代码做实验的阶段了

使用特权

评论回复
85
流星的脚步| | 2011-10-14 10:28 | 只看该作者
我也刚学ARM,都自学的,没办法,不过我有很多项目做,硬件自己设计,软件自己写,这样才会提高嘛

使用特权

评论回复
86
pkat| | 2011-10-14 18:41 | 只看该作者
很多知识的学习都有一个迷茫期

使用特权

评论回复
87
txcy| | 2011-10-14 22:10 | 只看该作者
刚开始学习的时候和楼主有相同的感觉

使用特权

评论回复
88
楚地潮人| | 2011-10-24 14:08 | 只看该作者
楼主小子干得不错,你都跑了,也用不着再迷茫了。要不我拿你的程序再去重用一次,如何?

使用特权

评论回复
89
火箭球迷| | 2011-10-24 15:52 | 只看该作者
一个月的迷茫期,很正常的,随着学习的深入就会云开雾散

使用特权

评论回复
90
21icer| | 2011-10-25 11:31 | 只看该作者
带着项目做,身边又有同伙随时商量,进步就比较快

使用特权

评论回复
91
秋天落叶| | 2011-10-25 16:03 | 只看该作者
学技术需要一个阶段积累的,不可能速成的

使用特权

评论回复
92
hsbjb| | 2011-10-25 16:57 | 只看该作者
楼主的基础估计比较薄弱

使用特权

评论回复
93
maodewen| | 2012-8-11 09:44 | 只看该作者
你不累吗,发这么多

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则