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

📄 tokenshadow.cpp

📁 自己写得串口多线程控制程序
💻 CPP
字号:
// TokenShadow.cpp : implementation file
//

#include "stdafx.h"
#include "Token.h"
#include "TokenShadow.h"
#include "afxmt.h"

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

extern HWND hBackPanelWnd;
extern HWND hDealWnd;
extern CString ComName;
extern int nCardPoped;
extern int nCardDealed;

extern CTokenShadow* m_TokenShadow;

extern CEvent  m_TokenShadowEvent;

UINT WatchTokenProc(LPVOID lpParam);

/////////////////////////////////////////////////////////////////////////////
// CTokenShadow

IMPLEMENT_DYNCREATE(CTokenShadow, CWinTimerThread)

CTokenShadow::CTokenShadow()
{
	bContinue=TRUE;
	bTokenWorking=TRUE;
	pTokenHandle=NULL;
	pTokenWatchThread =NULL;
}

CTokenShadow::~CTokenShadow()
{
}

BOOL CTokenShadow::InitInstance()
{
	/************************************************
	*												*
	*			Open the token serial port			*
	*												*
	************************************************/
#ifdef RELEASE_TOKEN
	bTokenWorking=FALSE;
#endif

	BOOL bTokenState = FALSE;
	
	//Open token serial
	pTokenHandle = new CTokenSerial;
	bTokenState = pTokenHandle->Open(ComName,CBR_9600,NOPARITY,ONESTOPBIT,8);
	if(!bTokenState)
	{
		delete pTokenHandle;
		pTokenHandle=NULL;
		TRACE("Open token serial port failed");
	}
	else
	{
		pTokenWatchThread=AfxBeginThread(WatchTokenProc , this,THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);	//start a thread for watching token serial port data
		ASSERT (NULL != pTokenWatchThread);
		pTokenWatchThread->m_bAutoDelete = FALSE;
		pTokenWatchThread->ResumeThread();
	}	
	::PostMessage(hBackPanelWnd,THREADINIT,(WPARAM)0,(LPARAM)0);
	return TRUE;
}

int CTokenShadow::ExitInstance()
{
	if(pTokenWatchThread!=NULL)
	{
		HANDLE  hEvent=OpenEvent(EVENT_ALL_ACCESS, TRUE, TOKENREADNAME);
		SetEvent(hEvent);

		hEvent=OpenEvent(EVENT_ALL_ACCESS, TRUE, TOKENWAITNAME);
		SetEvent(hEvent);

		bContinue=FALSE;

		WaitForSingleObject(pTokenWatchThread->m_hThread,INFINITE);
		delete pTokenWatchThread;
		TRACE("\nCTokenShadow ");
		pTokenWatchThread=NULL;
	}

	if(pTokenHandle!=NULL)
	{
		delete pTokenHandle;
		pTokenHandle=NULL;
	}

	return CWinTimerThread::ExitInstance();
}

BEGIN_MESSAGE_MAP(CTokenShadow, CWinTimerThread)
	//{{AFX_MSG_MAP(CTokenShadow)
	ON_THREAD_MESSAGE(TOKEN_SELCHKGOOD, OnTOKEN_SELCHKGOOD)
	ON_THREAD_MESSAGE(TOKEN_SELCHKBAD, OnTOKEN_SELCHKBAD)
	ON_THREAD_MESSAGE(TOKEN_UPBOXNUM, OnTOKEN_UPBOXNUM)
	ON_THREAD_MESSAGE(TOKEN_DOWNBOXNUM, OnTOKEN_DOWNBOXNUM)
	ON_THREAD_MESSAGE(TOKEN_TOKENSTATUS, OnTOKEN_TOKENSTATUS)
	ON_THREAD_MESSAGE(TOKEN_ONETOKENPOP, OnTOKEN_ONETOKENPOP)
	ON_THREAD_MESSAGE(TOKEN_DEALOVER, OnTOKEN_DEALOVER)
	ON_THREAD_MESSAGE(TOKEN_UPLOADDEALLOG, OnTOKEN_UPLOADDEALLOG)
	ON_THREAD_MESSAGE(TOKEN_DOWNTIME, OnTOKEN_DOWNTIME)
	ON_THREAD_MESSAGE(TOKEN_CARDNUM, OnTOKEN_CARDNUM)
	ON_THREAD_MESSAGE(TOKEN_UPBOXNULL, OnTOKEN_UPBOXNULL)
	ON_THREAD_MESSAGE(TOKEN_DOWNBOXFULL, OnTOKEN_DOWNBOXFULL)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTokenTokenShadow message handlers
