CSerialPort能否连续发送?发送数据丢失?

gilbertjuly 2009-08-18 07:04:01
我给一个机器发送串口命令,单个命令发送没问题,

连续发送的时候有问题,
比如,连续发了三个,如下:
m_ser.WriteToPort(chSend1);
m_ser.WriteToPort(chSend2);
m_ser.WriteToPort(chSend3);

只有最后一个发送的起作用.
是不是这个类不能连续发送数据的?
请各位指点, 先谢了啊.
...全文
562 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
yht8800 2012-08-09
  • 打赏
  • 举报
回复
怎么看不到有些内容啊
czxstarhust 2009-08-24
  • 打赏
  • 举报
回复
[Quote=引用楼主 gilbertjuly 的回复:]
我给一个机器发送串口命令,单个命令发送没问题,

连续发送的时候有问题,
比如,连续发了三个,如下:
m_ser.WriteToPort(chSend1);
m_ser.WriteToPort(chSend2);
m_ser.WriteToPort(chSend3);

只有最后一个发送的起作用.
是不是这个类不能连续发送数据的?
请各位指点, 先谢了啊.
[/Quote]

类没有问题,每次发送完一次数据后要有延时的,可以通过监控软件看看数据是否发送下去了。
gilbertjuly 2009-08-24
  • 打赏
  • 举报
回复
由于采用异步发送, 在它的那个线程里面, 只发送一次.
就是说:
m_ser.WriteToPort(chSend);
这句话执行好之后并不是马上发送串口数据
要等进入它的线程之后再发送.
你可以跟踪下是什么时候进入它的线程的.
三句writetoport都会进入这个线程
但是只能执行一个,最后一个.
雪影 2009-08-24
  • 打赏
  • 举报
回复
明白就好,串口本来就不支持异步操作。

所以只能等前一个数据发送完毕之后才能发送下一个数据

jf
gilbertjuly 2009-08-24
  • 打赏
  • 举报
回复
我终于明白了,这个类没有办法同步发送数据,看它的cpp文件中的初始化:
m_hComm = CreateFile(szPort,// communication port string (COMX)
GENERIC_READ | GENERIC_WRITE, // read/write types
0, // comm devices must be opened with exclusive access
NULL, // no security attributes
OPEN_EXISTING, // comm devices must use OPEN_EXISTING
FILE_FLAG_OVERLAPPED, // Async I/O
0); // template must be 0 for comm devices
FILE_FLAG_OVERLAPPED被设置为异步,并且不能改为同步,要同步的话用其他类吧,比如:
http://blog.chinaunix.net/u/32550/showart_365425.html
glacierful 2009-08-24
  • 打赏
  • 举报
回复
我觉得最好把要发的命令放到一个数组中。然后用一个时钟来逐条发送,发完一条,检查是否接收到正确返回,然后再发下一条。这中间可以定个超时,在指定时间内如果没有收到,可以认为串口连接断了,中断发送。

这种一问一答的方式比较保险。而且效率并不低。
雪影 2009-08-20
  • 打赏
  • 举报
回复
你设置了计时器,难道没有计时器的回调函数?也就是WM_TIMER消息响应函数OnTImer?
gilbertjuly 2009-08-20
  • 打赏
  • 举报
回复
我觉得是同步和异步的问题:假如函数中包含文件处理之类的低速处理,调用方等不得,需要把同步调用改为异步调用,去启动一个单独的线程,然后马上执行后续代码,其余的事让线程慢慢去做.

我设置了timer,将写放在timer的相应中,还是不可以.
是不是要用timer的回调函数?
gilbertjuly 2009-08-20
  • 打赏
  • 举报
回复
我是这样写的:

{
//chSend第一次赋值
chSend[0]=1;
...省略...
chSend[25]=1;
SetTimer(1,100,NULL);
sleep(200);

//chSend第二次赋值
chSend[0]=2;
...省略...
chSend[25]=2;
SetTimer(1,100,NULL);
sleep(200);
}

