SPCOMM 和 MSCOMM的问题(100分)

  • 主题发起人 主题发起人 山药蛋
  • 开始时间 开始时间

山药蛋

Unregistered / Unconfirmed
GUEST, unregistred user!
要写个简单的串口通讯的程序,已经在这两个控件上调了一天了,用的底子是网上找来的程序,但都没成功,真头痛,下面是我改动的程序,请各位帮忙看看哪里有错:
1、SPCOMM
//===============
procedure TForm1.FormShow(Sender: TObject);
begin
Comm1.StartComm;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Comm1.StopComm;
end;

procedure TForm1.SendData;
var
i:integer;
commflg:boolean;
begin
viewstring:='';
commflg:=true;
for i:=0 to 1 do
begin
if not comm1.writecommdata(@sbuf,1) then//就是writecommdata一直都False
begin
commflg:=false;
break;
end;
//发送时字节间的延时
sleep(2);
viewstring:=viewstring+inttohex(sbuf,2)+'';
end;
viewstring:='发送'+viewstring;
memo1.lines.add(viewstring);
memo1.lines.add('');
if not commflg then messagedlg('发送失败 !',mterror,[mbyes],0);
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
sbuf[0]:=100;
sbuf[1]:=10;
SendData;
end;
//接收的事件ReceiveData根本不触发,不写了。
//--------Comm1的属性如下-------
object Comm1: TComm
CommName = 'COM2'//我用的是COM2口
BaudRate = 9600
ParityCheck = False
Outx_CtsFlow = False
Outx_DsrFlow = False
DtrControl = DtrEnable
DsrSensitivity = False
TxContinueOnXoff = True
Outx_XonXoffFlow = True
Inx_XonXoffFlow = True
ReplaceWhenParityError = False
IgnoreNullChar = False
RtsControl = RtsEnable
XonLimit = 500
XoffLimit = 500
ByteSize = _8
Parity = None
StopBits = _1
XonChar = #17
XoffChar = #19
ReplacedChar = #0
ReadIntervalTimeout = 100
ReadTotalTimeoutMultiplier = 0
ReadTotalTimeoutConstant = 0
WriteTotalTimeoutMultiplier = 0
WriteTotalTimeoutConstant = 0
Left = 64
Top = 108
end
//===============
2、MSCOMM
//==============
procedure TForm1.FormShow(Sender: TObject);
begin
mscomm1.portopen:=True;
mscomm1.inbuffercount:=0;
mscomm1.Input;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
mscomm1.portopen:=False;
end;
procedure TForm1.MSComm1Comm(Sender: TObject);
var
RX:OleVariant;
SS,SReceive:String;
i,j:Integer;
begin
case mscomm1.commEvent of
comEvSend:
begin
//发送数据正确,内容同SPCOMM
end;
comEvReceive:
begin
j:=mscomm1.inbuffercount;
RX:=mscomm1.Input;
SS:=RX;
SReceive:='';
for i:=1 to j do
begin
SReceive:=SReceive+InttoHex(Byte(SS),2);
end;
Memo1.Lines.Add(SReceive);//根据协议,应收到"65 F0 0C FF"
mscomm1.inbuffercount:=0;//可是实际只收到"65 3F FF 00"
end;
end;//case
end;
//------------
MSComm属性只改动了如下的,其他保持默认值:
RThreshold:1
//===========
补充说明:
1、调试的时候都用“串口调试助手V2.1”验证过,串口设备的响应没有问题,即用“助手”能完全正常的收发数据,而用自己的程序则出现以上的问题。
2、我的编辑环境:WindowsXP_SP1、Delphi7、SPComm 2.5。
3、MSComm在VC6上作了测试,编出的程序没有问题,即没有收数据的错误。
 
对前个没有用过。
MSComm时,comm的inputMode默认为二进制模式?
还有,似乎要设置comm的inputlen=0,input属性才读取缓冲区中的全部内容
 
MSComm时,comm的inputMode默认为二进制模式?
不是,是文本流的形式
 
老大,前面这个好像是我写的吧,错误的原因是你根本改错了程序造成的,看一下本来的程序吧。

不过你要注意一点,SPCOMM不可以应答速度间隔小于100ms的数据流,如果你的系统发送数据的速度非常快,SPCOMM是不适合使用的,我推荐使用CPORT2.64。

正确的程序如下:

function TForm1.SendData(Len:Integer):Bool;
var
i:Integer;
S,HEXS: String;
CommFLG:Boolean;
begin
CommFLG:=True;
S:='';
HEXS:='';

Form1.TXP1.Color:=CLRED; //发送数据面板变成红色,表明正在发送数据
Application.ProcessMessages; //释放系统资源

