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

📄 initialize.cpp

📁 传感器读取程序
💻 CPP
字号:
#include <windows.h>
#include <stdio.h>
#include <shlwapi.h>  // include strTrim    should include shlwapi.lib

#include "initialize.h"
#include "accelerator.h"

/***************************************
函数功能:对串口读写的初始化.包括:
(1) 获取串口句柄
(2) 设置COM口的基本参数
(3) 和加速器建立连接
***************************************/
HANDLE Initialize(HANDLE hAccelerator, OVERLAPPED *pOverlappedRead, OVERLAPPED *pOverlappedWrite)
{

	hAccelerator = CreateFile(COMPORT,
		GENERIC_READ | GENERIC_WRITE,
		0,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 
		NULL );

	if (hAccelerator == INVALID_HANDLE_VALUE)
	{
		com_error = CANNOT_OPEN_COM;
		return NULL;
	}

	memset( pOverlappedRead, 0, sizeof( OVERLAPPED ) );
	memset( pOverlappedWrite, 0, sizeof( OVERLAPPED ) );

	pOverlappedRead->hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
	pOverlappedWrite->hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );

	if (!pOverlappedRead->hEvent || !pOverlappedWrite->hEvent)
	{
		CloseHandle(pOverlappedRead->hEvent);
		CloseHandle(pOverlappedWrite->hEvent);
		CloseHandle(hAccelerator);

		com_error = CANNOT_GET_EVENT_RESOURCE;
		return NULL;
	}

	if (!InitializeCOM(hAccelerator))
	{
		CloseHandle(hAccelerator);
		com_error = CANNOT_INITIALIZE_COM;
		return NULL;
	}

	//设置串口的MASK,当没有数据读入系统缓存时,WaitCommEvent处将阻塞
	SetCommMask(hAccelerator, EV_RXCHAR); 

	if(!SetupCommunication(hAccelerator, pOverlappedWrite,pOverlappedRead))
	{
		CloseHandle(hAccelerator);
		return NULL;
	}

	return hAccelerator;
}

/***************************************
函数功能:设置COM口的基本参数
***************************************/
bool InitializeCOM(HANDLE hAccelerator)
{	
	COMMTIMEOUTS CommTimeOuts;
	DCB dcb;

	CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
	CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
	CommTimeOuts.ReadTotalTimeoutConstant = 0;
	CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
	CommTimeOuts.WriteTotalTimeoutConstant = 5000;

	if(!SetCommTimeouts( hAccelerator, &CommTimeOuts))
	{
		return false;
	}

	dcb.DCBlength = sizeof(DCB);
	if (!GetCommState(hAccelerator, &dcb))
	{
		return false;
	}
	dcb.BaudRate = BAUDRATE;
	dcb.ByteSize = BYTESIZE;
	dcb.StopBits = STOPBITS;
	dcb.Parity = PARITY;

	if( !SetCommState(hAccelerator, &dcb ) || !SetupComm(hAccelerator, 10000, 10000))
	{
		return false;
	}

	return true;
}

/***************************************
函数功能: 和加速器建立连接. 包括:
(1) 向加速器发送请求建立控制符"R"
(2) 获得加速器响应"N"
如果握手成功,表示可以和加速器进行通信
***************************************/
bool SetupCommunication(HANDLE hAccelerator, OVERLAPPED *pOverlappedWrite,OVERLAPPED *pOverlappedRead)
{
	DWORD dwByteRead = 1;
	char szCommand[20];

	Sleep(50);

	if(!HandShakeToAccelerator(hAccelerator, pOverlappedWrite,'R', 1))
	{
		com_error = CANNOT_SEND_SIGNAL;
		return false;
	}

	Sleep(50);  //从串口读数据有延时.不加Sleep在开始启动加速器的时候经常需要多次重启

	if(!HandShakeFromAccelerator(hAccelerator,pOverlappedRead, szCommand, dwByteRead))
	{
		return false;
	}

	return true;
}

