This is an early version, and I have done a lot of modes in the later period. . . For learning reference only. In the data collection, and the control system, I suggest that you use the API to write communication classes. Do not use SPCOMM, and MSComm ... in actual applications, your own communication class will be more flexible and convenient. ^^ Of course, write this communication class is more time-consuming ...) When doing data collection, you can easily join the CRC or Checksum check mode .. 51 is based on CRC8 / 16 ... Using CRC You can use data transfer more reliable..
Unit mycomm;
{
THIS UNIT CREATE BY Li Jinhao
2004-3-12 23:26 correction
QQ: 67260745
E-mail: ltsoft918@163.com
}
Interface
Uses
Forms, Sysutils, Windows, Messages, Dialogs, Controls, Classes, Toolwin, Comctrls,
Extctrls, stdctrls, math;
// ----------------
(* Serial number *)
Const
COM1 = 1;
COM2 = 2;
COM3 = 3;
COM4 = 4;
COM5 = 5;
COM6 = 6;
COM7 = 7;
COM8 = 8;
COM9 = 9;
COM10 = 10;
(* STOPBIT *)
SBIT1 = 0;
SBIT1_5 = 1;
SBIT2 = 2;
(* MODEM event constant *)
MY_CTS = 1; // The CTS (Clear-to-Send) Signal IS ON.
MY_DSRL = 2; // The DSR (data-set-ready) Signal IS ON.
MY_RING = 4; // The Ring Indicator Signal IS ON.
MY_RLSD = 8; // the rlsd (receive-line-signal-detect) Signal is ON.
(* Processing message *)
MY_READCOMM = WM_USER 507;
TYPE TMYCOMM = Class Public (* Close Specified Serial Port *) // **************************** Function CloseComm (Const Com: Integer; Const Closeall: Boolean = FALSE): boolean; (* open the specified port *) function OpenComm (Const COM: integer; Const My_BandRate: DWORD = 4800; Const My_ByteSize: byte = 8; Const My_Parity: byte = NoParity; Const My_StopBits: byte = 0): Boolean; // serial read function set function ReadComm_string (const Com: integer; var revcStr: string; const len: DWORD = 0): boolean; // read the serial string function ReadComm_ByteArray (const Com: integer; var revcArray: array of byte; const len : DWORD = 0): boolean; function ReadComm_Byte (Const Com: integer; var OneByte: byte): boolean; // write serial port function set function WriteComm_String (Const Com: integer; Const SendString: string): boolean; function WriteComm_ByteArray ( Const COM: Integer; contray of byte; buflong: dword): boolean; function writecomm_byte (const const class ": boolean; // ------------- - Function GETRXDSIZE (COM: INTEGER): INTEGER; // Get RXD Buffer Data Length Function GetModemState (COM: Integer): DWORD; // Get Status of Status PROCEDURE SETREADOFFBYTE (Offbyte: Byte = $ 13); // Setting the reception stop Finction isReadoffByte (rbyte: byte): boolean; // Judging whether the reception is not stopped ending procedure clearrxd (com: integer); / / Empty RXD buffer content procedure clearTXD (com: integer); // Empty TXD buffer District content procedure clearcombuf (COM: integer); / / Clear all buffers end; // ------------------- Var MCOMM: TMYCOMM; // Create TMYCOMM Example // mythread: tthread; // Timer1: TTIMER; Boffbyte: Byte; // Receive end BYTE LPDCB: TDCB; COMHANDLE: Array [1..10] of thandle; // file handle ComopenFlag: array [1..10 ] of boolean; // file open Idi Rcommtimeouts: strtimeouts; bsuccessflag: boolean; iprror: dword; lpstat: pcomstat;
AbsendBuf, Abrecvbuf: array; nbyteswrite, nbytesread: dword; // Sets written / read number i: integer; // --------- Implementation {**** *********************************************} (* Open the file handle *) (* default format such as: MCMM.Opencomm (COM1, 4800, 8, NOPARITY, 0) *) {*********************** *****************************} Function TMYCOMM.OpenComm (Const COM: Integer; // port number const my_bandrate: dword; / / Baud rate const my_bytesize: Byte; // Data bit const my_parity: byte; // Is there a parity const my_stopbits: Byte): boolean; // Open Specify serial port // Open Specify serial port VAR / / default setting format : 4800, 8, n, 1 COMNUM: STRING; begin // If comopenflag [com] = false indicates that it is not open. . . Operation if not comopenflag [com] THEN // if ComopenFlag [COM] = false begin comnum: = Format ('COM% d', [com]); (* first. Creation file handle *) Comhandle [COM ]: = CREATEFILE (Pansichar (COMNUM), Generic_Read or Generic_Write, (* Access Read Writing *) 0, (* Not Shared *) NIL, (* No Security Attribute Pointer *) Open_EXISTING, (* Creation Way *) File_attribute_normal, 0);
If Comhandle [COM] = INVALID_HANDLE_VALUE INVALID_HANDLE_VALUE THEN BEGIN // ShowMessage ('COM1 Open Error!'); CloseComm (COM); // Call Close Serial RESULT: = FALSE; EXIT; ELSE BEGIN RESULT: = true; comopenflag [com] : = True // Indicates Open End; // if Comhandle [COM] = invalid_handle_value the
(* Second: Equipment COM Input Output Buffer *) BsuccessFlag: = Setupcomm (Comhandle [COM], 4096, 4096); if not bsuccessflag dam showMessage ('device COM input Output buffer error!'); CloseComm (COM) ); Result: = false; exit; end; (* Third: acquisition default DCB *) bsuccessflag: = getcommstate (Comhandle [com); if not bsuccessflag dam // ShowMessage ('getting default DCB error!' ); Closecomm (Comhandle [com); result: = false; exit; end; (* fourth, set DCB *) // 4800, 8, n, 1 lpdcb.baudrate: = my_bandrate; lpdcb.bytesize: = my_bytesize LPDCB.PARITY: = my_parity; // N No parity LPDCB.Stopbits: = my_stopbits; // 0, 1, 2 ===> 1, 1.5, 2 bsuccessflag: = setcommstate (COMHANDLE [COM], LPDCB) If not bsuccessflag kilns // showMessage ('Setting DCB error!'); CloseComm (COMHANDLE [COM]); EXIT; End; Clearcombuf (COM); // Clear all buffer clearcommerror (Comhandle [com], iperror, LPSTAT);
(* Sixth set TimeOut *) rCommTimeouts.ReadIntervalTimeout: = 0; rCommTimeouts.ReadTotalTimeoutConstant: = 250; rCommTimeouts.ReadTotalTimeoutMultiplier: = 0; rCommTimeouts.WriteTotalTimeoutMultiplier: = 0; rCommTimeouts.WriteTotalTimeoutConstant: = 250; bSuccessFlag: = SetCommTimeOuts (ComHandle [ COM], rcommtimeouts; // ev_rxchar a character was receifer. setcommmask (Comhandle [COM], EV_RXCHAR OR EV_CTS or EV_DSR or EV_RING OR EV_RLSD); // Settings the received message // ----- ------------------------------------- if not bsuccessflag dam // showMessage ('Setting Timeout error ! '); Result: = false; closecomm (Comhandle [COM]); EXIT; END; END ELSE BEGIN RESULT: = false; end; end; {**************** **********************************} (* Close file handle *) (* Closeall: Boolean The default is false; close all ports when True *) {****************************************************** ************} Function TMYCOMM.CLOSECMMMMMMMMMMMMMMMMMMMMMMMMMMMMM: Boolean; var csucc: boolean; i: integer; begin // Close file handle if not Closeall True; if comopenflag [com] then // If you are open, close the processing becom csucc: = closehandle (Comhandle [com); comopenflag [com]: = false; // Set to false. Indicates that the end; result: = csucc; END ELSE begin // Close all port for i: = 1 to 10 do begin closehandle (Comhandle [i]); end; result: = true ;; end; // --- ------------- End;
{*********************} (* Read Serial READCOMM_STRING *) (* Read string *) {*** **************************} Function TMYCOMM.Readcomm_String (const COM: Integer; var revcstr: string; constlin: dword = 0) : Boolean; Var sl: DWORD; begin // Read the front faded buffer Result: = true; sl: = LEN; // If you are len = 0, the system automatically obtains the buffer length if len = 0 THEN SL: = GETRXDSIZE (COM); Revcstr: = '; bsuccessflag: = readfile (Comhandle [COM], Pointer (Revcstr) ^, SL, NBYTESREAD, NIL) or (NbytesRead = 0) Then Result: = False; End; {******************************} (* read byte array *) {***** ************************} Function TMYCOMM.Readcomm_ByteArray (const COM: INTEGER; VAR RECARRAY: Array Of Byte; Const Len: DWORD = 0) : boolean; var i: integer; sl: dword; begin result: = true; sl: = LEN; // If not lin = 0, the system automatically gets the buffer length if len = 0 Then SL: = GETRXDSIZE (COMHANDLE [COM ]); If getrxdsize (Comhandle [COM])> High (Revcarray) THEN/ If the data of the buffer is greater than an array, it is wrong BeGin Clearrxd (Comhandle [COM]) ; // Empty reading buffer Result: = false; exit; end; // In reading front space buffer array for i: = low (revcarray) to high (revcarray) Do Begin // Clear read and write array Prevent reading chaos Revcarray [i]: = byte (0); end; bsuccessflag: = readfile (Comhandle [COM), Revcarray, SL, NBYTESREAD, NIL); if (NbytesRead = 0) THEN Result : = FALSE; END;
{*********************} (* Read Serial READCOMM_BYTE *) (* Read a Byte *) {** ***************************} Function TMYCOMM.Readcomm_byte (const com): Boolean; Begin Result: = True; if GetRxdsize (COM) <= 0 THEN Begin Result: = false; exit; end; bsuccessflag: = readfile (Comhandle [com), onebyte, 1, nbytesread, nil); if (NbytesRead = 0) Then Result: = false; end; {*******************************} (* write serial writecomm_string *) { ******************************} Function TMYCOMM.WRITECOMM_STRING (const const Com: integer; const callstring: string): boolean; begin Result: = true; purgecomm (Comhandle [com), 4); // Empty TXD buffer internal space BsuccessFlag: = Writefile (COMHANDLE [COM], Pointer (SendString) ^, LENGTH (SendString), Nbyteswrite, NIL); if (NOT BSUCCESSFLAG) or (nbyteswrite = 0).
{*************************** (* write serial port WriteComm_ByteArray *) (* Send a BYTE array *) {***** ********************} Function TMYCOMM.WRITECOMM_BYTEARRAY (Const COM: INTEGER; Const Sendbyte): Boolean; Begin Result: Boolean; Begin Result: = True; // ---------------- CleartXD (Comhandle [COM]); // Clear TXD Buffer Internal Air BsuccessFlag: = Writefile (Comhandle [com], sendbyte, buflong , nbyteswrite, nil); if bsuccessflag or (nbyteswrite = 0) THEN Result: = false;
{*************************** (* write a Byte *) {******* **************** * Function TMYCOMM.WRITECMMM_BYTE (const const Com: INTEGER): Boolean; begin result: = true; // --- ------------- CleartXD (Comhandle [COM]); // Empty TXD Buffer Internal Air BsuccessFlag: = Writefile (Comhandle [COM], Sendbyte, 1, Nbyteswrite, NIL); IF NOT BSUCCESSFLAG) or (nbyteswrite = 0).
{******************************** (* Get the data length of the RXD buffer * ) {*************************************} Function TMYCOMM.GETRXDSIZE (COM: Integer) : Integer; VAR CS: TcomStat; Begin Clearcommerror (Comhandle [COM], IPERROR, @ Cs); Result: = cs.cbinques; {*****************} * Clear RXD *) {*****************} Procedure Tmycomm.clearrxd (com: integer); recoms: (Comhandle [COM), 8); // Empty RXD Buffer inner air END;
{*************************************} (* Clear all buffers *) {** *******************************************} Procedure TMYCOMM.CLARCOMBUF (COM: Integer); Begin // 5: All characters of the input // purge_txabort = 1; {kill the pending / current} to the commge_rxabort = 2; {kill the pending / current} to the the the Comm port.} // purge_txclear = 4; {kill the transmit queue}} // purge_rxclea = 8; {Kill the Typeahead Buffer if There.} PurgeComm (Comhandle [COM], 1 Or 2 Or 4 OR 8); END;
{************* (* Clear TXD *) {*****************} Procedure TMYCOMM.CLARTXD (com: integer); begin purgeComm (Comhandle [COM], 4); // Clearing the internal space END in TXD buffer;
{*******************************} // port status message description // ms_cts_on // the CTS (Clear-to -send) Signal is ON. / / MS_DSR_ON // THE DSR (Data-set-ready) Signal IN. / / MS_RING_ON // The Ring Indicator Signal IS ON. / / MS_RLSD_ON /////////rus (Receive-Line-Signal -Detect) signal is on. {******************************} Function TMYCOMM.GETMODEMSTATE (COM: INTEGER): DWORD; var dwmodemstate: dword; begin if getcommodemstatus (Comhandle [com), dwmodemstate) Then Result: = dwmodemstate else result: = 0; // Operation Failback Returns 0nd;
{*************************************************** {Setting the reception end BYTE ---> Set the global variable OFFBYTE} {Note: The end of the reception end byte is not DCB Xoffchar is a custom} {****************** ******************************} procedure tmycomm.setReadoffByte (Offbyte: BYTE); begin boffbyte: = offbyteend; {** *************************************************} {Judgment Settings BYTE ---> Read the global variable OFFBYTE} {**************************************************} Function Tmycomm.isreadoffByte (rbyte: byte): boolean; begin result: = rbyte = boffbytend;
Initialization MCMM: = Tmycomm.create; Finalization Mcham.closeComm (0, true); // Turn off all ports MCOMM.FREE; END.