#include "stdafx.h"
#include <iostream>
#include "com.h"
#include <process.h>
My_Com::My_Com() :
hCom(INVALID_HANDLE_VALUE),
m_IsOpen(false),
m_Thread(NULL)
{
//void *memset(void *s, int ch, size_t n);将s中当前位置后面的n个字节用ch替换并返回s
memset(&m_ovWait, 0, sizeof(m_ovWait));
memset(&m_ovWrite, 0, sizeof(m_ovWrite));
memset(&m_ovRead, 0, sizeof(m_ovRead));
}
My_Com::~My_Com()
{
Close_Com();
}
bool My_Com::Open_Com(LPCWSTR Port)
{
hCom = CreateFile(
Port, //将要打开的串口逻辑名
GENERIC_READ | GENERIC_WRITE, //允许读和写
0, //指定共享属性,由于串口不能共享,该参数必须置为0,独占方式
NULL,//引用安全性属性结构,缺省值为NULL
OPEN_EXISTING, //打开而不是创建
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, //重叠方式
NULL //对串口而言该参数必须置为NULL
);
if (hCom == INVALID_HANDLE_VALUE)
{
printf ("打开串口失败!\n");
return FALSE;
}
else
{
printf("打开串口成功!\n");
}
return TRUE;
}
bool My_Com::Config_Com()
{
SetupComm(hCom, 1024, 1024); //输入缓冲区和输出缓冲区的大小都是1024
COMMTIMEOUTS TimeOuts; //设定读超时
TimeOuts.ReadIntervalTimeout = MAXDWORD;
TimeOuts.ReadTotalTimeoutMultiplier = 0;
TimeOuts.ReadTotalTimeoutConstant = 0; //设定写超时
TimeOuts.WriteTotalTimeoutMultiplier = 500;
TimeOuts.WriteTotalTimeoutConstant = 2000;
SetCommTimeouts(hCom, &TimeOuts); //设置超时
DCB dcb;
GetCommState(hCom, &dcb);
dcb.BaudRate = 9600; //波特率为9600
dcb.ByteSize = 8; //每个字节有8位
dcb.Parity = NOPARITY; //无奇偶校验位
dcb.StopBits = TWOSTOPBITS; //两个停止位
SetCommState(hCom, &dcb);
PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR);
m_ovRead.hEvent = CreateEvent(NULL, false, false, NULL);
m_ovWrite.hEvent = CreateEvent(NULL, false, false, NULL);
m_ovWait.hEvent = CreateEvent(NULL, false, false, NULL);
//SetCommMask设置要监控的事件
//EV_RXCHAR:输入缓冲区中已收到数据,即接收到一个字节并放入输入缓冲区。
//EV_ERR:线路状态错误,包括了CE_FRAME / CE_OVERRUN / CE_RXPARITY 3种错误。
SetCommMask(hCom, EV_ERR | EV_RXCHAR);
//_beginThreadex创建读取线程
m_Thread = (HANDLE)_beginthreadex(NULL, 0, &My_Com::ComRecv, this, 0, NULL);
m_IsOpen = true;
return TRUE;
}
bool My_Com::ComWrite(LPBYTE buf, int &len)
{
BOOL rtn = FALSE;
DWORD WriteSize = 0; //DWORD 代表 unsigned long
PurgeComm(hCom, PURGE_TXCLEAR | PURGE_TXABORT);
m_ovWait.Offset = 0;
rtn = WriteFile(hCom, buf, len, &WriteSize, &m_ovWrite);
if (FALSE == rtn && GetLastError() == ERROR_IO_PENDING)//后台读取
{
//等待数据写入完成
printf("已发送 :");
for (int i = 0; i < len; i++)
printf("%d ", buf[i]);
printf("\n");
}
return rtn != FALSE;
}
unsigned int __stdcall My_Com::ComRecv(void* LPParam)
{
My_Com *obj = static_cast<My_Com*>(LPParam);
DWORD WaitEvent = 0, Bytes = 0;
BOOL Status = FALSE;
BYTE ReadBuf[4096];
DWORD Error;
COMSTAT cs = { 0 };
int i;
while (obj->m_IsOpen)
{
WaitEvent = 0;
obj->m_ovWait.Offset = 0;
Status = WaitCommEvent(obj->hCom, &WaitEvent, &obj->m_ovWait);
/*
WaitCommEvent等待串口通信事件的发生
用途:用来判断用SetCommMask()函数设置的串口通信事件是否已发生。
原型:BOOL WaitCommEvent(HANDLE hFile,LPDWORD lpEvtMask,LPOVERLAPPED lpOverlapped);
参数说明:
-hFile:串口句柄
-lpEvtMask:函数执行完后如果检测到串口通信事件的话就将其写入该参数中。
-lpOverlapped:异步结构,用来保存异步操作结果。
*/
//GetLastError()函数返回ERROR_IO_PENDING,表明串口正在进行读操作
if (FALSE == Status && GetLastError() == ERROR_IO_PENDING)
{
// GetOverlappedResult函数的最后一个参数设为TRUE,函数会一直等待,直到读操作完成或由于错误而返回。
Status = GetOverlappedResult(obj->hCom, &obj->m_ovWait, &Bytes, TRUE);
}
//在使用ReadFile 函数进行读操作前,应先使用ClearCommError函数清除错误。
ClearCommError(obj->hCom, &Error, &cs);
if (TRUE == Status //等待事件成功
&& WaitEvent&EV_RXCHAR//缓存中有数据到达
&& cs.cbInQue > 0)//有数据
{
Bytes = 0;
obj->m_ovRead.Offset = 0;
memset(ReadBuf, 0, sizeof(ReadBuf));
/*
BOOL ReadFile(
HANDLE hFile, //串口的句柄
LPVOID lpBuffer,// 读入的数据存储的地址,即读入的数据将存储在以该指针的值为首地址的一片内存区
DWORD nNumberOfBytesToRead,// 要读入的数据的字节数
LPDWORD lpNumberOfBytesRead,// 指向一个DWORD数值,该数值返回读操作实际读入的字节数
LPOVERLAPPED lpOverlapped // 重叠操作时,该参数指向一个OVERLAPPED结构,同步操作时,该参数为NULL
);
*/
Status = ReadFile(obj->hCom, &ReadBuf, 4096, &Bytes, &obj->m_ovRead);
if (Status != FALSE)
{
printf("收到 :");
for (i = 0; i < Bytes; i++)
{
printf("%d ", ReadBuf[i]);
}
printf("\n");
}
//PurgeComm函数清空串口的输入输出缓冲区
PurgeComm(obj->hCom, PURGE_RXCLEAR | PURGE_RXABORT);
}
}
return 0;
}
void My_Com::Close_Com()
{
m_IsOpen = false;
if (INVALID_HANDLE_VALUE != hCom)
{
CloseHandle(hCom);
hCom = INVALID_HANDLE_VALUE;
}
if (NULL != m_ovRead.hEvent)
{
CloseHandle(m_ovRead.hEvent);
m_ovRead.hEvent = NULL;
}
if (NULL != m_ovWrite.hEvent)
{
CloseHandle(m_ovWrite.hEvent);
m_ovWrite.hEvent = NULL;
}
if (NULL != m_ovWait.hEvent)
{
CloseHandle(m_ovWait.hEvent);
m_ovWait.hEvent = NULL;
}
if (NULL != m_Thread)
{
WaitForSingleObject(m_Thread, 5000);//等待线程结束
CloseHandle(m_Thread);
m_Thread = NULL;
}
}
LPCWSTR stringToLPCWSTR(std::string orig)
{
size_t origsize = orig.length() + 1;
const size_t newsize = 100;
size_t convertedChars = 0;
wchar_t *wcstring = (wchar_t *)malloc(sizeof(wchar_t)*(orig.length() - 1));
mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);
return wcstring;
}

