VC6多线程串口编程问题

enlonely 2009-12-20 10:55:00
环境:VC6.0 windows xp

思路:通过RS232与单片机进行通讯。例如向单片机发送命令测试某个数据,如电压。然后返回测得的值。在PC端显示出来。
我想单独开个线程一直在那监听是否有从单片机返回数据。如果有数据就保存成TXT文件并且在CEDIT控件上显示出来。
但是,现在问题是这样,编译运行没问题。就是我开的那个线程要干的工作一点都没有做。不知道是怎么回事?劳驾各位帮忙看看。谢谢了。程序说明:我是根据孙鑫的VC视频教程15讲做的多线程。多线程部分用到的代码片段如下:

//定义消息
#define WM_RECVDATA WM_USER+1
//创建的线程和主进程共用窗口
struct RECVPARAM
{
HWND hwnd;
};

afx_msg void OnRecvData(WPARAM wParam,LPARAM lParam);//消息响应函数原型声明
ON_MESSAGE(WM_RECVDATA,OnRecvData)//消息映射


//下面这段代码放在初始化中的
RECVPARAM *pRecvParam=new RECVPARAM;
pRecvParam->hwnd=m_hWnd;
hThread = CreateThread(NULL,0,ReadDataProc,(LPVOID)pRecvParam,
CREATE_SUSPENDED,//串口还没打开,故该线程暂时不运行
NULL);
CloseHandle(hThread);

DWORD WINAPI CSerialRS232Dlg::ReadDataProc(LPVOID lpParameter)
{
HWND hwnd=((RECVPARAM*)lpParameter)->hwnd;
delete lpParameter;
CString RecvData;

OVERLAPPED m_osRead;
memset(&m_osRead,0,sizeof(OVERLAPPED));
m_osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

COMSTAT ComStat;
DWORD dwErrorFlags;

char str[100];
memset(str,'\0',100);

DWORD dwBytesRead=100;//读取的字节数
BOOL bReadStat;

ClearCommError(hCom,&dwErrorFlags,&ComStat);
dwBytesRead=min(dwBytesRead, (DWORD)ComStat.cbInQue);

while(true)
{
bReadStat=ReadFile(hCom,str,
dwBytesRead,&dwBytesRead,&m_osRead);
if(!bReadStat)
{
if(GetLastError()==ERROR_IO_PENDING)
//GetLastError()函数返回ERROR_IO_PENDING,表明串口正在进行读操作
{
WaitForSingleObject(m_osRead.hEvent,2000);
//使用WaitForSingleObject函数等待,直到读操作完成或延时已达到2秒钟
//当串口读操作进行完毕后,m_osRead的hEvent事件会变为有信号
}
}

//把接收到的数据以字符的形式保存到文件,每一行以"\n"结束
RecvData = str;
if(!RecvData.IsEmpty())//收到非空的数据时保存
{
::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)str);
memset(str,'\0',100);
}

PurgeComm(hCom, PURGE_TXABORT|
PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
}

return 0;
}

void CSerialRS232Dlg::OnRecvData(WPARAM wParam,LPARAM lParam)
{
FILE *fpData;//保存收到的数据
CString ErrorCode;
CString sTime,strSend;
strSend = (char *)lParam;

if((fpData = fopen("data.txt","a+")) == NULL)
{
ErrorCode.Format("Open data.txt error!");
return -1;
}

if(fprintf(fpData,"%s\n",strSend) == NULL)
{
ErrorCode.Format("Appending data error!");
return -1;
}

SYSTEMTIME sysTime;
GetLocalTime(&sysTime);
sTime.Format("%d.%d.%d %02d:%02d:%02d Sending Command:%s\r\n",sysTime.wYear,sysTime.wMonth,sysTime.wDay,
sysTime.wHour,sysTime.wMinute,sysTime.wSecond,strSend);
m_Message.SetSel(-1,-1);
m_Message.ReplaceSel(sTime);
}


...全文
487 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
vclongking 2009-12-22
  • 打赏
  • 举报
回复
学习
zhou1xp 2009-12-22
  • 打赏
  • 举报
