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

📄 serialcomm.cpp

📁 一个通过USB->UART读取C8051F060的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// SerialComm.cpp: implementation of the CSerialComm class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SerialComm.h"

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



/************************************************************************/
/*  代码从这里开始                                                      */
/************************************************************************/
#include "CommDef.h"
#include "MMSYSTEM.H"
#include "ReadSrlDataThread.h"
#include "StreamThread.h"

CPlotDataStream	  g_sDataStream;
CSerialComm		  g_objCalSerialComm;
CDataReaderImpl	  g_objBaseDataReader;

#ifdef __USEUSBXPRESS
CUART2USBComm     g_objUART2USBComm;
#endif

#ifdef	_USECVIRS232
#include "rs232.H"
#pragma comment(lib, "instrsup.lib")
#endif

static   CalSpeed_ArgCmdToCom  g_sArgObj;
CWinThread *g_arrRunThreads[2];
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#ifdef	_USEMSCOMM
	CMSComm  CSerialComm::m_Comm;
	VARIANT	 CSerialComm::m_vResponse;	
	CSerialComm::CSerialComm():m_bConfig(FALSE)
#else
	CSerialComm::CSerialComm():m_bConfig(FALSE), m_nPortNo(-1)
#endif
{

}

static   BOOL  g_bThread1 = FALSE;
CSerialComm::~CSerialComm()
{
		this->ClosePort();
}

void   CSerialComm::ClosePort()
{
		//退出线程
		//if (m_bInitThread)
		//	g_arrRunThreads[FETCHSERIALPORTTHREADID]->ExitInstance();
		
#ifdef	_USEMSCOMM
		if (::IsWindow(m_Comm.GetSafeHwnd()))
		{
				if (m_Comm.GetPortOpen())
				{
						m_Comm.SetPortOpen(FALSE);
				}
		}
#else
		int nStatus = ::CloseCom(m_nPortNo);
		m_bPortUsed   = !(nStatus>=0);
#endif	
		//m_bInitThread = FALSE;
}

/*默认配置串口*/
BOOL   CSerialComm::ConfigPort(short nPort, int nBaudRate)
{	
		if (m_bPortUsed == TRUE)
			return TRUE;

		TRY
		{
#ifdef	_USEMSCOMM
		char   szSetting[256];
		if (!::IsWindow(m_Comm.GetSafeHwnd()))
		{
				if (!m_Comm.Create("CalComm_11", WS_VISIBLE, CRect(0,0,0,0), ::AfxGetMainWnd(), 0x999))
				{
					  m_bPortUsed = FALSE;
					  return FALSE;
				}
		}
		
		::sprintf(szSetting, "%d,n,8,1", nBaudRate);
				m_Comm.SetCommPort(nPort);
				m_Comm.SetSettings(szSetting);
				m_Comm.SetHandshaking(0);	
				m_Comm.SetRThreshold(0);		
				m_Comm.SetSThreshold(0);		
				m_Comm.SetInputMode(1);			//binary
				m_Comm.SetInBufferSize(30000);	//要>20K+1
				m_Comm.SetOutBufferSize(1512);	//
				m_Comm.SetRTSEnable(TRUE);
				m_Comm.SetDTREnable(TRUE);
				m_Comm.SetEOFEnable(FALSE);
				m_Comm.SetNullDiscard(FALSE);
				//
				m_Comm.SetPortOpen(TRUE);
				m_bPortUsed = m_Comm.GetPortOpen();
#else
				m_nPortNo = nPort;
				int nStatus = ::OpenComConfig(m_nPortNo, NULL, 500*1000, 0,
											  8, 1, 30*1000, 512);
				m_bPortUsed = (nStatus >= 0);
#endif			
				
				m_bConfig  = TRUE;
		}
		CATCH_ALL(e)
		{
				m_bConfig   = FALSE;
				m_bPortUsed = FALSE;
		}
		END_CATCH_ALL
		
		return   m_bPortUsed;
}


