我在程序启动时,把串口打开的过程放到了一个多线程里, 运行时串口可以正常打开,也可以发送数据,但是接收不到设备返回的数据。
要是不放在多线程里,在OnInitDialog里打开串口,就可以正常的发送和接收。怎么才能解决?我是因为要同时打开多个串口,但是如果都放在OnInitDialog里打开,如果有一个串口是无效的那程序就停止在那里了,所以我才想在多线程里同时打开多个串口。不知道这样做对不对,或者还有别的方法??请诸位高手帮帮忙。
这么打开虽然可以正常接收到数据,但是如果COM8是无效的,那就直接弹出错误信息,程序就停了。
BOOL CTestDlg::OnInitDialog()
{
m_com2.SetCommPort(8);
m_com2.SetSettings("9600,n,8,1");
m_com2.SetInputLen(0);
m_com2.SetInputMode(1);
m_com2.SetRThreshold(1);
m_com2.SetInBufferSize(1024); //接收缓冲区
m_com2.SetOutBufferSize(1024);//发送缓冲区
m_com2.SetPortOpen(TRUE);
m_com2.GetInput(); m_com3.SetCommPort(9);
m_com3.SetSettings("9600,n,8,1");
m_com3.SetInputLen(0);
m_com3.SetInputMode(1);
m_com3.SetRThreshold(1);
m_com3.SetInBufferSize(1024); //接收缓冲区
m_com3.SetOutBufferSize(1024);//发送缓冲区
m_com3.SetPortOpen(TRUE);
m_com3.GetInput();}这个是我在OnInitDialog里启动多线程打开串口
BOOL CTestDlg::OnInitDialog()
{
AfxBeginThread(Thread_OpenCom2, this, THREAD_PRIORITY_NORMAL);
}UINT CTestDlg::Thread_OpenCom2(LPVOID lParam)
{
CTestDlg* p=(CTestDlg*)lParam; // this if(p->m_com2.GetPortOpen())
{
p->m_com2.SetPortOpen(FALSE);
}
p->m_com2.SetCommPort(8);
p->m_com2.SetSettings("9600,n,8,1");
p->m_com2.SetInputLen(0);
p->m_com2.SetInputMode(1);
p->m_com2.SetRThreshold(1);
p->m_com2.SetInBufferSize(1024); //接收缓冲区
p->m_com2.SetOutBufferSize(1024);//发送缓冲区
p->m_com2.SetPortOpen(TRUE);
p->m_com2.GetInput(); return 9999;
}
这么打开的话 同时打开4个 即使有1个串口时无效的也不会影响其它的,但是却不能接收到模块返回的数据了。我是初学者,恳请诸位帮帮忙。问题出现在哪里??
要是不放在多线程里,在OnInitDialog里打开串口,就可以正常的发送和接收。怎么才能解决?我是因为要同时打开多个串口,但是如果都放在OnInitDialog里打开,如果有一个串口是无效的那程序就停止在那里了,所以我才想在多线程里同时打开多个串口。不知道这样做对不对,或者还有别的方法??请诸位高手帮帮忙。
这么打开虽然可以正常接收到数据,但是如果COM8是无效的,那就直接弹出错误信息,程序就停了。
BOOL CTestDlg::OnInitDialog()
{
m_com2.SetCommPort(8);
m_com2.SetSettings("9600,n,8,1");
m_com2.SetInputLen(0);
m_com2.SetInputMode(1);
m_com2.SetRThreshold(1);
m_com2.SetInBufferSize(1024); //接收缓冲区
m_com2.SetOutBufferSize(1024);//发送缓冲区
m_com2.SetPortOpen(TRUE);
m_com2.GetInput(); m_com3.SetCommPort(9);
m_com3.SetSettings("9600,n,8,1");
m_com3.SetInputLen(0);
m_com3.SetInputMode(1);
m_com3.SetRThreshold(1);
m_com3.SetInBufferSize(1024); //接收缓冲区
m_com3.SetOutBufferSize(1024);//发送缓冲区
m_com3.SetPortOpen(TRUE);
m_com3.GetInput();}这个是我在OnInitDialog里启动多线程打开串口
BOOL CTestDlg::OnInitDialog()
{
AfxBeginThread(Thread_OpenCom2, this, THREAD_PRIORITY_NORMAL);
}UINT CTestDlg::Thread_OpenCom2(LPVOID lParam)
{
CTestDlg* p=(CTestDlg*)lParam; // this if(p->m_com2.GetPortOpen())
{
p->m_com2.SetPortOpen(FALSE);
}
p->m_com2.SetCommPort(8);
p->m_com2.SetSettings("9600,n,8,1");
p->m_com2.SetInputLen(0);
p->m_com2.SetInputMode(1);
p->m_com2.SetRThreshold(1);
p->m_com2.SetInBufferSize(1024); //接收缓冲区
p->m_com2.SetOutBufferSize(1024);//发送缓冲区
p->m_com2.SetPortOpen(TRUE);
p->m_com2.GetInput(); return 9999;
}
这么打开的话 同时打开4个 即使有1个串口时无效的也不会影响其它的,但是却不能接收到模块返回的数据了。我是初学者,恳请诸位帮帮忙。问题出现在哪里??
这个控件似乎是收到数据自动发送消息的吧,你要收到消息后,在消息处理函数里去进行接收工作
而你打开串口后马上紧接着GetInput()是什么意思?打开就已经有数据了?那后来的数据呢?不要了?
在单线程的情况下,接收串口数据是在串口控件消息响应函数OnComm()中进行接收数据的工作你要在其他线程里打开串口,接收数据,就得处理好读取的问题,要么根据消息去读取,要么就线程死读取(最好是中间sleep一下,不然容易高占用CPU)。
打开正确的串口后,后面的事情就很简单了。
自己建立一个通信机制来判断设备连接
另外打开串口会阻塞么?
为什么在OnInitDialog里不行呢
这样在串口不存在或是串口不可用的时候,你去打开程序就不会down掉了。
这是我以前的代码,和这个类似:
try {
m_mscomm.put__CommPort(m_portNum);
m_mscomm.put_InBufferSize(256); //设置输入和输出缓存的大小
m_mscomm.put_OutBufferSize(256);
if(!m_mscomm.get_PortOpen())
{
m_mscomm.put_PortOpen(TRUE);
m_mscommable = TRUE;
}
else
{
m_mscommable = FALSE;
}
m_mscommable = true;
} catch(COleDispatchException *e)
{
m_mscommable = false;
CString port; if(e->m_dwHelpContext == 8005)
{ port.Format(_T("串口COM%d已被占用"), m_portNum);
}
else if(e->m_dwHelpContext == 8002){
port.Format(_T("串口COM%d不存在"), m_portNum);
}
else {
port.Format(_T("串口COM%d打开时操作不合法"), m_portNum);
} MessageBox(port, _T("提示"), MB_OK | MB_ICONWARNING );
return false;
}
感谢回答
打开串口后马上紧接着GetInput()
是清空缓存空间用的,例子上也是这么写的,不是我乱加上的。