关于串口传输数据的大小写和异或效验值的问题 (200分)

H

hmuyu

Unregistered / Unconfirmed
GUEST, unregistred user!
小弟刚接触delphi不久,本人又比较愚笨,所以想各位高手解决一下问题。不胜感激。
程序如下,其中i1,k1,s2为全局变量。
var
s1:string;
k:integer;
begin
richedit1.Text:=('e7'+ '01'+'c1'+'04'+'00'+'00'+s1+'e8');//s1为其中要求的异或效验值。
k:=length(richedit1.Text);
k1:=k div 2;
fillmemory(@sbuf,255,0);
for i1:=0 to (k div 2)-1 do
begin
s2:=s2+chr(strtoint('$'+copy(richedit1.Text,2*i1+1,2)));
end;
p:=pchar(s2);
copymemory(@sbuf,p,k1);//k1如果换成strlen(p),数据中如出现‘00‘的话,
后面的数据就会全变成零,不知道为什么。
senddata;
end;

function senddata;
var
commflg:boolean;
begin
str1:='';
commflg:=true;
for i1:=1 to (k div 2) do
begin
if not form1.Comm1.WriteCommData(@sbuf[i1,1) then
begin
commflg:=false;
break;
end;
sleep(0);
str1:=str1+inttohex(sbuf[i1],2)+'';
end;
str1:='发送'+str1;
form1.Memo1.Lines.Add(str1);
form1.Memo1.Lines.Add('');
if not commflg then messagedlg('发送失败',mterror,[mbyes],0);
end;
很奇怪,我接到的数据是‘E701C104....'全是大写了,谁能帮我改一下。再者不知道异或效验值的算法如何?
分不够可再加。
 
大家帮小弟看一下!谢谢了
 
你是将字符变成16进制,所以不可能区分出大小写。可以先将字符变成响应的ASCLL码在发出,
就可以了。我不知道你指的异或效验值的算法是什么,如果是针校验位的话可以通过算法实现。
具体可以再讨论一下。至于k1如果换成strlen(p),数据中如出现‘00‘的话,后面的数据就会
全变成零的问题可能是认为00作为数组的结束标志了,你可以得到数组的长度后用循环语句完成。
我刚做了一个发送16进制并且带针校验位的程序,或许可以对你有帮助。
zj_cnc@sina.com.cn
 
可以查查相关的资料,搞串口的程序用不着自己编写吧,何况你还是新手,找个控件用吧,
很方便的,如果想控件和例子,请来EMIAL:b5790930@pub.xz.jsinfo.net。
 
to truecat:我用的是spcomm控件。
to 光芒:把字符变成ascii码,怎么实现,我试了很久,找不到资料,能不能说明白一些。
至于‘00’问题,好像传完‘00’后,数据还在传,没有停止。异或效应值是从‘e’开始,
和后位进行异或,所得值再和后位异或,到s1的前位为止。我们老总说要转换成二进制进行
异或。我不知道怎么实现。帮我看看。
 
第一个问题:
STRLEN是计算NULL-TERMINATE即空字符结尾的字符串的长度,你的数据中出现‘00’
经过chr(strtoint('$'+copy(richedit1.Text,2*i1+1,2)));也就是在字符串中出现了
NULL(空字符串结束标记),所以你拷贝的只有这空字符前面部分的字符了,又因为
你的fillmemory(@sbuf,255,0);将内存初始化为全0,所以在这空字符后面的所有单元
没有改变,仍然全为0;
第二个问题:
是因为inttohex这个函数返回的就是大写的十六进制字符串,至于要怎么和你的发送
端大小写保持一致则要经过一些技术处理,例如约定将一字节的第八BIT置为1表示大写,
置为0则表示小写,接收端经过逆过程处理解读;
第三个问题:
校验算法种类繁多,你说的异或效验值可以在发送时求出所有数据的异或效验和,如
xor_value:=0;
for i:=0 to length( datalength -1 ) do
xor_value:=xor_value xor data;
然后将xor_value一同发送,在接收端将接收到的数据经过同样的异或求和试看是不是
和接收到的xor_value一样以达到校验的目的。


 
to 刘李子,第一个问题已经明白。第二个问题,你能不能帮我实现一下,因为是新手,可能
实现比较困难。第三个问题,字符串的异或效验我已经知道,但老总说要先换成二进制。我
不知是什么道理。
我的email:hmuyu@sina.com
 
转换成二进制,就是ord(richedit1.text)
 
to 刘李子:我在补充一点,我数据是向单片机传的,而且接收方的单片机已经做好,
所以只能改发送的数据。
 
这是一个纯算法的问题阿!
而且有涉及到硬件通讯,所以要双方协调好才行,不过有时候硬件已经做完了,就逼着我们
做一些不可思议的事情,没办法啊!
 
不知道你的单片机软件只认小写字母呢
还是你要达到发送的是大写字母最后还是大写字母,发送的是小写字母最后还是小写字母?
你的硬件连接是如下关系么?
|---你的程序---| |--------------|
|e701c1040000e8|----------发送----------------->| 单 |
| | | 片 |
| | | 机 |
| | | |
|e701c1040000e8|<---------读取数据--------------|--------------|
|--------------|
注:发送接收数据同一应用程序?????
 
inttohex转换后,全部都变成了大写的
如果你想用ascii码,先用ord函数获取字符的ascii码,然后把ascii码作为16进制发送出去
收的时候,把收到的16进制数用chr函数转换成正常字符就可以了
 
接受答案了!
 
多人接受答案了。
 
顶部