vs2008 c++ 串口通讯 只要调用WaitCommEvent等待,再点发送,程序立马死机,求大侠指正

lh1611 2012-03-09 02:28:47
串口打开部分:
  hCom=CreateFile("COM1",//COM1口
GENERIC_READ|GENERIC_WRITE, //允许读和写
0, //独占方式
NULL,
OPEN_EXISTING, //打开而不是创建
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, //重叠方式
NULL);
if(hCom==(HANDLE)-1)
{
AfxMessageBox("打开COM失败!");
return FALSE;
}

SetupComm(hCom,100,100); //输入缓冲区和输出缓冲区的大小都是100

COMMTIMEOUTS TimeOuts;
//设定读超时
TimeOuts.ReadIntervalTimeout=MAXDWORD;
TimeOuts.ReadTotalTimeoutMultiplier=0;
TimeOuts.ReadTotalTimeoutConstant=0;
//在读一次输入缓冲区的内容后读操作就立即返回,
//而不管是否读入了要求的字符。


//设定写超时
TimeOuts.WriteTotalTimeoutMultiplier=100;
TimeOuts.WriteTotalTimeoutConstant=500;
SetCommTimeouts(hCom,&TimeOuts); //设置超时

DCB dcb;
GetCommState(hCom,&dcb);
dcb.BaudRate=9600; //波特率为9600
dcb.ByteSize=8; //每个字节有8位
dcb.Parity=NOPARITY; //无奇偶校验位
dcb.StopBits=TWOSTOPBITS; //两个停止位
SetCommState(hCom,&dcb);

//设置缓冲区
SetupComm(hComPort,1024,0);
//清空缓冲区
PurgeComm(hComPort,PURGE_RXCLEAR|PURGE_TXCLEAR);
//设置事件集
BOOL fSuccess = SetCommMask(hComPort, EV_BREAK|EV_RXCHAR);

//设置超时机制
COMMTIMEOUTS CommTimeouts;
GetCommTimeouts(hComPort, &CommTimeouts);

//改变COMMTIMEOUTS结构设置
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.WriteTotalTimeoutMultiplier = 1000;
CommTimeouts.WriteTotalTimeoutConstant = 1000;
if(!SetCommTimeouts(hComPort,&CommTimeouts))
return;
EscapeCommFunction(hComPort,SETDTR);
EscapeCommFunction(hComPort,SETRTS);

m_recvHandle = CreateThread(NULL,0,ReceiveProc,NULL,0,NULL); //1,运行接收线程

串口发送部分
//打开串口后发送数据
OVERLAPPED m_osWrite;
memset(&m_osWrite,0,sizeof(OVERLAPPED));
m_osWrite.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);


char lpOutBuffer[7];
memset(lpOutBuffer,'\0',7);
lpOutBuffer[0]='\x11';
lpOutBuffer[1]='0';
lpOutBuffer[2]='0';
lpOutBuffer[3]='1';
lpOutBuffer[4]='0';
lpOutBuffer[5]='1';
lpOutBuffer[6]='\x03';

DWORD dwBytesWrite=7;
COMSTAT ComStat;
DWORD dwErrorFlags;
BOOL bWriteStat;
ClearCommError(hComPort,&dwErrorFlags,&ComStat);
bWriteStat=WriteFile(hComPort,lpOutBuffer,dwBytesWrite,& dwBytesWrite,&m_osWrite); //程序死的地方
接收线程:DWORD CPlcDlg::ReceiveProc(LPVOID lp)
{
DWORD myevent;
// char *mybuf; //转移成全局变量
DWORD midnum, error, actualnum;
// COMSTAT mystate; //转移成全局变量

//清空缓冲区
PurgeComm(m_handle,PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
//设置事件集
SetCommMask(m_handle, EV_BREAK|EV_RXCHAR);
while(TRUE)
{
if(WaitCommEvent(m_handle, &myevent, NULL))
{
SetCommMask(m_handle, EV_BREAK|EV_RXCHAR);
if(myevent & EV_RXCHAR)
{
AfxMessageBox("事情到了!"); //加入处理函数
              }
         }


}

return 0;
}


//状态::如果我不打开接收线程,那么我的程序发送数据正常,即把启动线程注释掉
     如果启动线程,那么只要不点发送按钮,给串口发送字符,那么程序也不会死,并且接收线程运行正常,接收到字符,它会弹出对话框,表示事件到了.
     问题是,如果启动线程,并且点了发送按钮,给串口发送了字符,那么在发送字符那里,程序将永远死去.

问各位大牛,如何解决啊,串口通讯别的方法我用过了,总觉得还是事件触发好,但就是调不通,希望指点
...全文
533 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
aa136800 2012-05-05
  • 打赏
  • 举报
回复
头文件有哪些?
lh1611 2012-03-20
  • 打赏
  • 举报
回复
主要问题是我的程序在等待事件发生,但我看到别人写的串口程序也是这样写的,但不存在我这种问题,就是说必须发一个,收一个,这样的顺序.
lh1611 2012-03-20
  • 打赏
  • 举报
回复
我知道那是个死循环,但是那个死循环不是一直运行的,它是在等待事件的发生,并不占用资源,所以我没有感觉程序很卡,我的程序之所以运行停止,是因为在等待事件,呵呵,我是这样理解的.
lh1611 2012-03-14
  • 打赏
  • 举报
回复
这个问题怎么没有人回答啊,我感觉好像是线程挂起了,只有串口接收到一个数据以后,我的发送按钮才能醒过来,这个时候点发送,串口可以把数据成功发送出.也就是说,必须严格遵守一收一发,一收一发,只有串口收到数据后,我的发送按钮才能醒过来.为什么啊,求解.
chenmeng19850123 2012-03-14
  • 打赏
  • 举报
回复
你启动线程后,那个死循环就会占满资源,你没发现程序变卡了吗?

还有if(WaitCommEvent(m_handle, &myevent, NULL))这个函数是可以设置等到时间的,你试试看

7,540

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 VC.NET
社区管理员
  • VC.NET社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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