原创 VC++6.0做的 RS232 数据帧类

2010-6-13 15:03 3599 13 13 分类: 软件与OS

// ZBL232Frame1.h: interface for the CZBL232Frame class.
//
//////////////////////////////////////////////////////////////////////


#if !defined


(AFX_ZBL232FRAME1_H__8F6F0E88_F4A0_4BA9_96E6_E9DCC9AD8B86__INCLUDED_)
#define


AFX_ZBL232FRAME1_H__8F6F0E88_F4A0_4BA9_96E6_E9DCC9AD8B86__INCLUDED_


#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CZBL232Frame
{
public:
 CZBL232Frame();
 virtual ~CZBL232Frame();
 BYTE F_START;//帧起始字节
 BYTE F_ADDRESS;//帧地址字节
 BYTE F_LENGTH;//帧长度字节=内容+命令
 BYTE F_COMMAND;//帧命令字节
 BYTE* m_pbuf;//帧数据内容存放地址
 BYTE F_CHECK;//帧校验字节
 BYTE F_END;//帧结束字节


 VARIANT Frame;//VARIANT帧结构


 virtual BOOL UnPacket()=0;//解包,在子类中实现.
 virtual BOOL Packet()=0;//组包
};


#endif // !defined


(AFX_ZBL232FRAME_H__AA9846E8_0328_4D78_A0DF_14E87D5A7FED__INCLUDED_)


 


// ZBL232Frame1.cpp: implementation of the CZBL232Frame class.
//
//////////////////////////////////////////////////////////////////////


#include "stdafx.h"
#include "LPCSO.h"
#include "ZBL232Frame1.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


CZBL232Frame::CZBL232Frame()
{
F_START=0x3E;//ZBL232数据帧都是以0x3E开头
F_END=0x0D;//ZBL232数据帧都是以0x0D结束
Frame.vt=VT_UI1;
}


CZBL232Frame::~CZBL232Frame()
{


}


 


 



// MyFrame1.h: interface for the CMyFrame class.
//
//////////////////////////////////////////////////////////////////////


#if !defined


(AFX_MYFRAME1_H__F540A0C6_B2B6_474A_B8E9_B94FB6D3ECCD__INCLUDED_)
#define


AFX_MYFRAME1_H__F540A0C6_B2B6_474A_B8E9_B94FB6D3ECCD__INCLUDED_


#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


#include "ZBL232Frame1.h"


class CMyFrame:public CZBL232Frame 
{
public:
 CMyFrame();
 CMyFrame(BYTE addr,BYTE size,BYTE* pdata);
 virtual ~CMyFrame();


 BOOL UnPacket();////实现基类解包纯虚函数
 BOOL Packet();////实现基类组包纯虚函数
public:
 BYTE m_framesize;//整个帧的长度,方便组包
};


 



#endif // !defined


(AFX_BASEFRAME_H__F12585A9_9A70_4FB2_9F17_D34FF2F99E58__INCLUDED_)


 


 


// MyFrame1.cpp: implementation of the CMyFrame class.
//
//////////////////////////////////////////////////////////////////////


#include "stdafx.h"
#include "LPCSO.h"
#include "MyFrame1.h"
#include "assert.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


CMyFrame::CMyFrame()
{
}


CMyFrame::CMyFrame(BYTE addr,BYTE size,BYTE* pdata)//用户可以通过该函


数初始化帧内容中的一些可变部分,如地址,长度,数据内容(命令+内容)
{
 F_ADDRESS=addr;
 F_LENGTH=size;//数据字节数+命令字节数
 F_COMMAND=*pdata;//数据内容的第一个字节为命令


 m_framesize=sizeof(F_START)+sizeof(F_ADDRESS)+sizeof


(F_LENGTH)+F_LENGTH+sizeof(F_CHECK)+sizeof(F_END);//整个帧长度,只有组


包的时候有用。


 //m_pbuf=new BYTE[size];//为接收数据区开辟内存区,当解包的时候


收到其他数据量大于size的时候容易出错
 //ASSERT(m_pbuf!=NULL);
 //memcpy(m_pbuf,pdata,size);
 m_pbuf=new BYTE[256];//为接收数据区开辟内存区
 //ASSERT(m_pbuf!=NULL);
 memcpy(m_pbuf,pdata,256);


}



CMyFrame::~CMyFrame()
{
if(m_pbuf)
delete m_pbuf;//删除内存区
}


