串口发送数据的问题(100分)

  • 主题发起人 主题发起人 刘光涛
  • 开始时间 开始时间

刘光涛

Unregistered / Unconfirmed
GUEST, unregistred user!
各位:
我在编写pc和单片机的通讯程序,用的是SPCOMM。在发送数据时,我需要发送的都是
16进制的数据。但是SPCOMM发送的是字符串。如何转换。
是不是这样就行。
a:byte;
sendbuffer:=inttohex(a,2)
comm1.writecommdata(Pchar(sendbuffer),1)
 
我用的是如:sub[1]:=$64,sub[2]:=$65.....再写串口。(其中64,65就是16进制数)
 
不对吧?INTTOHEX返回的是STRING啊
试试下面:
a:byte;
...
a:=$ff;
comm1.writecommdata(Pchar(@a),1);
不过遇到#0时该怎么办呢?你自己处理一下吧
 
for i := 1 to Length(Packet) do
currentData := IntToHex(Ord(Packet), 2);
SendCommand(CurrentData); // 此时发送的就是16进制的数据了。
 
纠正一下,上面的是将接受来的数据转换成16进制字符串。
向串口发送16进制字符可用 #$F9 类似的字符。
对整形可通过位移来转换,如:
Result := Chr(((Address and $FF0000) shr 16)) +
Chr(((Address and $FF00) shr 8)) + Chr(Address and $FF);
也就是把数值按三个字节位扯开,形成一串字符发给串口即可。
 
发送16进制字符串,如每两位表示一个16进制数值,则可通过下面循环进行转换。
for i := 0 to (Length(cmd) div 2) - 1 do
begin
DataStr := DataStr + Chr(StrToInt('$' + Copy(cmd, i * 2 + 1, 2)));
end;
发送DataStr即可
 
看到以上的贴子,禁不住说两句。

以上说的转换全是不需要的,发送,发送的是字节流,不是字符串,也不是什么整型。

SPComm控件发送数据的函数原型:
function TComm.WriteCommData( pDataToWrite: PChar;
dwSizeofDataToWrite: Word ): Boolean;
第一个参数,表明的是缓存区的起始地址,第二个参数,说明这是这缓冲区有多大(以byte
为单位),也就是说,要发送多少个字节。

上面的讨论,是对第一个参数产生了误解,认为是个字符串指针,遇到/0就会停止,若是
这样的话,要第二个参数干啥?!

在函数WriteCommData里,第一个参数用来指明缓冲区的首地址,指针的本质就是地址,所
以,姑且把这个指针定义成字符指针PChar,若定义成其它类型,如PByte,PWORD……,甚至
TObject,TForm……,都可以。因为这些类型的本质,都是指针。

若理解了上面所说,再看看下面的程序
// .. 发送程序
procedure TForm1.OnSend(Sender : TObject);
const
szBuffer : array[0..5] of Byte={0,1,2,3,4,5}; // 16进制表示:$10,$32, $54
begin
// 发送上面定义的6个字符,注意:第一个为‘/0’;
SPComm1.WriteCommData(PChar(@szBuffer[0]), sizeof(szBuffer));
end;
// 接收程序(简单起见,假设BufferLength >= sizeof(szBuffer))
procedure TForm1.OnReceive((Sender: TObject; Buffer: Pointer;
BufferLength: Word);
const
szBuffer : array[0..5] of Byte;
p : PByte;
i: integer;
begin
p:= PByte(Buffer);
for i=0 to sizeof(szBuffer) - 1 do
begin
szBuffer:= p^; Inc(p);
end;
// 这时szBuffer的值肯定是 0,1,2,3,4,5,用16进制表示仍然是:$10,$32, $54
end;

不知上述所说可曾明白?
 
同意RACER的看法,数据在计算机中都是一样的,只不过显示的时候按照要求STRING,BYTE,
ARRAY这样来显示。
procedure OnSend(Sender : TObject; pBuffer : Pointer; Size : Cardinal);
var
Buffer : string; //用字符串做缓冲区,省得自己管理
begin
CopyMemory(PChar(Buffer),pBuffer,Size); //pBuffer指向自己的16进制数据,Size为长度
Comm1.WriteCommData(PChar(Buffer),Size);
end;
 
同意RACER的看法,接受的时候也是一样的,不要管/0,
按他的length取值就可以了。
 
后退
顶部