📄 synccomdoc.cpp
字号:
// SyncComDoc.cpp : implementation of the CSyncComDoc class
//
#include "stdafx.h"
#include "SyncCom.h"
#include "SyncComDoc.h"
#include "SyncComView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern CSyncComView* p_View;
/////////////////////////////////////////////////////////////////////////////
// CSyncComDoc
IMPLEMENT_DYNCREATE(CSyncComDoc, CDocument)
BEGIN_MESSAGE_MAP(CSyncComDoc, CDocument)
//{{AFX_MSG_MAP(CSyncComDoc)
ON_COMMAND(IDC_CONNECTION, OnConnection)
ON_COMMAND(IDC_SEND, OnSend)
ON_COMMAND(IDC_DTRCHECK, OnDtrcheck)
ON_COMMAND(IDC_DISCONNECTION, OnDisconnection)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSyncComDoc construction/destruction
CSyncComDoc::CSyncComDoc()
{
m_pThread= NULL;
m_bConnected = FALSE;
m_nBaud = 230400;
m_nDataBits = 8;
m_bEcho = FALSE;
m_nParity = 0;
m_nStopBits = 0;
m_sPort = "COM1";
m_bNewLine = FALSE;
m_nFlowCtrl = 0;
pos=1;
}
CSyncComDoc::~CSyncComDoc()
{
CloseComm();
}
BOOL CSyncComDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
if(!Initialize())
{
AfxMessageBox("打开串口失败!");
}
if(!ConfigConnection())
{
AfxMessageBox("初始化串口失败!");
}
((CEditView*)m_viewList.GetHead())->SetWindowText(NULL);
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CSyncComDoc serialization
void CSyncComDoc::Serialize(CArchive& ar)
{
// CEditView contains an edit control which handles all serialization
((CEditView*)m_viewList.GetHead())->SerializeRaw(ar);
}
/////////////////////////////////////////////////////////////////////////////
// CSyncComDoc diagnostics
#ifdef _DEBUG
void CSyncComDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CSyncComDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CSyncComDoc commands
BOOL CSyncComDoc::Initialize()//初始化串口
{
COMMTIMEOUTS TimeOuts;
m_hCom = CreateFile(m_sPort,GENERIC_READ|GENERIC_WRITE,0,NULL,
OPEN_EXISTING,0,NULL);//同步方式
if(m_hCom==INVALID_HANDLE_VALUE)
return FALSE;
SetupComm(m_hCom,MAXBLOCK,MAXBLOCK);
SetCommMask(m_hCom,EV_RXCHAR);
PurgeComm(m_hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);//清干净输入、输出缓冲区
//把间隔超时设为最大,把总超时设为0,将导致ReadFile立即返回并完成操作
TimeOuts.ReadIntervalTimeout = MAXDWORD;
TimeOuts.ReadTotalTimeoutMultiplier = 0;
TimeOuts.ReadTotalTimeoutConstant = 0;
/*设置写操时*/
TimeOuts.WriteTotalTimeoutMultiplier = 0;
TimeOuts.WriteTotalTimeoutConstant = 0;
SetCommTimeouts(m_hCom,&TimeOuts);
return TRUE;
}
BOOL CSyncComDoc::OpenConnection()
{
m_pThread = AfxBeginThread(CommProc,this,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED,NULL);
if(m_pThread==NULL)//线程创建不成功
{
CloseHandle(m_hCom);
return FALSE;
}
else //线程成功
{
m_bConnected = TRUE;
m_pThread->ResumeThread();//恢复线程运行
}
return TRUE;
}
BOOL CSyncComDoc::ConfigConnection()
{
if(!GetCommState(m_hCom,&dcb))
return FALSE;
dcb.fBinary = TRUE;
dcb.BaudRate = m_nBaud;//波特率
dcb.ByteSize = m_nDataBits;//字节数
dcb.fParity = m_nParity;//是否校验
switch(m_nParity)//校验
{
case 0:
dcb.Parity = NOPARITY;
break;
case 1:
dcb.Parity = EVENPARITY;
break;
case 2:
dcb.Parity = ODDPARITY;
break;
default:;
}
switch(m_nStopBits)//停止位
{
case 0:
dcb.StopBits = ONESTOPBIT;
break;
case 1:
dcb.StopBits = ONE5STOPBITS;
break;
case 2:
dcb.StopBits = TWOSTOPBITS;
break;
default:;
}
return SetCommState(m_hCom,&dcb);
}
UINT CommProc(LPVOID pParam)//该线程不属于DOC
{
DWORD dwMask,dwTrans;
COMSTAT ComStat;//这个结构判断是否有数据进入
DWORD dwErrorFlags;
CSyncComDoc* pDoc = (CSyncComDoc*)pParam; //所以要申明之
CSyncComView* pView;
ClearCommError(pDoc->m_hCom,&dwErrorFlags,&ComStat);
PurgeComm(pDoc->m_hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);//清干净输入、输出缓冲区
//应该在此加入控制语句
while (pDoc->m_bConnected)//循环检测串口
{
ClearCommError(pDoc->m_hCom,&dwErrorFlags,&ComStat);
if(ComStat.cbInQue)//是否有数据进入
{
//同步操作不需要下面这一句
// WaitForSingleObject(pDoc->m_hPostMsgEvent,INFINITE);
ResetEvent(pDoc->m_hPostMsgEvent);
//下面发消息给VIEW,在VIEW中显示收到的数据
p_View->SendMessage(MSG_REPORTRECEIVE,EV_RXCHAR,NULL);
continue;
}
dwMask=0;
/* if (!WaitCommEvent(pDoc->m_hCom,&dwMask,NULL))// 等待串口通信事件的发生,只用于异步结构
{
dwErrorFlags = GetLastError();
//返回ERROR_INVALID_HANDLE错误
}*///这一段放开后,线程停不了,串口关不了,为什么?是同步和异步的关系的吗?
}
CloseHandle(pDoc->m_hCom);
return 0;
}
void CSyncComDoc::OnConnection()
{
if(!OpenConnection())
{
AfxMessageBox("打开串口失败!");
}
}
DWORD CSyncComDoc::ReadComm(char* buf,DWORD dwLength)//从串口读取
{
DWORD length = 0;
COMSTAT ComStat;
DWORD dwErrorFlags;
ClearCommError(m_hCom,&dwErrorFlags,&ComStat);
length = min(dwLength,ComStat.cbInQue);
ReadFile(m_hCom,buf,length,&length,NULL);//不使用异步方式
return length;
}
void CSyncComDoc::OnSend() //发送数据
{
char szMessage[20] = "qqqqq you very much";
int s;
s = strlen(szMessage);
DWORD dwBytesWritten;
// PurgeComm(pDoc->m_hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);//清干净输入、输出缓冲区
if(!WriteFile(m_hCom, (LPSTR)&szMessage, s, &dwBytesWritten, NULL))
{
AfxMessageBox("kkkkkkkkk失败!");
}
}
void CSyncComDoc::OnDtrcheck()
{
int resu;
// dcb.fDtrControl = DTR_CONTROL_DISABLE;
// m_bConnected = FALSE;
// resu = SetCommState(m_hCom,&dcb);
if(p_View->pos==1)
{
p_View->pos=2;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
resu = SetCommState(m_hCom,&dcb);
// resu = EscapeCommFunction(m_hCom,CLRDTR);
}
else
{
p_View->pos=1;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
resu = SetCommState(m_hCom,&dcb);
}
}
BOOL CSyncComDoc::CloseComm()
{
if (!m_bConnected)
return FALSE;
m_bConnected=FALSE;
m_pThread=NULL;
CloseHandle(m_hCom);
return TRUE;
}
void CSyncComDoc::OnDisconnection()
{
CloseComm();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -