你好,请问各位高手们,我现在使用DELPHI+SPCOMM想开发一个对下位机设备的串口通讯程序,但是使用过程中遇到这样的问题,还想大家指教指教。比如MOBUS RTU 的协议我使用了3号命读取下位机的两段寄存器,(比如读取的寄存器是0200H~023FH,和0280H~02BFH)两段寄存器都是有64个的,
我用发送的命令分别是:03 03 02 00 00 40 44 60
:03 03 02 80 00 40 45 88
地址 3号命令 起始位置 读取长度 CRC校验接收的格式是:地址 命令号 数据长度 数据1 数据2........CRC校验
(两者返回数据开头都是:03 03 80 xx xx .........,返回长度也一样)对于以上的情况,就是发送的起始地址不同,但是读取长度是相同的,两个命令返回的数据都是131个字节,在SPCOMM的Comm1ReceiveData方法中要判断的话,要怎样判断啊?我是直接定义了一个定时器定时发送以上两个发送命令的,是不是能够设定我发送第一个命令后,一定要等接收了数据,判断后,再发送第二个命令这样啊?不是很懂, 不知一般是用长度来区分还是怎样做才好,迷茫中,请高手们指教指教还有一个问题就是,如果我发送的命令比较多,是不是都要在一个Comm1ReceiveData方法里面判断啊?如果程序较大,是不是能够单独出来一个单元直接用来发送接收的,再传给其他单元使用啊?????不知具体是用全局变量还是怎样做,还请高手指导一下,最好能详细一点,小弟不胜感激,谢谢谢谢
我用发送的命令分别是:03 03 02 00 00 40 44 60
:03 03 02 80 00 40 45 88
地址 3号命令 起始位置 读取长度 CRC校验接收的格式是:地址 命令号 数据长度 数据1 数据2........CRC校验
(两者返回数据开头都是:03 03 80 xx xx .........,返回长度也一样)对于以上的情况,就是发送的起始地址不同,但是读取长度是相同的,两个命令返回的数据都是131个字节,在SPCOMM的Comm1ReceiveData方法中要判断的话,要怎样判断啊?我是直接定义了一个定时器定时发送以上两个发送命令的,是不是能够设定我发送第一个命令后,一定要等接收了数据,判断后,再发送第二个命令这样啊?不是很懂, 不知一般是用长度来区分还是怎样做才好,迷茫中,请高手们指教指教还有一个问题就是,如果我发送的命令比较多,是不是都要在一个Comm1ReceiveData方法里面判断啊?如果程序较大,是不是能够单独出来一个单元直接用来发送接收的,再传给其他单元使用啊?????不知具体是用全局变量还是怎样做,还请高手指导一下,最好能详细一点,小弟不胜感激,谢谢谢谢
解决方案 »
- 各位大侠帮我详细一下这段代码的含义行吗?
- 请教:学习CSDN的“绝对经典的完整的RPG”源码
- if CheckBox1.click=true then Label1.visable=true...以此类推CheckBox是第几,Label1就是第几,怎么写?
- 请问怎么捕获收到的ICMP报文??
- 进来拿分吧(Treeview控件怎么判断被select的节点没有子节点)
- combobox问题
- 如何实现“超级兔子”那样的虚拟桌面?
- 动态调用动态连接库的时传参数的问题!
- 查询符合条件的记录显示在表格中
- 不知是否荒唐,大虾请
- 图片的属性问题(the image property)
- delphi中类似VB中函数string(),这样的函数吗?
2 spcomm组件有个readintervaltimeout属性用来设置,Comm1ReceiveData事件的时间,简单的说如果Comm1ReceiveData=100,那么在一百ms的时间中的数据有200个那么bufferlength就是200
2,这只是程序结构上的问题,这个随便你了,你可以在commentsreceivedata里先根据命令号先做一次区分,在调用不同的函数来解析。
至于是否用 全局变量也是看你通讯的数据了,如果非常固定,你可以使用了。这个东西没什么太多建议,主要是和你具体的工作相关。
const
sendarr1: array[0..7] of byte=(03,03,02,00,00,40,44,60);
sendarr2: array[0..7] of byte=(03,03,02,80,00,40,45,88);var
sendflag: integer;
rdat1,rdat2: array[0..130] of byte;procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
rbuf: array of byte;
i: integer;
begin
setLength(rbuf, BufferLength);
move(Buffer^, PChar(rbuf)^, BufferLength);
if (bufferlength=131) and (sendflag=1) then
begin
// rdat1<-rbuf
end;
if (bufferlength=131) and (sendflag=2) then
begin
//rdat2<-rbuf
end;
end;procedure TForm1.send(sbuf: array of byte);
begin
for i:=0 to length(sbuf)-1 do
comm1.WriteCommData(sbuf,length(sbuf));
end;procedure TForm1.Button1Click(Sender: TObject);
begin
sendflag:=1;
send(sendarr1);
sleep(100);
sendflag:=2;
send(sendarr2);end;
begin
for i:=0 to length(sbuf)-1 do
begin
comm1.WriteCommData(sbuf[i],1);
//这儿是否需要考虑延时
end;
end;
我用MSCOOM32.OCX轮询同步方式访问(非事件),应答很快;
很简单!你给它发MODBUS串,发完后就在规定的时间内(否则超时处理)接收应答.
procedure TForm1.send(sbuf: array of byte);
begin
comm1.WriteCommData(sbuf,length(sbuf));
end;
//1、将MODEM通讯用的参数去除,不受0x11和0X13限制
//2、简化串口参数设置过程
//3、提高发送数据接收目标窗体效率
//4、注意:目标窗体接收过程和发送速度1定要匹配呵呵,注意组件中是用POSTMESSAGE的,上位机接收速度跟不上会丢包的。
学习组件前,建议楼主学下:
1、事件、信号在线程控制中的作用;
2、用消息传递数据(为了封装读的事件,记得这里好象有个缓冲复制过程,影响效率);
3、重叠结构异步读写的作用。
学习透彻了应该比较收益的。