for i:=1 to Len do //Len为发送数据的长度
begin
if not Form1.Comm1.WriteCommData(@SBuf1,1) then //发送数据过程,如果出现发送错误,标记位标记为发送错误
begin
CommFLG:=false;
Break;
end;
// Sleep(2); //发送时字节间的延时
HEXS:=HEXS+inttohex(SBuf1,2)+''; //HEX Disp
S:=S+Char(SBuf1); //DEC Disp
end;

Form1.Memo1.Lines.Add('Com1 Send '+DateTimeToStr(NOW)+' DEC ---> '+S); //发送的数据按照10进制显示
Form1.Memo1.Lines.Add('Com1 Send '+DateTimeToStr(NOW)+' HEX ---> '+HEXS); //发送的数据按照16进制显示
Form1.Memo1.Lines.Add('...');

TX1:=TX1+Int64(i-1); //发送的字节数累加
Form1.TXP1.Caption:=' TX1: '+IntToStr(TX1); //显示发送的总字节数
Form1.TXP1.Color:=CLWhite; //改回原有颜色,表明发送结束
Application.ProcessMessages; //释放系统资源,用于控件刷新

if not CommFLG then //发送成功或者错误的标志返回主调用函数
SendData:=False
else
SendData:=True;
end;



procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
DECS,HEXS: String;
Msg:Pchar;
begin
DECS:='';
HEXS:='';
//接收RS232的数据并显示Memo1上。
Move(Buffer^,RBuf1,BufferLength);

RX1:=RX1+BufferLength; //累计接收字节数量
RXP1.Caption:=' RX1: '+IntToStr(RX1); //显示总接收的字节数
RXP1.Color:=CLLIME; //显示绿色,表明数据开始接收
Application.ProcessMessages;

For i:=1 to BufferLength do //数据接收过程按照每个字节进行处理
begin
//Sleep(1) //接收延迟
HEXS:=HEXS+inttohex(RBuf1,2)+''; //HEX Disp
DECS:=DECS+Char(RBuf1); //DEC Disp
end;

Memo1.Lines.Add('Com1 Recv '+DateTimeToStr(NOW)+' DEC ---> '+DECS);
Memo1.Lines.Add('Com1 Recv '+DateTimeToStr(NOW)+' HEX ---> '+HEXS);
Memo1.Lines.Add('...');

Application.ProcessMessages;
RXP1.Color:=CLWhite;
Application.ProcessMessages;

//接收数据处理过程
if DECS=NAK then //PABX未接收到正确的消息数据,原消息重新发送
begin
//原消息开始重发
Len2:=1;
SBuf2[1]:=Byte(ACK);
if SendData2(Len2)=False then MessageDlg('发送失败 !' ,mterror,[mbyes],0); //调用发送函数
exit;
//重发消息结束
exit;
end;
程序没有结束,因为太多了处理过程了,NAK为定义的消息标识,这个你不用注意的,主要是看消息发送的要求。

注意在Delphi系统中数组的下标是从1开始的。
 
SPcomm
发送数据部分应该没问题,(和你的是一个模子)
procedure TFCOMM.Senddata;
var
i:Integer;
commflg:boolean;
begin
viewstring:='';
commflg:=True;
for i:=1 to 6 do //发六个字节
begin
if not fcomm.Comm1.WriteCommData(@sbuf,1) then
begin
commflg:=false;
break;
end;
sleep(2); {发送时字节间的延时}
viewstring:=viewstring+IntToHex(sbuf,2)+' ';
// Series1.AddXY(Xaxis1,sbuf,'',clred) ;//发送数据用图显示,接收一一样
// Xaxis1:=Xaxis1+1;
end;
viewstring:=TimeToStr(Time)+' 发送 : '+viewstring;
fcomm.Memo1.Lines.Add(viewstring);
if not commflg then
begin
Memo1.Lines.Add('发送失败!请检查串口是否已打开');
messagedlg('发送失败!请检查串口是否已打开',mterror,[mbyes],0);
end;
end

另外,用两台pc机测试收发时 注意: R_1-->W_2 W_1-->R_2
 
不好意思浪费大家时间了——
SPOMM的问题已经找到:我下的那个控件是被人编辑过的,在write线程创建之前就“exit”了,所以comm1.writecommdata(@sbuf,1)就一直False。解决方法自然就是把那个该死的“exit”注释掉!
现在这个程序已经用SPOMM写完,效果还不错。
只是有点遗憾:MSCOMM在D7下的问题还是没解决。
不过也不想去追究了,实在没那么多时间,反正“逮到老鼠就是好猫”了。
 
后退
顶部