16进制数据串口通讯的问题

lt8024 2008-07-22 03:43:28
最近一个项目用到以16进制数据进行串口通讯
要求:读取信号测量值
命令:A30CC
A (范围0X00-0XFF),表示指定传感器的16进制地址,一字节
30 功能码(十六进制)
CC CRC16校验码
回答:A3004(data)CC
A (范围0X00-0XFF),表示指定传感器的16进制地址,一字节
30 功能码(十六进制)
04 数据字节长度
data 四字节数据,表示信号的测量值
CC CRC16校验码

命令集中所有数据均为16进制表示

以前只做过串口读取ascii码的数据,没做过读取16进制数据,不知道怎么发送请求命令,并读取数据.还有数据是16进制的,在控件上要不要设什么

还有最后的crc16效验码不知道怎么生成,网上看见些现成的crc16函数,但不知道怎么和这问题结合起来

高手帮帮我啊,我一般使用cnrs232控件(spcomm的修改版)
...全文
330 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
yuqianyi1974 2008-07-22
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 yuqianyi1974 的回复:]
var
f:single;
b:array[0..3] of byte;//b[0]:=rbuf[3]还是b[0]:=rbuf[0]

begin

move(b,f,sizeof(f));
end;
[/Quote]
b中的顺序要变一下,你试一下
lt8024 2008-07-22
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 yuqianyi1974 的回复:]
定点还是浮点?高位在前还是地位在前?
[/Quote]

这些有什么影响吗,能不能解释下
lt8024 2008-07-22
  • 打赏
  • 举报
回复
刚找到crc16算法

unit CRCUnit;

interface
uses
Windows,SysUtils;
type
PBYTE =^Byte;

//计算CRC检验码
function Get_CRC16(const pData:Pointer;nLength:Integer):string;
//检验函数
function Check_CRC16(const pData:Pointer;nLength:Integer):Boolean;
//获取指定字符串的CRC验证码
function Get_CRC16Code(strValue : string) : string;

const
//16位的CRC检验表
CRCTable16 : array[0..255] of Word = (
$0000, $1189, $2312, $329b, $4624, $57ad, $6536, $74bf,
$8c48, $9dc1, $af5a, $bed3, $ca6c, $dbe5, $e97e, $f8f7,
$1081, $0108, $3393, $221a, $56a5, $472c, $75b7, $643e,
$9cc9, $8d40, $bfdb, $ae52, $daed, $cb64, $f9ff, $e876,
$2102, $308b, $0210, $1399, $6726, $76af, $4434, $55bd,
$ad4a, $bcc3, $8e58, $9fd1, $eb6e, $fae7, $c87c, $d9f5,
$3183, $200a, $1291, $0318, $77a7, $662e, $54b5, $453c,
$bdcb, $ac42, $9ed9, $8f50, $fbef, $ea66, $d8fd, $c974,
$4204, $538d, $6116, $709f, $0420, $15a9, $2732, $36bb,
$ce4c, $dfc5, $ed5e, $fcd7, $8868, $99e1, $ab7a, $baf3,
$5285, $430c, $7197, $601e, $14a1, $0528, $37b3, $263a,
$decd, $cf44, $fddf, $ec56, $98e9, $8960, $bbfb, $aa72,
$6306, $728f, $4014, $519d, $2522, $34ab, $0630, $17b9,
$ef4e, $fec7, $cc5c, $ddd5, $a96a, $b8e3, $8a78, $9bf1,
$7387, $620e, $5095, $411c, $35a3, $242a, $16b1, $0738,
$ffcf, $ee46, $dcdd, $cd54, $b9eb, $a862, $9af9, $8b70,
$8408, $9581, $a71a, $b693, $c22c, $d3a5, $e13e, $f0b7,
$0840, $19c9, $2b52, $3adb, $4e64, $5fed, $6d76, $7cff,
$9489, $8500, $b79b, $a612, $d2ad, $c324, $f1bf, $e036,
$18c1, $0948, $3bd3, $2a5a, $5ee5, $4f6c, $7df7, $6c7e,
$a50a, $b483, $8618, $9791, $e32e, $f2a7, $c03c, $d1b5,
$2942, $38cb, $0a50, $1bd9, $6f66, $7eef, $4c74, $5dfd,
$b58b, $a402, $9699, $8710, $f3af, $e226, $d0bd, $c134,
$39c3, $284a, $1ad1, $0b58, $7fe7, $6e6e, $5cf5, $4d7c,
$c60c, $d785, $e51e, $f497, $8028, $91a1, $a33a, $b2b3,
$4a44, $5bcd, $6956, $78df, $0c60, $1de9, $2f72, $3efb,
$d68d, $c704, $f59f, $e416, $90a9, $8120, $b3bb, $a232,
$5ac5, $4b4c, $79d7, $685e, $1ce1, $0d68, $3ff3, $2e7a,
$e70e, $f687, $c41c, $d595, $a12a, $b0a3, $8238, $93b1,
$6b46, $7acf, $4854, $59dd, $2d62, $3ceb, $0e70, $1ff9,
$f78f, $e606, $d49d, $c514, $b1ab, $a022, $92b9, $8330,
$7bc7, $6a4e, $58d5, $495c, $3de3, $2c6a, $1ef1, $0f78);

