关于spcomm的问题?小弟初次接触串口,请多多关照!!(100分)

  • 主题发起人 主题发起人 IceRain
  • 开始时间 开始时间
I

IceRain

Unregistered / Unconfirmed
GUEST, unregistred user!
1.
procedure TFCOMM.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;BufferLength: Word);
var
i:integer;
begin
viewstring:=‘’ ;
move(buffer^,pchar(@rbuf)^,bufferlength); ///这段是什么意思??作用什么??
for i:=1 to bufferlength do
viewstring:=viewstring+ inttohex(rbuf,2)+‘’ ;
viewstring:=‘接收’+ viewstring;
memo1.lines.add(viewstring);
memo1.lines.add(‘’ );
end;

2.硬件的说明只有这些:“四个字节组成一个数值;前两位表示站号,第三位的前半位表示物理量,第三位的后半位和第四位表示数值。”怎么设置spcomm的属性,象:
●波特率  ●奇偶校验位  ●字节长度  ●停止位 等信息???

谢谢!!!!!
 
(1)把buffer中bufferlength个字节拷到数组rbuf中去
(2)直接在对象观察器中设置,按顺序:BoundRate,Parity,ByteSize,StopBits
 
补充说明::
四个字节组成一个数值;
前两位表示站号,第三位的前半位表示物理量,第三位的后半位和第四位表示数值
第三位的前半位必须是3个数之中的数,这3个数是:
'&HC 表示 雨量
'&HF 表示 水位
'&HD 表示 电压
例如:&H47,&H69,&HF0,&HEC表示站号为&H46, 物理量为F,数值为&H0EC既70号站的水位是236cm
 
takashiki:你好!!!
我的意思是根据“补充说明”中的信息,com的属性值都应该是多少??
 
TO IceRain:
你上面所说的“补充说明”只是对接收到的数据的格式说明,并没有指明
●波特率  ●奇偶校验位  ●字节长度  ●停止位 等信息
如果没有其他说明,用默认值先试试,即9600,N,8,1,不行且没有其他说明的话只能这样一个一个去试了:)
 
设备与电脑的哪一个串口连接?这就是spcomm的Com值。
●波特率  ●奇偶校验位  ●字节长度  ●停止位 等信息???这些数据要看你设备的资料!

你现在的问题是要先将设备送出的数据读到,然后再根据你说的"补充说明"来分析数据。
 
谢谢!!我试试吧!!
 
波特率,奇偶校验位,停止位等信息应该于设备的一致
COM口你插在哪一个上就设为哪一个
字节长度一般设为8(也得看你的设备),每次发送4个字节,接收5个字节(多了停止位)
接受后,如你的程序:
(rbuf[0] and $f0) + (fbuf[1] shr 4)表示站号
rbuf[2] shr 4:物理量
(rbuf[2] and $0f) shl 4+rbuf[3]:数值
rbuf[4]=$00:停止位
我是使用的每字节8位,如果是其他位,你自己改一改。
 

谢谢,有人说cport的实时性比这个spcomm好,我要作的这个是,接收200多个雨量遥测点,发回的雨量数据,如果下大雨的话,数据发送的频率很大的(雨量每增加1mm)就发一组数(站号,时间,雨量)回来???是不是要换呢??有点拿不定主意???
 
这个没有问题!
 
在delphi中有将16进制数转成10进制的函数吗??
 
这是用VC写的源程序的一部分:应该是接收数据的一部分,转成DELPHI怎么写??
站号: m_zh = find(buf(0)) * 16 + find(buf(1)); find() 字节转成10进制

物理量: feature = int(buf(2) & 0xF0) / 16;

数值: m_ysz = (int)(buf(2) & 0xF) * 256 + (int)buf(3);



jycode[0] = 0x0;
jycode[1] = 0x1B;
jycode[2] = 0x2E;
jycode[3] = 0x35;
jycode[4] = 0x47;
jycode[5] = 0x5C;
jycode[6] = 0x69;
jycode[7] = 0x72;
jycode[8] = 0x8D;
jycode[9] = 0x96;
jycode[10] = 0xA3;
jycode[11] = 0xB8;
jycode[12] = 0xCA;
jycode[13] = 0xD1;
jycode[14] = 0xE4;
jycode[15] = 0xFF;


