电子大神的日记本,供应链专家的功夫茶盘,在这里记录、分享与共鸣。

登录以开始

VC++6.0做的 RS232 数据帧类

// 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;
}

 

 

 

 

博主
34661013@qq.com
povoss's Blog
欢迎各位兄弟姐妹常来踩踩我的空间!贴上我的日志,留下您的足迹。
点击跳转