BOOL CMyFrame::UnPacket()//将接收到的数据帧VARIANT类型变换为BYTE[]
{
 SAFEARRAY* PSA;//safearray*类型的指针
 BYTE mycheck="0x00";
 //if(m_pbuf!=NULL)//帧数据缓冲区有数据
  //return FALSE;
 if(Frame.vt==VT_EMPTY)//数据缓冲区没有数据
  return FALSE;


 ASSERT(Frame.vt==(VT_ARRAY|VT_UI1));


 PSA=Frame.parray;//数据帧中的数据指针的指针 给 PSA指针


 HRESULT hr;
 void HUGEP* pb;
 hr=SafeArrayAccessData(PSA,&pb);//调用SafeArrayAccessData获取


数据在内存中的指针
  if(FAILED(hr))
   return FALSE;


 ASSERT(PSA->cDims==1);


 long lbound,ubound,arraysize;


 hr=SafeArrayGetUBound(PSA,1,&ubound);//获得一维数组的上界
  if(FAILED(hr))
   return FALSE;


 hr=SafeArrayGetLBound(PSA,1,&lbound);//下界
  if(FAILED(hr))
   return FALSE;


 arraysize=ubound-lbound+1;


//------------------------------//内存拷贝
 CMemFile file;
 file.Attach((BYTE*)pb,arraysize,0);//定位在数据指针pb所指向的


内存区域//arraysize//解包最大长度为255
 file.Read((void*)&F_START,sizeof(F_START));//读取数据帧起始字



 file.Read((void*)&F_ADDRESS,sizeof(F_ADDRESS));//地址
 file.Read((void*)&F_LENGTH,sizeof(F_LENGTH));//长度字节=命令+


内容
 //file.Read((void*)&F_COMMAND,sizeof(F_COMMAND));//命令字节
 file.Read((void*)m_pbuf,F_LENGTH);//读取数据区(命令+内容),这里


就是解包得到的数据区
 file.Read((void*)&F_CHECK,sizeof(F_CHECK));
 file.Read((void*)&F_END,sizeof(F_END));
 file.Detach();


 F_COMMAND=*m_pbuf;//便于外部访问
 mycheck=F_ADDRESS+F_LENGTH;//+F_COMMAND;//地址和长度字节参加校



  for(int i="0";i<F_LENGTH;i++)//数据区每个字节都参加校验
   mycheck+=*(m_pbuf+i);//跳过F_COMMAND
 hr=SafeArrayUnaccessData(PSA);//解锁一次
  ASSERT(!FAILED(hr));


 if(mycheck!=F_CHECK)//帧校验
  return FALSE;
 else
  return TRUE;
}



BOOL CMyFrame::Packet()//将数据帧BYTE[]变换为VARIANT类型
{
  SAFEARRAY* PSA;//safearray*类型的指针


  //int len="sizeof"(F_START)+sizeof(F_ADDRESS)+sizeof


(F_LENGTH)+F_LENGTH+sizeof(F_CHECK)+sizeof(F_END);//F_LENGTH=命令字节


数+内容字节数
   PSA="SafeArrayCreateVector"(VT_UI1,0,m_framesize);//len


创建帧格式
   if(!PSA)
    return FALSE;
   HRESULT hr;
   void HUGEP* pb;
  
   hr="SafeArrayAccessData"(PSA,&pb);////调用


SafeArrayAccessData获取数据在内存中的指针
   if(FAILED(hr))
    return FALSE;
   //------------------------------//开始内存拷贝
   CMemFile file;
   file.Attach((BYTE*)pb,m_framesize,0);//定位
   file.Write((void*)&F_START,sizeof(F_START));//写入帧


起始字节0x3E
   file.Write((void*)&F_ADDRESS,sizeof(F_ADDRESS));//
   file.Write((void*)&F_LENGTH,sizeof(F_LENGTH));//
   //file.Write((void*)&F_COMMAND,sizeof(F_COMMAND));//
   file.Write((void*)m_pbuf,F_LENGTH);//F_LENGTH-1
  
   F_CHECK=F_ADDRESS+F_LENGTH;//校验和
   for(int i="0";i<F_LENGTH;i++)//F_LENGTH-1
   F_CHECK+=*(m_pbuf+i);


   file.Write((void*)&F_CHECK,sizeof(F_CHECK));//
   file.Write((void*)&F_END,sizeof(F_END));//
   file.Detach();


   Frame.vt=VT_ARRAY|VT_UI1;
   Frame.parray=PSA;


   hr="SafeArrayUnaccessData"(PSA);
   ASSERT(!FAILED(hr));



return TRUE;
}


 


 


 



 

文章评论0条评论)

登录后参与讨论
我要评论
0
13
关闭 站长推荐上一条 /2 下一条