Anda di halaman 1dari 5

Serial I/O (RS232) Using Delphi

http://mc-computing.com/languages/delphi/delphi_serialio.htm

Serial I/O (RS232) Using Delphi (RS232)


All Intel PCs have one or two serial ports usually referred to as Com1 and Com2. These comm ports provide voltages and pin outs consistent with RS-232C. Normally, these ports are used for mice, modems, printers, and the like. Under DOS, it was possible to directly access these ports. However, Windows 95 and above forbid direct hardware access. Therefore, this page exists to help get around windows. Generic References | Basic Commands | Writing a Port | Reading a Port | TCommPort | Additional References

Generic References
I provide numerous references in Serial I/O (RS232).

Basic Commands
I really don't get it, with all the available windows API commands, why doesn't Delphi provide a built-in wrapper function for SerialIO? Borland provides the following Delphi FAQ's (delphi-faq.zip 915K). 16193: Setting comm port configuration programmatically under Win95 16199: Changing com port config via Win95 CommConfig Dialog (Pure gold :) ... except that only the baud rate can be changed :( the other 4 fields are ignored. 16400: How can I dial out through the modem under Win32? How to write to the comm port 16774: How can I determine the names of the installed comm ports? The data is read from the registry In addition to the Delphi File I/O commands, there are several Windows API commands. Most of these comm commands (such as CommConfigDialog) are defined in kernel32.

Writing a Port

1 of 5

2012/04/21 01:28 AM

Serial I/O (RS232) Using Delphi

http://mc-computing.com/languages/delphi/delphi_serialio.htm

The following code from FAQ 16400 shows how to write to the comm port as a file. The code in the FAQ also verifies a valid handle before writing to it. Warning: There is an error in the FAQ - NumberWritten must be dword not LongInt
PhoneNumber := 'ATDT 1-555-555-1212' + #13 + #10; CommPort := 'COM2'; hCommFile := CreateFile(PChar(CommPort), GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); WriteFile(hCommFile, PChar(PhoneNumber)^, Length(PhoneNumber), NumberWritten, nil)

This code works for comports 1 thru 9, but not for ports 10 and higher. Instead, use code similar to the following
CommPort := '\\.\COM33';

Reading a Port
Well, reading the port is almost trivial ... if you know the trick. You must configure the TimeOutBuffer. I don't know what good values should be, so I used 300.
var //hCommFile : THandle; // Global variable set elsewhere TimeoutBuffer: PCOMMTIMEOUTS; begin GetMem(TimeoutBuffer, sizeof(COMMTIMEOUTS)); GetCommTimeouts (hCommFile, TimeoutBuffer^); TimeoutBuffer.ReadIntervalTimeout := 300; TimeoutBuffer.ReadTotalTimeoutMultiplier := 300; TimeoutBuffer.ReadTotalTimeoutConstant := 300; SetCommTimeouts (hCommFile, TimeoutBuffer^); FreeMem(TimeoutBuffer, sizeof(COMMTIMEOUTS));

2 of 5

2012/04/21 01:28 AM

Serial I/O (RS232) Using Delphi

http://mc-computing.com/languages/delphi/delphi_serialio.htm

Having done that, ReadFile waits until I scan a barcode. Eventually, I will use ReadFileEx because it will call a routine when a barcode is scanned. Once the port is open and configured, here are 2 routines that will read the port. For test purposes, each was connected to its own button. Uh, both routines work when run from the IDE ... the second refuses to work if you double click on the exe file. I have no idea why.
procedure TForm1.Read_ComPort_UIButtonClick(Sender: TObject); var InputBuffer : string; NumberOfBytesRead : dword; Buffer : array[0..255] of char; i: Integer; begin if hCommFile=INVALID_HANDLE_VALUE then exit; for i := 0 to 255 do Buffer[I] := #42; // This is just for test // It demonstrates why InputBuffer // is built inside a "for" loop

if ReadFile(hCommFile, Buffer, sizeof(Buffer), NumberOfBytesRead, nil) = false then begin ShowMessage('Unable to read from comport'); exit; end; InputBuffer := ''; for i := 0 to NumberOfBytesRead - 1 do InputBuffer := InputBuffer + Buffer[i]; Test_UIEdit.Text := InputBuffer; end;

This next routine works from the IDE, but not if you run the app by double clicking the exe file.
procedure TForm1.ReadToString_UIButtonClick(Sender: TObject); var InputBuffer : string; NumberOfBytesRead : dword; MaxBytesToRead : dword; begin if hCommFile=INVALID_HANDLE_VALUE then exit; InputBuffer := '11111111111111'; // the string must be longer than // the number of bytes you expect to read //InputBuffer :=''; // This fails, the string must have a length

3 of 5

2012/04/21 01:28 AM

Serial I/O (RS232) Using Delphi

http://mc-computing.com/languages/delphi/delphi_serialio.htm

MaxBytesToRead := 14;

// could use sizeof(InputBuffer) instead

if ReadFile(hCommFile, PChar(InputBuffer)^, MaxBytesToRead, NumberOfBytesRead, nil) = false then begin ShowMessage('Unable to read from comport'); exit; end; InputBuffer := copy(InputBuffer, 1, NumberOfBytesRead); Test_UIEdit.Text := InputBuffer; end;

When CreateFile, ReadFile, and WriteFile are used, Delphi does not use MSComm. Instead, it uses the following Kernel32 commands (found using Depends.exe)
SetCommTimeouts, SetCommConfig GetCommTimeouts, GetCommConfig CommConfigDialogA

If you try to search the Delphi 5 help for ReadFile, there are no hits. This is because ReadFile is a Windows API command ... not a Delphi command. Instead, click on it in your code and press F1. Here is a reference that helped me develop this section.

TCommPort
On the Internet, there are several TCommPort type components (see the references below or just search for them). I have been successful using TCommPort by Dirk Claessens (freeware with full source code). I strongly suggest using someone else's component rather than trying to build one yourself. Why? Because they have already been tested on numerous systems and various undocumented "features" have been taken into account.

Additional References
There are numerous communications routines available at Torry's Delphi Pages, including TSerial (shareware) is frequently mentioned in the Delphi newsgroups

4 of 5

2012/04/21 01:28 AM

Serial I/O (RS232) Using Delphi

http://mc-computing.com/languages/delphi/delphi_serialio.htm

Delphi I/O Port Programming under NT v2.0 which includes a driver for manipulating the kernel I/O permissions map Simple I/O for Windows 95/98 only. Assembler code fails in NT. Dirk's Delphi Pages - lots of freeware with source code - including TCommPort. Author: Robert Clemenzi - clemenzi@cpcug.org
URL: http:// cpcug.org / user / clemenzi / technical / Languages / Delphi / Delphi_SerialIO.htm

5 of 5

2012/04/21 01:28 AM

Anda mungkin juga menyukai