⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 digitaldongle.cpp

📁 eVCComm3.0.zip eVC3.0写的程序
💻 CPP
字号:
// DigitalDongle.cpp: implementation of the CDigitalDongle class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "eVCComm.h"
#include "DigitalDongle.h"
#include "Mmsystem.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
enum {PACKET_TYPE_WRITE=0x01,PACKET_TYPE_READ=0x02};
enum {WAIT_FOR_PACKET_TYPE,WAIT_FOR_STATUS,WAIT_FOR_SUCCESS_DATA_LENGTH,
		WAIT_FOR_ADDRESS,WAIT_FOR_DATA,WAIT_FOR_CHECKSUM}state;

CDigitalDongle::CDigitalDongle(int PortNum)
{
	m_pSerialPort=new CSerialPort();	
	m_pSerialPort->OpenPort(PortNum);
	m_pSerialPort->set_data_callback(OnDataFromPort,this);
	state=WAIT_FOR_PACKET_TYPE;
	done=TRUE;
	operate_done_func=NULL;

	monitor_operate_thread_terminate=FALSE;
	Monitor_Operate();
}

CDigitalDongle::~CDigitalDongle()
{
	monitor_operate_thread_terminate=TRUE;
	Sleep(0);
}

void CDigitalDongle::OnDataFromPort(void * data, DWORD nDataCount,void * context)
{
	static unsigned long addr;
	static BYTE data_buf[256];
	static int dataCount;
	static int tmp_pos;
	CDigitalDongle *pDongle;

	int count;
	int c;     /* Temporary variable for index calculations */   
	BYTE *buf; /* Temporary pointer to the incoming data */
	buf = (BYTE *)data;
	count= nDataCount;
	pDongle=(CDigitalDongle *)context;

	while (count > 0) {
		switch (state) 
		{
		case WAIT_FOR_PACKET_TYPE:
			tmp_pos = 0;
			dataCount = 0;
			switch(*buf) {
			case PACKET_TYPE_WRITE:
			case PACKET_TYPE_READ:
				state = WAIT_FOR_STATUS;
				break;
			default:
#ifdef DEBUG
				CString tmp;
				tmp.Format(_T("packet type error[0x%02X] count=%d"),*buf,count);
				AfxMessageBox(tmp);
#endif
				return;
			}
			data_buf[dataCount++]=*buf;
			buf++;
			count--;
			break;

		case WAIT_FOR_STATUS:
			data_buf[dataCount++]=*buf;
			if((*buf)!=0x00)//status is failed
			{
				state = WAIT_FOR_CHECKSUM;
			}
			else
			{
				state = WAIT_FOR_SUCCESS_DATA_LENGTH;
			}
			buf++;
			count--;
			break;

		case WAIT_FOR_SUCCESS_DATA_LENGTH:
			data_buf[dataCount++]=*buf;
			state = WAIT_FOR_ADDRESS;
			buf++;
			count--;
			break;
		case WAIT_FOR_ADDRESS:
			if (tmp_pos <4) {
				c = min(count,4 - tmp_pos);
				memcpy(data_buf + dataCount,buf,c);
				dataCount += c;
				tmp_pos+=c;
				count -=c;
				buf += c;
				if(tmp_pos == 4)
				{
					if(data_buf[0]==PACKET_TYPE_WRITE)
					{
						state = WAIT_FOR_CHECKSUM;
					}
					else
					{
						tmp_pos = 0;
						state = WAIT_FOR_DATA;
					}
				}
			}
			break;

		case WAIT_FOR_DATA:
			if (tmp_pos < data_buf[2]/*data length*/) {
				c = min(count, data_buf[2] - tmp_pos);
				memcpy(data_buf + dataCount,buf,c);
				dataCount += c;
				tmp_pos += c;
				count -= c;
				buf += c;
				if (tmp_pos == data_buf[2]) {
					state = WAIT_FOR_CHECKSUM;
				}
			}
			break;
		case WAIT_FOR_CHECKSUM:
			data_buf[dataCount++]=*buf;
			buf++;
			count--;
			pDongle->ProcessPacket(data_buf,dataCount);
			break;
		default:
#ifdef DEBUG
			AfxMessageBox(_T("not this message"));
#endif
			break;
		}
	}
}

