串口通信中使用SendMessage发现问题,请高手指点。
我建一个串口类
class CCom
{
.
.
CCom() { m_bComOpen=FALSE; };
BOOL m_bComOpen
CWinThread * m_Thread;
init(...); //初始化
static UINT ComThread(LPCIOD lp); //监视线程
RecChar(); //在线程中的有接收事件时调用此函数读数据,并SendMessage 发到窗口。
.
.
}
要求运行中改变串口。
我在init()中
...
if (m_bComOpen)
{
m_bComOpen=FALSE;
SetEvent(m_hShutdownEvent);
WaitForSingleObject(m_Thread->m_hThread,INFINITE);
delete m_Thread;
}
...打开串口并配置
if (!(m_Thread = AfxBeginThread(CommThread, this)))
{
m_bComOpen=FALSE;
return FALSE;
}else
{
m_Thread->m_bAutoDelete=FALSE;
m_bComOpen=TRUE;
return TRUE;
}
在ComThread(LPCIOD lp)中
...
m_hEventArray[0] = m_hShutdownEvent; // 高优先级
m_hEventArray[1] = m_ov.hEvent;
Event = WaitForMultipleObjects(2, port->m_hEventArray, FALSE,INFINITE);
switch (Event)
{
case 0: //退出线程 init()中 SetEvent(m_hShutdownEvent);
return 0;
break;
case 1: // read event
GetCommMask(port->m_hComm, &CommEvent);
if (CommEvent & EV_RXCHAR) // Receive character event from port.
RecChar(port, comstat);
break;
}
在RecChar()中
...
while (1)
{
EnterCriticalSection(&port->m_csCommunicationSync);
bResult = ClearCommError(port->m_hComm, &dwError, &comstat);
LeaveCriticalSection(&port->m_csCommunicationSync);
if (comstat.cbInQue == 0)
break;
EnterCriticalSection(&port->m_csCommunicationSync);
bResult = ReadFile(port->m_hComm,&RXBuff, 1,&BytesRead,&port->m_ov);
bResult = GetOverlappedResult(port->m_hComm, &port->m_ov,&BytesRead,TRUE);
if (!bResult)
{
port->Error("GetOverlappedResults() in ReadFile()");
}
LeaveCriticalSection(&port->m_csCommunicationSync);
::SendMessage((port->m_hWnd, WM_COMM_RXCHAR,
(WPARAM) RXBuff,LPARAM port->m_nPort);
}
程序中改变串口时时用init()
!!!!!!!!当接收大量数据时,有时程序停在SendMessage处,界面没反映。(用PostMessage不行)
问题点数:20、回复次数:22Top
1 楼auly403(卡西*丁布)回复于 2004-11-03 08:20:12 得分 0
upTop
2 楼fu256(大圣)回复于 2004-11-11 21:11:54 得分 0
怎么没有高手回答???Top
3 楼woweijunge(花弄影)回复于 2004-11-11 21:50:49 得分 0
你可以借鉴一下子CSerialPort类的写法,改类的源程序在网上可以下载.Top
4 楼fu256(大圣)回复于 2004-11-12 23:41:31 得分 0
woweijunge(花弄影) :
CSerialPort类也有此问题!!!
请大家帮帮忙!!!!!!!!!!!Top
5 楼qzh1119(大浪淘沙)回复于 2004-11-13 16:04:14 得分 0
upTop
6 楼38062708(土豆精)回复于 2004-11-13 18:43:55 得分 0
SendMessage 容易丢消息,而且会中断程序,建议用 PostMessageTop
7 楼Saimen(沉默是金)回复于 2004-11-13 19:24:51 得分 5
当接收大量数据时,有时程序停在SendMessage处,界面没反映。
呵呵,我想问题出来了,SENDMESSAGE 是要等对方执行完了才返回的,估计你这条消息的响应函数出了错.
说不定进了死循环,换角度看问题Top
8 楼fu256(大圣)回复于 2004-11-14 20:23:29 得分 0
void CComTestMDlg::OnComRec(WPARAM wp, LPARAM lp)
{
CString str;
str.Format("%X ",(BYTE)(char)(wp));
m_szRec+=str;
UpdateData(FALSE);
}
没有用循环的.Top
9 楼fu256(大圣)回复于 2004-11-14 20:26:05 得分 0
////////////////////////////////////////////
SendMessage 容易丢消息,而且会中断程序,建议用 PostMessage
////////////////////////////////////////////
会丢数据的!Top
10 楼fu256(大圣)回复于 2004-11-14 20:30:54 得分 0
请大家帮忙!!!!!!!!!!!
我发现SENDMESSAGE 后,还没有调用消息响应函数!就死锁了!
求救!!!Top
11 楼mybios(俊俊哥哥)回复于 2004-11-14 20:41:03 得分 0
线程中不能使用UpdateData(FALSE);的吧??
Top
12 楼AthlonxpX86(一坨屎)回复于 2004-11-14 21:25:53 得分 10
bResult = ReadFile(port->m_hComm,&RXBuff, 1,&BytesRead,&port->m_ov);
我晕,已经不止一个人问到过我这个问题了,你们之间互相抄袭代码???
不死才怪,一次一字节,然后就发消息给窗口,你的效率低到极点,如果串口波特率115k你是不是没秒要发送10k个消息给窗口???
bResult = ReadFile(port->m_hComm,&RXBuff, comstat.cbInQue ,&BytesRead,&port->m_ov);
然后根据上面的修改你的消息函数Top
13 楼fu256(大圣)回复于 2004-11-14 21:27:21 得分 0
////////////////////////////////////////////////////
线程中不能使用UpdateData(FALSE);的吧??
///////////////////////////////////////////////////
是 消息响应函数 !!!
在线等高手
在线等高手
在线等高手
在线等高手Top
14 楼fu256(大圣)回复于 2004-11-14 22:19:30 得分 0
to: AthlonxpX86(桃源村)
你的方法不行!!!
虽然处理次数少了,但问题依然存在,SENDMESSAGE 后,还没有调用消息响应函数!就死了!
在线等高手
Top
15 楼AthlonxpX86(一坨屎)回复于 2004-11-15 17:16:08 得分 0
那就应该是你的窗口问题,检查看看你的窗口中是否有什么代码使自己停止响应消息,另外建议你不要学CSerialPort类那样用消息同志窗口的方法接受数据,因为Windows的消息机制并不是实时的,有时甚至会丢失,因此你用堵塞方式的SENDMESSAGE有时是不能成功的,比如托动一下窗口可能就会使你的这种方式的程序死掉Top
16 楼fu256(大圣)回复于 2004-11-15 23:44:52 得分 0
to: AthlonxpX86(桃源村)
请问你有什么好建议!请多多指教!
我想写一谢通用的类,如串口类,socket类,你说用消息不好,用回调函数\虚函数怎么样?
我的QQ:86363405 Email:86363405@qq.com
谢谢!!!Top
17 楼fu256(大圣)回复于 2004-11-16 03:30:23 得分 0
我用虚函数的方式重写了一下(在原SendMessage处调用虚处理函数).
问题明显减轻.
测试环境 发送数据 325/s
-----------------------------------------------------------------------------------
方式 操作 操作N次数出错 问题
消息 运行时改变串口或程序退出 N=10至20 SENDMESSAGE 后,还没调用消息响
应函数!就死了!
虚函数 运行时改变串口或程序退出 N=100至200 虚处理函数中向列表添加数据时死Top
18 楼kikyang(紫辰)回复于 2004-11-16 03:49:48 得分 5
http://home.ict.nl/~ramklein/Projects/Serial.html
看下这个类,应该比CSerialPort要更好一些。
Top
19 楼AthlonxpX86(一坨屎)回复于 2004-11-16 10:29:24 得分 0
简单说就是异步串行多线程
将SendMessage换成SetEvent(),在你要处理数据的线程中等待这个信号(处理完数据就等待这个信号,有信号就接收数据然后处理数据),当然comstat.cbInQue 要足够大后才引起数据传输,这是为了效率,这也是异步操作的思想所在,每次1字节的话就失去异步操作的真正意义Top
20 楼fu256(大圣)回复于 2004-11-20 20:26:06 得分 0
我想做成通用的类!
现在用虚函数+主意线程同步=基本稳定!
请大家提供更好的方法! 谢谢!!
Top
21 楼fu256(大圣)回复于 2004-11-22 12:25:39 得分 0
请大家关注Top
22 楼fu256(大圣)回复于 2004-11-23 19:53:56 得分 0
请高手关注
Top




