请教:在多线程里打开串口,可以打开,但是发送数据没有回应

水瓶座雨夕 2010-12-21 05:36:16
我在程序启动时,把串口打开的过程放到了一个多线程里, 运行时串口可以正常打开,也可以发送数据,但是接收不到设备返回的数据。
要是不放在多线程里,在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个串口时无效的也不会影响其它的,但是却不能接收到模块返回的数据了。

我是初学者,恳请诸位帮帮忙。问题出现在哪里??
...全文
284 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
sd6814466 2010-12-22
  • 打赏
  • 举报
回复
MSCOMM控件?
这个控件似乎是收到数据自动发送消息的吧,你要收到消息后,在消息处理函数里去进行接收工作
而你打开串口后马上紧接着GetInput()是什么意思?打开就已经有数据了?那后来的数据呢?不要了?
在单线程的情况下,接收串口数据是在串口控件消息响应函数OnComm()中进行接收数据的工作

你要在其他线程里打开串口,接收数据,就得处理好读取的问题,要么根据消息去读取,要么就线程死读取(最好是中间sleep一下,不然容易高占用CPU)。
Metrosexual 2010-12-22
  • 打赏
  • 举报
回复
++
[Quote=引用 9 楼 wuyan6293 的回复:]
把打开串口的操作放到try catch 里面,
这样在串口不存在或是串口不可用的时候,你去打开程序就不会down掉了。
这是我以前的代码,和这个类似:

C/C++ code
try {
m_mscomm.put__CommPort(m_portNum);
m_mscomm.put_InBufferSize(256); ……
[/Quote]
水瓶座雨夕 2010-12-22
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 wuyan6293 的回复:]
把打开串口的操作放到try catch 里面,
这样在串口不存在或是串口不可用的时候,你去打开程序就不会down掉了。
这是我以前的代码,和这个类似:

C/C++ code
try {
m_mscomm.put__CommPort(m_portNum);
m_mscomm.put_InBufferSize(256); ……
[/Quote]


感谢回答:
非常非常感谢...
水瓶座雨夕 2010-12-22
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 muzizongheng 的回复:]
你的逻辑很有问题, 首先程序应该只占有 有用的资源。 你打开那么多串口,万一有别的设备怎么办? 没意思, 也没效率。

其实正规的通用的方法是: 你从com1开始试, 是否打开, 能打开, 然后给仪器发一个命令,如果在规定的时间内从收到正确的响应包, 则就用此串口, 如果超时,重试n次(一般为3次),还是收不到正确命令, 切换到下一个串口。。


打开正确的串口后,后面的事情就很简单了。……
[/Quote]

感谢回答:
我很想要这种效果,但是无从下手,能否请你帮忙做个小例子?
我的邮箱是:desehawk@sina.com
水瓶座雨夕 2010-12-22
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 sd6814466 的回复:]
MSCOMM控件?
这个控件似乎是收到数据自动发送消息的吧,你要收到消息后,在消息处理函数里去进行接收工作
而你打开串口后马上紧接着GetInput()是什么意思?打开就已经有数据了?那后来的数据呢?不要了?
在单线程的情况下,接收串口数据是在串口控件消息响应函数OnComm()中进行接收数据的工作

你要在其他线程里打开串口,接收数据,就得处理好读取的问题,要么根据消息去读取,要么就线……
[/Quote]

感谢回答
打开串口后马上紧接着GetInput()
是清空缓存空间用的,例子上也是这么写的,不是我乱加上的。
__Silent 2010-12-22
  • 打赏
  • 举报
回复
把打开串口的操作放到try catch 里面,
这样在串口不存在或是串口不可用的时候,你去打开程序就不会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;
}
傻X 2010-12-22
  • 打赏
  • 举报
回复
串口例子么? 查 龚建伟 的主页吧,全是串口例子.
向立天 2010-12-22
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 muzizongheng 的回复:]
你的逻辑很有问题, 首先程序应该只占有 有用的资源。 你打开那么多串口,万一有别的设备怎么办? 没意思, 也没效率。

其实正规的通用的方法是: 你从com1开始试, 是否打开, 能打开, 然后给仪器发一个命令,如果在规定的时间内从收到正确的响应包, 则就用此串口, 如果超时,重试n次(一般为3次),还是收不到正确命令, 切换到下一个串口。。


打开正确的串口后,后面的事情就很简单了。……
[/Quote]
是这个意思
自己建立一个通信机制来判断设备连接
另外打开串口会阻塞么?
为什么在OnInitDialog里不行呢
muzizongheng 2010-12-22
  • 打赏
  • 举报
回复
你的逻辑很有问题, 首先程序应该只占有 有用的资源。 你打开那么多串口,万一有别的设备怎么办? 没意思, 也没效率。

其实正规的通用的方法是: 你从com1开始试, 是否打开, 能打开, 然后给仪器发一个命令,如果在规定的时间内从收到正确的响应包, 则就用此串口, 如果超时,重试n次(一般为3次),还是收不到正确命令, 切换到下一个串口。。


打开正确的串口后,后面的事情就很简单了。
jyh_baoding 2010-12-22
  • 打赏
  • 举报
回复
用控件比较简单
水瓶座雨夕 2010-12-21
  • 打赏
  • 举报
回复
各位高手,麻烦帮帮忙
水瓶座雨夕 2010-12-21
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 ouyh12345 的回复:]
再开线程来接收,然后通过回调函数把数据给界面
[/Quote]

感谢回答。能否给做个例子??
ouyh12345 2010-12-21
  • 打赏
  • 举报
回复
再开线程来接收,然后通过回调函数把数据给界面

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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