/************************************************************************/
/* 定义界面上下放命令部分                                               */
/************************************************************************/
BOOL  CSerialComm::SendUiCmd(void *pArg, BOOL bImmd)
{		
		//g_critSec.Lock(4000);
		if (m_bPortUsed != TRUE)
		{
				//g_critSec.Unlock();	
				return FALSE;
		}
		BOOL   bRet = FALSE;
		TRY
		{	
				this->ClearBuff();
				this->ClearOutBuff();

				//先转换成字符串, 发送命令字符串
				LPCalSpeed_ArgCmdToCom  pDataStr = (LPCalSpeed_ArgCmdToCom)pArg;		
				if (pDataStr != NULL)
						bRet = this->SendStr((LPCTSTR)pDataStr->szCmdBuff, pDataStr->nActualLen);									
		}
		END_TRY
		//g_critSec.Unlock();
		
		return  bRet;
}

//向COM口发送字节
void  CSerialComm::SendBytes(char szBuffer[], int nLen)
{
		g_critSec.Lock(2000);
		this->SendStr((LPCTSTR)szBuffer, nLen);
		g_critSec.Unlock();
}

//向COM口发送字符串
BOOL CSerialComm::SendStr(const char *pSendBuff, int nBufSize)
{
		g_critSec.Lock(2000);		
		ASSERT(nBufSize>0);
		ASSERT(AfxIsValidString(pSendBuff, nBufSize));

#ifdef	_USEMSCOMM
		CByteArray	array;
		array.SetSize(nBufSize);		
		//
		if (m_bPortUsed == TRUE)
		{
				for (int j=0; j<nBufSize; j++)
				{
						array.SetAt(j, pSendBuff[j]);
				}
				m_Comm.SetOutput(COleVariant(array));	//发送BY字节
		}
#else
		::ComWrt(m_nPortNo, pSendBuff, nBufSize);		
#endif
		g_critSec.Unlock();
		return  m_bPortUsed;
}

/************************************************************************/
/*从COM口接收字符串直接转通知显示和数据存储,							*/
/*...此处搜寻出上报数据,写入数据池.										*/
/************************************************************************/
static   ULONG   g_bSaveCount   = 0;
#define SAVEBUFFERSIZE	2097200		//2M
static  int   g_nArrayTag  = 1;
static  char  g_TmpArray1[SAVEBUFFERSIZE];
static  char  g_TmpArray2[SAVEBUFFERSIZE];
static  char  *gpTmpArray = NULL;

static   ULONG   g_sElapseBytes = 0;
static   ULONG   g_sElapseBytes_Cmp = 10;
static   ULONG   g_bSaveSize  = 0;			//存储字节大小

static   int     g_nOVLTimers = 0;
static   int     g_nCmdId = 0;
static   int     g_nSkipTimes = 0;

