MFC串口通讯

来源:互联网 发布:淘宝xylife海外专营店 编辑:程序博客网 时间:2024/05/17 02:54

一、环境配置

使用的VS版本为VS2015. 对话框工程。
操作串口需要包含以下头文件,工程配置中注意增加依赖项:setupapi.lib
#include "stdafx.h"#include "stdlib.h"#include "windows.h"#include "setupapi.h"
并且在工程配置中:链接器->输入->附加依赖项 中输入setupapi.lib

二、从设备管理器中枚举Ports类设备



Ports类设备为串口所在的设备类型分组,其他包括并口,打印机端口等都在此分组中。首先通过Windows提供的API函数,将设备信息进行提取。
wchar_t SerialName[50][100] = { 0 };//保存串口设备名称unsigned char COM_RecvData[200] = { 0 };/******************************************************************************** @Function    : FindSerialDevice* @Description : 枚举出所有的串口外设,将外设信息保存到SerialName数组中* @Input       : None* @Output      : PortsName数组* @Return      : n,串口外设数量* @Auth        : Solen           2016/10/11*******************************************************************************/int FindSerialDevice(void){/*1 变量声明*//*2 获取当前所有设备的信息*//*3 依次枚举所有设备,如果枚举成功则进行以下判断*//*4 若枚举成功则判断是否为Ports类设备,是则将该设备的名称端口存放到PortsName数组中*//*5 从Ports类中提取串口*//*1*/HDEVINFO hDevInfo;SP_DEVINFO_DATA DeviceInfoData;wchar_t PortsName[50][100] = { 0 };//保存Ports类设备名称 DWORD t;//计数变量int i;//计数变量int m = 0;//PortsName 序号int n = 0;//SerialName 序号wchar_t szClassBuf[MAX_PATH] = { 0 };int COM_Flag = 0;/*2*/hDevInfo = SetupDiGetClassDevs(NULL, 0, 0, DIGCF_PRESENT | DIGCF_ALLCLASSES);if (hDevInfo == INVALID_HANDLE_VALUE) return NULL;/*3*/DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);for (t = 0; SetupDiEnumDeviceInfo(hDevInfo, t, &DeviceInfoData); t++){SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_CLASS, NULL, (PBYTE)szClassBuf, MAX_PATH - 1, NULL); //continue;//先找到设备的类/*4*/if (szClassBuf[0] == 'P'&&szClassBuf[1] == 'o'&&szClassBuf[2] == 'r'&&szClassBuf[3] == 't'&&szClassBuf[4] == 's'){SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_FRIENDLYNAME, NULL, (PBYTE)PortsName[m], MAX_PATH - 1, NULL);for (i = 0; PortsName[m][i] != 0; i++){switch (PortsName[m][i]){case '(':COM_Flag++;break;case 'C':if (COM_Flag == 1)COM_Flag++;break;case 'O':if (COM_Flag == 2)COM_Flag++;break;case 'M':if (COM_Flag == 3)COM_Flag++;break;case ')':if (COM_Flag == 4)COM_Flag++;break;default:break;}}if (COM_Flag == 5){COM_Flag = 0;SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_FRIENDLYNAME, NULL, (PBYTE)SerialName[n], MAX_PATH - 1, NULL);n++;}m++;}}return n;}

三、打开串口设备

这里需要指定串口号以及波特率,其他均为默认设置。串口号可以根据(二)中扫描到的串口号信息进行提取。
/******************************************************************************** @Function    : OpenSerialDevice* @Description : 打开指定的串口设备* @Input       : None* @Output      : * @Return      :  1:成功 0:失败* @Auth        : Solen           2016/10/11*******************************************************************************/int OpenSerialDevice(wchar_t *SerialPort,int Baudrate){hCom = CreateFile(SerialPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);if (hCom == INVALID_HANDLE_VALUE)return 0;SetupComm(hCom, 1024, 1024);COMMTIMEOUTS ComTimeOut;ComTimeOut.ReadIntervalTimeout = 1000;ComTimeOut.ReadTotalTimeoutMultiplier = 500;ComTimeOut.ReadTotalTimeoutConstant = 5000;ComTimeOut.WriteTotalTimeoutMultiplier = 500;ComTimeOut.WriteTotalTimeoutConstant = 2000;SetCommTimeouts(hCom, &ComTimeOut);DCB ComDcb;GetCommState(hCom, &ComDcb);ComDcb.BaudRate = Baudrate;ComDcb.fBinary = 0;ComDcb.ByteSize = 8;ComDcb.Parity = NOPARITY;ComDcb.StopBits = ONESTOPBIT;SetCommState(hCom, &ComDcb);PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR);return 1;}

四、串口写操作

这里串口的读写与USB的读写使用的都是WriteFile函数/ReadFile函数
int SerialTransmit(char *SendData,DWORD DataLength){DWORD dwBytesWrite = (DWORD)DataLength;COMSTAT ComStat;DWORD dwErrorFlags;BOOL bWriteStat;OVERLAPPED m_osWrite;//建立Overlapped结构 m_osWrite.InternalHigh = 0;m_osWrite.Offset = 0;m_osWrite.OffsetHigh = 0;m_osWrite.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);//初始化Overlapped结构ClearCommError(hCom, &dwErrorFlags, &ComStat);bWriteStat = WriteFile(hCom, SendData, dwBytesWrite, &dwBytesWrite, &m_osWrite);//异步写串口if (!bWriteStat) {return 0;}PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);return 1;}

int SerialRecv(void){DWORD dwBytesRead = 1000;memset(COM_RecvData, 0, 200);COMSTAT ComStat;DWORD dwErrorFlags;OVERLAPPED m_osRead; memset(&m_osRead, 0, sizeof(OVERLAPPED));m_osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);ClearCommError(hCom, &dwErrorFlags, &ComStat);dwBytesRead = min(dwBytesRead, (DWORD)ComStat.cbInQue);if (!dwBytesRead) {return 0;}BOOL bReadStatus;bReadStatus = ReadFile(hCom, COM_RecvData, dwBytesRead, &dwBytesRead, &m_osRead);if ((!bReadStatus)||(dwBytesRead == 0)){return 0;}return dwBytesRead;}




0 0
原创粉丝点击