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

📄 synccomdoc.cpp

📁 VC的串口同步例子
💻 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 + -