MFC串口通讯
2016-10-11 12:51
246 查看
一、环境配置
使用的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 , 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; }
相关文章推荐
- MFC单文档之串口通讯三次无返回值报错提醒
- 多线程串口编程工具CserialPort类(附VC基于MFC单文档协议通讯源程序及详细编程步骤)
- 简单而强大的多线程串口编程工具CserialPort类(附VC基于MFC单文档协议通讯源程序及详细编程步骤)
- MFC 串口通讯程序
- MFC单文档之利用全局变量一次设置多个对话框的串口通讯
- MFC单文档之串口通讯实现16进制数据的发送和接收
- MFC单文档之基于MSCOMM的多个编辑框的串口通讯
- 简单而强大的多线程串口编程工具CserialPort类(附VC基于MFC单文档协议通讯源程序及详细编程步骤)
- 简单而强大的多线程串口编程工具CserialPort类(附VC基于MFC单文档协议通讯源程序及详细编程步骤)
- 详解linux下的串口通讯开发
- 用Windows API 编写串口通讯程序
- MFC 串口发送文件
- 自动检测可用串口实现串口通讯程序(可实现串口热插拔检测)
- VC++ 的串口通讯(4)
- MFC串口编程——使用标准SerialCom类
- 自动检测可用串口实现串口通讯程序(可实现串口热插拔检测)
- STM32F10x 学习笔记之USART实现串口通讯 DMA 方式
- rs232串口通讯中,读串口与读端口的区别
- 通讯端口协议大致分成三类:串口,现场总线,以太网
- MFC 视图、文档、框架(通讯)