MSComm控件串口接受数据?(100分)

Y

yjhzzgl

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大虾,请看:
485通讯指令协议
接口规格:
使用计算机对设备进行控制,计算机为主控制机(主机),设备为从机(分机)。
1、通讯方法:485异步通讯,双绞线总线方式
2、波特率:19200bps
3、控制字方式:1位开始位,8个数据位,一个停止位,无奇偶校验
通讯协议格式:
----------------------------------
|开始标志|分机地址|命令|数据|校验|
----------------------------------
[开始标志]长度1个字节,主机给分机发4个AAH
分机给主机发4个BBH
[分机地址]长度1个字节,00H---FEH
[广播地址]FFH
[参数]
[校验]长度1个字节,是设备地址、命令和参数中所有字节的异或和
--------------------------------------------------------------------
读记录
[功能]从设备读取一条读卡记录
[命令]A2H
[参数]
设备送回:从设备里读取一条记录,共4个字节(卡号)
如果设备此时没有记录可以送给主机,发送77h给主机。
例如:
主机:AA AA AA AA 08(分机地址) A2 aa
分机:BB BB BB BB 00 22 34 55 43(校验)
或者分机:BB BB BB BB 77 77(校验)
注意:卡号是4个字节的16进制数
////////////////////////////////////////////////////////////////////////////////
我这样接受数据:
procedure TForm1.MSComm1Comm(Sender: TObject);
var
vRec: variant;
sss:string;
begin
if mscomm1.CommEvent =2 then
begin
vRec:= MSComm1.Input;
sss:=vRec;
Memo1.Lines.Text:=Memo1.Lines.Text+sss;
end;
可是全都是乱码,是进制转换问题吗?论坛上查过了,都不详细,请高手指点,谢谢!
 
如果是十六进制,用这个函数转换:inttohex
 
提前!盼解!
 
你能不能说详细点呀,你的数据到底是二进制数据呢,还是ASCII字符数据?????

如果是二进制数据,当然是乱码啦,如果是ASCII字符数据,那会不会是错位了呢??
 
InputMode 常数
常数 值 描述
comInputModeText 0 (缺省)通过 Input 属性以文本方式取回数据。
comInputModeBinary 1 通过 Input 属性以二进制方式检取回数据。
试着更改一下这个属性看看,收下来的一不一样???
 
就算他试你这两个方式 ,但当对方以二进制方式发送的,而以文本方式取回数据,那当然是乱码了,这时只能把二进制换转成十六进制字符来显示.

如果以ASCII字符数据发送,当然以文本方式取回数据就不会是乱码了.
 
我没用过你这个控件,但我原来用另一个控件(忘了名字了:))时也出现这种情况,就拼命在程序里找错误,最后发现竟然是很自信没设错的控制字方式设错了。呵呵,建议再检查一下全部的设置属性:)
 
把你接受到的内容转化成字符串就可以了吧。用inttohex,
 
各位老大:
数据是以十六进制进制方式发送的,Input 属性设置只有两种:
1.comInputModeText 为0 以文本方式取回数据
2.comInputModeBinary为 1 以二进制方式检取回数据
以二进制方式检取回的数据如何以十进制方式显示。
谢谢!!
 
首先确定硬件有没有问题啊?这么高的波特率是比较容易出错的,不过从上面的情况看来应该是你以二进制方式传送数据的原因,把收到的数据用INTOHEX转换一下看看!
 
我有个串口调试的DEMO,你留个EMAIL,发一个你看一下吧
 
各位老大:
还是不行啊,哪位用过mscomm,请指教啊!
 
to app2001:
你好!谢谢指教。
e-mail:zhao6982118@yahoo.com.cn
 
各位老大:
不好意思,数据发送是这样的:
procedure TForm1.Button3Click(Sender: TObject);
var
buffer_send: array of byte;
begin
Mscomm1.DTREnable :=true;
Mscomm1.RTSEnable :=true;
MSComm1.OutBufferCount:=0;
buffer_send:=VarArrayCreate([0,6], varbyte);
buffer_send[0]:=$aa;
buffer_send[1]:=$aa;
buffer_send[2]:=$aa;
buffer_send[3]:=$aa;



mscomm1.Output:=buffer_send;
end;
buffer_send[0]可能以二进制进制方式发送数据,而不是以十六进制进制方式发送,对吗?
 
都是也二制的方式发送的.只是看你实际的数据到底是ASCII字符呢,还是十六进制.
就好像字符'3'一样,发送是以31发送出去的.不是十六进制的03.
 
发给你了
 
to jianguobu:
大虾,实际的数据是十六进制。
 
mscomm使用注意几点:
1。RThreshold:=?
//接收触发事件的字节数『如果设置不正确,接收到的数据可能丢失或者多余,假设设为1,则接收一个字节数,就触发一次MSComm1Comm事件』;
2。设置InputMode //0 - comInputModeText为只能接收ASCII码<128的字符,接收一般的数字,字符就够了,如果需要接收汉字,则设为1 - comInputModeBinary,它的ASCII接收范围为0~256;
3。需要判断length(RD)是否>0,大于0才开始读数据;
RD:string;
RD:=MSComm1.Input;
if length(RD)>0 then
begin
.....判断数据是否合法,然后进行相应的操作
end;
4。如果传输数据有延时,则需要在接收事件时先进行延时,等到数据全部接收完,再读数据。
 
如果收回来是二进制数,那这样显示数据肯定不对
procedure TForm1.MSComm1Comm(Sender: TObject);
var
vRec: variant;
sss:string;
begin
if mscomm1.CommEvent =2 then
begin
vRec:= MSComm1.Input;
sss:=vRec;
Memo1.Lines.Text:=Memo1.Lines.Text+sss;
end;
可以改成如下试试
procedure TForm1.MSComm1Comm(Sender: TObject);
var
vRec: array of byte;
i:integer;
begin
if mscomm1.CommEvent =2 then
begin
setlength(vRec,sizeof(MSComm1.Input));
vRec:= MSComm1.Input;
for i:=0 to length(vRec)-1 do
Memo1.Lines.append(inttohex(vRec)+' ');
end;
关键是要把接收到的数据一个BYTE一个BYTE的显示出来
 
各位老大:
请帮看看,楼上的 inttohex(vRec)编译有错误
[Error] Unit1.pas(121): There is no overloaded version of 'IntToHex' that can be called with these arguments
谢谢!
 

Similar threads

回复
0
查看
666
不得闲
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
740
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
顶部