/****************************************************
*													*
*				deal with token event				*
*													*
****************************************************/

long CTokenShadow::OnTOKEN_SELCHKGOOD(WPARAM wparam, LPARAM lparam)
{
	TRACE("\nSelfCheckGood");
	return 0;
}

long CTokenShadow::OnTOKEN_SELCHKBAD(WPARAM wparam, LPARAM lparam)
{
	TRACE("\nSelfCheckBad");
	return 0;
}

long CTokenShadow::OnTOKEN_UPBOXNUM(WPARAM wparam, LPARAM lparam)
{
	return 0;
}

long CTokenShadow::OnTOKEN_DOWNBOXNUM(WPARAM wparam, LPARAM lparam)
{
	return 0;
}

long CTokenShadow::OnTOKEN_TOKENSTATUS(WPARAM wparam, LPARAM lparam)
{
	if(bTokenWorking)
	{
		this->pTokenHandle->ToTokenCardStatus(TRUE);
		SetEvent(pTokenHandle->m_Event_CardNum);
	}
	TRACE("\nToken Status");
	return 0;
}

long CTokenShadow::OnTOKEN_ONETOKENPOP(WPARAM wparam, LPARAM lparam)
{
	if(bTokenWorking)
	{
		::nCardPoped++;
		::PostMessage(hDealWnd,WM_USERPOPTOKENCONTINUEFROMSHADOW,(WPARAM)0,(LPARAM)0);
		SetEvent(pTokenHandle->m_Event_CardPoped);
		TRACE("\nPop token one,and this is the %d token",::nCardPoped);
	}
	return 0;
}

long CTokenShadow::OnTOKEN_DEALOVER(WPARAM wparam, LPARAM lparam)
{
	TRACE("\nDeal over");
	if(bTokenWorking)
	{
		if(::nCardDealed!=::nCardPoped)
		{
			::PostMessage(hDealWnd, WM_USERPOPTOKENOVERFROMSHADOW, (WPARAM)0, (LPARAM)0);
		}
		else
		{
			::PostMessage(hDealWnd, WM_USERPOPTOKENOVERFROMSHADOW, (WPARAM)1, (LPARAM)0);
		}
	}
	return 0;
}

long CTokenShadow::OnTOKEN_UPLOADDEALLOG(WPARAM wparam, LPARAM lparam)
{
	return 0;
}

long CTokenShadow::OnTOKEN_DOWNTIME(WPARAM wparam, LPARAM lparam)
{
	return 0;
}

long CTokenShadow::OnTOKEN_CARDNUM(WPARAM wparam, LPARAM lparam)
{
	return 0;
}

long CTokenShadow::OnTOKEN_UPBOXNULL(WPARAM wparam, LPARAM lparam)
{
	::PostMessage(hBackPanelWnd, WM_EXCEPTIONALERT, (WPARAM)1, (LPARAM)0);
	return 0;
}

