procedure TForm1.Button1Click(Sender: TObject); var CommPort : string; hCommFile : THandle; Buffer : PCommConfig; size : DWORD; begin CommPort := 'COM1'; {Open the comm port} hCommFile := CreateFile(PChar(CommPort), GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if hCommFile=INVALID_HANDLE_VALUE then begin ShowMessage('Unable to open '+ CommPort); exit; end; {Allocate a temporary buffer} GetMem(Buffer, sizeof(TCommConfig)); {Get the size of the CommConfig structure} {as it may be different than documented} size := 0; GetCommConfig(hCommFile, Buffer^, size); {Free the temporary buffer} FreeMem(Buffer, sizeof(TCommConfig)); {Allocate the CommConfig structure} GetMem(Buffer, size); GetCommConfig(hCommFile, Buffer^, size); {Change the baud rate} Buffer^.dcb.BaudRate := 1200; {Set the comm port to the new configuration} SetCommConfig(hCommFile, Buffer^, size); {Free the buffer} FreeMem(Buffer, size); {Close the comm port} CloseHandle(hCommFile); end; ////////////////////////////////////////////////////////////////////////// procedure TForm1.Button1Click(Sender: TObject); var CommPort : string; hCommFile : THandle; Buffer : PCommConfig; size : DWORD; begin CommPort := 'COM1'; {Open the comm port} hCommFile := CreateFile(PChar(CommPort), GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if hCommFile=INVALID_HANDLE_VALUE then begin ShowMessage('Unable to open '+ CommPort); exit; end; {Get a temporary buffer} GetMem(Buffer, sizeof(TCommConfig)); {Get the size of the CommConfig structure} {as it may be different than documented} size := 0; GetCommConfig(hCommFile, Buffer^, size); {Free the temporary buffer} FreeMem(Buffer, sizeof(TCommConfig)); {Get the CommConfig structure} GetMem(Buffer, size); GetCommConfig(hCommFile, Buffer^, size); {Pop up the comm port config dialog} if CommConfigDialog(PChar(CommPort), Form1.Handle, Buffer^) = true then begin {Set the com port to the values entered} {in the dialog if the user pressed ok} SetCommConfig(hCommFile, Buffer^, size); end; {Free the buffer} FreeMem(Buffer, size); {Close the comm port} CloseHandle(hCommFile); end;采用Microsoft的MSComm控件。利用API编写串口通信程序较为复杂,需 要掌握大量通信知识,其优点是可实现的功能更强大,应用面更广泛,更适合于编 写较为复杂的低层次通信程序。而利用MSComm控件则相对较简单,该控件具有丰富 的与串口通信密切相关的属性及事件,提供了对串口的各种操作。 一、MSComm控件的主要属性及事件 (1)CommPort:设置或返回串行端口号,缺省为1。 (2)Setting:设置或返回串口通信参数,格式为“波特率,奇偶校验位,数 据位,停止位”。例如:MSComm1.Setting:='9600,n,8,1' (3)PortOpen:打开或关闭串行端口,格式为:MSComm1.PortOpen: ={True|False} (4)InBufferSize:设置或返回接收缓冲区的大小,缺省值为1024字节。 (5)InBufferCount:返回接收缓冲区内等待读取的字节数,可通过设置该属 性为0来清空接收缓冲区。 (6)RThreshold:该属性为一阀值,它确定当接收缓冲区内的字节个数达到 或超过该值后就产生代码为ComEvReceive的OnComm事件。 (7)SThreshold:该属性为一阀值,它确定当发送缓冲区内的字节个数少于 该值后就产生代码为ComEvSend的OnComm事件。 (8)InputLen:设置或返回接收缓冲区内用Input读入的字节数,设置该属性 为0表示Input读取整个缓冲区的内容。 (9)Input:从接收缓冲区读取一串字符。 (10)OutBufferSize:设置或返回发送缓冲区的大小,缺省值为512字节。 (11)OutBufferCount:返回发送缓冲区内等待发送的字节数,可通过设置该 属性为0来清空缓冲区。 (12)OutPut:向发送缓冲区传送一串字符。 如果在通信过程中发生错误或事件,就会引发OnComm事件,并由CommEvent属 性代码反映错误类型,在通信程序的设计中可根据该属性值来执行不同的操作。 CommEvent属性值及其含义如下: (1)ComEvSend:值为1,发送缓冲区的内容少于SThreshold指定的值。 (2)ComEvReceive:值为2,接收缓冲区内字符数达到RThreshold指定的值。
(3)ComEvFrame:值为1004,硬件检测到帧错误。 (4)ComEvRxOver:值为1008,接收缓冲区溢出。 (5)ComEvTxFull:值为1010,发送缓冲区溢出。 (6)ComEvRxParity:值为1009,奇偶校验错误。 (7)ComEvEOF:值为7,接收数据中出现文件尾(ASCII码为26)字符。 二、程序样例 在Delphi3.0中无法使用MSComm控件,笔者使用的是Delphi5.0。MSComm控件是 VB中的OCX控件,首先需要将其添加到Delphi中,选择菜单“Component”→“ Import ActiveX Control”,在“Import ActiveX”页内选择“Microsoft Comm Control”,点击“Install”安装,安装后在“ActiveX”组件板中出现MSComm图 标,即可被使用。有一点要注意,在Object Inspector中MSComm控件的Input和 Output属性是不可见的,但它们仍然存在,这两个属性的类型是OleVariant(Ole 万能变量)。 下面是一接收程序的样例(主要部分),大家可根据实际需要进行完善。 在Form中放置一Memo控件用于显示接收的数据,Combobox1选择通信参数( Setting属性值),Combobox2选择串口(CommPort属性值),按Button1开始接收 数据,按Button2停止接收。 procedure TForm1.FormCreate(Sender: TObject); begin Mscomm1.InBufferCount :=0; // 清空接收缓冲区 Mscomm1.InputLen :=0; // Input读取整个缓冲区内容 Mscomm1.RThreshold :=1; // 每次接收到字符即产生OnComm事件 end; procedure TForm1.Button1Click(Sender: TObject); begin Mscomm1.Settings :=ComboBox1.Text; if ComboBox2.Text ='com1' then // 假设只考虑com1和com2两种情况 Mscomm1.CommPort :=1 else Mscomm1.CommPort :=2; Mscomm1.PortOpen :=true; // 打开串口 Mscomm1.DTREnable :=true; // 数据终端准备好 Mscomm1.RTSEnable :=true; // 请求发送 end; procedure TForm1.Button2Click(Sender: TObject); begin Mscomm1.PortOpen :=false; // 关闭串口 Mscomm1.DTREnable :=false; Mscomm1.RTSEnable :=false; end; procedure TForm1.MSComm1Comm(Sender: TObject); var recstr:Olevariant; begin if Mscomm1.CommEvent = 2 then begin recstr := Mscomm1.Input ; Memo1.text := Memo1.Text + recstr; end; end;
unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, SPComm;type TForm1 = class(TForm) Comm1: TComm; Memo1: TMemo; edtcomm: TEdit; Label1: TLabel; Label2: TLabel; edtbaud: TEdit; Label3: TLabel; cmbByteSize: TComboBox; Label4: TLabel; cmbstopsize: TComboBox; Label5: TLabel; cmbparity: TComboBox; Button1: TButton; Button2: TButton; Button3: TButton; Button4: TButton; EdtSendText: TEdit; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Comm1ReceiveData(Sender: TObject; Buffer: Pointer; BufferLength: Word); procedure edtbaudExit(Sender: TObject); procedure cmbByteSizeExit(Sender: TObject); procedure cmbstopsizeExit(Sender: TObject); procedure cmbparityChange(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); private { Private declarations } public { Public declarations } end;const MinBase = 2; MaxBase = 36;var Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject); begin comm1.CommName :=edtcomm.Text ; comm1.BaudRate :=strtoint(edtbaud.Text); comm1.ByteSize :=TByteSize(cmbbytesize.ItemIndex); comm1.StopBits :=TStopBits(cmbstopsize.ItemIndex); comm1.Parity :=TParity(cmbparity.ItemIndex); try comm1.StartComm ; except raise Exception.Create('串口打开错误') end; end;procedure TForm1.Button2Click(Sender: TObject); begin comm1.StopComm ; end;function StrToNum(const s: string; base: Integer; neg: Boolean; max: Integer): Integer; var negate, done: Boolean; i, ind, len, digit, mmb: Integer; c: Char; mdb, res: Integer; begin res := 0; i := 1; digit := 0; if (base >= MinBase) and (base <= MaxBase) then begin mmb := max mod base; mdb := max div base; len := Length(s); negate := False; while (i <= len) and (s[i] = '') do Inc(i); if neg then begin case s[i] of '+': Inc(i); '-': begin Inc(i); negate := TRUE; end; end; (* CASE *) end; (* IF neg *) done := len > i; while (i <= len) and done do begin c := Upcase(s[i]); case c of '0'..'9': digit := ORD(c) - 48; 'A'..'Z': digit := ORD(c) - 55; else done := FALSE end; (* CASE *) done := done and (digit < base); if done then begin done := (res < mdb) or ((res = mdb) and (digit <= mmb)); if done then begin res := res * base + digit; Inc(i); end; (* IF done *) end; (* IF done *) end; (* WHILE *) if negate then res := -res; end; (* IF done *) Result := res; end;procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer; BufferLength: Word); var //strRecv:array of Byte; strRecv:string; i:integer; Temp:integer; begin setlength(strRecv,BufferLength); copyMemory(pChar(strRecv),Buffer,7); for i:=0 to High(strRecv) do Memo1.Lines.Add(inttostr(strRecv[i])); Memo1.Invalidate ; end;procedure TForm1.edtbaudExit(Sender: TObject); var i:integer; begin try i:=strtoint(edtbaud.Text); except edtbaud.SetFocus; raise exception.Create('错误'); end; comm1.BaudRate :=strtoint(edtbaud.Text); end;procedure TForm1.cmbByteSizeExit(Sender: TObject); begin comm1.ByteSize :=TByteSize(cmbbytesize.ItemIndex); end;procedure TForm1.cmbstopsizeExit(Sender: TObject); begin comm1.StopBits :=TStopBits(cmbstopsize.ItemIndex); end;procedure TForm1.cmbparityChange(Sender: TObject); begin comm1.Parity :=TParity(cmbparity.ItemIndex); end;procedure TForm1.Button3Click(Sender: TObject); begin Memo1.Clear; end;procedure TForm1.Button4Click(Sender: TObject); var str: Pchar; Count: integer; i:array [0..2]of Byte; begin str := Pchar(edtSendText.Text); Count := Length(str); if Comm1.WriteCommData(@i, Count) then Memo1.Lines.Add('已发送' + intTostr(Count) + '个字符') else raise exception.Create('发送错误'); end;end.用到了spcomm控件
怎样可以在同1台电脑上实现COM1 COM2端口通信 只需要传几个简单的字符就行
毕业论文 大侠救命
重酬~~~~~~~~~~~~~
菜鸟上#:(
怎样可以在同1台电脑上实现COM1 COM2端口通信 只需要传几个简单的字符就行
毕业论文 大侠救命
重酬~~~~~~~~~~~~~
菜鸟上#:(
COM1 COM2
RX RX
- -
- -
- -
- -
TX TX
按上图接好就OK
然后再找个通讯控件,很容易的,一个发,一个收。
连接方法:比如PC的a,b双方都是9针插座,使用全部信号线,a(2)-b(3),a(3)-b(2),a(4)-b(6),a(6)-b(4),a(7)-b(8),a(8)-b(7),a(5)-b(5)
使用方法:可用控件mscomm32.ocx,两端参数设置相同,RTS和DTR属性设为1,在COMM事件中编程
CreatFile
打 开 串 行 口
CloseHandle
关 闭 串 行 口
SetupComm
设 置 通 信 缓 冲 区 的 大 小
ReadFile
读 串 口 操 作
WriteFile
写 串 口 操 作
SetCommState
设 置 通 信 参 数
GetCommState
获 取 默 认 通 信 参 数
ClearCommError
procedure TForm1.Button1Click(Sender: TObject);
var
CommPort : string;
hCommFile : THandle;
Buffer : PCommConfig;
size : DWORD;
begin
CommPort := 'COM1';
{Open the comm port}
hCommFile := CreateFile(PChar(CommPort),
GENERIC_WRITE,
0,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if hCommFile=INVALID_HANDLE_VALUE then
begin
ShowMessage('Unable to open '+ CommPort);
exit;
end;
{Allocate a temporary buffer}
GetMem(Buffer, sizeof(TCommConfig)); {Get the size of the CommConfig structure}
{as it may be different than documented}
size := 0;
GetCommConfig(hCommFile, Buffer^, size); {Free the temporary buffer}
FreeMem(Buffer, sizeof(TCommConfig)); {Allocate the CommConfig structure}
GetMem(Buffer, size);
GetCommConfig(hCommFile, Buffer^, size); {Change the baud rate}
Buffer^.dcb.BaudRate := 1200; {Set the comm port to the new configuration}
SetCommConfig(hCommFile, Buffer^, size); {Free the buffer}
FreeMem(Buffer, size); {Close the comm port}
CloseHandle(hCommFile);
end;
//////////////////////////////////////////////////////////////////////////
procedure TForm1.Button1Click(Sender: TObject);
var
CommPort : string;
hCommFile : THandle;
Buffer : PCommConfig;
size : DWORD;
begin
CommPort := 'COM1';
{Open the comm port}
hCommFile := CreateFile(PChar(CommPort),
GENERIC_WRITE,
0,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if hCommFile=INVALID_HANDLE_VALUE then
begin
ShowMessage('Unable to open '+ CommPort);
exit;
end;
{Get a temporary buffer}
GetMem(Buffer, sizeof(TCommConfig));
{Get the size of the CommConfig structure}
{as it may be different than documented}
size := 0;
GetCommConfig(hCommFile, Buffer^, size);
{Free the temporary buffer}
FreeMem(Buffer, sizeof(TCommConfig));
{Get the CommConfig structure}
GetMem(Buffer, size);
GetCommConfig(hCommFile, Buffer^, size); {Pop up the comm port config dialog}
if CommConfigDialog(PChar(CommPort),
Form1.Handle,
Buffer^) = true then begin
{Set the com port to the values entered}
{in the dialog if the user pressed ok}
SetCommConfig(hCommFile, Buffer^, size);
end; {Free the buffer}
FreeMem(Buffer, size); {Close the comm port}
CloseHandle(hCommFile);
end;采用Microsoft的MSComm控件。利用API编写串口通信程序较为复杂,需
要掌握大量通信知识,其优点是可实现的功能更强大,应用面更广泛,更适合于编
写较为复杂的低层次通信程序。而利用MSComm控件则相对较简单,该控件具有丰富
的与串口通信密切相关的属性及事件,提供了对串口的各种操作。
一、MSComm控件的主要属性及事件
(1)CommPort:设置或返回串行端口号,缺省为1。
(2)Setting:设置或返回串口通信参数,格式为“波特率,奇偶校验位,数
据位,停止位”。例如:MSComm1.Setting:='9600,n,8,1'
(3)PortOpen:打开或关闭串行端口,格式为:MSComm1.PortOpen:
={True|False}
(4)InBufferSize:设置或返回接收缓冲区的大小,缺省值为1024字节。
(5)InBufferCount:返回接收缓冲区内等待读取的字节数,可通过设置该属
性为0来清空接收缓冲区。
(6)RThreshold:该属性为一阀值,它确定当接收缓冲区内的字节个数达到
或超过该值后就产生代码为ComEvReceive的OnComm事件。
(7)SThreshold:该属性为一阀值,它确定当发送缓冲区内的字节个数少于
该值后就产生代码为ComEvSend的OnComm事件。
(8)InputLen:设置或返回接收缓冲区内用Input读入的字节数,设置该属性
为0表示Input读取整个缓冲区的内容。
(9)Input:从接收缓冲区读取一串字符。
(10)OutBufferSize:设置或返回发送缓冲区的大小,缺省值为512字节。
(11)OutBufferCount:返回发送缓冲区内等待发送的字节数,可通过设置该
属性为0来清空缓冲区。
(12)OutPut:向发送缓冲区传送一串字符。
如果在通信过程中发生错误或事件,就会引发OnComm事件,并由CommEvent属
性代码反映错误类型,在通信程序的设计中可根据该属性值来执行不同的操作。
CommEvent属性值及其含义如下:
(1)ComEvSend:值为1,发送缓冲区的内容少于SThreshold指定的值。
(2)ComEvReceive:值为2,接收缓冲区内字符数达到RThreshold指定的值。
(3)ComEvFrame:值为1004,硬件检测到帧错误。
(4)ComEvRxOver:值为1008,接收缓冲区溢出。
(5)ComEvTxFull:值为1010,发送缓冲区溢出。
(6)ComEvRxParity:值为1009,奇偶校验错误。
(7)ComEvEOF:值为7,接收数据中出现文件尾(ASCII码为26)字符。
二、程序样例
在Delphi3.0中无法使用MSComm控件,笔者使用的是Delphi5.0。MSComm控件是
VB中的OCX控件,首先需要将其添加到Delphi中,选择菜单“Component”→“
Import ActiveX Control”,在“Import ActiveX”页内选择“Microsoft Comm
Control”,点击“Install”安装,安装后在“ActiveX”组件板中出现MSComm图
标,即可被使用。有一点要注意,在Object Inspector中MSComm控件的Input和
Output属性是不可见的,但它们仍然存在,这两个属性的类型是OleVariant(Ole
万能变量)。
下面是一接收程序的样例(主要部分),大家可根据实际需要进行完善。
在Form中放置一Memo控件用于显示接收的数据,Combobox1选择通信参数(
Setting属性值),Combobox2选择串口(CommPort属性值),按Button1开始接收
数据,按Button2停止接收。
procedure TForm1.FormCreate(Sender: TObject);
begin
Mscomm1.InBufferCount :=0; // 清空接收缓冲区
Mscomm1.InputLen :=0; // Input读取整个缓冲区内容
Mscomm1.RThreshold :=1; // 每次接收到字符即产生OnComm事件
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Mscomm1.Settings :=ComboBox1.Text;
if ComboBox2.Text ='com1' then // 假设只考虑com1和com2两种情况
Mscomm1.CommPort :=1
else
Mscomm1.CommPort :=2;
Mscomm1.PortOpen :=true; // 打开串口
Mscomm1.DTREnable :=true; // 数据终端准备好
Mscomm1.RTSEnable :=true; // 请求发送
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Mscomm1.PortOpen :=false; // 关闭串口
Mscomm1.DTREnable :=false;
Mscomm1.RTSEnable :=false;
end;
procedure TForm1.MSComm1Comm(Sender: TObject);
var
recstr:Olevariant;
begin
if Mscomm1.CommEvent = 2 then
begin
recstr := Mscomm1.Input ;
Memo1.text := Memo1.Text + recstr;
end;
end;
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, SPComm;type
TForm1 = class(TForm)
Comm1: TComm;
Memo1: TMemo;
edtcomm: TEdit;
Label1: TLabel;
Label2: TLabel;
edtbaud: TEdit;
Label3: TLabel;
cmbByteSize: TComboBox;
Label4: TLabel;
cmbstopsize: TComboBox;
Label5: TLabel;
cmbparity: TComboBox;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
EdtSendText: TEdit;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
procedure edtbaudExit(Sender: TObject);
procedure cmbByteSizeExit(Sender: TObject);
procedure cmbstopsizeExit(Sender: TObject);
procedure cmbparityChange(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;const
MinBase = 2;
MaxBase = 36;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
begin
comm1.CommName :=edtcomm.Text ;
comm1.BaudRate :=strtoint(edtbaud.Text);
comm1.ByteSize :=TByteSize(cmbbytesize.ItemIndex);
comm1.StopBits :=TStopBits(cmbstopsize.ItemIndex);
comm1.Parity :=TParity(cmbparity.ItemIndex);
try
comm1.StartComm ;
except
raise Exception.Create('串口打开错误')
end;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
comm1.StopComm ;
end;function StrToNum(const s: string; base: Integer;
neg: Boolean; max: Integer): Integer;
var
negate, done: Boolean;
i, ind, len, digit, mmb: Integer;
c: Char;
mdb, res: Integer;
begin
res := 0;
i := 1;
digit := 0;
if (base >= MinBase) and (base <= MaxBase) then
begin
mmb := max mod base;
mdb := max div base;
len := Length(s);
negate := False;
while (i <= len) and (s[i] = '') do
Inc(i);
if neg then
begin
case s[i] of
'+': Inc(i);
'-':
begin
Inc(i);
negate := TRUE;
end;
end; (* CASE *)
end; (* IF neg *)
done := len > i;
while (i <= len) and done do
begin
c := Upcase(s[i]);
case c of
'0'..'9': digit := ORD(c) - 48;
'A'..'Z': digit := ORD(c) - 55;
else
done := FALSE
end; (* CASE *)
done := done and (digit < base);
if done then
begin
done := (res < mdb) or ((res = mdb) and (digit <= mmb));
if done then
begin
res := res * base + digit;
Inc(i);
end; (* IF done *)
end; (* IF done *)
end; (* WHILE *)
if negate then
res := -res;
end; (* IF done *)
Result := res;
end;procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
//strRecv:array of Byte;
strRecv:string;
i:integer;
Temp:integer;
begin
setlength(strRecv,BufferLength);
copyMemory(pChar(strRecv),Buffer,7);
for i:=0 to High(strRecv) do
Memo1.Lines.Add(inttostr(strRecv[i]));
Memo1.Invalidate ;
end;procedure TForm1.edtbaudExit(Sender: TObject);
var
i:integer;
begin
try
i:=strtoint(edtbaud.Text);
except
edtbaud.SetFocus;
raise exception.Create('错误');
end;
comm1.BaudRate :=strtoint(edtbaud.Text);
end;procedure TForm1.cmbByteSizeExit(Sender: TObject);
begin
comm1.ByteSize :=TByteSize(cmbbytesize.ItemIndex);
end;procedure TForm1.cmbstopsizeExit(Sender: TObject);
begin
comm1.StopBits :=TStopBits(cmbstopsize.ItemIndex);
end;procedure TForm1.cmbparityChange(Sender: TObject);
begin
comm1.Parity :=TParity(cmbparity.ItemIndex);
end;procedure TForm1.Button3Click(Sender: TObject);
begin
Memo1.Clear;
end;procedure TForm1.Button4Click(Sender: TObject);
var
str: Pchar;
Count: integer;
i:array [0..2]of Byte;
begin
str := Pchar(edtSendText.Text);
Count := Length(str);
if Comm1.WriteCommData(@i, Count) then
Memo1.Lines.Add('已发送' + intTostr(Count) + '个字符')
else
raise exception.Create('发送错误');
end;end.用到了spcomm控件
成功了 马上散分 保证人人有分~~~~~~~~~~~~