📄 serialcomm.cpp
字号:
// 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 + -