Huster_Mark
- 粉丝: 13
最新资源
- CAD图书馆源文件-长86.6米 宽64.9米 5层某市图书馆电气施工图设计 11275平米框架结构.zip
- 一套精细园林广场施工详图-公园广场景观CAD平面方案立面节点大样施工图.zip
- CAD图书馆源文件-某高校图书馆方案.zip
- 园林广场规划总平面图-公园广场景观CAD平面方案立面节点大样施工图.zip
- 岩石园绿化-公园广场景观CAD平面方案立面节点大样施工图.zip
- 鑫唐佳苑规划总平面图-公园广场景观CAD平面方案立面节点大样施工图.zip
- 花园施工图纸-公园广场景观CAD平面方案立面节点大样施工图.zip
- 办公室CAD布局方案-直播公司办公室平面布置图.zip
- 办公室CAD布局方案-办公室平面布置图_施工图.zip
- 世园会主题外环境绿化施工图-公园广场景观CAD平面方案立面节点大样施工图.zip
- 宫廷花园景观总平面图-公园广场景观CAD平面方案立面节点大样施工图.zip
- CAD图书馆源文件-长21米 宽15.2米 哈尔滨小型图书馆建筑施工图_t3.zip
- 达川市罗顶寨公园规划-公园广场景观CAD平面方案立面节点大样施工图.zip
- 某县城南佳景步行街景观-公园广场景观CAD平面方案立面节点大样施工图.zip
- 三角岛绿化-公园广场景观CAD平面方案立面节点大样施工图.zip
- 宾馆CAD源文件-长30.4米 宽16.3米 6层单位院内宾馆建筑设计【各层及屋顶平面 3立面 总平 门窗表】.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈


