15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Работа с COM портом в Visual C++


Автор: Paul Belikian.

Обычно порт открывается как обычный файл. Как только порт открыт, то в него можно записывать и считывать как из обычного файла. Конечно же прийдётся добавить различные проверки байтов при чтении и записи.

CComPort::CComPort(CString& sComPort)
{
	m_sComPort = sComPort;
	m_bPortReady = FALSE;
} // конец конструктора CComPort

CComPort::~CComPort()
{

} // конец деструктора CComPort

//
// инициализация COM порта
//
BOOL CComPort::Initialize()
{
	DWORD	dwRC;
	DWORD	dwError;
	char	sMsg[512];

	m_bPortReady = TRUE; // всё OK

	m_hCom = CreateFile(m_sComPort, 
		GENERIC_READ | GENERIC_WRITE,
		0, // экслюзивно занимаем порт
		NULL, // no security
		OPEN_EXISTING,
		0, // no overlapped I/O
		NULL); // null template

	if (m_hCom == INVALID_HANDLE_VALUE)
	{
		m_bPortReady = FALSE;
		dwError = GetLastError();
		
		// обработка ошибки
		LPVOID lpMsgBuf;
		lpMsgBuf = NULL;
		dwRC = FormatMessage( 
			FORMAT_MESSAGE_ALLOCATE_BUFFER | 
			FORMAT_MESSAGE_FROM_SYSTEM | 
			FORMAT_MESSAGE_IGNORE_INSERTS,
			 NULL,
			dwError, //  из GetLastError(),
			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // 
			(LPTSTR) &lpMsgBuf,
			0,
			NULL);
		
		if (dwRC && lpMsgBuf)
		{
			sprintf(sMsg, "COM open failed: Port=%s Error=%d - %s",
				m_sComPort, dwError, lpMsgBuf);
			AfxMessageBox(sMsg);
		}
		else
		{
			sprintf(sMsg, "COM open failed: Port=%s Error=%d ",
				m_sComPort, dwError);
			AfxMessageBox(sMsg);
		} // end if
		if (dwRC && lpMsgBuf)
		{
			LocalFree( lpMsgBuf );
		} // end if
 
	} // end if

	if (m_bPortReady)
	{
		m_bPortReady = SetupComm(m_hCom, 
				128, 128); // размер буфера
		if (!m_bPortReady)
		{
			dwError = GetLastError();
			sprintf(sMsg, "SetupComm failed: Port=%s Error=%d",
				m_sComPort, dwError);
			AfxMessageBox(sMsg);
			
		} // end if
	} // end if

	if (m_bPortReady)
	{
		m_bPortReady = GetCommState(m_hCom, &m_dcb);
		if (!m_bPortReady)
		{
			dwError = GetLastError();
			sprintf(sMsg, "GetCommState failed: Port=%s Error=%d",
				m_sComPort, dwError);
			AfxMessageBox(sMsg);
		} // end if
	} // end if

	if (m_bPortReady)
	{
		m_dcb.BaudRate = 9600;
		m_dcb.ByteSize = 8;
		m_dcb.Parity = NOPARITY;
		m_dcb.StopBits = ONESTOPBIT;
		m_dcb.fAbortOnError = TRUE;

		m_bPortReady = SetCommState(m_hCom, &m_dcb);
		if (!m_bPortReady)
		{
			dwError = GetLastError();
			sprintf(sMsg, "SetCommState failed: Port=%s Error = %d",
				m_sComPort, dwError);
			AfxMessageBox(sMsg);
		}
	} // end if

	if (m_bPortReady)
	{
		m_bPortReady = GetCommTimeouts (m_hCom, &m_CommTimeouts);
		if (!m_bPortReady)
		{
			dwError = GetLastError();
			sprintf(sMsg, "GetCommTimeouts failed: Port=%s Error = %d",
				m_sComPort, dwError);
			AfxMessageBox(sMsg);
		} // end if
	} // end if

	if (m_bPortReady)
	{
		m_CommTimeouts.ReadIntervalTimeout = 50;
		m_CommTimeouts.ReadTotalTimeoutConstant = 50;
		m_CommTimeouts.ReadTotalTimeoutMultiplier = 10;
		m_CommTimeouts.WriteTotalTimeoutConstant = 50;
		m_CommTimeouts.WriteTotalTimeoutMultiplier = 10;
		m_bPortReady = SetCommTimeouts (m_hCom, &m_CommTimeouts);
		if (!m_bPortReady)
		{
			dwError = GetLastError();
			sprintf(sMsg, "SetCommTimeouts failed: Port=%s Error = %d",
				m_sComPort, dwError);
			AfxMessageBox(sMsg);
		} // end if
	} // end if

	return m_bPortReady;
} // end CComPort::Initialize


//
// освобождаем COM порт
//
void CComPort::Terminate()
{
	CloseHandle(m_hCom);
} /