void CMainFrame::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
KillTimer(1);
if(m_bSerialPortOpened) //检测串口是否打开
m_SerialPort.WriteToPort((LPCTSTR)chSend,26); //发送
CMDIFrameWnd::OnTimer(nIDEvent);
}

没有用SetTimer(1,100,NULL)的第三个参数
gilbertjuly 2009-08-19
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 zhouchuan111 的回复:]
我也遇到同样的问题,
m_ser.WriteToPort(chSend1);
m_ser.WriteToPort(chSend2);
m_ser.WriteToPort(chSend3);
最后用把chSend1,chSend2,chSend3一次发送完成解决的

期待更好的解决方法
[/Quote]

恩...一起发实在是控制不方便
gilbertjuly 2009-08-19
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 tttyd 的回复:]
采用上面3楼的方法也不行吗?

引用 3 楼 zhoujiamurong 的回复:
楼上的办法有隐患,可能遗留上次的缓冲内容!

原来我一直用这类,很好用,这个问题我也遇到,后仔细研究发现它在写的时候是
void CSerialPort::WriteToPort(const char* string)
{
VERIFY(m_hComm != 0);

memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
strcpy(m_szWriteBuffer, string);

// set event for write//设置成信号态以便写
SetEvent(m_hWriteEvent);
}
所以你这样连续用,就会出问题。
后来我的解决方法是这样的:开一个Timer
在Timer中控制一次写,每次进来Timer的写就可以了。
你只要控制Timer就可以控制写的次数。
这样既不会缓冲区遗留上次写的内容,也不会写失败了。

[/Quote]

啊呀...不会啊, 有谁知道这个timer怎么用?
zhouchuan111 2009-08-19
  • 打赏
  • 举报
回复
我也遇到同样的问题,
m_ser.WriteToPort(chSend1);
m_ser.WriteToPort(chSend2);
m_ser.WriteToPort(chSend3);
最后用把chSend1,chSend2,chSend3一次发送完成解决的

期待更好的解决方法
雪影 2009-08-19
  • 打赏
  • 举报
回复
采用上面3楼的方法也不行吗?

[Quote=引用 3 楼 zhoujiamurong 的回复:]
楼上的办法有隐患,可能遗留上次的缓冲内容!

原来我一直用这类,很好用,这个问题我也遇到,后仔细研究发现它在写的时候是
void CSerialPort::WriteToPort(const char* string)
{
VERIFY(m_hComm != 0);

memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
strcpy(m_szWriteBuffer, string);

// set event for write//设置成信号态以便写
SetEvent(m_hWriteEvent);
}
所以你这样连续用,就会出问题。
后来我的解决方法是这样的:开一个Timer
在Timer中控制一次写,每次进来Timer的写就可以了。
你只要控制Timer就可以控制写的次数。
这样既不会缓冲区遗留上次写的内容,也不会写失败了。
[/Quote]
gilbertjuly 2009-08-19
  • 打赏
  • 举报
回复
参考了http://topic.csdn.net/u/20080630/13/384560cd-6a96-4c19-b543-fc245cb2357a.html
我如果在每句后面添加AfxMessageBox("");像:

m_ser.WriteToPort(chSend1);
AfxMessageBox("");
m_ser.WriteToPort(chSend2);
AfxMessageBox("");
m_ser.WriteToPort(chSend3);
AfxMessageBox("");

这样三句就都能发出去,我想不是延时的问题,因为我延时了10秒钟都没有用.
雪影 2009-08-18
  • 打赏
  • 举报
回复
可以采用Sleep(1000)
雪影 2009-08-18
  • 打赏
  • 举报
回复
//CSerialPort是异步串口操作,并且在每次WriteToPort()时,有清除发送缓冲区,要连续发送,只要把清除发送缓冲区的那个语句屏蔽就可以了。
//或者等待WriteFile真正操作成功,那样就和同步方式没有什么区别了。
feilinhe 2009-08-18
  • 打赏
  • 举报
回复
没用过这个串口类,不过相传口发送数据时可以连续发送的,你先用调试助手试试,连续发送回收到多少字符,或许是机器没响应到

2,644

社区成员

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

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