我用mfc写一个小程序,读取GPS通过串口发送过来的信息,然后像超级终端那样把信息显示出来,现在遇到两个问题:
1.串口我使用重叠模式(非阻塞),创建了一个新的线程来监听串口,读出信息并通过自定义消息发给主线程.我主要用了一个while(1)的循环,发现cpu占用很高,我加上sleep(100),cpu还是会占用到百分之十几二十,sleep(1000)的话,情况就会比较好,但是实时性满足不了,显示出来很卡.我的GPS是5hz,每秒发5次数据.我观察超级终端,他的cpu占用率平均0.X%,而且实时性很好,它是怎样做可以实时监听端口而cpu占用又这么低的?
2.我把读取出来的信息放到editbox上,怎样可以做到像终端那样自动滚屏,保持看到最新的消息?我试过设置edit box的auto scroll,但是没有效.下面是代码
初始化串口的函数:
void CdingweiDlg::OnBnClickedConnectgps()
{
// TODO: Add your control notification handler code here
m_hCom=CreateFile("\\\\.\\COM17",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,NULL);
if(m_hCom ==INVALID_HANDLE_VALUE)
{
MessageBox("打开串口失败!","错误");
return;
}
SetupComm( m_hCom, 1024,1024) ; //设置输入、输出缓冲区的大小
PurgeComm( m_hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR| PURGE_RXCLEAR ); //清干净输入、输出缓冲区

DCB dcb ; // 定义数据控制块结构
GetCommState(m_hCom, &dcb ) ; //读串口原来的参数设置
dcb.BaudRate =38400;
dcb.ByteSize =8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
SetCommState(m_hCom, &dcb ) ; //串口参数配置 COMMTIMEOUTS TimeOuts;
//设定读超时
TimeOuts.ReadIntervalTimeout=1000;
TimeOuts.ReadTotalTimeoutMultiplier=500;
TimeOuts.ReadTotalTimeoutConstant=5000;
//设定写超时
TimeOuts.WriteTotalTimeoutMultiplier=500;
TimeOuts.WriteTotalTimeoutConstant=2000;
SetCommTimeouts(m_hCom,&TimeOuts); //设置超时
DWORD dwThreadID;
m_hCommWatchThread=CreateThread( (LPSECURITY_ATTRIBUTES) NULL, //安全属性
0,//初始化线程栈的大小,缺省为与主线程大小相同
(LPTHREAD_START_ROUTINE)CommWatchProc, //线程的全局函数
GetSafeHwnd(), //此处传入了主框架的句柄
0, &dwThreadID );
if(m_hCommWatchThread==NULL)
{
MessageBox("创建线程失败!");
return;
}}线程函数:
UINT CommWatchProc(HWND hSendWnd)
{
OVERLAPPED READ_OS;
memset(&READ_OS,0,sizeof(OVERLAPPED));
READ_OS.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
COMSTAT ComStat;
DWORD dwErrorFlags;
DWORD dwLength=1024;

while(1)
{
  ClearCommError(m_hCom, &dwErrorFlags, &ComStat);
dwLength = min(dwLength,(DWORD)ComStat.cbInQue);//输入缓冲区的数据长度
BOOL fReadStat;
  fReadStat=ReadFile(m_hCom,lpInBuffer,dwLength, &dwLength,&READ_OS);//读数据
if (!fReadStat)
{
if (GetLastError() == ERROR_IO_PENDING)
{
WaitForSingleObject(READ_OS.hEvent,2000);
}
}
PurgeComm( m_hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR| PURGE_RXCLEAR ); 
::SendMessage(hSendWnd, COM_RECVDATA, (unsigned int)lpInBuffer,dwLength); 发送自定义消息给主线程,通知读到消息,让主线程显示出来
Sleep(100);
}
return TRUE;
}主线程收到消息回调的函数
LRESULT CdingweiDlg::OnRecvData(WPARAM wParam, LPARAM lParam)
{
CString recvStr((char *)wParam);
m_gpsdata+= recvStr;
UpdateData(false);
return TRUE;
}谢谢各位指教!