线程读串口的问题 我用的API写的串口读写,在读串口的时候用线程实时读取,然后用虚拟串口工具设置两个串口COM1 COM2,用程序打开COM1,用串口调试工具打开COM2,2者进行串口通信,发现在程序读数据的时候,每次都要先写一次,这是为什么???? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 HWND hwnd = (HWND)pParam; while(true) { OVERLAPPED os; memset(&os,0,sizeof(OVERLAPPED)); os.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); DWORD dwMask,dwTrans,dwError=0; if(!WaitCommEvent(m_hComm,&dwMask,&os)) { if(ERROR_IO_PENDING==GetLastError()) GetOverlappedResult(m_hComm,&os,&dwTrans,true); } WaitForSingleObject(os.hEvent,INFINITE); if (dwMask==EV_RXCHAR) { ::SendMessage(hwnd,WM_COMM_RXCHAR,0,0); } }这是我的读线程 hello 详细在这里:http://topic.csdn.net/u/20120604/15/4ae6674d-2ec8-4213-8a99-39fc227a4c51.html#r_achor //打开串口void OpenComm(){ if(bIfopen) AfxMessageBox("串口已经打开!"); else { hCom = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING, FILE_FLAG_OVERLAPPED,NULL); //创建串口,异步方式 if (hCom == INVALID_HANDLE_VALUE) AfxMessageBox("打开串口失败!"); else { bIfopen = TRUE; SetCommMask( hCom, EV_RXCHAR|EV_TXEMPTY ); //设置串口事件 SetupComm( hCom, 4096,4096); //设置读写缓冲区大小 PurgeComm( hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); COMMTIMEOUTS comTimeOut; //设置超时 comTimeOut.ReadIntervalTimeout = 100; //两字符之间最大的延时 comTimeOut.ReadTotalTimeoutMultiplier = 50; //读取每字符间的超时 comTimeOut.ReadTotalTimeoutConstant = 1000; //一次读取串口数据的固定超时 comTimeOut.WriteTotalTimeoutMultiplier = 50; //写入每字符间的超时 comTimeOut.WriteTotalTimeoutConstant = 1000; //一次写入串口数据的固定超时 SetCommTimeouts(hCom,&comTimeOut); DCB dcb; GetCommState(hCom, &dcb ); //串口设置 dcb.BaudRate = 9600; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; dcb.fBinary = TRUE; dcb.fParity = FALSE; SetCommState( hCom, &dcb ); } }} //读取数据int ReadComm(int inum, BYTE* bdata ){ DWORD dwRes; DWORD dwDataRead; Read_OS.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if ( NULL == Read_OS.hEvent) return -1; if (ReadFile(hCom, bdata, inum, NULL, &Read_OS)) return 0; //成功读出 else { dwRes = WaitForSingleObject(Read_OS.hEvent, 5000); //设置5秒超时 switch(dwRes) { case WAIT_OBJECT_0: if (!GetOverlappedResult(hCom, &Read_OS, &dwDataRead, TRUE)) { //操作失败,可用GetLastError()获取失败信息 return 1; } else { //成功 return 0; } break; case WAIT_TIMEOUT: //超时 return 2; break; default: return 3; break; } } CloseHandle(Read_OS.hEvent); return 0;} //以事件驱动的读线程DWORD TheardEvent(LPVOID pParam){ BOOL bCommState = TRUE; DWORD deEvtMask, dwRes, dwLength; DWORD dwErrors; COMSTAT ComStat; int i; CString str; BOOL bifwan = FALSE; BYTE bmydata[25]; OS.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); while (bCommState) { WaitCommEvent(hCom, &deEvtMask, &OS); dwRes = WaitForSingleObject(OS.hEvent, INFINITE); if(WAIT_OBJECT_0 == dwRes) { if(EV_RXCHAR == deEvtMask) { ClearCommError(hCom, &dwErrors, &ComStat); dwLength = ComStat.cbInQue; if (dwLength > 0) { ReadComm(dwLength, bmydata); } memcpy(&Buffer[igbal], bmydata, dwLength); igbal += dwLength; for (i=0; i<(int)dwLength; i++) { if(0x16 == bmydata[i]) bifwan = TRUE; } if(bifwan) { ::PostMessage(HWND(mainhandle), WM_DEBUG, 0, 0); bifwan = FALSE; } } } } return 0;} 呵呵,好吧,同情一下lz,为什么你当时不用两个串口工具互相通讯试试呢?赞一下,lz的串口编程调试方法很好--用虚拟串口和串口调试软件。 进程外Com组件实现 请问‘a’和_T('a')有区别吗?注意是单引号 有两个EDITBOX如何让一个显示,另一个即时显示第一个的内容? 成都招聘软件工程师 关于DLL和COM 字体不按照要求显示,请高手们看一下我的代码问题在哪里? 关于Botton的问题 VC新手提一个添加新对话框的问题,请高手前辈指教! 请问关于热插拔硬件插拔消息在win98和win2000中有什么不同? MFC串口编程,get_input()函数意外退出 商业软件是以哦那个GNU/GPL下的图片的问题? 在繁体系统下开发的程序,在简体系统打开为乱码(汉字)
HWND hwnd = (HWND)pParam;
while(true)
{
OVERLAPPED os;
memset(&os,0,sizeof(OVERLAPPED));
os.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
DWORD dwMask,dwTrans,dwError=0;
if(!WaitCommEvent(m_hComm,&dwMask,&os))
{
if(ERROR_IO_PENDING==GetLastError())
GetOverlappedResult(m_hComm,&os,&dwTrans,true);
}
WaitForSingleObject(os.hEvent,INFINITE);
if (dwMask==EV_RXCHAR)
{
::SendMessage(hwnd,WM_COMM_RXCHAR,0,0);
}
}这是我的读线程
详细在这里:
http://topic.csdn.net/u/20120604/15/4ae6674d-2ec8-4213-8a99-39fc227a4c51.html#r_achor
//打开串口
void OpenComm()
{
if(bIfopen)
AfxMessageBox("串口已经打开!");
else
{
hCom = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING, FILE_FLAG_OVERLAPPED,NULL); //创建串口,异步方式
if (hCom == INVALID_HANDLE_VALUE)
AfxMessageBox("打开串口失败!");
else
{
bIfopen = TRUE;
SetCommMask( hCom, EV_RXCHAR|EV_TXEMPTY ); //设置串口事件
SetupComm( hCom, 4096,4096); //设置读写缓冲区大小
PurgeComm( hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );
COMMTIMEOUTS comTimeOut; //设置超时
comTimeOut.ReadIntervalTimeout = 100; //两字符之间最大的延时
comTimeOut.ReadTotalTimeoutMultiplier = 50; //读取每字符间的超时
comTimeOut.ReadTotalTimeoutConstant = 1000; //一次读取串口数据的固定超时
comTimeOut.WriteTotalTimeoutMultiplier = 50; //写入每字符间的超时
comTimeOut.WriteTotalTimeoutConstant = 1000; //一次写入串口数据的固定超时
SetCommTimeouts(hCom,&comTimeOut);
DCB dcb;
GetCommState(hCom, &dcb ); //串口设置
dcb.BaudRate = 9600;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fBinary = TRUE;
dcb.fParity = FALSE;
SetCommState( hCom, &dcb );
}
}
}
//读取数据
int ReadComm(int inum, BYTE* bdata )
{
DWORD dwRes;
DWORD dwDataRead; Read_OS.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if ( NULL == Read_OS.hEvent)
return -1; if (ReadFile(hCom, bdata, inum, NULL, &Read_OS))
return 0; //成功读出
else
{
dwRes = WaitForSingleObject(Read_OS.hEvent, 5000); //设置5秒超时
switch(dwRes)
{
case WAIT_OBJECT_0:
if (!GetOverlappedResult(hCom, &Read_OS, &dwDataRead, TRUE))
{
//操作失败,可用GetLastError()获取失败信息
return 1;
}
else
{
//成功
return 0;
}
break;
case WAIT_TIMEOUT:
//超时
return 2;
break;
default:
return 3;
break;
}
} CloseHandle(Read_OS.hEvent);
return 0;
}
//以事件驱动的读线程
DWORD TheardEvent(LPVOID pParam)
{
BOOL bCommState = TRUE;
DWORD deEvtMask, dwRes, dwLength;
DWORD dwErrors;
COMSTAT ComStat;
int i;
CString str;
BOOL bifwan = FALSE;
BYTE bmydata[25]; OS.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
while (bCommState)
{
WaitCommEvent(hCom, &deEvtMask, &OS);
dwRes = WaitForSingleObject(OS.hEvent, INFINITE);
if(WAIT_OBJECT_0 == dwRes)
{
if(EV_RXCHAR == deEvtMask)
{
ClearCommError(hCom, &dwErrors, &ComStat);
dwLength = ComStat.cbInQue; if (dwLength > 0)
{
ReadComm(dwLength, bmydata);
} memcpy(&Buffer[igbal], bmydata, dwLength);
igbal += dwLength; for (i=0; i<(int)dwLength; i++)
{
if(0x16 == bmydata[i])
bifwan = TRUE;
} if(bifwan)
{
::PostMessage(HWND(mainhandle), WM_DEBUG, 0, 0);
bifwan = FALSE;
} }
}
}
return 0;
}