BOOL CDigitalDongle::SendWriteCmd(unsigned long addr, LPBYTE data, int len)
{
	BYTE buffer[4];

	if(!m_pSerialPort->IsOpen())
		return FALSE;
	if(len>128)//每个分组的数据量不能超过128个字节
		return FALSE;
	if(done==FALSE)	//上一次操作还没有完成
		return FALSE;

	buffer[0]=PACKET_TYPE_WRITE;
	m_pSerialPort->WriteData(buffer,1);
	buffer[0]=len;
	m_pSerialPort->WriteData(buffer,1);
	buffer[0]=(BYTE)((addr >> 24) & 0xff);
	buffer[1]=(BYTE)((addr >> 16) & 0xff);
	buffer[2]=(BYTE)((addr >>  8) & 0xff);
	buffer[3]=(BYTE)((addr >>  0) & 0xff);
	m_pSerialPort->WriteData(buffer,4);
	m_pSerialPort->WriteData(data,len);
	buffer[0]=CheckSum(data,len);
	m_pSerialPort->WriteData(buffer,1);

	lastPacketType=PACKET_TYPE_WRITE;
	lastAddr=addr;
	memcpy(lastData,data,len);
	lastDataLength=len;
	lastRetryTime=CTime::GetCurrentTime().GetTime();
	retryNum=0;
	done=FALSE;

	return TRUE;
}

BOOL CDigitalDongle::SendReadCmd(unsigned long addr, int len)
{
	return TRUE;
}

/*计算数据的校验和*/
BYTE CDigitalDongle::CheckSum(LPBYTE data, int len)
{
	BYTE checksum;
	checksum=0;
	for(int i=0;i<len;i++)
	{
		checksum+=data[i];
	}
	return checksum;
}

void CDigitalDongle::ProcessPacket(LPBYTE data, int len)
{
	BYTE packet_type;
	BYTE status;
	BYTE length;
	unsigned long addr;
	packet_type=data[0];
	status=data[1];
	length=data[2];
	addr=(((data[3]*256)+data[4])*256+data[5])+data[6];
	if(CheckSum(data,len-1)!=data[len])/*校验失败*/
	{
		if(status==0x00)
			status=STATUS_OPERATE_TIMEOUT;
	}
	if(operate_done_func)
	{
		operate_done_func(packet_type,status,addr,length,operate_done_func_context);
	}
	done=TRUE;
}

void CDigitalDongle::Monitor_Operate()
{
	DWORD thread_id;
	CreateThread(0, 0, CDigitalDongle::monitor_operate_thread, this, 0, &thread_id);
}

DWORD WINAPI CDigitalDongle::monitor_operate_thread(LPVOID arg)
{
	CDigitalDongle	*pDongle;
	DWORD currTime;
	pDongle = (CDigitalDongle *) arg;

	pDongle->monitor_operate_thread_terminate=FALSE;
	while (!pDongle->monitor_operate_thread_terminate)
	{
		if(pDongle->done==FALSE)//已经进行了一次操作,但还没有收到应答
		{
			currTime=CTime::GetCurrentTime().GetTime();
			if(currTime - pDongle->lastRetryTime >= OPERATE_TIMEOUT)//操作超时
			{
				if(pDongle->retryNum<MAX_RETRY_COUNT)
				{
					pDongle->RedoLastOperator();
					pDongle->retryNum++;
				}
				else
				{
					if(pDongle->operate_done_func)
					{
						pDongle->operate_done_func(pDongle->lastPacketType,STATUS_OPERATE_TIMEOUT,pDongle->lastAddr,0,pDongle->operate_done_func_context);
						pDongle->done=TRUE;
					}
				}
			}
		}
		Sleep(100);
	}
	return 0;
}

void CDigitalDongle::set_operate_complete_callback(void (*func)(BYTE, BYTE, unsigned long,BYTE,void *), void *context)
{
	operate_done_func=func;
	operate_done_func_context=context;
}

void CDigitalDongle::RedoLastOperator()
{

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -