关于RS232串口通信的问题,初次接触,大家帮忙看看,搞定马上结贴^_^

sjz_2000 2007-01-25 04:34:26
发送命令后没有数据传回,不知道问题出在哪里,大家帮忙看看,谢谢了!
HANDLE hComm;
DCB dcb;
DWORD nBytesRead,dwError;
COMSTAT cs;
char *Senddata,inbuff[1024];
unsigned long lrc,BS;
if((hComm=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,0))!=INVALID_HANDLE_VALUE)
{
GetCommState(hComm,&dcb);
dcb.BaudRate=CBR_9600;
dcb.ByteSize=8;
dcb.Parity=NOPARITY;
dcb.StopBits=ONESTOPBIT;
SetCommState(hComm,&dcb);
Senddata=Edit1->Text.c_str();
BS=Edit1->Text.Length();
WriteFile(hComm,Senddata,BS,&lrc,NULL);
ClearCommError(hComm,&dwError,&cs);
if(cs.cbInQue>sizeof(inbuff))
{
PurgeComm(hComm,PURGE_RXCLEAR);
ReadFile(hComm,inbuff,cs.cbInQue,&nBytesRead,NULL);
inbuff[cs.cbInQue]='\0';
Memo1->Text=inbuff;
}
if(hComm!=INVALID_HANDLE_VALUE)
CloseHandle(hComm);
}
else
{
ShowMessage("开打通信端口错误!");
}
...全文
449 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
信念 2007-01-27
  • 打赏
  • 举报
回复
TO 毛毛:
又试了一次,程序没有响应。。。
哪位大哥也帮忙试试看,看看是不是我的机器有问题呢?
信念 2007-01-27
  • 打赏
  • 举报
回复
if(cs.cbInQue>sizeof(inbuff))
PurgeComm(hComm,PURGE_RXCLEAR);
清除是有条件的啊。。。
sjz_2000 2007-01-27
  • 打赏
  • 举报
回复
谢谢各位的支持,现在搞定了,分数不多,不成敬意!
结贴!
lailaiququ 2007-01-26
  • 打赏
  • 举报
回复
如果是查询方式应该循环读串口状态,检测到缓冲区有数据再做相应的处理。
用API函数一般自己写监听线程。用控件简单些。
yhec 2007-01-26
  • 打赏
  • 举报
回复
gz
constantine 2007-01-26
  • 打赏
  • 举报
回复
mscomm32发送的是Variant,所以你要先写一个函数将你要发送的存到Variant里面,然后才可以发送
网上找找<<通信控件MSComm使用详解>>看看
我http://www.zhujiangroad.com/上面看到过,你可以去看看,带格式贴出来太乱了
Waiting4you 2007-01-26
  • 打赏
  • 举报
回复
据说Win2k以上不再支持同步模式的读写,改成这样就行了:

HANDLE hComm;
DCB dcb;
DWORD nBytesRead,dwError;
COMSTAT cs;
char *Senddata,inbuff[1024];
unsigned long lrc,BS;
if((hComm=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0))!=INVALID_HANDLE_VALUE)
{
OVERLAPPED osWrite;
OVERLAPPED osRead;
COMMTIMEOUTS TimeOuts={100,0,0,0,0};
osWrite.hEvent=CreateEvent(NULL, true, false, NULL);
osRead.hEvent=CreateEvent(NULL, true, false, NULL);
GetCommState(hComm,&dcb);
dcb.BaudRate=CBR_9600;
dcb.ByteSize=8;
dcb.Parity=NOPARITY;
dcb.StopBits=ONESTOPBIT;
SetCommState(hComm,&dcb);
SetCommTimeouts(hComm,&TimeOuts);

Senddata=Edit1->Text.c_str();
BS=Edit1->Text.Length();
PurgeComm(hComm,PURGE_RXCLEAR);
WriteFile(hComm,Senddata,BS,&lrc,&osWrite);
if (GetLastError() == ERROR_IO_PENDING) GetOverlappedResult(hComm, &osWrite, &lrc, true);
ZeroMemory(inbuff,sizeof(inbuff));
ReadFile(hComm,inbuff,sizeof(inbuff),&nBytesRead,&osRead);
if (GetLastError() == ERROR_IO_PENDING) GetOverlappedResult(hComm, &osRead, &nBytesRead, true);
Memo1->Text=inbuff;
if(hComm!=INVALID_HANDLE_VALUE)
{
CloseHandle(hComm);
CloseHandle(osRead.hEvent);
CloseHandle(osWrite.hEvent);
}
}
else
{
ShowMessage("开打通信端口错误!");
}
柯本 2007-01-26
  • 打赏
  • 举报
回复
用ASYNC32更简单些,大概写一下(没测试)
comm->Open(); //comm为ASYNC32控件名,你先设为波特率等参数
static char sendbuff[]={0x1b,0z10,0x10,0x00,0x05,0xc5,0x93};
comm->Write(buff,sizeof(sendbuff));
char recvbuff[1024];
comm->Read(recvbuff,200); //读200个返回字节,就是你要的结果了

星光伴月 2007-01-26
  • 打赏
  • 举报
回复
PurgeComm(hComm,PURGE_RXCLEAR);
ReadFile(hComm,inbuff,cs.cbInQue,&nBytesRead,NULL);

你都将收到的内容清掉了,再读当然读不出东西来了.
sjz_2000 2007-01-26
  • 打赏
  • 举报
回复
mscomm32这个控件有没有对应的简单点的例子呢?
初次接触,不太会用,麻烦两位老大了。
我想发送的命令是十六进制的数据,是否还要经过处理呢?
例如:0x1b,0z10,0x10,0x00,0x05,0xc5,0x93
Waiting4you 2007-01-26
  • 打赏
  • 举报
回复
我改的代码里没if(cs.cbInQue>sizeof(inbuff))这段啊,你把整段代码一起copy替换你原来的代码试试,我在我的电脑上试是正确的.
另外,上面的代码里没有考虑溢出控制,如果默认是Hardware的话也会卡住的.
dcb.fOutxCtsFlow=0;
dcb.fInX=dcb.fOutX=0;
dcb.fRtsControl=RTS_CONTROL_ENABLE;
建议SetCommState之前再加这个
信念 2007-01-26
  • 打赏
  • 举报
回复
改过后我看了一下值,
cs.cbInQue的值为40
而inbuff的值为5。
wz 2007-01-26
  • 打赏
  • 举报
回复
lg
「已注销」 2007-01-26
  • 打赏
  • 举报
回复
关注...
信念 2007-01-26
  • 打赏
  • 举报
回复
Waiting4you(毛毛)
我按你写的改过后运行就没响应了。。。
if(cs.cbInQue>sizeof(inbuff))
{
PurgeComm(hComm,PURGE_RXCLEAR);
ReadFile(hComm,inbuff,cs.cbInQue,&nBytesRead,NULL);
inbuff[cs.cbInQue]='\0';
Memo1->Text=inbuff;
}
这里错了
if(cs.cbInQue>sizeof(inbuff))
PurgeComm(hComm,PURGE_RXCLEAR);
ReadFile(hComm,inbuff,cs.cbInQue,&nBytesRead,NULL);
inbuff[cs.cbInQue]='\0';
Memo1->Text=inbuff;
改成这样后有数据相应了,但传回的数据不对
大家再帮忙看看,谢谢各位。
constantine 2007-01-25
  • 打赏
  • 举报
回复
就如keiy说的,我们公司也说用超级终端看,本机我自己就用一些串口调试工具,如果你有2个以上串口,用串口连接线(不知道别人是不是这样叫)连接起来,然后自己给自己发也行,这样你自己再打开一个串口调试软件就可以知道你的程序有没有问题了,很容易的
柯本 2007-01-25
  • 打赏
  • 举报
回复
直接用API写串口通讯也不是不可以,我以前就根据网上的自己写了一个串口类(for VC的),改在BCB下也可用(for BCB的找不到了,不过基本不用改的)
http://topic.csdn.net/t/20050602/22/4055364.html
一般情况下,用BCB开发串口应用还是按 安吉儿 所说,用控件方便的多,且BCB下有很多控件可用,如mscomm32,spcomm,ASYNC32等
你的串口程序的确发出数据了吗?用个串口监控软件(很久不做了,也应该有很多,最简的方法直接用超级终端.用二台机相连接,一边用你的程序,一边用超级终端,用你的程序发一些字符到串口,看看超级终端是否收到)
看你的程序少设了很多参数如:RTS/CTS,XON/XOFF,Timeout等,估计发送都有问题,另外. 安吉儿 说的也对,发送后要稍做延时(我以前一般用Sleep(100)),毕竞232是个低速设备
constantine 2007-01-25
  • 打赏
  • 举报
回复
直接用mscomm32控件吧,api不太懂,另外你写完马上就读也太快了吧

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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