📄 serialcom.cpp
字号:
// SerialCom.cpp: implementation of the CSerialCom class.
// For Vorager 2.0
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "SerialCom.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//串口接收线程
UINT ComMonitor(LPVOID pParam)
{
OVERLAPPED m_os={0};
m_os.hEvent=NULL;
CSerialCom * pCom=(CSerialCom *)pParam;
DWORD dwMaskFlag;
DWORD dwCommEvent;
DWORD dwByteToRead;
DWORD dwRes;
BYTE rechar[1]={0xff};
bool bWaitingOnStatusHandle = false;
dwMaskFlag=EV_RXCHAR | EV_CTS;
if (!SetCommMask(pCom->m_hCom,dwMaskFlag))
{
return 0;
}
m_os.hEvent=CreateEvent(NULL,true,false,NULL);
if (m_os.hEvent==NULL)
return 0;
while (true)
{
if (!WaitCommEvent(pCom->m_hCom,&dwCommEvent,&m_os))
{
if (GetLastError() == ERROR_IO_PENDING)
{
bWaitingOnStatusHandle = true;
}
else
break;
}
else
{
bWaitingOnStatusHandle=false;
}
if (bWaitingOnStatusHandle)
{
dwRes = WaitForSingleObject(m_os.hEvent, INFINITE);
GetCommMask(pCom->m_hCom,&dwCommEvent);
if ((dwCommEvent & EV_RXCHAR)==EV_RXCHAR)
{
do
{
COMSTAT comstat;
DWORD dwError = 0;
ClearCommError(pCom->m_hCom,&dwError,&comstat);
if (comstat.cbInQue==0)
break;
ReadFile(pCom->m_hCom,rechar,1,&dwByteToRead,&m_os);
if (pCom->driveDebug_flag)
{
pCom->csDriver+=rechar;
pCom->pDriver->SetWindowText(pCom->csDriver);
}
else
{
if (pCom->m_pCmd!=NULL)
pCom->m_pCmd->Parse(rechar,1);
}
}
while (true);
}
if (dwRes==WAIT_OBJECT_0)
{
if (!GetOverlappedResult(pCom->m_hCom, &m_os, &dwByteToRead, false))
{
do
{
COMSTAT comstat;
DWORD dwError = 0;
ClearCommError(pCom->m_hCom,&dwError,&comstat);
if (comstat.cbInQue==0)
break;
ReadFile(pCom->m_hCom,rechar,1,&dwByteToRead,&m_os);
if (dwByteToRead>0)
{
if (pCom->driveDebug_flag)
{
pCom->csDriver+=rechar;
pCom->pDriver->SetWindowText(pCom->csDriver);
}
else
{
if (pCom->m_pCmd!=NULL)
pCom->m_pCmd->Parse(rechar,1);
}
}
else
{
CloseHandle(m_os.hEvent);
return 0;
}
}
while (true);
}
}
}
}
CloseHandle(m_os.hEvent);
return 0;
}
//串口发送线程
UINT SendingThread(LPVOID pParam)
{
CSerialCom * pCom = (CSerialCom *) pParam;
POSITION pos;
UINT cnt = 0; //延时计数
while (pCom->IsRuning)
{
pos = pCom->m_cmdlist.GetHeadPosition();
if (pos != NULL)
{
CMDBUF * pCbuf = (CMDBUF *)pCom->m_cmdlist.GetNext(pos);
//如果发送回合未结束,则等待
while (pCom->bSending == TRUE)
{
Sleep(10);
cnt ++;
if (cnt > 10)
break;
}
cnt = 0;
//发送缓冲列表里的指令
pCom->ComSend(pCbuf->pCmdBuf,pCbuf->nLen);
//释放缓冲列表里已发送指令占用的资源
pCom->m_cmdlist.RemoveHead();
delete []pCbuf->pCmdBuf;
delete pCbuf;
}
Sleep(5);
}
return 0L;
}
CSerialCom::CSerialCom()
{
//默认串口属性
m_baudrate=CBR_19200;
m_bytesize=8;
m_stopbits=ONESTOPBIT;
m_parity=NOPARITY;
bSending = FALSE;
IsRuning = FALSE;
driveDebug_flag=FALSE;
}
CSerialCom::~CSerialCom()
{
IsRuning = FALSE;
//清除缓冲列表里的数据
m_cmdlist.RemoveAll();
ASSERT(m_cmdlist.GetCount()==0);
POSITION pos = m_cmdlist.GetHeadPosition();
while (pos != NULL)
{
CMDBUF * m_pTempCmd = (CMDBUF *)m_cmdlist.GetNext(pos);
m_pTempCmd->pCmdBuf=NULL;
m_pTempCmd=NULL;
}
Sleep(50);
}
BOOL CSerialCom::Create(int inCom)
{/**/
if (TRUE == IsRuning)
{
if (inCom == m_com)
{ //重复打开同一串口
return FALSE;
}
else
{ //未关闭原来的串口
CloseHandle(m_hCom);
}
}
m_com = inCom;
//建立串口
CString strCom;
strCom.Format("COM%d:",inCom); //生成一个串口号字符串
//用串口号字符串打开串口并返回打开的串口句柄
m_hCom=CreateFile(strCom,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
if (m_hCom==INVALID_HANDLE_VALUE) //打开串口失败的处理
{
m_hCom=NULL;
AfxMessageBox("无法打开串口!",MB_OK|MB_ICONEXCLAMATION);
return false;
}
else
{
// AfxMessageBox("打开串口!",MB_OK|MB_ICONEXCLAMATION);
}
DCB dcb; //设备配置对象,下面是对串口的一般配置
COMMTIMEOUTS m_CommTimeouts;
m_CommTimeouts.ReadIntervalTimeout = 1000;
m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000;
m_CommTimeouts.ReadTotalTimeoutConstant = 1000;
m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000;
m_CommTimeouts.WriteTotalTimeoutConstant = 1000;
if (!SetCommTimeouts(m_hCom, &m_CommTimeouts))
{
CloseHandle(m_hCom);
m_hCom=NULL;
return false;
}
GetCommState(m_hCom,&dcb); //将配置对象设置到打开的串口
dcb.BaudRate=m_baudrate; //设置串口波特率
dcb.ByteSize=m_bytesize; //设置传输的字节数
dcb.StopBits=m_stopbits; //设置停止位
dcb.Parity=m_parity; //设置校验方式
//将配置对象设置到打开的串口,如果该失败,清除句柄关闭串口
if (!SetCommState(m_hCom,&dcb))
{
CloseHandle(m_hCom);
m_hCom=NULL;
return false;
}
IsRuning = TRUE;
//开启串口接收线程
AfxBeginThread(ComMonitor,(LPVOID)this,THREAD_PRIORITY_NORMAL);
//开启串口发送线程
AfxBeginThread(SendingThread,(LPVOID)this,THREAD_PRIORITY_NORMAL);
return true;
}
void CSerialCom::Send(const void *pBuffer, const int iLength)
{
CMDBUF * m_pTempCmd = new CMDBUF;
m_pTempCmd->pCmdBuf = new UCHAR[iLength];
memcpy(m_pTempCmd->pCmdBuf,pBuffer,iLength);
m_pTempCmd->nLen = iLength;
m_cmdlist.AddTail(m_pTempCmd);
}
void CSerialCom::ComSend(const void *pBuffer, const int iLength)
{
if (m_hCom==NULL)
return;
bSending = TRUE;
OVERLAPPED m_os={0};
DWORD dwByteWrite;
if (!WriteFile(m_hCom,pBuffer,iLength,&dwByteWrite,&m_os))
DWORD iErr=GetLastError();
//Sleep(100); //延时100ms
DWORD dwNumberOfBytesTransferred;
GetOverlappedResult(m_hCom,&m_os,&dwNumberOfBytesTransferred,TRUE);
//bSending = FALSE;
}
void CSerialCom::Close()
{
//关闭串口
if (m_hCom!=NULL)
CloseHandle(m_hCom);
IsRuning = FALSE;
m_hCom=NULL;
}
void CSerialCom::SetCmd(CFstarCmd *pCmd)
{
m_pCmd = pCmd;
if (m_pCmd != NULL)
{
m_pCmd->m_pPhy = this;
}
}
void CSerialCom::SetComProp(DCB* inProp)
{
if (inProp == NULL)
return;
m_baudrate=inProp->BaudRate;
m_bytesize=inProp->ByteSize;
m_stopbits=inProp->StopBits;
m_parity=inProp->Parity;
}
void CSerialCom::ClearBuffer()
{
//清除缓冲列表里的数据
m_cmdlist.RemoveAll();
ASSERT(m_cmdlist.GetCount()==0);
POSITION pos = m_cmdlist.GetHeadPosition();
while (pos != NULL)
{
CMDBUF * m_pTempCmd = (CMDBUF *)m_cmdlist.GetNext(pos);
m_pTempCmd->pCmdBuf=NULL;
m_pTempCmd=NULL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -