| |||||||||||||||||
| |||||||||||||||||
| text: | ||
Implementation of serial communication in Delphi With the development of modern information technology and the widespread use of computer networks, computer communication technology has become increasingly mature. However, serial communication, as a flexible, convenient and reliable communication method, is still an effective communication method and is widely used in industrial control. In industrial production practice, using a PC to monitor projects in real time usually requires the PC to have functions such as data collection, data processing, and control signal generation and transmission on the user interface. In this specific environment, if the PC is to be connected with the real-time signals of process control, it is required to directly operate the serial port of the PC. Delphi launched by Borland is a powerful high-level programming language with visual object-oriented features and is particularly suitable for the preparation of graphical interfaces and user programs in the Windows environment. Serial communication mechanism based on WIN95/NT The mechanism of the Windows operating system prohibits applications from directly accessing computer hardware, but it provides programmers with a series of standard API functions, making application preparation more convenient and eliminating the trouble of debugging related hardware. In Windows95/NT, the original WM_COMMNOTIFY message of Windows3. Just operate on the read/write buffer. Several commonly used serial communication operation functions in WIN95/NT are as follows: CreatFile opens the serial port CloseHandle closes the serial port SetupComm sets the size of the communication buffer ReadFile reads serial port operation WriteFile writes serial port operation SetCommState sets communication parameters GetCommState gets default communication parameters ClearCommError clears the serial port error and gets the current status In addition to the above functions, an important record DCB (Device Control Block) is often used. There are definable serial port parameters recorded in DCB. When setting the serial port parameters, you must first use the GetCommState function to fill in the system default values into the DCB control block, and then set the custom values that the user wants to change. To carry out serial communication in WIN95/NT, in addition to understanding the basic communication operation functions, you must also master multi-thread programming. A thread is the path of execution within a process and is the basic entity used by the operating system to allocate CPU time. Each process starts with a single thread to complete the execution of the application. Serial communication needs to be implemented using multi-thread technology. Its main processing logic can be expressed as follows: at the beginning of the process, the main thread does some necessary initialization work, and then the main thread establishes a communication monitoring thread to monitor the communication port at the appropriate time as needed. When the specified serial port event occurs, a WM_COMMNOTIFY message is sent to the main thread (since WIN95 cancels the WM_COMMNOTIFY message, you must create it yourself), and the main thread processes it. If the WM_COMMNOTIFY message is not needed, the main thread terminates the communication monitoring thread. Simultaneous execution of multiple threads will cause conflicts on shared resources. To avoid conflicts, it is necessary to use synchronized multi-threads to access shared resources. WIN95 provides many methods to maintain thread synchronization. The author uses the creation of event objects to maintain thread synchronization. Create an event object through CraeteEvent() and set the event object to signal synchronization using the etEvent() or PulseEvent() function. In the application, use the WaitSingleObject() function to wait for the synchronization trigger, and wait until the specified event is set to have a signal by other threads before continuing to execute the program. Specific implementation method under Delphi Delphi's powerful functions and object-oriented programming technology that supports multi-threading make serial communication very simple and convenient. It is implemented by calling external API functions. The main steps are as follows: First, use the CreateFile function to open the serial port to determine the ownership of the serial port by this application and block other applications from operating the serial port; secondly, , fill the device control block DCB through the GetCommState function, and then configure the baud rate, data bits, parity bits and stop bits of the serial port by calling the SetCommState function. Then, create a serial port monitoring thread to monitor serial port events. On this basis, you can operate the data transmission on the corresponding serial port; finally, use the CloseHandle function to close the serial port. The specific program is as follows. This program was compiled with Delphi3.0 and debugged in the Win95 environment. It has been put into practical application for the reference of readers. program: unit comdemou; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; const Wm_commNotify=Wm_User+12; type TForm1 = class(TForm) PRocedure FormCreate(Sender: TObject); private Procedure comminitialize; Procedure MsgcommProcess(Var Message:Tmessage); Message Wm_commnotify; {Private declarations} public {Public declarations} end; //Thread declaration TComm=Class(TThread) protected procedure Execute;override; end; var Form1: TForm1; hcom,Post_Event:Thandle; lpol:Poverlapped; implementation {$R *.DFM} Procedure TComm.Execute; //Thread execution process var dwEvtMask:DWord; Wait:Boolean; Begin fillchar(lpol,sizeof(toverlapped),0); While True do Begin dwEvtMask:=0; Wait:=WaitCommEvent(hcom,dwevtmask,lpol); //Wait for serial port events; if Wait Then Begin waitforsingleobject(post_event,infinite); //Wait for synchronization event to be set; resetevent(post_event); //Synchronization event reset; PostMessage(Form1.Handle,WM_COMMNOTIFY,0,0);//Send message; end; end; end; procedure Tform1.comminitialize; //Serial port initialization var lpdcb:Tdcb; Begin hcom:=createfile('com2',generic_read or generic_write,0,nil,open_existing, file_attribute_normal or file_flag_overlapped,0);//Open the serial port if hcom=invalid_handle_value then else setupcomm(hcom,4096,4096); //Set the input and output buffers to 4096 bytes getcommstate(hcom,lpdcb); //Get the current default settings of the serial port lpdcb.baudrate:=2400; lpdcb.StopBits:=1; lpdcb.ByteSize:=8; lpdcb.Parity:=EvenParity; //Even parity Setcommstate(hcom,lpdcb); setcommMask(hcom,ev_rxchar); //Specify the serial port event as received characters; end; Procedure TForm1.MsgcommProcess(Var Message:Tmessage); var Clear:Boolean; Coms:Tcomstat; cbNum,ReadNumber,lpErrors:Integer; Read_Buffer:array[1..100]of char; Begin Clear:=Clearcommerror(hcom,lpErrors,@Coms); if Clear Then Begin cbNum:=Coms.cbInQue; ReadFile(hCom,Read_Buffer,cbNum,ReadNumber,lpol); //Process the received data SetEvent(Post_Event); //Synchronization event setting end; end; procedure TForm1.FormCreate(Sender: TObject); begin comminitialize; post_event:=CreateEvent(nil,true,true,nil); //Create a synchronization event; Tcomm.Create(False); //Create a serial port monitoring thread; end; end. Author member name: ruan_bangqiu | ||