long CTokenShadow::OnTOKEN_DOWNBOXFULL(WPARAM wparam, LPARAM lparam)
{
	::PostMessage(hBackPanelWnd, WM_EXCEPTIONALERT, (WPARAM)2, (LPARAM)0);
	return 0;
}
/////////////////////////////////////////////////////////////////////////////
// Global functions
UINT WatchTokenProc(LPVOID lpParam)
{
	//判断上一个数据帧是否收完
	BOOL IsBuffOver=TRUE;

	//串口读出字节数
	DWORD read=0;
	//要求串口读出数
	DWORD toread=0;

	//串口事件掩码字
	DWORD m_ComMask=0;	
	//校验字
	UCHAR m_Chk=0;
	//命令字
	UCHAR m_Command=0;

	//返回结果	
	BOOL bSuccess=FALSE;
	DWORD nRet=0;
	DWORD mRet=0;
	
	//得到串口指针和数据
	CTokenShadow* pTokenShadow;
	CTokenSerial* pTokenSerial;
	pTokenShadow=(CTokenShadow*)lpParam;
	pTokenSerial = pTokenShadow->pTokenHandle;

	//定义串口缓冲区
	UCHAR Buff[MAXREADBUFFLEN]={0};
	DWORD BuffLen=0;

	UCHAR CmdData[MAXREADBUFFLEN]={0};
	DWORD CmdDataLen = 0;

	UCHAR TmpBuff[MAXTMPBUFFLEN]={0};

	//计数器
	long i=0;
	
	while(pTokenShadow->bContinue)
	{
		pTokenSerial->ClearError();
		TRACE("\nWAIT...");
		//监听串口事件
		pTokenSerial->WaitData(m_ComMask);
		
		//如果不是字符到达事件,返回重新监听事件
		if(!(m_ComMask & EV_RXCHAR))
			continue;

		//清除串口错误
		pTokenSerial->ClearError(_T("读前"));

		if(IsBuffOver)
		{
			//将缓冲区读取字节数设置为0
			BuffLen=0;
			//将缓冲区置零清空
			memset(Buff,0,sizeof(UCHAR)*MAXREADBUFFLEN);
		}
		else
		{
			if(BuffLen==1)
			{
				goto LENGTHBYTE;
			}
			else if(BuffLen>=2&&BuffLen<4)
			{
				goto ADDRESSBYTE;
			}
			else if(BuffLen>=4&&BuffLen<Buff[1])
			{
				goto COMMANDBYTE;
			}
			else if(BuffLen==Buff[1])
			{
				goto CHKBYTE;
			}
			else
			{
				goto TAILBYTE;
			}
		}

FIRSTBYTE:		
		//没有读出第一个字节,返回重新监听事件
		if(pTokenSerial->ReadData(Buff,1,"FIRSTBYTE")<1)
			continue;
		BuffLen=1;

		//读出第一个字节,但不是0x55,重新读取第一个字节
		if(Buff[0]!=0x55)
			goto FIRSTBYTE;

LENGTHBYTE:
		m_Chk=0;
		//没有读出长度字节,将读帧完成标志置否,返回重新监听事件
		if(pTokenSerial->ReadData(Buff+1,1,"LENGTHBYTE")<1)
		{
			IsBuffOver=FALSE;
			continue;
		}
		BuffLen=2;
		m_Chk=m_Chk^Buff[1];

ADDRESSBYTE:
		toread=4-BuffLen;
		//读取收发地址。如果读出长度小于2,将读帧完成标志置否,返回重新监听事件
		if(read=pTokenSerial->ReadData(Buff+2,toread,"ADDRESSBYTE")<toread)
		{
			BuffLen+=read;
			IsBuffOver=FALSE;
			continue;
		}
			
		//接受地址不是本机地址,抛弃该帧
		if(Buff[3]!=TERMI_ADDRESS)
		{	
			//没有读完废弃帧,返回重新监听事件
			if(pTokenSerial->ReadData(TmpBuff,Buff[Buff[1]-4])<Buff[Buff[1]-4])
				continue;
			//读完废弃帧,重新读取第一个字节
			goto FIRSTBYTE;
		}
		BuffLen=4;	
		m_Chk=m_Chk^Buff[2];
		m_Chk=m_Chk^Buff[3];

COMMANDBYTE:
		//读取除帧尾和校验位外剩余字节
		toread=Buff[1]-BuffLen;
		for(i=toread;i>0;i=i-1)
		{
			//读取字节失败,将读帧完成标志置否,返回重新监听事件
			if(pTokenSerial->ReadData(Buff+BuffLen,1,"COMMANDBYTE")<1)
			{
				IsBuffOver=FALSE;
				continue;
			}
			BuffLen+=1;
			m_Chk=m_Chk^Buff[BuffLen-1];
		}

CHKBYTE:
		//读取校验位失败,将读帧完成标志置否,返回重新监听事件
		if(pTokenSerial->ReadData(Buff+BuffLen,1,"CHKBYTE")<1)
		{
			IsBuffOver=FALSE;
			continue;
		}

		//校验不对,抛弃该帧,重新读取第一个字节
		if(m_Chk!=Buff[BuffLen])
		{
			//没有读完废弃帧,返回重新监听事件
			if(pTokenSerial->ReadData(TmpBuff,1)<1)
				continue;
			//读完废弃帧,重新读取第一个字节
			goto FIRSTBYTE;
		}
		BuffLen+=1;

TAILBYTE:
		//读取帧尾失败,将读帧完成标志置否,返回重新监听事件
		if(pTokenSerial->ReadData(Buff+BuffLen,1,"TAILBYTE")<1)
		{
			IsBuffOver=FALSE;
			continue;
		}
		BuffLen+=1;

		//帧尾不是0xAA,抛弃该帧,重新读取第一个字节
		if(Buff[BuffLen-1]!=0xAA)
			goto FIRSTBYTE;

		//完成一个帧的读取,将读帧完成标志置真
		IsBuffOver=TRUE;
		
		//获得命令字
		m_Command=Buff[4];
		//获得命令帧中的数据
		for(i=0; i<Buff[2]-7; i++)
			CmdData[i]=Buff[5+i];
		CmdDataLen=Buff[1]-5;
				
		//重置串口中的事件
		pTokenSerial->ResetHandle();

		switch(m_Command)
		{
		case 0x30:
			pTokenSerial->ToTokenAck();
			pTokenShadow->PostThreadMessage(TOKEN_SELCHKGOOD,(WPARAM)0 ,(LPARAM)0);
			break;
		case 0x31:
			pTokenSerial->ToTokenAck();
			pTokenShadow->PostThreadMessage(TOKEN_SELCHKBAD,(WPARAM)0 ,(LPARAM)0);
			break;
		case 0x50:
			SetEvent(pTokenSerial->m_Event_TokenAck);
			break;
		case 0x34:
			pTokenShadow->PostThreadMessage(TOKEN_TOKENSTATUS,(WPARAM)CmdData ,(LPARAM)0);
			break;
		case 0x35:
			pTokenSerial->ToTokenAck();
			pTokenShadow->PostThreadMessage(TOKEN_ONETOKENPOP,(WPARAM)0 ,(LPARAM)0);
			break;
		case  0x36:
			pTokenSerial->ToTokenAck();
			::nCardDealed=CmdData[0]*256+CmdData[1];
			if(::nCardDealed!=::nCardPoped)
			{
				pTokenShadow->PostThreadMessage(TOKEN_DEALOVER,(WPARAM)(-1) ,(LPARAM)0);
			}
			else
			{
				pTokenShadow->PostThreadMessage(TOKEN_DEALOVER,(WPARAM)0 ,(LPARAM)0);
			}
			break;
		case  0x38:
			pTokenSerial->ToTokenAck();
			pTokenShadow->PostThreadMessage(TOKEN_UPBOXNULL,(WPARAM)0 ,(LPARAM)0);
			break;
		case  0x39:
			pTokenSerial->ToTokenAck();
			pTokenShadow->PostThreadMessage(TOKEN_DOWNBOXFULL,(WPARAM)0 ,(LPARAM)0);
			break;
		default:
			break;
		}
		
		//返回读取下一个帧
		goto FIRSTBYTE;
	}

	//将临时指针置NULL和句柄置0
	pTokenShadow=NULL;
	pTokenSerial=NULL;
	return 0;
}










































⌨️ 快捷键说明

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