implementation

function Get_CRC16(const pData:pointer;nLength:Integer):string;
var
fcs : Word;
p : PBYTE;
begin
p := PBYTE(pData);
fcs := $ffff;
while(nLength>0)do
begin
fcs := (fcs shr 8) xor CRCTable16[(fcs xor p^) and $ff];
Dec(nLength);
Inc(p);
end;
Result := IntToStr(not fcs);
end;

function Check_CRC16(const pData:Pointer;nLength: Integer):Boolean;
var
fcs:Word;
p:PBYTE;
begin
p := PBYTE(pData);
fcs := $ffff;
while(nLength>0) do
begin
fcs := (fcs shr 8) xor CRCTable16[(fcs xor p^) and $ff];
Dec(nLength);
Inc(p);
end;
end;

function Get_CRC16Code(strValue : string) : string;
var
crc , i:Word;
begin
crc := 0;
for i:= 1 to length(strValue) do
begin
crc := CRCTable16[(Byte(crc shr 8) and $ff) xor (ord(strValue[i]) and $ff)] xor (crc shr 8);
end;
Result := IntTohex(crc,2);
end;

yuqianyi1974 2008-07-22
  • 打赏
  • 举报
回复
var
f:single;
b:array[0..3] of byte;

begin

move(b,f,sizeof(f));
end;
lt8024 2008-07-22
  • 打赏
  • 举报
回复
data为单精度浮点数,命令集中四字节data为浮点数的IEEE存储格式数据d[0],d[1].d[2],d[3],依次按照从高字节到低字节的先后顺序发送
yuqianyi1974 2008-07-22
  • 打赏
  • 举报
回复
定点还是浮点?高位在前还是地位在前?
yuqianyi1974 2008-07-22
  • 打赏
  • 举报
回复
你从下位机接收的数据格式是什么?是标准的float吗?
yuqianyi1974 2008-07-22
  • 打赏
  • 举报
回复
我的程序一直都是在用的,好用的
lt8024 2008-07-22
  • 打赏
  • 举报
回复
16进制看明白了

那收到的data是四字节的16进制数据,我怎么转换成实际数值(float数据)啊
lt8024 2008-07-22
  • 打赏
  • 举报
回复
ascii是这样做的

//发送
var
Output: array[1..3] of Char;
begin
Output := 'S'#13#10;
dmMain.RS232_1.WriteCommData(@OutPut[1], 3);
end;

//接收
procedure TdmMain.RS232_1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
Input: array of byte;
i: Integer;
begin
Input := Buffer;
for i := 0 to BufferLength - 1 do
begin
S_RS232[1] := S_RS232[1] + Chr(Input[i]);
end;
//分析串口接收到的数据
FenXiS_RS232(1);
end;

yuqianyi1974 2008-07-22
  • 打赏
  • 举报
回复
接收
procedure Tfrmmain.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
rbuf:array of byte;
begin
setLength(rbuf, BufferLength);
move(Buffer^, PChar(rbuf)^, BufferLength);
//如果接收的数据为$01 $30..那么 rbuf[0]=$01 rbuf[1]=$30 rbuf[2]
end;
yuqianyi1974 2008-07-22
  • 打赏
  • 举报
回复
var
buf: array[0..4] of byte;
procedure send;
begin
buf[0]:=$01;
buf[1]:=$30;
buf[2]:=..;
senddata(buf);
end;

procedure senddata(sbuf:array of byte);
begin
if not comm1.WriteCommData(@sbuf,length(sbuf)) then
begin
showmessage('发送错误');
end;
end;
luxuewei5214 2008-07-22
  • 打赏
  • 举报
回复
你ascii怎么发的啊?把ascii字符替换成十六进制的数就可以了啊,比如给一个byte数组的某一元素复制:
A[0]:=$30;
Corn1 2008-07-22
  • 打赏
  • 举报
回复
十六进制只是在程序内部表示用的,在网络上传输的还是十进制的。你用byte数组好了。
lt8024 2008-07-22
  • 打赏
  • 举报
回复
不明白

比如,我请求数据的时候该发什么(A30CC, A是0X01,30本来已经是16进制,CC要通过CRC16算出来)
返回的数据中,data是四字节的16进制,我如何转化为实际的数据啊
luxuewei5214 2008-07-22
  • 打赏
  • 举报
回复
会读ascii就会十六进制,十六进制数前加$就行:$A$30$CC;CRC校验有自己的一套算法吧,看看就行

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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