hSerial = CreateFile(L"COM1:",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if(m_hSerial == NULL)
{
///L"串口打开失败";
return;
}
///配置串口
DCB PortDCB;
PortDCB.DCBlength = sizeof(DCB);
// 默认串口参数
GetCommState(hSerial, &PortDCB);
PortDCB.BaudRate = 115200; // baud
PortDCB.ByteSize = 8; // Number of bits/byte, 4-8
PortDCB.Parity = NOPARITY;
PortDCB.StopBits = ONESTOPBIT;
if (! SetCommState(hSerial, &PortDCB))
{
///L"配置串口失败";
return;
}
////配置超时值
COMMTIMEOUTS CommTimeouts;
GetCommTimeouts(m_hSerial, &CommTimeouts);
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
CommTimeouts.ReadTotalTimeoutMultiplier = 10;
CommTimeouts.ReadTotalTimeoutConstant = 10;
CommTimeouts.WriteTotalTimeoutMultiplier = 50;
CommTimeouts.WriteTotalTimeoutConstant = 100;
if (!SetCommTimeouts(hSerial, &CommTimeouts))
{
///L"不能设置超时参数";
return;
} CE的串口驱动不支持重叠,这个大家都知道的。这样的话收和发就要分开。要接收串口数据就必须创建一个线程专门用于接收数据。串口的配置不需要设置很多参数,默认的配置大部分是不需要修改的。一般改动就是波特率、位数、奇偶校检等几项。超时值是需要改动的。ReadIntervalTimeout是指两个字符传送之间的超时时间。一次写操作的超时时间等于WriteTotalTimeoutMultiplier 乘以 要发送的字符数 加上WriteTotalTimeoutConstant。 单位是毫秒。读操作的超时和写类似。所以设置超时是一个关键。设置太小可能丢失数据。if(hSerial != NULL)
{
CloseHandle(hSerial);
hSerial = NULL;
}
三、向串口发送数据 WriteFile (hSerial, // 句柄
&Byte, // 数据缓冲区地址
nByte, // 数据大小
&dwNumBytes, // 返回发送出去的字节数
NULL // 不支持重叠
);
向串口发送数据一般都会成功。需要注意的是如果终端设备需要一定处理时间或者称反应时间的话,那么两个写操作之间一定要注意时间间隔不能太小。具体的时间由终端设备的反应时间和缓冲区大小有关。*** 假设接收的都是字符 ***
UINT ReadThread(LPVOID pParam) ?////接收串口数据线程
{
HANDLE hPort = *(HANDLE*)pParam;
BYTE Byte;
int iCounter = 0;
DWORD dwBytes;
char ReceiveBuf[1000]; ///缓冲区的大小
SetCommMask (hPort, EV_RXCHAR); ///只接收字符
while (hPort != INVALID_HANDLE_VALUE)
{
DWORD dwCommStatus;
WaitCommEvent(hPort, &dwCommStatus, 0);
SetCommMask (hPort, EV_RXCHAR); ///重新设置要等待的信号
//// 接收数据
do
{
ReadFile(hPort, &Byte, 1, &dwBytes, 0);
if(dwBytes == 1)
{
ReceiveBuf[iCounter++] = Byte;
if(iCounter == 1000)
{
///L"接收缓冲区已满";
return -1;
}
}
} while (dwBytes == 1);
if(iCounter == 0) ?////没接到数据
{
continue;
}
//////保存数据
char* pTmp = new char[iCounter + 1];
if(pTmp == NULL)
{
///L"内存不足,接收串口数据线程关闭";
return -1;
}
memcpy(pTmp, ReceiveBuf, iCounter);
pTmp[iCounter] = NULL; ////字符串结尾
////////创建新线程处理数据
////在ProcessData函数中处理数据。别忘了delete[] pTmp;
AfxBeginThread(ProcessData, pTmp);
iCounter = 0; ////清空计数器
} ///////end while
return 0;
}
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/10294527/viewspace-126794/ ,如需转载,请注明出处,否则将追究法律责任。