int CEX21View::find(BYTE ic)
{
int j;
int temp;
for(j=0;j<16; j++)
{
if(ic==jycode[j])
{
temp=j;
}
}
return temp;

}


2 .Comm1ReceiveData(Sender: TObject; Buffer: Pointer;BufferLength: Word);
其中的BufferLength由什么决定???
 
注::
1.其中jycode[]数组中保存的是规定好的数据,也就是,前两位必须是这16个数之中的一个,否则视为错数。
2.用的是spcomm,在其Comm1ReceiveData事件中应该怎么写??
3.spcomm最多一秒中接收多少组这样的数据??
 
我用 takashiki 说的那个算法,试了。
但是我用inttostr函数对rbuf[0],rbuf[1],rbuf[2],rbuf[3],进行察看,前两个字节中的数据根本和实际数据不沾边,后两个字节都是00???????
 
各位老兄::快点帮忙看看!!!!!!!
 
如果在 Delphi 里用我认为用 Spcomm 比较好一点。

2 .Comm1ReceiveData(Sender: TObject; Buffer: Pointer;BufferLength: Word);
其中的BufferLength由什么决定???
BufferLength 是由 Spcomm 传给你程序的,是告诉你接收到多少数据了。

一般的用法是:
var
buf:array of byte;
begin
SetLength(Buf,BufferLength);
CopyMemory(@Buf[0],Buffer,BufferLength);
//---对 buf 中的数据进行分析
Setlength(Buf,0);

还有:一般下位机与下位机通讯都有通信协议的
你最好把协议贴出来。
不然我们不太明白你要说的意思。


>>这是用VC写的源程序的一部分:应该是接收数据的一部分,转成DELPHI怎么写??
站号: m_zh = find(buf(0)) * 16 + find(buf(1)); find() 字节转成10进制

物理量: feature = int(buf(2) &amp; 0xF0) / 16;

数值: m_ysz = (int)(buf(2) &amp; 0xF) * 256 + (int)buf(3);

find 是一个函数,不是C 自带的
转为 Delphi为:
物理量: feature := (integer(buf(2)) and $F0) div 16;
或:feature := (integer(buf(2)) and $F0) shr 4;

数值: m_ysz := (integer(buf(2)) and $0F)* 256 + (integer(buf(3)));
或: m_ysz := ((integer(buf(2)) and $0F) shl 8) + (integer(buf(3)));

int CEX21View::find(BYTE ic)
{
int j;
int temp;
for(j=0;j<16; j++)
{
if(ic==jycode[j])
{
temp=j;
}
}
return temp;

}
转为 Delphi 为:
CEX21View是一个类
function CEX21View.find(BYTE ic):Longint;
var
j: Longint;
begin
for j:= 0 to 15 do
begin
if(ic=jycode[j]) then
begin
Result =j;
exit;
end;
end;
return -1; // 出现错误

end;


 
{=================================================================
功 能: 转换一个十六进制字符为整数
参 数: HexToken
返回值: Integer
=================================================================}
function HexCharToInt(HexToken : char):Integer;
begin
Result:=0;
if (HexToken>#47) and (HexToken<#58) then { chars 0....9 }
Result:=Ord(HexToken)-48
else if (HexToken>#64) and (HexToken<#71) then { chars A....F }
Result:=Ord(HexToken)-65 + 10;
end;
 
看来,大家都回家过节了,在这里祝大家十一过的愉快!!
 
procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
HexText: PChar;
begin
GetMem(HexText,BufferLength*2+1);
FillChar(HexText^,BufferLength*2+1,#0);
BinToHex(Buffer,HexText,BufferLength);
Memo1.Lines.Add(HexText);
FreeMem(HexText);
end;
你找个串口调试器,或者是用上面的方法以十六进制的方式将接收到的数据显示出来
如果数据与预期的不同,那么你应该从协议,串口参数(比如波特率)方面,检查是不是有误。。。
 
后退
顶部