回复
我晕,楼主你自己到MSDN去查那两个函数啊,我是用的同步,但你自己改下你的程序就行了,到这个地步是要自己写了啊,不可能我给你改完整个代码啊
enlonely 2009-12-22
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 zhou1xp 的回复:]
我晕,楼主你自己到MSDN去查那两个函数啊,我是用的同步,但你自己改下你的程序就行了,到这个地步是要自己写了啊,不可能我给你改完整个代码啊
[/Quote]
我说的消息响应函数值的是在执行完::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)str);之后。系统收到WM_RECVDATA消息之后所调用的函数。也就是我写的CSerialRS232Dlg::OnRecvData(WPARAM wParam,LPARAM lParam)
enlonely 2009-12-22
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 gerrade 的回复:]
建议楼主加断点调试,我前段时间也做过多线程的收发,思路和你差不多,最后利用断点调试才发现是readfile的问题,那后面的数据处理就更没发执行了
[/Quote]
我调试的时候一直在while循环里挑不出来,没发现有错误。你的readfile那里出错了啊?
enlonely 2009-12-22
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 zhou1xp 的回复:]
我晕,楼主你自己到MSDN去查那两个函数啊,我是用的同步,但你自己改下你的程序就行了,到这个地步是要自己写了啊,不可能我给你改完整个代码啊
[/Quote]
查过了,在读写之前加了SetCommMask,在Wile循环里加了WaitCommEvent。现在的问题是消息响应函数没执行到。
GERRADE 2009-12-22
  • 打赏
  • 举报
回复
建议楼主加断点调试,我前段时间也做过多线程的收发,思路和你差不多,最后利用断点调试才发现是readfile的问题,那后面的数据处理就更没发执行了
nwao7890 2009-12-21
  • 打赏
  • 举报
回复
也遇到过类似问题,关注
zhou1xp 2009-12-21
  • 打赏
  • 举报
回复
楼主你这用的是一个异步读取的方式,这不是监听程序,你应该去查一下这两个函数,SetCommMask(),这是一个
设置串口等待接受数据信号的函数,在读的线程用WaitCommEvent()来查询是否有数据读入,如果有线程才开始执行,否则堵塞
wangk 2009-12-21
  • 打赏
  • 举报
回复
这个要看单片机的行为模式了,如果必须你发一个测量命令,它才会回应一个结果的话,你必须要定时给它发测量命令。

如果发一个测量命令,它会一直报告结果,需要你发停止命令的结束话,那你也要初始化的时候发生测量命令,不需要测量时(比如进程退出),发送停止命令
enlonely 2009-12-21
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 zhou1xp 的回复:]
哦,我说明白一点, if (!SetCommMask(hSerial, EV_RXCHAR))
      {
          AfxMessageBox(TEXT("不能设置数据接收事件!"));
      } 
  PurgeComm(hSerial,PURGE_TXCLEAR|PURGE_RXCLEAR);
这是设在打开串口的程序中,
bool flag=WaitCommEvent(hSerial, &dwCommStatus, 0);这个加到你的 while(true)

循环中,我以前就是这样写监听的,你自己在看下程序,不要用CEvent和WaitForSingleObject()这个是异步读取方式,不是监听,楼主自己在看下程序,这样是没有问题的
[/Quote]
可是我打开串口的方式是异步的啊
	hCom = CreateFile(m_strCurrentCom,//打开当前端口
GENERIC_READ|GENERIC_WRITE,//读写
0,//独占
NULL,
OPEN_EXISTING,//打开
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,//重叠
NULL);
zhou1xp 2009-12-21
  • 打赏
  • 举报
回复
哦,我说明白一点, if (!SetCommMask(hSerial, EV_RXCHAR))
{
AfxMessageBox(TEXT("不能设置数据接收事件!"));
}
PurgeComm(hSerial,PURGE_TXCLEAR|PURGE_RXCLEAR);
这是设在打开串口的程序中,
bool flag=WaitCommEvent(hSerial, &dwCommStatus, 0);这个加到你的 while(true)

循环中,我以前就是这样写监听的,你自己在看下程序,不要用CEvent和WaitForSingleObject()这个是异步读取方式,不是监听,楼主自己在看下程序,这样是没有问题的
enlonely 2009-12-21
  • 打赏
  • 举报
回复
感觉没有进入到消息响应函数里头去。。
enlonely 2009-12-21
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 zhou1xp 的回复:]
楼主你这用的是一个异步读取的方式,这不是监听程序,你应该去查一下这两个函数,SetCommMask(),这是一个
设置串口等待接受数据信号的函数,在读的线程用WaitCommEvent()来查询是否有数据读入,如果有线程才开始执行,否则堵塞
[/Quote]
我加进去这两函数了,但是貌似就没有进入我创建的线程执行似得。不知道是怎么回事?
enlonely 2009-12-21
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wangk 的回复:]
这个要看单片机的行为模式了,如果必须你发一个测量命令,它才会回应一个结果的话,你必须要定时给它发测量命令。

如果发一个测量命令,它会一直报告结果,需要你发停止命令的结束话,那你也要初始化的时候发生测量命令,不需要测量时(比如进程退出),发送停止命令
[/Quote]
恩,不过现在问题不在单片机上。不管单片机什么模式,我的目的是要监听是否有数据到来。

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