/***************************************
函数功能: 向加速器发送控制命令. 
发送"R"表示请求和加速器进行通信,期望获得
返回值"N";
发送"V"表示请求获得加速器当前数据,期望获
得返回值"X X-value Y Y-value Z Z-value"
***************************************/
bool HandShakeToAccelerator(HANDLE hAccelerator, OVERLAPPED *pOverlappedWrite , char cCommand,int nLength)
{
	BOOL bWriteStat;
	DWORD dwByteWritten;

	bWriteStat = WriteFile(hAccelerator, (LPSTR) &cCommand, nLength, &dwByteWritten, pOverlappedWrite);

	if (!bWriteStat && (GetLastError() == ERROR_IO_PENDING))
	{
		switch(WaitForSingleObject(pOverlappedWrite->hEvent, 1000))
		{
		case WAIT_OBJECT_0:
			break;
		case WAIT_TIMEOUT:
		case WAIT_ABANDONED:
			return false;
		}
	}
	else
	{
		return false;
	}

	return true;
}

/***************************************
函数功能: 从加速器获得返回值. 
若发送的值为"R",则期望获得的返回值为"N";
若发送的值为"V",则期望获得返回值为
"X X-value Y Y-value Z Z-value"
***************************************/
bool HandShakeFromAccelerator(HANDLE hAcclerator, OVERLAPPED *pOverlappedRead, char *szBuffer, DWORD dwByteRead)
{
	BOOL bReadStat, bSetup;

	DWORD dwEvtMask;

	static OVERLAPPED OverlappedRecv;

	//用于判断超时
	static int iTimeOut = 0;

	int cTotalLength;
	int cCount = 0;

	//判断是否为发送"R"期望获得的输出
	bSetup = (dwByteRead == 1) ? true : false;
	if (bSetup)
	{
		cTotalLength = 1;
	}
	else
	{
		cTotalLength = 6;
	}

	OverlappedRecv.hEvent = CreateEvent(NULL,false, false, NULL);

	bool bResult = WaitCommEvent(hAcclerator, &dwEvtMask ,&OverlappedRecv);

	if (bResult != true && GetLastError() == ERROR_IO_PENDING)
	{
		switch(WaitForSingleObject(OverlappedRecv.hEvent, 200))
		{
		case WAIT_OBJECT_0:
			break;
		case WAIT_TIMEOUT:
		case WAIT_ABANDONED:
			com_error = CANNOT_SETUP_ACCELERATOR;
			return false;
		}
	}
	else if (bResult != true)
	{
		com_error = CANNOT_RECV_DATA;
		return false;
	}

	if (dwEvtMask & EV_RXCHAR)
	{
		DWORD dwErrorFlags;
		COMSTAT ComStat;

		do 
		{
			ClearCommError(hAcclerator, &dwErrorFlags, &ComStat );
			if (ComStat.cbInQue > 0)
			{
				dwByteRead = ComStat.cbInQue;
			}

			bReadStat = ReadFile( hAcclerator, (char*)szBuffer, dwByteRead, &dwByteRead, pOverlappedRead);
			if (!bReadStat && (GetLastError() == ERROR_IO_PENDING))
			{
				switch(WaitForSingleObject(pOverlappedRead->hEvent, 1000))
				{
				case WAIT_OBJECT_0:
					break;
				case WAIT_TIMEOUT:
				case WAIT_ABANDONED:
					com_error = CANNOT_RECV_DATA;
					return false;
				}
			}
			cCount += dwByteRead;

			++iTimeOut;
			if (iTimeOut >= 5000)
			{
				break;
			}

		}while(cCount < cTotalLength);

		if (iTimeOut >= 5000)
		{
			iTimeOut = 0;
			com_error = TIME_OUT;
			return false;
		}

		iTimeOut = 0;

		if ((*szBuffer != 'N') && bSetup)
		{
			com_error = CANNOT_SETUP_ACCELERATOR;
			return false;
		}

		return true;
	}  // end of if (dwEvtMask & EV_RXCHAR)

	com_error = CANNOT_RECV_DATA;
	return false;
}

