vc++无法实现串口通信的问题

miketry0313 2014-01-05 04:27:08
大家好,我正在用VC++写一个与机器人的串口通信程序, 通信使用的是XBee transmitter。现在的问题是,当我发送命令要求机器人返回信息以后,我收不到机器人发给我的任何信息。这个问题的一个难点就是,我事先不知道机器人会发送给我多大的数据,所以代码中buffer的size不知道有没有定义对。另外运行代码以后,error返回的结果一直是1. 同样的硬件,我用MATLAB程序能够实现串口通信,所以很大可能就是代码的问题。代码已附上,希望大家能帮助我。
#include "StdAfx.h"
#include <iostream>
#define WIN32_LEAN_AND_MEAN //for GetCommState command
#include "Windows.h"
#include <WinBase.h>

using namespace std;

int main(){

char init[]="";

HANDLE serialHandle;

// Open serial port
serialHandle = CreateFile("\\\\.\\COM8", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

// Do some basic settings
DCB serialParams;
DWORD read, written;
serialParams.DCBlength = sizeof(serialParams);

if((GetCommState(serialHandle, &serialParams)==0))
{
printf("Get configuration port has a problem.");
return FALSE;
}

GetCommState(serialHandle, &serialParams);
serialParams.BaudRate = CBR_57600;
serialParams.ByteSize = 8;
serialParams.StopBits = ONESTOPBIT;
serialParams.Parity = NOPARITY;

//set flow control="hardware"
serialParams.fOutX=false;
serialParams.fInX=false;
serialParams.fOutxCtsFlow=true;
serialParams.fOutxDsrFlow=true;
serialParams.fDsrSensitivity=true;
serialParams.fRtsControl=RTS_CONTROL_HANDSHAKE;
serialParams.fDtrControl=DTR_CONTROL_HANDSHAKE;

if (!SetCommState(serialHandle, &serialParams))
{
printf("Set configuration port has a problem.");
return FALSE;

}


GetCommState(serialHandle, &serialParams);

// Set timeouts
COMMTIMEOUTS timeout = { 0 };
timeout.ReadIntervalTimeout = 3;
timeout.ReadTotalTimeoutConstant = 3;
timeout.ReadTotalTimeoutMultiplier = 3;
timeout.WriteTotalTimeoutConstant = 3;
timeout.WriteTotalTimeoutMultiplier = 3;

SetCommTimeouts(serialHandle, &timeout);

if (!SetCommTimeouts(serialHandle, &timeout))
{
printf("Set configuration port has a problem.");
return FALSE;

}



//write packet to poll data from robot
WriteFile(serialHandle,">*>p4",sizeof(">*>p4"),&written,NULL);


//check whether the data can be received

char buffer[257];

if (!ReadFile(serialHandle,buffer,sizeof(buffer),&read,NULL))
{
printf("Reading data to port has a problem.");
return FALSE;
}
int t;
bool error;
DWORD numberOfBytesRead=0;
DWORD err = GetLastError();
for (int jj=0;jj<10;jj++)
{
error=ReadFile(serialHandle,LPVOID(buffer),255,&numberOfBytesRead,NULL);
buffer[numberOfBytesRead]=0;
cout<<buffer<<endl;
cout<<error;
}





CloseHandle(serialHandle);
return 0;
}
...全文
247 24 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
baichi4141 2014-01-10
  • 打赏
  • 举报
回复
引用 19 楼 miketry0313 的回复:
还麻烦大神指点一下如何加边界检查,我刚才百度搜了一下,关于边界检查,啥都没搜到。 这个循环运行了挺久的,buffer只读到一个数据,因为read返回为0的原因,buffer的指针jj一直不变。但有点奇怪的是,每个循环buffer读的都是同一个数据。
jj++;
if(jj>=103)
break;
在你的代码里我没看见buffer被使用 你是怎么检查read都是0的?如果1000次里有999次都是0,你能看见剩下那个1不?
miketry0313 2014-01-10
  • 打赏
  • 举报
回复
引用 21 楼 French_fries 的回复:
你确定下面的设备用的是com8么?还有串口参数必须和下位机设备一致才行,否则通讯会有误的,可能会出现读不到数据的情况
引用 21 楼 French_fries 的回复:
你确定下面的设备用的是com8么?还有串口参数必须和下位机设备一致才行,否则通讯会有误的,可能会出现读不到数据的情况
谢谢你的回复,其他的我都挺确定的,就是把flow control设置成hardware那一块我不确定写没写对。现在我已经能收到数据了,但问题是ReadFile (serialHandle,&data[jj],1,&read, NULL);给我返回的read值一直都是0
Burcy Wen 2014-01-10
  • 打赏
  • 举报
回复
你确定下面的设备用的是com8么?还有串口参数必须和下位机设备一致才行,否则通讯会有误的,可能会出现读不到数据的情况
Burcy Wen 2014-01-10
  • 打赏
  • 举报
回复
运行这个代码,没发现问题,读写都正常,应该不是这段代码的问题吧。
miketry0313 2014-01-10
  • 打赏
  • 举报
回复
引用 18 楼 baichi4141 的回复:
[quote=引用 17 楼 miketry0313 的回复:] [quote=引用 16 楼 baichi4141 的回复:] [quote=引用 15 楼 miketry0313 的回复:] [quote=引用 3 楼 baichi4141 的回复:] 串口读数据每次只读一个字节,自己组合 二进制数据不该使用strlen
现在我用for循环可以读到一些数据了,但是还有一个问题。我用了ReadFile(serialHandle,LPVOID(buffer),1,&numberOfBytesRead,NULL); 以后,每个循环cout<<numberOfBytesRead的结果都是0. 所以这样的话,完全不能应用while循环,每次循环一次就跳出了。能不能麻烦你继续帮助我?[/quote] 串口每秒钟返回10个字节,你每秒钟读取1000次,你猜会有多少次读到0个字节? 完全不能应用while循环的原因在于你的逻辑不对,为啥要跳出?读到0个字节继续循环,读到1个字节就保存这1个字节后继续循环,就这么简单[/quote] 大神,我按照你的意思写了下,请问你觉得这样对么?
char buffer[1];
char data[103];
int t=0;
int jj=0;

do {
	
	ReadFile (serialHandle,&data[jj],1,&read, NULL);
	cout<<read;
	if (read!=0) 
	{
	  	jj++;
	    
	}
	t++;
 } while (t<10000); 
但是结果,我得到了一万个0. 我觉得奇怪的是,我实在串口能得到数据,为什么read返回的值总是0.能不能请你继续指点我?[/quote] 没加边界检查,data中只能存放103个数据,如果这段时间接收到了超过103个数据,那么就越界了 这个循环运行多长时间?这段时间内串口有没有收到数据?如果串口在这段循环运行的时间内压根没收到数据,你当然什么也读不出来[/quote] 还麻烦大神指点一下如何加边界检查,我刚才百度搜了一下,关于边界检查,啥都没搜到。 这个循环运行了挺久的,buffer只读到一个数据,因为read返回为0的原因,buffer的指针jj一直不变。但有点奇怪的是,每个循环buffer读的都是同一个数据。
baichi4141 2014-01-10
  • 打赏
  • 举报
回复
引用 17 楼 miketry0313 的回复:
[quote=引用 16 楼 baichi4141 的回复:] [quote=引用 15 楼 miketry0313 的回复:] [quote=引用 3 楼 baichi4141 的回复:] 串口读数据每次只读一个字节,自己组合 二进制数据不该使用strlen
现在我用for循环可以读到一些数据了,但是还有一个问题。我用了ReadFile(serialHandle,LPVOID(buffer),1,&numberOfBytesRead,NULL); 以后,每个循环cout<<numberOfBytesRead的结果都是0. 所以这样的话,完全不能应用while循环,每次循环一次就跳出了。能不能麻烦你继续帮助我?[/quote] 串口每秒钟返回10个字节,你每秒钟读取1000次,你猜会有多少次读到0个字节? 完全不能应用while循环的原因在于你的逻辑不对,为啥要跳出?读到0个字节继续循环,读到1个字节就保存这1个字节后继续循环,就这么简单[/quote] 大神,我按照你的意思写了下,请问你觉得这样对么?
char buffer[1];
char data[103];
int t=0;
int jj=0;

do {
	
	ReadFile (serialHandle,&data[jj],1,&read, NULL);
	cout<<read;
	if (read!=0) 
	{
	  	jj++;
	    
	}
	t++;
 } while (t<10000); 
但是结果,我得到了一万个0. 我觉得奇怪的是,我实在串口能得到数据,为什么read返回的值总是0.能不能请你继续指点我?[/quote] 没加边界检查,data中只能存放103个数据,如果这段时间接收到了超过103个数据,那么就越界了 这个循环运行多长时间?这段时间内串口有没有收到数据?如果串口在这段循环运行的时间内压根没收到数据,你当然什么也读不出来
miketry0313 2014-01-10
  • 打赏
  • 举报
回复
引用 16 楼 baichi4141 的回复:
[quote=引用 15 楼 miketry0313 的回复:] [quote=引用 3 楼 baichi4141 的回复:] 串口读数据每次只读一个字节,自己组合 二进制数据不该使用strlen
现在我用for循环可以读到一些数据了,但是还有一个问题。我用了ReadFile(serialHandle,LPVOID(buffer),1,&numberOfBytesRead,NULL); 以后,每个循环cout<<numberOfBytesRead的结果都是0. 所以这样的话,完全不能应用while循环,每次循环一次就跳出了。能不能麻烦你继续帮助我?[/quote] 串口每秒钟返回10个字节,你每秒钟读取1000次,你猜会有多少次读到0个字节? 完全不能应用while循环的原因在于你的逻辑不对,为啥要跳出?读到0个字节继续循环,读到1个字节就保存这1个字节后继续循环,就这么简单[/quote] 大神,我按照你的意思写了下,请问你觉得这样对么?
char buffer[1];
char data[103];
int t=0;
int jj=0;

do {
	
	ReadFile (serialHandle,&data[jj],1,&read, NULL);
	cout<<read;
	if (read!=0) 
	{
	  	jj++;
	    
	}
	t++;
 } while (t<10000); 
但是结果,我得到了一万个0. 我觉得奇怪的是,我实在串口能得到数据,为什么read返回的值总是0.能不能请你继续指点我?
Burcy Wen 2014-01-10
  • 打赏
  • 举报
回复
ReadFile() Return Value The ReadFile function returns when one of the following conditions occur: 1.A write operation completes on the write end of the pipe. 2.The number of bytes requested is read. 3.An error occurs. If the function succeeds, the return value is nonzero. If the function fails, the return value is zero (0). To get extended error information, call GetLastError. If the return value is nonzero and the number of bytes read is zero (0), the file pointer is beyond the current end of the file at the time of the read operation. However, if the file is opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the return value is zero (0) and GetLastError returns ERROR_HANDLE_EOF when the file pointer goes beyond the current end of file. 你看看是不是有不满足的导致返回error了
baichi4141 2014-01-08
  • 打赏
  • 举报
回复
引用 15 楼 miketry0313 的回复:
[quote=引用 3 楼 baichi4141 的回复:] 串口读数据每次只读一个字节,自己组合 二进制数据不该使用strlen
现在我用for循环可以读到一些数据了,但是还有一个问题。我用了ReadFile(serialHandle,LPVOID(buffer),1,&numberOfBytesRead,NULL); 以后,每个循环cout<<numberOfBytesRead的结果都是0. 所以这样的话,完全不能应用while循环,每次循环一次就跳出了。能不能麻烦你继续帮助我?[/quote] 串口每秒钟返回10个字节,你每秒钟读取1000次,你猜会有多少次读到0个字节? 完全不能应用while循环的原因在于你的逻辑不对,为啥要跳出?读到0个字节继续循环,读到1个字节就保存这1个字节后继续循环,就这么简单
miketry0313 2014-01-08
  • 打赏
  • 举报
回复
引用 3 楼 baichi4141 的回复:
串口读数据每次只读一个字节,自己组合 二进制数据不该使用strlen
现在我用for循环可以读到一些数据了,但是还有一个问题。我用了ReadFile(serialHandle,LPVOID(buffer),1,&numberOfBytesRead,NULL); 以后,每个循环cout<<numberOfBytesRead的结果都是0. 所以这样的话,完全不能应用while循环,每次循环一次就跳出了。能不能麻烦你继续帮助我?
miketry0313 2014-01-08
  • 打赏
  • 举报
回复
引用 10 楼 xiaohuh421 的回复:
[quote=引用 6 楼 miketry0313 的回复:] 你的意思是,ReadFile(serialHandle,LPVOID(buffer),255,&numberOfBytesRead,NULL);我这个语句是正确的,但是每次只会往buffer里面塞一个数据是么?
是每次只往buffer塞一个字节的数据 ReadFile(serialHandle,LPVOID(buffer),1,&numberOfBytesRead,NULL); //注意第二个参数. 这样每次读取后, 如果成功, 就只读取一个字符, 然后循环读取, 直到读取完成. 注意你的程序是WriteFile后马上去ReadFile, 你在确定对方能有这么快的返回速度吗? 你的timeout时间是不是太短了点. 串口设备是低速设备.[/quote] 现在我用for循环可以读到一些数据了,但是还有一个问题。我用了ReadFile(serialHandle,LPVOID(buffer),1,&numberOfBytesRead,NULL); 以后,每个循环cout<<numberOfBytesRead的结果都是0. 所以这样的话,完全不能应用while循环,每次循环一次就跳出了。能不能麻烦你继续帮助我?
miketry0313 2014-01-08
  • 打赏
  • 举报
回复
引用 12 楼 zhao4zhong1 的回复:
推荐使用portmon软件辅助调试串口通信程序。
谢谢你的回复,但portmon好像不能用于win7 64bit系统啊,我一connect local就出现error2
赵4老师 2014-01-07
  • 打赏
  • 举报
回复
推荐使用portmon软件辅助调试串口通信程序。
xiaohuh421 2014-01-06
  • 打赏
  • 举报
回复
要不纠结内存分配多少, 串口是字符设备, 你完全可以每次读取一个字符. 循环读取, 直到读取不到为止.
hushoubo 2014-01-06
  • 打赏
  • 举报
回复
定义一个大的缓冲去接收,PC端不要吝啬那么点儿内存
baichi4141 2014-01-06
  • 打赏
  • 举报
回复
串口读数据每次只读一个字节,自己组合 二进制数据不该使用strlen
hushoubo 2014-01-06
  • 打赏
  • 举报
回复
引用 9 楼 Binzo 的回复:
while(1){ //recieve the meaage; } 不然,程序都退出了,你到哪儿去接收消息。
正解,只要保证发出的指令正确,那就循环接收,不会收不到的
xiaohuh421 2014-01-06
  • 打赏
  • 举报
回复
引用 6 楼 miketry0313 的回复:
你的意思是,ReadFile(serialHandle,LPVOID(buffer),255,&numberOfBytesRead,NULL);我这个语句是正确的,但是每次只会往buffer里面塞一个数据是么?
是每次只往buffer塞一个字节的数据 ReadFile(serialHandle,LPVOID(buffer),1,&numberOfBytesRead,NULL); //注意第二个参数. 这样每次读取后, 如果成功, 就只读取一个字符, 然后循环读取, 直到读取完成. 注意你的程序是WriteFile后马上去ReadFile, 你在确定对方能有这么快的返回速度吗? 你的timeout时间是不是太短了点. 串口设备是低速设备.
miketry0313 2014-01-06
  • 打赏
  • 举报
回复
引用 1 楼 ALNG 的回复:
//write packet to poll data from robot WriteFile(serialHandle,">*>p4",sizeof(">*>p4"),&written,NULL); 这行是错的。sizeof是求一个类型的size, 如果你给的是一个char [], 比如稍后的ReadFile(serialHandle,buffer,sizeof(buffer),&read,NULL,sizeof就正确。这里你需要用是strlen //write packet to poll data from robot WriteFile(serialHandle,">*>p4",strlen(">*>p4"),&written,NULL); 如果你是在32的平台上,sizeof(const char *)为4,会少些一个4, 如果是在64为平台上sizeof(const char *)为8,后面会带上3个字节的垃圾。 这肯定是个问题,不过是不是唯一的问题我就不确定了。
谢谢你的回复,sizeof输出为6,strlen输出为5.但是我改成strlen以后,还是收不到任何数据。
Binzo 2014-01-06
  • 打赏
  • 举报
回复
while(1){ //recieve the meaage; } 不然,程序都退出了,你到哪儿去接收消息。
加载更多回复(4)

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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