#define  KBYTESNUM  40	    //2通道
#define  ELAPSECOUNT  300
#define  SAVELEVELCOUNT  2*1024*1024
void CSerialComm::RecieveStr()	
{
		////////////////////////////////////////////////////////////////
		//判断缓存大小
#ifdef  _USEMSCOMM
		int nBuffLen = m_Comm.GetInBufferCount();
#else
		int nBuffLen = this->ReadNumBytes();
#endif
		if (nBuffLen <= 0)
		{
				nBuffLen = 0;
				::Sleep(3);
				if (g_nOVLTimers++ <= ELAPSECOUNT)
					return ;
		}
		
		///////////////////////////////////////////////////////////////////////
		//1.计数
		g_sElapseBytes += nBuffLen;
		if (g_nSkipTimes++ <10)		//通知界面计数
		{
				if (m_pReader != NULL)
				{
						g_nCmdId = 0x02;
						float fRecvTime = g_sElapseBytes/(KBYTESNUM*1024.0);
						if (fRecvTime >0.1)
							fRecvTime -= 0.1;

						m_pReader->NotifyData(&g_nCmdId, (ULONG)&fRecvTime);
				}
				g_nSkipTimes = 0;
		}
		if(g_nOVLTimers > ELAPSECOUNT)			//超时数据量不再变化,即传输结束时
		{
				g_bSaveSize= g_bSaveCount;		//存储线程来保存字节大小				
				TRACE1("2. Recv Bytes = %d.\n", g_sElapseBytes);
				
				if (g_bSaveSize > 0 )
				{
						static char *pHeader= NULL;

						if (g_bSaveSize >= SAVELEVELCOUNT/*1M*/)
							if (g_nArrayTag ==2)
								pHeader= g_TmpArray1;
							else	
								pHeader= g_TmpArray2;
						else
							if (g_nArrayTag ==1)
								pHeader= g_TmpArray1;
							else	
								pHeader= g_TmpArray2;
						//
						g_sDataStream.Stream(pHeader/*首地址*/, (ULONG)g_bSaveSize/*大小*/);
				}
				//结束,发送消息
				if (m_pReader != NULL)
				{
						g_nCmdId = 0x02;
						float fRecvTime = g_sElapseBytes/(KBYTESNUM*1024.0);
						if (fRecvTime >0.1)
							fRecvTime -= 0.1;
						m_pReader->NotifyData(&g_nCmdId, (ULONG)&fRecvTime);
						g_nCmdId = 0x01;
						m_pReader->NotifyData(&g_nCmdId, 1);
				}
				return ;
		}
		g_nOVLTimers     =0;
		if (nBuffLen <= 0)
			return ;

		///////////////////////////////////////////////////////////////////////
		//2.有新有效数据则压入数据池
#ifdef  _USEMSCOMM
		m_vResponse=m_Comm.GetInput();		
		::memcpy(gpTmpArray+g_bSaveCount, (char*)m_vResponse.parray->pvData, nBuffLen);
#else
		char  *pBuffer = gpTmpArray+g_bSaveCount;
		nBuffLen = this->RecvBytes((char *&)pBuffer, nBuffLen);
#endif		
		g_bSaveCount += nBuffLen;

		///////////////////////////////////////////////////////////////////////
		//3.把通道数据写入文件
		if (g_bSaveCount >= SAVELEVELCOUNT/*1M*/)
		{		
				g_bSaveCount = 0;					//计数器清零
				g_bSaveSize  = SAVELEVELCOUNT;		//保存字节大小
				TRACE1("1. Recv Bytes = %d.\n", g_sElapseBytes);
				//
				if (g_nArrayTag ==1)
				{
						g_nArrayTag = 2;
						gpTmpArray = (char *)g_TmpArray2;
						g_sDataStream.Stream(g_TmpArray1/*首地址*/, (ULONG)g_bSaveSize/*大小*/);
				}
				else
				{
						g_nArrayTag = 1;
						gpTmpArray = (char *)g_TmpArray1;
						g_sDataStream.Stream(g_TmpArray2/*首地址*/, (ULONG)g_bSaveSize/*大小*/);
				}
		}
}

void   CSerialComm::InitArv()
{
		g_nOVLTimers     = 0;
		g_sElapseBytes   = 0;
		g_bSaveCount     = 0;
		g_nArrayTag      = 1;
		gpTmpArray       = g_TmpArray1;
}

int CStreamThread::Run() 
{
		return   1;
}




//////////////////////////////////////////////////////////////////////////////////////////
//清空接收缓冲区
void   CSerialComm::ClearBuff()
{
		g_critSec.Lock(2000);
		if (m_bPortUsed == TRUE)
		{
			#ifdef	_USEMSCOMM
				m_Comm.SetInBufferCount(0);
			#else
				::FlushInQ(m_nPortNo);
			#endif
		}
		g_critSec.Unlock();	
}

void   CSerialComm::ClearOutBuff()
{
		g_critSec.Lock(2000);
		if (m_bPortUsed == TRUE)

⌨️ 快捷键说明

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