/***************************************
函数功能: 显示读串口数据时的错误信息
***************************************/
void DisplayCOMError()
{
	char szErrorString[30];

	switch(com_error)
	{
	case CANNOT_OPEN_COM:
		strcpy(szErrorString,"无法打开串口!");
		break;
	case CANNOT_GET_EVENT_RESOURCE:
		strcpy(szErrorString,"系统资源event无法得到分配!");
		break;
	case CANNOT_INITIALIZE_COM:
		strcpy(szErrorString,"无法初始化串口!");
		break;
	case CANNOT_SEND_SIGNAL:
		strcpy(szErrorString,"无法发送数据!");
		break;
	case CANNOT_RECV_DATA:
		strcpy(szErrorString,"无法接收数据!");
		break;
	case TIME_OUT:
		strcpy(szErrorString,"超时!");
		break;
	case CANNOT_SETUP_ACCELERATOR:
		strcpy(szErrorString,"请重启加速器!");
		break;
	default:
		strcpy(szErrorString,"未知错误!");
		break;
	}
	MessageBox(NULL,szErrorString, "警告",MB_OK);
}

/***************************************
函数功能: 关闭程序.
***************************************/
bool EndProgram()
{
	char szComdLine[1024];
	strcpy(szComdLine,GetCommandLine());

	int iLength = strlen(szComdLine);
	if (szComdLine[iLength-1] == 'e' && szComdLine[iLength - 2] == '-')
	{
		return true;
	}
	else
	{
		return false;
	}
}

/***************************************
函数功能: 设置注册表键值,用与关闭程序.
***************************************/
void SetRegedit()
{
	HKEY keyHandle;
	DWORD dwDisposition;

	char szBuf[] = "关闭加速器"; 
	char szcmd[1024];

	if (RegCreateKeyEx(HKEY_CLASSES_ROOT,
		SUBKEY,
		0,
		NULL,
		REG_OPTION_NON_VOLATILE,
		KEY_READ | KEY_WRITE,
		NULL,
		&keyHandle,
		&dwDisposition
		) != ERROR_SUCCESS)
	{
		MessageBox(NULL,"无法写注册表!","警告",MB_OK);
		return;
	}

	if (RegSetValueEx(keyHandle,
		NULL,
		0,
		REG_SZ,
		(LPBYTE)szBuf,
		strlen(szBuf) + 1) != ERROR_SUCCESS)
	{
		MessageBox(NULL,"无法写注册表!","警告",MB_OK);
		return;
	}

	RegCloseKey(keyHandle);

	if (RegCreateKeyEx(HKEY_CLASSES_ROOT,
		ACCELERATOR_SUBKEY,
		0,
		NULL,
		REG_OPTION_NON_VOLATILE,
		KEY_READ | KEY_WRITE,
		NULL,
		&keyHandle,
		&dwDisposition
		) != ERROR_SUCCESS)
	{
		MessageBox(NULL,"无法写注册表!","警告",MB_OK);
		return;
	}

	strcpy(szcmd, GetCommandLine());
	
	char szTrim[] = TEXT("\"\0");
	StrTrim(szcmd, szTrim);
	
	StrCpyN(szcmd,szcmd,strlen(szcmd) - 1);
	
	strcat(szcmd, " -e");

	if (RegSetValueEx(keyHandle,
		NULL,
		0,
		REG_SZ,
		(LPBYTE)szcmd,
		strlen(szcmd) + 1) != ERROR_SUCCESS)
	{
		MessageBox(NULL,"无法写注册表!","警告",MB_OK);
		return;
	}

}

/***************************************
函数功能: 程序结束,删除相关注册表键值
***************************************/
void DeleteReg()
{
	HKEY hkey;
	RegOpenKeyEx(HKEY_CLASSES_ROOT,
		SUBKEY,
		0,
		KEY_ALL_ACCESS,
		&hkey);

	RegDeleteKey(hkey,"command");

	RegOpenKeyEx(HKEY_CLASSES_ROOT,
		SHELL_SUBKEY,
		0,
		KEY_ALL_ACCESS,
		&hkey);

	RegDeleteKey(hkey,"accelerator");

	RegCloseKey(hkey);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -