在Delphi环境下使用PComm Pro通讯函数库必须先引入函数声明,将用到的3个单元文件分别是Global.pas、Mxtool.pas、PComm.pas,预先复制到工程目录中,在工程使用加入单元功能将这3个模块加入工程中即可。 数据的输入输出包括了串行数据的送出、读入、硬件线路的控制/检测及事件的引发与执行等函数;所有函数均有返回值,错误返回值均以常数定义在PComm.pas模块中,如下: (********** PComm.pas -- PComm Lib unit for Delphi (32 bit version).
History: Date Author Comment 5/29/98 Casper Wrote it. 12/11/98 Casper Update
{ 调制解调器线路状态 modem line status } S_CTS = $1; S_DSR = $2; S_RI = $4; S_CD = $8;
{ 错误代码 error code } SIO_OK = 0; //正确 SIO_BADPORT = -1; { 没有此端口或端口未打开 No such port or port not opened } SIO_OUTCONTROL = -2; { 无法控制此板 Can't control board } SIO_NODATA = -4; { 没有数据供读取或没有缓冲区供写入 No data to read or no buffer to write } SIO_OPENFAIL = -5; { 没有此端口或端口已打开 No such port or port has opened } SIO_RTS_BY_HW = -6; { 因为H/W流量控制而不能设置RTS Can't set because H/W flowctrl } SIO_BADPARM = -7; { 无效参数 Bad parameter } SIO_WIN32FAIL = -8; (* 调用WIN32函数失败请调用GetLastError函数以获取错误代码 Call win32 function fail, please call } GetLastError to get the error code *) SIO_BOARDNOTSUPPORT = -9; { 此版不支持这个函数 Board does not support this function} SIO_FAIL = -10; { PCOMM函数执运行结果失败 PComm function run result fail } SIO_ABORT_WRITE = -11; { 写入已被锁定,用户也放弃写入 Write has blocked, and user abort write } SIO_WRITETIMEOUT = -12; { 已发生写入超时 Write timeout has happened }
{ 文件传输错误代码 file transfer error code } SIOFT_OK = 0; //正确 SIOFT_BADPORT = -1; { 通讯端口不存在或未打开 No such port or port not open } SIOFT_TIMEOUT = -2; { 协议超时 Protocol timeout } SIOFT_ABORT = -3; { 用户键入的放弃 User key abort } SIOFT_FUNC = -4; { 函数返回的放弃 Func return abort } SIOFT_FOPEN = -5; { 无法打开文件 Can not open files } SIOFT_CANABORT = -6; { YMODEM取消信号终止 Ymodem CAN signal abort } SIOFT_PROTOCOL = -7; { 协议错误检测终止 Protocol checking error abort } SIOFT_SKIP = -8; { ZMODEM远程忽略此文件 Zmodem remote skip this send file } SIOFT_LACKRBUF = -9; { ZMODEM接收缓冲区过小 Zmodem Recv-Buff size must >= 2K bytes } SIOFT_WIN32FAIL = -10; (* 操作系统失败 OS fail } GetLastError to get the error code *) //调用GetLastError函数取得错误代码 SIOFT_BOARDNOTSUPPORT = -11; { 此版不支持这个函数 Board does not support this function}
function sio_flowctrl(port, mode: Longint): Longint; stdcall; (* 设置软件或硬件流量控制。有两个参数, 第一个是通讯端口号码,第二个是流量控制的设置,如下: mode=bit 0:CTS flow control bit 1:RTS flow control bit 2:Tx XON/XOFF flow control bit 3:Rx XON/XOFF flow control(0=OFF,1=ON) *)
function sio_linput(port: Longint; buf:PChar; len: Longint; term:Longint): Longint; stdcall;
function sio_putch(port, term: Longint): Longint; stdcall; (*将一个字符写到输出缓冲区。有两个参数,其一是 端口号,第二是将传送出去的字节(数值0~255)。*)
function sio_putb(port: Longint; buf:PChar; len: Longint): Longint; stdcall;
function sio_write(port: Longint; buf:PChar; len: Longint): Longint; stdcall; (*输出字符串。有三个参数, 第一个是端口号;第二是输出字符串的地址;第三是输出字符串的长度。*)
function sio_putb_x(port: Longint; buf:PChar; len: Longint; tick:Longint): Longint; stdcall;
function sio_putb_x_ex(port: Longint; buf:PChar; len: Longint; tms:Longint): Longint; stdcall;
function sio_lstatus(port: Longint): Longint; stdcall; (* 得到现在硬件线路的状态(DCD、CTS、DSR、RI)。 参数只有一个,通讯端口号码;返回值由0位至第3位分别表示CTS、DSR、RI、CD四条线的状态。*)
function sio_iqueue(port: Longint): Longint; stdcall; function sio_oqueue(port: Longint): Longint; stdcall; function sio_Tx_hold(port: Longint): Longint; stdcall; function sio_getbaud(port: Longint): Longint; stdcall; function sio_getmode(port: Longint): Longint; stdcall; function sio_getflow(port: Longint): Longint; stdcall; function sio_data_status(port: Longint): Longint; stdcall;
function sio_break(port, time: Longint): Longint; stdcall; function sio_view(port: Longint; buf: PChar; len: Longint): Longint; stdcall; function sio_TxLowWater(port, size: Longint): Longint; stdcall;
function sio_AbortWrite(port: Longint): Longint; stdcall; (*终止输出的动作。有一个参数,即通讯端口号码*)
function sio_AbortRead(port: Longint): Longint; stdcall; (*中断字符或字符串的读取。有一个参数,端口号*)
function sio_SetWriteTimeouts(port, timeouts: Longint): Longint; stdcall; function sio_GetWriteTimeouts(port: Longint; var TotalTimeouts:Longint): Longint; stdcall; function sio_SetReadTimeouts(port, TotalTimeouts, IntervalTimeouts: Longint): Longint; stdcall; function sio_GetReadTimeouts(port: Longint; var TotalTimeouts, IntervalTimeouts: Longint): Longint; stdcall;
//文件传输函数
function sio_FtASCIITx(port:Longint; fname:PChar; func:CallBackProc; key:Longint): Longint; stdcall; {使用ASCII协议传送文件。参数4个:第一个是端口号码;第二个是传送的文件名;第三个是回调函数,用来指明传输的 相关状态;第四个是用户定义的取消快速键}
function sio_FtASCIIRx(port:Longint; fname:PChar; func:CallBackProc; key:Longint; sec:Longint): Longint; stdcall; {使用ASCII协议接收文件。参数5个,第一个是端口号码;第二个是文件名称;第三个是回调函数,用来指明传输的 相关状态;第四个是用户定义的取消快速键;第五个是以秒计的超时时间}
function sio_FtXmodemCheckSumTx(port:Longint; fname:PChar; func:CallBackProc; key:Longint): Longint; stdcall; {使用XMODEM,Checksum协议传送文件。有四个参数:第一个是端口号;第二个是文件名;第三个是回调函数; 第四个是用户定义的取消快速键}
function sio_FtXmodemCheckSumRx(port:Longint; fname:PChar; func:CallBackProc; key:Longint): Longint; stdcall; {使用XMODEM,Checksum协议接收文件。有四个参数:第一个是端口号;第二个是文件名;第三个是回调函数; 第四个是用户定义的取消快速键}
function sio_FtXmodemCRCTx(port:Longint; fname:PChar; func:CallBackProc; key:Longint): Longint; stdcall; {使用XMODEM,CRC协议传送文件。有四个参数:第一个是端口号;第二个是文件名;第三个是回调函数; 第四个是用户定义的取消快速键}
function sio_FtXmodemCRCRx(port:Longint; fname:PChar; func:CallBackProc; key:Longint): Longint; stdcall; {使用XMODEM,CRC协议接收文件。有四个参数:第一个是端口号;第二个是文件名;第三个是回调函数; 第四个是用户定义的取消快速键}
function sio_FtXmodem1KCRCTx(port:Longint; fname:PChar; func:CallBackProc; key:Longint): Longint; stdcall; {使用XMODEM,1K CRC协议传送文件。有四个参数:第一个是端口号;第二个是文件名;第三个是回调函数; 第四个是用户定义的取消快速键}
function sio_FtXmodem1KCRCRx(port:Longint; fname:PChar; func:CallBackProc; key:Longint): Longint; stdcall; {使用XMODEM,1K CRC协议接收文件。有四个参数:第一个是端口号;第二个是文件名;第三个是回调函数; 第四个是用户定义的取消快速键}
function sio_FtYmodemTx(port:Longint; fname:PChar; func:CallBackProc; key:Longint): Longint; stdcall; {使用YXMODEM协议传送文件。有4个参数:第一个是端口号;第二个是文件名;第三个是回调函数; 第四个是用户定义的取消快速键}
function sio_FtYmodemRx(port:Longint; var fname:PChar;fno:LongInt;func:CallBackProc; key:Longint): Longint; stdcall; {使用YXMODEM协议接收文件。有5个参数:第一个是端口号;第二个是文件数据数组地址;第三个是可接收的最多文件数; 第四个是回调函数;第五个是用户定义的取消快速键}
function sio_FtZmodemTx(port:Longint; fname:PChar; func:CallBackProc; key:Longint): Longint; stdcall; {使用ZXMODEM协议传送文件。有4个参数:第一个是端口号;第二个是文件名;第三个是回调函数; 第四个是用户定义的取消快速键}
function sio_FtZmodemRx(port:Longint; var fname:PChar;fno:LongInt;func:CallBackProc; key:Longint): Longint; stdcall; {使用ZXMODEM协议接收文件。有5个参数:第一个是端口号;第二个是文件数据数组地址;第三个是可接收的最多文件数; 第四个是回调函数;第五个是用户定义的取消快速键}
function sio_FtKermitTx(port:Longint; fname:PChar; func:CallBackProc; key:Longint): Longint; stdcall; {使用Kermit协议传送文件。有4个参数:第一个是端口号;第二个是文件名;第三个是回调函数; 第四个是用户定义的取消快速键}
function sio_FtKermitRx(port:Longint; var fname:PChar;fno:LongInt;func:CallBackProc; key:Longint): Longint; stdcall; {使用Kermit协议接收文件。有5个参数:第一个是端口号;第二个是文件数据数组地址;第三个是可接收的最多文件数; 第四个是回调函数;第五个是用户定义的取消快速键}
implementation function sio_open; external 'PComm.dll'; function sio_close; external 'PComm.dll'; function sio_ioctl; external 'PComm.dll'; function sio_flowctrl; external 'PComm.dll'; function sio_flush; external 'PComm.dll'; function sio_DTR; external 'PComm.dll'; function sio_RTS; external 'PComm.dll'; function sio_lctrl; external 'PComm.dll'; function sio_baud; external 'PComm.dll'; function sio_getch; external 'PComm.dll'; function sio_read; external 'PComm.dll'; function sio_linput; external 'PComm.dll'; function sio_putch; external 'PComm.dll'; function sio_putb; external 'PComm.dll'; function sio_write; external 'PComm.dll'; function sio_putb_x; external 'PComm.dll'; function sio_putb_x_ex; external 'PComm.dll'; function sio_lstatus; external 'PComm.dll'; function sio_iqueue; external 'PComm.dll'; function sio_oqueue; external 'PComm.dll'; function sio_Tx_hold; external 'PComm.dll'; function sio_getbaud; external 'PComm.dll'; function sio_getmode; external 'PComm.dll'; function sio_getflow; external 'PComm.dll'; function sio_data_status; external 'PComm.dll'; function sio_term_irq; external 'PComm.dll'; function sio_cnt_irq; external 'PComm.dll'; function sio_modem_irq; external 'PComm.dll'; function sio_break_irq; external 'PComm.dll'; function sio_Tx_empty_irq; external 'PComm.dll'; function sio_break; external 'PComm.dll'; function sio_view; external 'PComm.dll'; function sio_TxLowWater; external 'PComm.dll'; function sio_AbortWrite; external 'PComm.dll'; function sio_AbortRead; external 'PComm.dll'; function sio_SetWriteTimeouts; external 'PComm.dll'; function sio_GetWriteTimeouts; external 'PComm.dll'; function sio_SetReadTimeouts; external 'PComm.dll'; function sio_GetReadTimeouts; external 'PComm.dll'; function sio_FtASCIITx; external 'PComm.dll'; function sio_FtASCIIRx; external 'PComm.dll'; function sio_FtXmodemCheckSumTx; external 'PComm.dll'; function sio_FtXmodemCheckSumRx; external 'PComm.dll'; function sio_FtXmodemCRCTx; external 'PComm.dll'; function sio_FtXmodemCRCRx; external 'PComm.dll'; function sio_FtXmodem1KCRCTx; external 'PComm.dll'; function sio_FtXmodem1KCRCRx; external 'PComm.dll'; function sio_FtYmodemTx; external 'PComm.dll'; function sio_FtYmodemRx; external 'PComm.dll'; function sio_FtZmodemTx; external 'PComm.dll'; function sio_FtZmodemRx; external 'PComm.dll'; function sio_FtKermitTx; external 'PComm.dll'; function sio_FtKermitRx; external 'PComm.dll';
var Form1: TForm1; DTRMode,RTSMode,Port:Integer; Function PortSet():Boolean; implementation uses PComm,MxTool,EXGLOBAL; //PCOmm引用声明放于此 {$R *.DFM}
//以下是打开通信端口的程序 procedure TForm1.btnOpenPortClick(Sender: TObject); var Ret:Integer; begin //打开通信端口 Port := rdCom.ItemIndex+1; //指定通信端口 Ret := sio_Open(Port); If ret <> SIO_OK Then begin ShowMessage('打开通信端口错误'); sio_close (Port); Exit; end; If Not PortSet() Then //参数设置 begin sio_close(Port); ShowMessage('通信端口参数设置发生错误'); Exit; End; //降低DTR及RTS的电压 ret := sio_DTR(Port, 0); ret := sio_RTS(Port, 0); //激活定时器 Timer1.Enabled := True; end;
//以下是结束按钮的动作 procedure TForm1.btnEndClick(Sender: TObject); begin //关闭通信端口 sio_Close(Port); //结束程序 close; end;
procedure TForm1.Timer1Timer(Sender: TObject); var Ret:Integer; begin ret := sio_lstatus(Port);//读取状态 If ret < 0 Then begin ShowMessage('状态错误'); Timer1.Enabled := False; end Else begin //各线路状态检查 If (ret And S_DSR) > 0 Then spDSR.Brush.Color := clRed Else spDSR.Brush.Color := clWhite;
If (ret And S_CD) > 0 Then spCD.Brush.Color := clRed Else spCD.Brush.Color := clWhite;
If (ret And S_RI) > 0 Then spRI.Brush.Color := clRed Else spRI.Brush.Color := clWhite;
If (ret And S_CTS) > 0 Then spCTS.Brush.Color := clRed Else spCTS.Brush.Color := clWhite; End;
end;
procedure TForm1.btnDTRClick(Sender: TObject); var ret:Integer; begin //计算DTR线路状态 DTRMode := (DTRMode + 1) Mod 2 ; If DTRMode = 1 Then spDTR.Brush.Color:=clRed Else spDTR.Brush.Color:=clWhite; //控制DTR线路状态 ret := sio_DTR(Port, DTRMode); If ret <> SIO_OK Then begin ShowMessage('DTR控制错误'); Exit; end; end;
procedure TForm1.btnRTSClick(Sender: TObject); var ret:Integer; begin //计算RTS状态 RTSMode := (RTSMode + 1) Mod 2 ; If RTSMode = 1 Then spRTS.Brush.Color:=clRed Else spRTS.Brush.Color:=clWhite; //控制RTS状态 ret := sio_RTS(Port, RTSMode); If ret <> SIO_OK Then begin ShowMessage('RTS控制错误'); Exit; end; end;
//以下是通信参数的函数实现 Function PortSet():Boolean; var mode,Hw,Sw,ret,tout:LongInt; begin //参数设置子程序 mode := P_NONE Or BIT_8 Or STOP_1; Hw := 0 ; //没有硬件流量控制 Sw := 0 ; //没有软件流量控制 Result := False ; ret := sio_ioctl(Port, B38400, mode); //Setting If ret <> SIO_OK Then begin ShowMessage('设置时发生错误'); Exit; end; ret := sio_flowctrl(Port, Hw or Sw); //Flow Control If ret <> SIO_OK Then begin ShowMessage('流量设置时发生错误'); Exit; end; Result := True; End; end.
var Form1: TForm1; DTRMode,RTSMode,Port:Integer; Function PortSet():Boolean; implementation uses PComm,MxTool,EXGLOBAL; //PCOmm引用声明放于此 {$R *.DFM}
//以下是打开通信端口的程序 procedure TForm1.btnOpenPortClick(Sender: TObject); var Ret:Integer; begin //打开通信端口 Port := rdCom.ItemIndex+1; //指定通信端口 Ret := sio_Open(Port); If ret <> SIO_OK Then begin ShowMessage('打开通信端口错误'); sio_close (Port); Exit; end; If Not PortSet() Then //参数设置 begin sio_close(Port); ShowMessage('通信端口参数设置发生错误'); Exit; End; //降低DTR及RTS的电压 ret := sio_DTR(Port, 0); ret := sio_RTS(Port, 0); end;
//以下是结束按钮的动作 procedure TForm1.btnEndClick(Sender: TObject); begin //关闭通信端口 sio_Close(Port); //结束程序 close; end;
procedure TForm1.btnSendClick(Sender: TObject); var TxtStr:String; begin //输出字符串指定 TxtStr := mSend.Text; //把Pascal字符串转成C字符串后送出 sio_write(Port, PChar(TxtStr), Length(TxtStr)) end;
//以下是通信参数的函数实现 Function PortSet():Boolean; var mode,Hw,Sw,ret:LongInt; begin //参数设置子程序 mode := P_NONE Or BIT_8 Or STOP_1; Hw := 0 ; //没有硬件流量控制 Sw := 0 ; //没有软件流量控制 Result := False ; ret := sio_ioctl(Port, B38400, mode); //Setting If ret <> SIO_OK Then begin ShowMessage('设置时发生错误'); Exit; end; ret := sio_flowctrl(Port, Hw or Sw); //Flow Control If ret <> SIO_OK Then begin ShowMessage('流量设置时发生错误'); Exit; end; Result := True; End; end.
//以下是打开通信端口的程序 procedure TForm1.btnOpenPortClick(Sender: TObject); var Ret:Integer; begin //打开通信端口 Port := rdCom.ItemIndex+1; //指定通信端口 Ret := sio_Open(Port); If ret <> SIO_OK Then begin ShowMessage('打开通信端口错误'); sio_close (Port); Exit; end; If Not PortSet() Then //参数设置 begin sio_close(Port); ShowMessage('通信端口参数设置发生错误'); Exit; End; //降低DTR及RTS的电压 ret := sio_DTR(Port, 0); ret := sio_RTS(Port, 0); //设置中断 if not InitIrq then begin sio_close(Port); ShowMessage('通信端口参数设置发生错误'); Exit; end; end;
//以下是通信参数的函数实现 Function TForm1.PortSet():Boolean; var mode,Hw,Sw,ret:LongInt; begin //参数设置子程序 mode := P_NONE Or BIT_8 Or STOP_1; Hw := 0 ; //没有硬件流量控制 Sw := 0 ; //没有软件流量控制 Result := False ; ret := sio_ioctl(Port, B38400, mode); //Setting If ret <> SIO_OK Then begin ShowMessage('设置时发生错误'); Exit; end; //设置流量控制 ret := sio_flowctrl(Port, Hw or Sw); //Flow Control If ret <> SIO_OK Then begin ShowMessage('流量设置时发生错误'); Exit; end; Result := True; End;
//准备被调用的回调函数,此函数必须独立,不可放进窗体 //此函数用来检测硬件线路状态 Procedure ModemIrq(iPort:LongInt);stdcall; var ret:integer; begin ret := sio_lstatus(iPort); //读取状态 If ret < 0 Then ShowMessage('状态错误') Else //以下依状况改变灯号的颜色 begin If (ret And S_DSR) > 0 Then Form1.spDSR.Brush.Color := clRed Else Form1.spDSR.Brush.Color := clWhite;
If (ret And S_CD) > 0 Then Form1.spCD.Brush.Color := clRed Else Form1.spCD.Brush.Color := clWhite;
If (ret And S_RI) > 0 Then Form1.spRI.Brush.Color := clRed Else Form1.spRI.Brush.Color := clWhite;
If (ret And S_CTS) > 0 Then Form1.spCTS.Brush.Color := clRed Else Form1.spCTS.Brush.Color := clWhite;
End ; End ;
//中断的初始化函数 //在此指定了Count的中断及硬件线路的中断 Function TForm1.InitIrq():Boolean; var ret:LongInt; begin Result := False; ret := sio_cnt_irq(Port, CntIrq, 1); //指定接收事件中断 If ret <> SIO_OK Then begin ShowMessage('事件设置时发生错误-cntIrq'); Exit; End; ret := sio_modem_irq(Port, ModemIrq); //指定硬件线路中断 If ret <> SIO_OK Then begin ShowMessage('事件设置时发生错误-ModemIrq'); Exit; End; Result := True End ;
//中断的清除 //将原先设置的中断全部清除掉 Procedure TForm1.ClearIrq(); var ret:LongInt; begin sio_cnt_irq(Port, nil, 0); sio_modem_irq(Port,nil); End;
//将输入的字符送出 procedure TForm1.mSendKeyPress(Sender: TObject; var Key: Char); begin //送出字符 sio_putch(Port,Ord(Key)); end;
procedure TForm1.Button3Click(Sender: TObject); begin sio_Close(Port); //关闭程序 Close; end;
procedure TForm1.btnOpenPortClick(Sender: TObject); var Ret:Integer; begin //开启通讯端口 Port := rdCom.ItemIndex+1; //指定通讯端口 Ret := sio_Open(Port); If ret <> SIO_OK Then begin ShowMessage('打开通讯端口错误'); sio_close (Port); Exit; end; If Not PortSet() Then //参数设定 begin sio_close(Port); ShowMessage('通讯端口参数设定发生错误'); Exit; End; //降低DTR及RTS的电压 ret := sio_DTR(Port, 0); ret := sio_RTS(Port, 0);
end;
//以下是通讯参数的函数实现 Function TForm1.PortSet():Boolean; var mode,Hw,Sw,ret:LongInt; begin //参数设定副程序 mode := P_NONE Or BIT_8 Or STOP_1; Hw := 0 ; //没有硬件流量控制 Sw := 0 ; //没有软件流量控制 Result := False ; //指定必要的参数 ret := sio_ioctl(Port, B38400, mode); //Setting If ret <> SIO_OK Then begin ShowMessage('设定时发生错误'); Exit; end; //设定流量控制 ret := sio_flowctrl(Port, Hw or Sw); //Flow Control If ret <> SIO_OK Then begin ShowMessage('流量设定时发生错误'); Exit; end; Result := True; End;