菜鸟发问:SPCOMM通讯问题 (100分)

  • 主题发起人 主题发起人 forfor
  • 开始时间 开始时间
F

forfor

Unregistered / Unconfirmed
GUEST, unregistred user!
各位前辈好!我刚学DELPHI。我从网上下载了一个SPCOMM通讯的例子,但却不能编译通过。请大家帮我看看是哪里不对。先谢啦!

下面是一个利用 SPCOMM控件的串口通信的例子。

以实现 PC机与单片机 8051之间的通信为例,首先要调通它们之间的握手信号。假定它们之间的通信协议是: PC到 8051一帧数据 6个字节, 8051到 PC一帧数据也为 6个字节。当 PC发出( F0,01,FF,FF,01,F0)后 8051能收到一帧( F0,01,FF,FF,01,F0),表示数据通信握手成功,两者之间就可以按照协议相互传输数据。

创建一个新的工程 COMM.DPR,把窗体的 NAME属性定为 FCOMM,把窗体的标题定义为测试通信,按照图 2添加控件 (图 2中黑色矩形围住的控件即为 COMM1)。



图 2 (窗体中有一个发送按钮,一个关闭按钮,一个MEMO,一个COMM1)

1.设定 COMM1属性:

●波特率: 4800;

●奇偶校验位:无;

●字节长度: 8;

●停止位: 1;

●串口: COM1。

Memo1中将显示发送和接收的数据。将新的窗体存储为 Comm.pas。

2.编写源代码

//变量说明

var

fcomm: TFCOMM;

viewstring:string;

i:integer;

rbuf,sbuf:array[1..6] of byte;

//打开串口

procedure TFCOMM.FormShow(Sender: TObject);

begin

comm1.StartComm;

end;

//关闭串口

procedure TFCOMM.FormClose(Sender: TObject; var Action: TCloseAction);

begin

comm1.StopComm;

end;

//自定义发送数据过程

procedure senddata;

var

i:integer;

commflg:boolean;

begin

viewstring:=‘’ ;

commflg:=true;

for i:=1 to 6 do

begin

if not fcomm.comm1.writecommdata(@sbuf,1) then

begin

commflg:=false;

break;

end;

//发送时字节间的延时

sleep(2);

viewstring:=viewstring+ inttohex(sbuf,2)+‘’ ; end;

viewstring:=‘发送’+ viewstring;

fcomm.memo1.lines.add(viewstring);

fcomm.memo1.lines.add(‘’ );

if not commflg then messagedlg(‘发送失败 !’ ,mterror,[mbyes],0);

end;

//发送按钮的点击事件

procedure TFCOMM.Btn_sendClick(Sender: TObject);

begin

sbuf[1]:=byte($ f0); //帧头

sbuf[2]:=byte($ 01); //命令号

sbuf[3]:=byte($ ff);

sbuf[4]:=byte($ ff);

sbuf[5]:=byte($ 01);

sbuf[6]:=byte($ f0); //帧尾

senddata;//调用发送函数

end;

//接收过程

procedure TFCOMM.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;BufferLength: Word);

var

i:integer;

begin

viewstring:=‘’ ;

move(buffer^,pchar(@rbuf^),bufferlength); //请问这个buffer^中的^是什么意思?

for i:=1 to bufferlength do

viewstring:=viewstring+ inttohex(rbuf,2)+‘’ ;

viewstring:=‘接收’+ viewstring;

memo1.lines.add(viewstring);

memo1.lines.add(‘’ );

end;

如果 memo1上显示发送 F0 01 FF FF 01 F0和接收到 F0 01 FF FF 01 F0,这表示串口已正确地发送出数据并正确地接收到数据,则串口通信成功。
 
你先把中文的加号,单引号改成英文的再说吧.
 
我也参照这个做了一个串口通讯的很小的程序。如果需要
QQ:241268990
 
//我干脆帮你改好了!
//变量说明
var
fcomm: TFCOMM;
viewstring:string;
i:integer;
rbuf,sbuf:array[1..6] of byte;

//打开串口
procedure TFCOMM.FormShow(Sender: TObject);
begin
comm1.StartComm;
end;

//关闭串口
procedure TFCOMM.FormClose(Sender: TObject; var Action: TCloseAction);
begin
comm1.StopComm;
end;

//自定义发送数据过程
procedure senddata;
var
i:integer;
commflg:boolean;
begin
viewstring:="";
commflg:=true;
for i:=1 to 6 do
begin
if not fcomm.comm1.writecommdata(@sbuf,1) then
begin
commflg:=false;
break;
end;
//发送时字节间的延时
sleep(2);
viewstring:=viewstring + inttohex(sbuf,2) + "" ;
end;
viewstring:="发送"+ viewstring;
fcomm.memo1.lines.add(viewstring);
fcomm.memo1.lines.add("");
if not commflg then messagedlg("发送失败 !" ,mterror,[mbyes],0);
end;

//发送按钮的点击事件
procedure TFCOMM.Btn_sendClick(Sender: TObject);
begin
sbuf[1]:=byte($f0); //帧头
sbuf[2]:=byte($01); //命令号
sbuf[3]:=byte($ff);
sbuf[4]:=byte($ff);
sbuf[5]:=byte($01);
sbuf[6]:=byte($f0); //帧尾
senddata;//调用发送函数
end;

//接收过程
procedure TFCOMM.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;BufferLength: Word);
var
i:integer;
begin
viewstring :="";
move(buffer^,pchar(@rbuf^),bufferlength); //^是表示指针的意思,但这一句有错,我也不太记得怎么改了,我得看我得源程序了,在公司!
for i:=1 to bufferlength do
viewstring:=viewstring + inttohex(rbuf,2) + "";
viewstring:="接收" + viewstring;
memo1.lines.add(viewstring);
memo1.lines.add("");
end;

如果 memo1上显示发送 F0 01 FF FF 01 F0和接收到 F0 01 FF FF 01 F0,这表示串口已正确地发送出数据并正确地接收到数据,则串口通信成功。
 
你用了双引号 是不对的.
 
我修改后,编译后出现如下错误提示:
[Error]unit1.pas(17):unsatisfied forward or external declaration:'Tfcomm.senddata
整个源程序如下:
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, SPComm, StdCtrls;

type
Tfcomm = class(TForm)
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
Comm1: TComm;
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure senddata;             //这是第17行
procedure Button1Click(Sender: TObject);
procedure Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);

private
{ Private declarations }
public
{ Public declarations }

end;

var
fcomm: Tfcomm;
viewstring:string;
i:integer;
rbuf,sbuf:array[1..6] of byte;


implementation

{$R *.dfm}

procedure Tfcomm.FormShow(Sender: TObject);
begin
comm1.StartComm;
end;




procedure Tfcomm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
comm1.StopComm;
end;

procedure senddata;
var
i:integer;
commflg:boolean;
begin
viewstring:='';
commflg:=true;
for i:=1 to 6 do
begin
if not fcomm.comm1.writecommdata(@sbuf,1) then
begin
commflg:=false;
break;
end;
//发送时字节间的延时
sleep(2);
viewstring:=viewstring + inttohex(sbuf,2) + '';
end;
viewstring:='发送'+viewstring;
fcomm.memo1.lines.add(viewstring);
fcomm.memo1.lines.add('');
if not commflg then messagedlg('发送失败 !' ,mterror,[mbyes],0);
end;


procedure Tfcomm.Button1Click(Sender: TObject);
begin
sbuf[1]:=byte($f0); //帧头
sbuf[2]:=byte($01); //命令号
sbuf[3]:=byte($ff);
sbuf[4]:=byte($ff);
sbuf[5]:=byte($01);
sbuf[6]:=byte($f0); //帧尾
senddata;//调用发送函数
end;



procedure Tfcomm.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
i:integer;
begin
viewstring :='';
move(buffer^,rbuf,bufferlength);
for i:=1 to bufferlength do
viewstring:=viewstring + inttohex(rbuf,2) + '';
viewstring:='接收'+ viewstring;
memo1.lines.add(viewstring);
memo1.lines.add('');
end;

end.
 
你把17移出去.不能放在这个里面Tfcomm = class(TForm)
除非你在实现部份这样:procedure Tfcomm.senddata;
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, SPComm, StdCtrls;

type
Tfcomm = class(TForm)
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
Comm1: TComm;
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
procedure Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);

private
{ Private declarations }
public
{ Public declarations }

end;

procedure senddata;             //这是第17行
var
fcomm: Tfcomm;
viewstring:string;
i:integer;
rbuf,sbuf:array[1..6] of byte;


implementation

{$R *.dfm}

procedure Tfcomm.FormShow(Sender: TObject);
begin
comm1.StartComm;
end;




procedure Tfcomm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
comm1.StopComm;
end;

procedure senddata;
var
i:integer;
commflg:boolean;
begin
viewstring:='';
commflg:=true;
for i:=1 to 6 do
begin
if not fcomm.comm1.writecommdata(@sbuf,1) then
begin
commflg:=false;
break;
end;
//发送时字节间的延时
sleep(2);
viewstring:=viewstring + inttohex(sbuf,2) + '';
end;
viewstring:='发送'+viewstring;
fcomm.memo1.lines.add(viewstring);
fcomm.memo1.lines.add('');
if not commflg then messagedlg('发送失败 !' ,mterror,[mbyes],0);
end;


procedure Tfcomm.Button1Click(Sender: TObject);
begin
sbuf[1]:=byte($f0); //帧头
sbuf[2]:=byte($01); //命令号
sbuf[3]:=byte($ff);
sbuf[4]:=byte($ff);
sbuf[5]:=byte($01);
sbuf[6]:=byte($f0); //帧尾
senddata;//调用发送函数
end;



procedure Tfcomm.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
i:integer;
begin
viewstring :='';
move(buffer^,rbuf,bufferlength);
for i:=1 to bufferlength do
viewstring:=viewstring + inttohex(rbuf,2) + '';
viewstring:='接收'+ viewstring;
memo1.lines.add(viewstring);
memo1.lines.add('');
end;

end.
 
谢谢gianguobu!
上面的程序已调通。现在我想传送几个中文字符,把程序稍微改了一下,但好象不能接收,请大家再帮我看看啊


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, SPComm, StdCtrls;

type
Tfcomm = class(TForm)
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
Comm1: TComm;
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);

procedure Button1Click(Sender: TObject);
procedure Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);

private
{ Private declarations }
public
{ Public declarations }

end;
procedure senddata;

var
fcomm: Tfcomm;
viewstring:string;
i:integer;
rbuf,sbuf:array[1..6] of string;


implementation

{$R *.dfm}

procedure Tfcomm.FormShow(Sender: TObject);
begin
comm1.StartComm;
end;




procedure Tfcomm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
comm1.StopComm;
end;

procedure senddata;
var
i:integer;
commflg:boolean;
begin
viewstring:='';
commflg:=true;
for i:=1 to 6 do
begin
if not fcomm.comm1.writecommdata(@sbuf,1) then
begin
commflg:=false;
break;
end;
//发送时字节间的延时
sleep(2);
viewstring:=viewstring + sbuf + '';
end;
viewstring:='发送'+viewstring;
fcomm.memo1.lines.add(viewstring);
fcomm.memo1.lines.add('');
if not commflg then messagedlg('发送失败 !' ,mterror,[mbyes],0);
end;


procedure Tfcomm.Button1Click(Sender: TObject);
begin
sbuf[1]:='我'; //帧头
sbuf[2]:='爱'; //命令号
sbuf[3]:='我';
sbuf[4]:='的';
sbuf[5]:='祖';
sbuf[6]:='国'; //帧尾
senddata;//调用发送函数
end;



procedure Tfcomm.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
i:integer;
begin
viewstring :='';
move(buffer^,rbuf,bufferlength);
for i:=1 to bufferlength do
viewstring:=viewstring + rbuf + ' ';
viewstring:='接收'+ viewstring;
memo1.lines.add(viewstring);
memo1.lines.add('');
end;

end.
 
一个汉字是两个字节

我想你应该会改了吧.
 
多人接受答案了。
 
后退
顶部