Віртуальний вимірювальний комплекс на базі учбового лабораторного стенду EV 8031

скачати

unit SerialNGBasic;  interface  uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,   Buttons, ExtCtrls, SerialNG;  type   TSerialNGBasicDLG = class(TForm)     OKBtn: TButton;     CancelBtn: TButton;     Bevel1: TBevel;     Label3: TLabel;     Label4: TLabel;     Label5: TLabel;     Label6: TLabel;     Label7: TLabel;     Label8: TLabel;     CBPort: TComboBox;     CBBaud: TComboBox;     CBData: TComboBox;     CBStop: TComboBox;     CBParity: TComboBox;     CBFlow: TComboBox;   private     { Private declarations }   public     { Public declarations }     procedure SetDLGData(SerialPortNG : TSerialPortNG);     procedure GetDLGData(SerialPortNG : TSerialPortNG);   end; var   SerialNGBasicDLG: TSerialNGBasicDLG;  implementation  {$R *.DFM} procedure TSerialNGBasicDLG.SetDLGData(SerialPortNG : TSerialPortNG); var i : Integer; begin   i := CBPort.Items.IndexOf(SerialPortNG.CommPort);   if i >= 0 then     CBPort.ItemIndex := i   else     CBPort.ItemIndex := 1; //COM2   i := CBBaud.Items.IndexOf(IntToStr(SerialPortNG.BaudRate));   if i >= 0 then     CBBaud.ItemIndex := i   else     CBBaud.ItemIndex := 6; // 9600   i := CBData.Items.IndexOf(IntToStr(SerialPortNG.DataBits)+' Bit');   if i >= 0 then     CBData.ItemIndex := i   else     CBData.ItemIndex := 4; // 8 Bit   CBStop.ItemIndex := SerialPortNG.StopBits;   CBParity.ItemIndex := SerialPortNG.ParityType;   case SerialPortNG.FlowControl of     fcNone : CBFlow.ItemIndex := 0;     fcXON_XOFF : CBFlow.ItemIndex := 1;     fcRTS_CTS : CBFlow.ItemIndex := 2;     fcDSR_DTR : CBFlow.ItemIndex := 3;   else     CBFlow.ItemIndex := 0;   end;   end;  procedure TSerialNGBasicDLG.GetDLGData(SerialPortNG : TSerialPortNG); begin   SerialPortNG.CommPort := CBPort.Items[CBPort.ItemIndex];   SerialPortNG.BaudRate := StrToIntDef(CBBaud.Items[CBBaud.ItemIndex],9600);   SerialPortNG.DataBits := StrToIntDef(Copy(CBData.Items[CBData.ItemIndex],1,1),8);   SerialPortNG.StopBits := CBStop.ItemIndex;   SerialPortNG.ParityType := CBParity.ItemIndex;   SerialPortNG.FlowControl := BasicFlowModes[CBFlow.ItemIndex];   SerialPortNG.Active := True; end;  end. 
unit SerialNG; // DomIS Internet Solutions http://www.domis.de // Visit SerialNG Homepage http://www.domis.de/serialng.htm  // This Source is distributed under the terms of Open-Source // This mean You can use this Source free for Open-Source development // Additionally I allow the use for any inhouse Projects // If You want to make a Closed-Source Project with this Source, // You have to reference Back to the Source and have to distribute the Source // Any changes should be marked and this header should remain here // Under all circumstances it is prohibited to use this source for military Products!!! // Refer the readme.txt  // This is Version 2 of the Basic Communication Component // I've made a complete redesign of the whole Component // So the Component is incompatible with the Version 1 // News: // Using Overlapped features for Windows Platform Compatiblity // Using CommEvents for state detection // More (and more meaningfull) Events // Sending will not block the main Program  // Support the development of SerialNG with a donation. Any amount will be welcome // You may transmit the Money to my  Bank-Account //  Kto. 654130-604, Postbank Frankfurt/M, BLZ 500 100 60, Kennwort SerialNG // for International transmission, use the IBAN Code // IBAN DE 56 5001 0060 0654 1306 04 // You may also use Paypal if You like // Link for EURO transmission // https://www.paypal.com/xclick/business=paypal%40domis.de&item_name=Support+SerialNG+Development&item_number=SerialNG-EUR&tax=0&currency_code=EUR // Link for USD transmission // https://www.paypal.com/xclick/business=paypal%40domis.de&item_name=Support+SerialNG+Development&item_number=SerialNG-USD&tax=0&currency_code=USD // Thank You for using and supporting SerialNG!  // Installation // You have to register this component with the Delphi funktion "Component/Install Component" // create a new component library and add this component // the TSerialNG component appears in the "Samples" part of the component toolbar // See http://domis.de/serialnginst.htm  // Usage // Please take a look to the Demofiles. // Start with SerialNGBasicDemo.dpr, this contains a very simple approach to the component  // The Base of the Version 1.X of this unit is taken from "TSerialPort: Basic Serial Communications in Delphi" // created by Jason "Wedge" Perry, but I could not find him again  // PC serial port Pins are as follows // Name Dir  9Pin 25Pin // DCD   In   1    8 // RXD   In   2    3 // TXD   Out  3    2 // DTR   Out  4    20 // GND   -    5    7 // DSR   In   6    6 // RTS   Out  7    4 // CTS   In   8    5 // RI    In   9    22 // Dir means the direction from the ports view (e.g. DCD is an input, You can read this port)  // Version History // All Version are available at http://www.domis.de/serialng.htm // 2.0.0  28. Aug 2001, Basic stable Version // 2.0.1  30. Aug 2001, Fixing Thread stoperror in PortWord // 2.0.2  17. Sep 2001, Deleting double declared Property Error, use instead CommError //                      Changed declaration of procedure GetCommNames(CommNames : TStrings); //                      prevent duplicate Entries in this function // 2.0.3   9. Nov 2001, Changed Cardinal type to DWORD in TWorkThread.Execute for //                      Delphi 3 backcompatibility // 2.0.4  28. Nov 2001, Problem in not Active Mode fixed ( //                      sleep(200) prevent consuming 100% of cpu-time in inactive mode) // 2.0.5   8. Jan 2002, Problem in GetDataAsPChar fixed ( //                      The pending Zero was not patched in the right place) // 2.0.6   4. Apr 2002, Changed *all* Cardinal type to DWORD and made several Changes in //                      Demo Forms for Delphi 3 backcompatibility // 2.0.7  16. Apr 2002, Found and fixed the norty Error which occours sometimes after //                      the Termination of the Threads (the Overlapped Result wrote into undefined Memory) //                      The Thread waits now until everything Pending Overlapped is done // 2.0.8  13. Mai 2002, Correct Error with the default timing settings (Thanks to Hynek Cernoch) // 2.0.9  27. Mai 2002, Patched an "\\.\" in front of Comportname to allow connection to virtual Comports // 2.0.10 27. Aug 2002, Function for finding the CommPorts in the Registry created and placed in //                      Unit CommPortList. The CheckOS function is moved into theis Unit too. // 2.0.11  6. Sep 2002, Again or Finally? Found and fixed the norty Error which occours sometimes after //                      the Termination of the Threads (the Overlapped Result wrote into undefined Memory) //                      Now the WaitCommEvent Overlapped is manually Terminated, by Setting (!) the hEvent manually //                      Some minor cleanups in Destroy and PortWork. It seem (!) to run now! // 2.0.12 10. Sep 2002, Again! Small, but significant Error in PortWork. Closing the Handles to the Overlapped //                      Records should not be there - fixed and running. Thanks to Jens G�hring // 2.0.13 25. Sep 2002, Fixed a Problem for multi instancing, e.g. running two or more SerialNGPorts at the same time //                      The Names of the Overlapped Events are allway the same, so the second Port used the event from //                      the previous instanced Port instead creating a new event // 2.0.14  1. Okt 2002, Made a more robust solution for creating the Eventnames. There is now a 1:200000 chance that //                      the program can not create a Eventname. This occours only on Multiport installation. //                      The 1:200000 chance is a compromise between hangup the program in an endless loop and returning an Error. // 2.0.15 17. Okt 2002, A Ssmall change in the ReadSettings from Registry Procedure suggested by Ron Hoving //                      After reading the Settings they are used now instantly // 2.0.16 14. Nov 2002, Patched an suggestion from Krystian (Poland) //                      The Linestates CTS, DSR and RLSD are now updated, even if no Event is assigned // 2.0.17 25. Mrz 2003  GetStatus is now (and must!) called prior to DoCommEvent, to ensure the actual state is used //                      Prozesserror gives the Self pointer (instead the wrong Owner pointer) //                      The silly Eventname stuff removed // 2.0.18 24. Jun 2003  Changes on the RI behaviour: //                      The RI Linestate is now updated at the same place as CTS,DSR and RLSD and valid in the OnCommEvent //                      The RI Event is now on Win9x/mE simulated as NT/2K/XP does, on the falling RI edge only!!! //                      Thus the OnRingEvent is called *only* on the falling edge of the signal //                      Additionally a new OnRIEvent has been inserted. This Event is manually generated if a //                      change in the RI Signal has been detected. //                      If Your Program should show a 'RING' ... 'RING' because a Modem is attached use the OnRingEvent //                      If Your Program will track the RI Pin State use the OnRIEvent // 2.0.19 07. Okt 2003  New Parameterlist fpr processerror, reinstall of component neccessary // 2.0.20 15. Okt 2003  Fixing a Thread error: StartTime was uninitilized in the case of receiving Chars between //                      the opening of the Port and the first 'ReadNoWait'. //                      Probably this Error will occour only in Debugsessions // 2.0.21 01. Dec 2003  Made some changes for (more) compatibility to francois piette's ICS. //                      If in a 'OnDataAvailable' Event of the TWSocket the SerialNG Thread calls 'Synchronize' //                      the Thread is locked, and the 'SendInProgress' Flag will never become reset. //                      This behaviour results (probably) in the WndProc work of ICS. //                      I made a work around: A new Property 'ThreadQuiteMode' is now integrated. //                      If this Flag become True the Thread will not call synchronize. //                      Be careful with this Flag, since You receive no messages, you may been misleaded. //                      You have to Poll incoming data by Yourself. // 2.0.22 13. Jan 2004  Fixed an Error in QuieteMode using Enter and LeaveCriticalSection. This is made //                      to add and remove the Data securily without the need of Threadsynchronize // 2.0.23 13. Mrz 2004  Found and fixed a Problem under fast (2.4GHz) Win2K and XP Computers: //                      Windows seems to send the EventCharEvent before the received Chars are moved into //                      the WindowsQueue. So the CommStatus.cbInQue contains an invalid char amount //                      I now call the ClearCommError at least twice until no changes in the results // 2.0.24 16. Nov 2004  Fixed a Problem occours under Win2K: wrong result out of GetOverlappedResult //                      Thanks to Phil Young (62Nds), and ThomasD // I am working on a Multiport-Single-Thread version, this will cause some incompatiblities to the current version // This will become Version 2.1.0  interface {$BOOLEVAL OFF} uses   Windows, Messages, SysUtils, Classes,   Graphics, Controls, Forms, Dialogs;    // Definitions for the DCB found in windows.pas for reference only   // All of the baud rates that the DCB supports. const   BaudRateCount = 15;   BaudRates : array[0..BaudRateCount-1] of DWord =     (CBR_110, CBR_300, CBR_600, CBR_1200, CBR_2400, CBR_4800, CBR_9600, CBR_14400, CBR_19200, CBR_38400, CBR_56000, CBR_57600, CBR_115200, CBR_128000, CBR_256000); // The business with the TimeOuts during sending Data, and esspeccialy during // reception of Data depends on the selected Baudrate. // while on 9600 Baud every 1ms a Char is received, is this time on 256KBaud only 4�s // Strange enough, windows support only 1ms as shortest Intervall! // Below some standard TimeOuts for the given Baudrates in �s   XTOCharDelayDef : array [0..BaudRateCount-1] of DWord = (100000, 37000, 18000, 9000, 4500, 2300, 1100, 760, 570, 290, 200, 190, 95, 85, 43);   // Parity types for parity error checking   // NOPARITY = 0;  ODDPARITY = 1;  EVENPARITY = 2;  MARKPARITY = 3;  SPACEPARITY = 4;   // Stopbits   // ONESTOPBIT = 0;   ONE5STOPBITS = 1;  TWOSTOPBITS = 2;   // Bitmasks for the "Flags" Field of the DCB record const   bmfBinary = $0001;          // binary mode, no EOF check   bmfParity = $0002;          // enable parity checking   bmfOutxCtsFlow = $0004;      // CTS output flow control   bmfOutxDsrFlow = $0008;      // DSR output flow control // DTR Control Flow Values  DTR_CONTROL_DISABLE = 0;  DTR_CONTROL_ENABLE = 1;  DTR_CONTROL_HANDSHAKE = 2;   bmfDtrControlEnable = $0010;       // DTR Enable   bmfDtrControlHandshake = $0020;       // DTR Handshake   bmfDsrSensitivity = $0040;   // DSR sensitivity   bmfTXContinueOnXoff = $0080; // XOFF continues Tx   bmfOutX = $0100;            // XON/XOFF out flow control   bmfInX = $0200;             // XON/XOFF in flow control   bmfErrorChar = $0400;       // enable error replacement   bmfNull = $0800;            // enable null stripping // RTS Control Flow Values  RTS_CONTROL_DISABLE = 0;  RTS_CONTROL_ENABLE = 1;  RTS_CONTROL_HANDSHAKE = 2;  RTS_CONTROL_TOGGLE = 3;   bmfRtsControlEnable = $1000;       // RTS Enable   bmfRtsControlHandshake = $2000;       // RTS Enable   bmfRtsControlToggle = $3000;       // RTS Enable   bmfAbortOnError = $4000;     // abort reads/writes on error  // Basic FlowControlModes // You may declare more _exotic_ Modes, like Sending RTS/CTS, receiving XOn/XOff :-) const   fcNone = 0;   fcXON_XOFF = bmfOutX or bmfInX or  bmfTXContinueOnXoff;   fcRTS_CTS = bmfOutxCtsFlow or bmfRtsControlHandshake;   fcDSR_DTR = bmfOutxDsrFlow or bmfDtrControlHandshake;   fcClearFlowCtrl = Not (fcXON_XOFF or fcRTS_CTS or fcDSR_DTR or bmfDtrControlEnable or bmfRtsControlEnable); const BasicFlowModes : array[0..3] of Word = (fcNone, fcXON_XOFF, fcRTS_CTS, fcDSR_DTR);  // Constants for using in the ErrorNoise Property // I tried to catch Errors, send Warnings or sometimes Messages for Your convinience. // If You set the ErrorNoise Property to one of the Values this kind of Messages will be reported // while those with higher Numbers not const   enError = 0;   // Errors like unable to Open Port   enWarning = 1; // Warnings like cant pause Thread   enMsg = 2;     // Messages like starting with Port opening   enDebug = 3;   // Debughelpermessage like im am here or there   enAll = 255;   // Show all  const // Set some constant defaults. // These are the equivalent of COM2:9600,N,8,1;   dflt_CommPort = 'COM2';   dflt_BaudRate = CBR_9600;   dflt_ParityType = NOPARITY;   dflt_ParityErrorChar = #0;   dflt_ParityErrorReplacement = False;   dflt_StopBits = ONESTOPBIT;   dflt_DataBits = 8;   dflt_XONChar = #$11;  {ASCII 11h}   dflt_XOFFChar = #$13; {ASCII 13h}   dflt_XONLimDiv = 33; // Set the XONLimit to dflt_XONLimDiv/100*RxQueueSize   dflt_XOFFLimDiv = 33; // Set the XONLimit to dflt_XONLimDiv/100*RxQueueSize   dflt_FlowControl = fcNone;   dflt_StripNullChars = False;   dflt_BinaryMode = True;   dflt_EventChar = #0; // Timeout defaults, fits only to 9600 Baud! // Look that CharDelay is in micro, ExtraDely in milli Seconds!   dflt_RTOCharDelayTime = 1100; // 1100microsec (1100E-06 secs)   dflt_RTOExtraDelayTime = 250; // 250msec      ( 250E-03 secs)   dflt_WTOCharDelayTime = 1100; // 1100microsec (1100E-06 secs)   dflt_WTOExtraDelayTime = 250; // 1000msec     ( 250E-03 secs)   dflt_XTOAuto = True; // lets the Component adjust CharDelay timing on every Baudrate change   dflt_ClusterSize = 3072; //Max Clustersize   dflt_RTSState = True;   dflt_DTRState = True;   dflt_ErrorNoise = enMsg;   dflt_BREAKState = False;   dflt_RxQueueSize = 4096;   dflt_TxQueueSize = 4096;   dflt_ThreadQuietMode = False;   dflt_AutoReadRequest = False; type  // Special Event function for the Error and Warning   TNotifyErrorEvent = procedure(Sender : TObject;Place, Code: DWord; Msg : String; Noise : Byte) of object;  // TSerialCluster is a Object for the Receiving Process. // If You just want to receive some Data, don't care // Under normal circumstances You have not to deal with this Object  // I decided to realize the receiving Process as follow: // Between two cycles in the WorkThread may the SerialPort receive more than one Character. // Basicly those Chars are named "Cluster" (and not "Telegram", as You might expect) // How many Chars are stored in one TSerialCluster depeds on, User controlled,  Conditions // 1. the ClusterSize is reched // 2. the Receivingtime is reached // 3. an (Line-) Error occoured // 4. The Program set the "ReadRequest" Property to "True" // If the condition is met, the received Chars are Stored as a Cluster into the ClusterList    PSerialCluster = ^TSerialCluster;   TSerialCluster = class (TObject)     private       ClusterData : Pointer; // Pointer to Data       ClusterSize : Integer; // How many Bytes in Datafield       ClusterCCError : DWord; // This Value comes from the ClearCommError function and is a Bitfield //  CE_RXOVER = 1;        { Receive Queue overflow } //  CE_OVERRUN = 2;       { Receive Overrun Error } //  CE_RXPARITY = 4;      { Receive Parity Error } //  CE_FRAME = 8;         { Receive Framing error } //  CE_BREAK = $10;       { Break Detected } //  CE_TXFULL = $100;     { TX Queue is full } //  CE_MODE = $8000;      { Requested mode unsupported }      public     constructor Create(Data : Pointer; Size : Integer; CCError : DWord);     function GetCCError : DWord;     function GetSize : Integer;     procedure GetData(Dest : Pointer);     function GetDataAsString : String;     function GetDataAsPChar(Dest : PChar) : PChar;     destructor Destroy; override;   end;  // TSerialPortNG is the Heart of the Job, everything what has to do with the // SerialPort should be done with this Component // The Concept is as follows: // After instancing the Port is still closed // You should set the Property "CommPort" to the full Name of the Port e.g. 'COM1' // After this set the "Active" Property to "True" // Sending Data ist performed with the SendData or the SendString procedures // since Sendig is "Overlapped" the procedures returns immidiatly and You can do // some other Jobs in Your main Programm // You should not reentry this Procedures until they done there Job (Will give a warning). // If send is done the component call the "OnWriteDone" Event. // You also can ask the "SendInProgress" Property. // Reading Data is fairly simple, just Read the Data with one of the "ReadNextCluster..." functions // You place the read Access into the "OnRxClusterEvent". // See sample Programs for more Information   TSerialPortNG = class(TComponent)   private     // Variables holding Values for Properties     fCommPort : ShortString;     fBaudRate : DWord;     fParityType : Byte;     fParityErrorChar : Char;     fParityErrorReplacement : Boolean;     fStopBits : Byte;     fDataBits : Byte;     fXONChar : Char;     fXOFFChar : Char;     fXONLimDiv : Byte; // 0..100     fXOFFLimDiv : Byte; // 0..100     fFlowControl : LongInt;     fStripNullChars : Boolean;  // Strip null chars?     fEventChar : Char;     fErrorNoise : Byte;     // These fields are set in the EventThread     fCommStateFlags : TComStateFlags;     fCommStateInQueue : DWord;     fCommStateOutQueue : DWord;     fCommError : DWord;     fCommEvent : DWord;     fModemState : DWord;     // TimeOut definitions     fRTOCharDelayTime : DWord;     // in �s max: 4.294.967.295�s aprox 1h 20min     fRTOExtraDelayTime : Word;    // in ms     fWTOCharDelayTime : DWord;     // in �s     fWTOExtraDelayTime : Word;    // in ms     fXTOAuto : Boolean;     fActive : Boolean;     fRTSState : Boolean;     fDTRState : Boolean;     fBREAKState : Boolean;     fCTSState : Boolean;     fDSRState : Boolean;     fRLSDState : Boolean;     fRingState : Boolean;     fClusterSize : Word;     fRxQueueSize : Word;     fTxQueueSize : Word;     fReadRequest : Boolean; // Force Thread to Read the Queue     fSendInProgress : Boolean;     fWrittenBytes : DWord;     fThreadQuietMode : Boolean;     fAutoReadRequest : Boolean;     // Eventvariables     fOnTxQueueEmptyEvent : TNotifyEvent;     fOnCommEvent : TNotifyEvent;     fOnCommStat : TNotifyEvent;     fOnBreakEvent : TNotifyEvent;     fOnCTSEvent : TNotifyEvent;     fOnDSREvent : TNotifyEvent;     fOnLineErrorEvent : TNotifyEvent;     fOnRingEvent : TNotifyEvent;     fOnRIEvent : TNotifyEvent;     fOnRLSDEvent : TNotifyEvent;     fOnRxClusterEvent : TNotifyEvent;     fOnRxCharEvent : TNotifyEvent;     fOnRxEventCharEvent : TNotifyEvent;     fOnWriteDone : TNotifyEvent;     fOnProcessError : TNotifyErrorEvent;      hCommPort : THandle; // Handle to the port.     WriteOverlapped : TOverlapped; //Overlapped field for Write     ReadOverlapped : TOverlapped;  //Overlapped field for Read     StatusOverlapped : TOverlapped; //Overlapped field for Status     BytesToWrite : DWord;     WriteStartTime : DWord;     WorkThread : TThread;     WorkThreadIsRunning : Boolean;     WorkThreadIsTerminated : Boolean;     ShutdownInProgress : Boolean;     RxDClusterList : TList;     LastErr : Integer;     Platform : Integer; // 0 Win32s on Win3.11, 1 Win 9x, 2 WinNT     CriticalSection: TRTLCriticalSection;     // Procedures for setting the variables, refrenced in the Properties     procedure SetCommPort(value : ShortString);     procedure SetBaudRate(value : DWord);     procedure SetParityType(value : Byte);     procedure SetParityErrorChar(value : Char);     procedure SetParityErrorReplacement(value : Boolean);     procedure SetStopBits(value : Byte);     procedure SetDataBits(value : Byte);     procedure SetXONChar(value : Char);     procedure SetXOFFChar(value : Char);     procedure SetXONLimDiv(value : Byte);     procedure SetXOFFLimDiv(value : Byte);     procedure SetFlowControl(value : LongInt);     procedure SetStripNullChars(value : Boolean);     procedure SetEventChar(value : Char);     procedure SetRTOCharDelayTime(value : DWord);     procedure SetRTOExtraDelayTime(value : Word);     procedure SetWTOCharDelayTime(value : DWord);     procedure SetWTOExtraDelayTime(value : Word);     procedure SetXTOAuto(value : Boolean);     procedure SetClusterSize(value : Word);     procedure SetRxQueueSize(value : Word);     procedure SetTxQueueSize(value : Word);     procedure SetErrorNoise(value : Byte);     procedure SetSignalRTS(State : Boolean);     procedure SetSignalDTR(State : Boolean);     procedure SetSignalBREAK(State : Boolean);     procedure SetReadRequest(value : Boolean);     procedure SetActive(NewState : Boolean);     // Rest of Procedures     procedure InitOverlapped(var Overlapped : TOverlapped);     procedure ResetOverlapped(var Overlapped : TOverlapped);     procedure SetOverlapped(var Overlapped : TOverlapped);     procedure SetupDCB;     procedure PortWork (ReOpen : Boolean); //If ReOpen is True the Port will be (Re-) Opened, otherwise closed. The ActiveFlag will bes Set!     procedure EnableEvents;     procedure ProcessError(Place, Code : DWord; Msg : String; Noise : Byte);     procedure WorkThreadDone(Sender: TObject);     procedure WaitForThreadNotRunning(Counter : Integer);   protected   public     // Procedures for external calling     constructor Create(AOwner : TComponent); override; //Create the Component     destructor Destroy; override; //Destroy     procedure SendData (Data : Pointer; Size : DWord); //Send binary Data     procedure SendString(S : String); //Send String Data     // Clusterfunctions works on received Datapackages     function NextClusterSize : Integer;     function NextClusterCCError : DWord;     function ReadNextCluster(var ClusterSize : Integer; var CCError : DWord) : Pointer;     function ReadNextClusterAsString : String;     function ReadNextClusterAsPChar(Dest : PChar) : PChar;     // Clears the Queues     procedure ClearTxDQueue;     procedure ClearRxDQueue;     // Sets the Timingfields in depedecy to the Baudrate     procedure XTODefault;     // Save and retrieves the Setting to/from the registry     procedure WriteSettings(Regkey, RegSubKey : String); // e.g. WriteSettings('Software/DomIS','SerialNGAdvDemo') will save to HKEY_CURRENT_USER\Software\DomIS\SerialAdvDemo     procedure ReadSettings(Regkey, RegSubKey : String);   published     //If You set Active to True, the component tries to Open the Port, if Opened the state remains True.     property Active : Boolean read FActive write SetActive default False;     property ComHandle : THandle read hCommPort default INVALID_HANDLE_VALUE;     property CommPort : ShortString read fCommPort write SetCommPort;     property BaudRate :  DWord read fBaudRate write SetBaudRate default dflt_BaudRate;     property ParityType : Byte read fParityType write SetParityType default dflt_ParityType;     property ParityErrorChar : Char read fParityErrorChar write SetParityErrorChar default dflt_ParityErrorChar;     property ParityErrorReplacement :  Boolean read fParityErrorReplacement  write SetParityErrorReplacement  default dflt_ParityErrorReplacement;     property StopBits : Byte read fStopBits write SetStopBits default dflt_StopBits;     property DataBits : Byte read fDataBits write SetDataBits default dflt_DataBits;     property XONChar : Char read fXONChar  write SetXONChar  default dflt_XONChar;     property XOFFChar : Char read fXOFFChar write SetXOFFChar  default dflt_XOFFChar;     property XONLimDiv : Byte read fXONLimDiv  write SetXONLimDiv default dflt_XOnLimDiv;     property XOFFLimDiv : Byte read fXOFFLimDiv  write SetXOFFLimDiv default dflt_XOffLimDiv;     property FlowControl : LongInt read fFlowControl write SetFlowControl default dflt_FlowControl;     property StripNullChars : Boolean read fStripNullChars write SetStripNullChars default dflt_StripNullChars;     property EventChar : Char read fEventChar write SetEventChar default dflt_EventChar;  // One part of the Clusterdefinition is here, please read carefully // The "RTOCharDelayTime" is the Time that may delay between two received Chars // This Time should be Computed depending from the Baudrate e.g. 9600 Baud -> 960 Chars per Second -> Delay 1ms // You can use the CharDelayDefault Procedure to set RTOCharDelayTime and WTOCharDelayTime depending // of the selected Baudrate!     property RTOCharDelayTime : DWord read fRTOCharDelayTime write SetRTOCharDelayTime default dflt_RTOCharDelayTime; // The "RTOExtraDelayTime" is the Time that may delay addionally once // So if the (CharCount*RTOCharDelayTime)/1000 + RTOExtraDelayTime extends the measured Time, a Cluster will be build     property RTOExtraDelayTime : Word read fRTOExtraDelayTime write SetRTOExtraDelayTime default dflt_RTOExtraDelayTime; // Clustersize specify how long one Cluster could become max     property ClusterSize : Word read fClusterSize write SetClusterSize default dflt_ClusterSize; // RxQueueSize specify the amount of Chars that could be received without reading, // this should be longer than the Cluster size to prevent overrun errors     property RxQueueSize : Word read fRxQueueSize write SetRxQueueSize default dflt_RxQueueSize;     property TxQueueSize : Word read fTxQueueSize write SetTxQueueSize default dflt_TxQueueSize;      property WTOCharDelayTime : DWord read fWTOCharDelayTime write SetWTOCharDelayTime default dflt_WTOCharDelayTime;     property WTOExtraDelayTime : Word read fWTOExtraDelayTime write SetWTOExtraDelayTime default dflt_WTOExtraDelayTime;     property XTOAuto : Boolean read fXTOAuto write SetXTOAuto default dflt_XTOAuto;     property RTSState : Boolean read fRTSState write SetSignalRTS default dflt_RTSState;     property DTRState : Boolean read fDTRState write SetSignalDTR default dflt_DTRState;     property BREAKState : Boolean read fBREAKState write SetSignalBREAK default dflt_BreakState;     property CTSState : Boolean read fCTSState;     property DSRState : Boolean read fDSRSTate;     property RLSDState : Boolean read fRLSDState;     property RingState : Boolean read fRingState;     property ErrorNoise : Byte read fErrorNoise write SetErrorNoise default dflt_ErrorNoise;     property ReadRequest : Boolean read fReadRequest write SetReadRequest default False;     property SendInProgress : Boolean read fSendInProgress;     property CommError : DWord read fCommError;     property CommStateFlags : TComStateFlags read fCommStateFlags;     property CommStateInQueue: DWord read fCommStateInQueue;     property CommStateOutQueue : DWord read fCommStateOutQueue;     property ModemState : DWord read fModemState;     property CommEvent : DWord read fCommEvent;     property WrittenBytes : DWord read fWrittenBytes;     property ThreadQuietMode : Boolean read fThreadQuietMode write fThreadQuietMode default dflt_ThreadQuietMode;     //THIS FLAG SHOULD BE SET TO TRUE ONLY IN VERY SPECIAL CASES!!! No Syncromize call in the Thread if True.     property AutoReadRequest : Boolean read fAutoReadRequest write fAutoReadRequest default dflt_AutoReadRequest;      // Event Properties     property OnCommEvent : TNotifyEvent read fOnCommEvent write fOnCommEvent;     property OnCommStat : TNotifyEvent read fOnCommStat write fOnCommStat;     property OnTxQueueEmptyEvent : TNotifyEvent read fOnTxQueueEmptyEvent write fOnTxQueueEmptyEvent;     property OnWriteDone : TNotifyEvent read fOnWriteDone write fOnWriteDone;     property OnBreakEvent : TNotifyEvent read fOnBreakEvent write fOnBreakEvent;     property OnCTSEvent : TNotifyEvent read fOnCTSEvent write fOnCTSEvent;     property OnDSREvent : TNotifyEvent read fOnDSREvent write fOnDSREvent;     property OnLineErrorEvent : TNotifyEvent read fOnLineErrorEvent write fOnLineErrorEvent;     property OnRingEvent : TNotifyEvent read fOnRingEvent write fOnRingEvent; // RING, RING on falling edge of the RI Pin     property OnRIEvent : TNotifyEvent read fOnRIEvent write fOnRIEvent;       // on every change of the RI Pin     property OnRLSDEvent : TNotifyEvent read fOnRLSDEvent write fOnRLSDEvent;     property OnRxClusterEvent : TNotifyEvent read fOnRxClusterEvent write fOnRxClusterEvent;     property OnRxCharEvent : TNotifyEvent read fOnRxCharEvent write fOnRxCharEvent;     property OnRxEventCharEvent : TNotifyEvent read fOnRxEventCharEvent write fOnRxEventCharEvent;     property OnProcessError : TNotifyErrorEvent read fOnProcessError write fOnProcessError;   end;  // The TWorkThread class deals with several CommEvents and controll the receiving // of Clusters and check the Sendprocess // Under normal cirumstances You don't have to deal with   TWorkThread = class(TThread)   private     Owner : TSerialPortNG;     Place, Code : DWord;     Msg : String;     Noise : Byte;     Cluster : TSerialCluster;     procedure ThreadSynchronize(Method: TThreadMethod);     procedure SetProcessError(APlace, ACode : DWord; AMsg : String; ANoise : Byte);     procedure ProcessError;     procedure RxClusterEvent;     procedure CommEvent;     procedure CommStatEvent;     procedure BreakEvent;     procedure CTSEvent;     procedure DSREvent;     procedure LineErrorEvent;     procedure RingEvent;     procedure RIEvent;     procedure RLSDEvent;     procedure RxCharEvent;     procedure RxEventCharEvent;     procedure TxQueueEmptyEvent;     procedure WriteDone;    protected   public     constructor Create(AOwner : TSerialPortNG);     procedure Execute; override;   end;  procedure Register;  implementation uses Registry, CommPortList;  var VersionInfo : TOSVersionInfo;  procedure Register; begin   RegisterComponents('Samples', [TSerialPortNG]); end;   // // TSerialCluster Component //  constructor TSerialCluster.Create(Data : Pointer; Size : Integer; CCError : DWord); begin   inherited Create;   ClusterData := Data; // Take the Pointer   ClusterSize := Size; // Size of Data   ClusterCCError := CCError; end;  function TSerialCluster.GetCCError : DWord; begin   GetCCError := ClusterCCError; end;  function TSerialCluster.GetSize : Integer; begin   GetSize := ClusterSize; end;  procedure TSerialCluster.GetData(Dest : Pointer); begin   if Dest <> Nil then     Move(ClusterData^, Dest^, ClusterSize); end;  function TSerialCluster.GetDataAsString : String; var S : String; begin   SetLength(S,ClusterSize);   Move(ClusterData^, S[1], ClusterSize);   GetDataAsString := S; end;  function TSerialCluster.GetDataAsPChar(Dest : PChar) : PChar; type TMaxSize = array[0..MaxLongInt-1] of Char;      PMaxSize = ^TMaxSize; begin   if Dest <> Nil then     begin       Move(ClusterData^, Dest^, ClusterSize);       PMaxSize(Dest)^[ClusterSize] := #0;     end;   GetDataAsPChar := Dest; end;  destructor TSerialCluster.Destroy; begin   Dispose(ClusterData);   inherited Destroy; end;   // // TSerialPortNG Component definition //  // // Serveral "Set..." procedure for the Property mapping  procedure TSerialPortNG.SetCommPort(value : ShortString); begin   if value <> fCommPort then     begin       fCommPort := value;       PortWork(fActive);     end; end;  procedure TSerialPortNG.SetBaudRate(value : DWord); begin   if value <> fBaudRate then     begin       fBaudRate := value;       if fXTOAuto then         XTODefault; // Adjust the CharDelay Timeouts       if fActive then         SetupDCB;     end; end;  procedure TSerialPortNG.SetParityType(value : Byte); begin   if value <> fParityType then     begin       fParityType := value;       if fActive then         SetupDCB;     end; end;  procedure TSerialPortNG.SetParityErrorChar(value : Char); begin   if value <> fParityErrorChar then     begin       fParityErrorChar := value;       if fActive then         SetupDCB;     end; end;  procedure TSerialPortNG.SetParityErrorReplacement(value : Boolean); begin   if value <> fParityErrorReplacement then     begin       fParityErrorReplacement := value;       if fActive then         SetupDCB;     end; end;  procedure TSerialPortNG.SetStopBits(value : Byte); begin   if value <> fStopBits then     begin       fStopBits := value;       if fActive then         SetupDCB;     end; end;  procedure TSerialPortNG.SetDataBits(value : Byte); begin   if value <> fDataBits then     begin       fDataBits := value;       if fActive then         SetupDCB;     end; end;  procedure TSerialPortNG.SetXONChar(value : Char); begin   if value <> fXONChar then     begin       fXONChar := value;       if fActive then         SetupDCB;     end; end;  procedure TSerialPortNG.SetXOFFChar(value : Char); begin   if value <> fXOFFChar then     begin       fXOFFChar := value;       if fActive then         SetupDCB;     end; end;  procedure TSerialPortNG.SetXONLimDiv(value : Byte); begin   if value <> fXONLimDiv then     begin       if value > 100 then         begin           ProcessError(0100,value,'Warning XOnLimDef set to 100',enWarning);           value := 100;         end;       fXONLimDiv := value;       if fActive then         SetupDCB;     end; end;  procedure TSerialPortNG.SetXOFFLimDiv(value : Byte); begin   if value <> fXOFFLimDiv then     begin       if value > 100 then         begin           ProcessError(0100,value,'Warning XOffLimDef set to 100',enWarning);           value := 100;         end;       fXOFFLimDiv := value;       if fActive then         SetupDCB;     end; end;  procedure TSerialPortNG.SetFlowControl(value : LongInt); begin   if value <> fFlowControl then     begin       fFlowControl := value;       if fActive then         SetupDCB;     end; end;  procedure TSerialPortNG.SetStripNullChars(value : Boolean); begin   if value <> fStripNullChars then     begin       fStripNullChars := value;       if fActive then         SetupDCB;     end; end;  procedure TSerialPortNG.SetEventChar(value : Char); begin   if value <> fEventChar then     begin       fEventChar := value;       if fActive then         SetupDCB;     end; end;  procedure TSerialPortNG.SetRTOCharDelayTime(value : DWord); begin   if value <> fRTOCharDelayTime then     fRTOCharDelayTime := value; end;  procedure TSerialPortNG.SetRTOExtraDelayTime(value : Word); begin   if value <> fRTOExtraDelayTime then     fRTOExtraDelayTime := value; end;  procedure TSerialPortNG.SetWTOCharDelayTime(value : DWord); begin   if value <> fWTOCharDelayTime then     begin       fWTOCharDelayTime := value;       if fActive then         SetupDCB;     end; end;  procedure TSerialPortNG.SetWTOExtraDelayTime(value : Word); begin   if value <> fWTOExtraDelayTime then     begin       fWTOExtraDelayTime := value;       if fActive then         SetupDCB;     end; end;  procedure TSerialPortNG.SetXTOAuto(value : Boolean); begin   if value <> fXTOAuto then     begin       fXTOAuto := value;       if fXTOAuto then         XTODefault;     end; end;  procedure TSerialPortNG.SetClusterSize(value : Word); begin   fClusterSize := value; end;  procedure TSerialPortNG.SetRxQueueSize(value : Word); begin   if value <> fRxQueueSize then     begin       fRxQueueSize := value;       if not SetupComm(hCommPort,fRxQueueSize,fTxQueueSize) then         ProcessError(0101,GetLastError,'Error can not set Quesize',enError);     end; end;  procedure TSerialPortNG.SetTxQueueSize(value : Word); begin   if value <> fTxQueueSize then     begin       fTxQueueSize := value;       if not SetupComm(hCommPort,fRxQueueSize,fTxQueueSize) then         ProcessError(0102,GetLastError,'Error can not set Quesize',enError);     end; end;  procedure TSerialPortNG.SetErrorNoise(value : Byte); begin   fErrorNoise := value; end;  procedure TSerialPortNG.SetReadRequest(value : Boolean); begin   fReadRequest := value; end;  procedure TSerialPortNG.SetActive(NewState : Boolean); begin   // You may expect that this function set only the fActive Value   // This is done by the PortWork procedure, depending from the successful   // opened Port   if NewState <> fActive then     PortWork(NewState); end;  // // Several Methods  procedure TSerialPortNG.ProcessError(Place, Code : DWord; Msg : String; Noise : Byte); begin   if ShutdownInProgress then Exit; // No Messages now the Component is in Destroystate   if Noise <= fErrorNoise then     if assigned(fOnProcessError) then       fOnProcessError(Self,Place,Code,Msg,Noise); //Owner replaced by Self end;  procedure TSerialPortNG.InitOverlapped(var Overlapped : TOverlapped); begin   Overlapped.Offset := 0;   Overlapped.OffsetHigh := 0;   Overlapped.Internal := 0;   Overlapped.InternalHigh := 0;   Overlapped.hEvent := CreateEvent(nil,True,False,'');   if Overlapped.hEvent = 0 then     ProcessError(1001,GetLastError,'Error Creating Overlapped Event',enError)   else if GetLastError = ERROR_ALREADY_EXISTS then     ProcessError(1002,ERROR_ALREADY_EXISTS,'Error Overlapped Event Exists',enError) end;  procedure TSerialPortNG.ResetOverlapped(var Overlapped : TOverlapped); begin   if not ResetEvent(Overlapped.hEvent) then     ProcessError(1101,GetLastError,'Error resetting Overlapped Event',enError); end;  procedure TSerialPortNG.SetOverlapped(var Overlapped : TOverlapped); begin   if not SetEvent(Overlapped.hEvent) then // EVENT_MODIFY_STATE     ProcessError(1101,GetLastError,'Error resetting Overlapped Event',enError); end;   // // Create method. constructor TSerialPortNG.Create(AOwner : TComponent); begin   inherited Create(AOwner);   InitializeCriticalSection(CriticalSection);    ShutdownInProgress := False;   hCommPort := INVALID_HANDLE_VALUE;   Platform := CheckOS(VersionInfo);    // Set initial settings.  Even though   // the default parameter was specified   // in the property, if you were to   // create a component at runtime, the   // defaults would not get set.  So it   // is important to call them again in   // the create of the component.   fCommPort := dflt_CommPort;   fBaudRate := dflt_BaudRate;   fParityType := dflt_ParityType;   fStopBits := dflt_StopBits;   fDataBits := dflt_DataBits;   fXONChar := dflt_XONChar;   fXOFFChar := dflt_XOFFChar;   fXONLimDiv := dflt_XONLimDiv;   fXOFFLimDiv := dflt_XOFFLimDiv;   fFlowControl := dflt_FlowControl;   fRTOCharDelayTime := dflt_RTOCharDelayTime;   fRTOExtraDelayTime := dflt_RTOExtraDelayTime;   fWTOCharDelayTime := dflt_WTOCharDelayTime;   fWTOExtraDelayTime := dflt_WTOExtraDelayTime;   fXTOAuto := dflt_XTOAuto;   fClusterSize := dflt_ClusterSize;   fRxQueueSize := dflt_RxQueueSize;   fTxQueueSize := dflt_TxQueueSize;   fErrorNoise := enAll;   fReadRequest := False;   fRTSState := dflt_RTSState;   fDTRState := dflt_DTRState;   fBREAKState := dflt_BREAKState;   fOnTxQueueEmptyEvent := Nil;   fOnBreakEvent := Nil;   fOnCTSEvent := Nil;   fOnDSREvent := Nil;   fOnLineErrorEvent := Nil;   fOnRingEvent := Nil;   fOnRLSDEvent := Nil;   fOnRxCharEvent := Nil;   fOnRxEventCharEvent := Nil;   fOnRxClusterEvent := Nil;   fOnProcessError := Nil;   fThreadQuietMode := dflt_ThreadQuietMode;   fAutoReadRequest := dflt_AutoReadRequest;   LastErr := 0;   RxDClusterList := TList.Create; // Create the List to store the received Clusters   InitOverlapped(WriteOverlapped);   InitOverlapped(ReadOverlapped);   InitOverlapped(StatusOverlapped);   WorkThread := TWorkThread.Create(Self);   WorkThread.OnTerminate := WorkThreadDone; end;  // Destroy method. destructor TSerialPortNG.Destroy; var i : Integer; begin   ShutdownInProgress := True;   PortWork(False);   WorkThread.Terminate;   WaitForThreadNotRunning(10);   CloseHandle(WriteOverlapped.hEvent);   CloseHandle(StatusOverlapped.hEvent);   CloseHandle(ReadOverlapped.hEvent);   for i := 0 to RxDClusterList.Count-1 do     begin       if RxDClusterList.Items[i] <> Nil then         begin           TSerialCluster(RxDClusterList.Items[i]).Free;           RxDClusterList.Items[i] := Nil;         end;     end;   RxDClusterList.Free;   WorkThread.Free;   DeleteCriticalSection(CriticalSection);   inherited Destroy; end;  // PortWork Closes or Opens the Port depending of the Parm // It sets the fActive Variable depending of result of Opening the Port procedure TSerialPortNG.PortWork(ReOpen : Boolean); var   CommPortName : array [0..127] of Char; begin   if fActive then // The Port is Open, Close first     begin       ProcessError(0100,0,'Msg start deactivating Port',enMsg);       if not SetCommMask(hCommPort,0) then         ProcessError(0101,GetLastError,'Error disabling CommEvents',enError);       fActive := False; // The WorkThread check this Flag       if not PurgeComm(hCommPort, PURGE_RXABORT or PURGE_RXCLEAR or PURGE_TXABORT or PURGE_TXCLEAR) then         ProcessError(0102,GetLastError,'Error clearing Queues',enError);       WaitForThreadNotRunning(15);       if WorkThreadIsRunning then         ProcessError(0104,0,'Warning ThreadIsRunning',enWarning);       SetSignalDTR(False);       SetSignalRTS(False);       if not CloseHandle(hCommPort) then         ProcessError(0103,GetLastError,'Error closing Port',enError);       hCommPort := INVALID_HANDLE_VALUE;     end; // The Port is Closed, the Thread is Idle   if  ReOpen then     begin // Reopen the Port with (new) Parms       ProcessError(0110,0,'Msg start reactivating Port',enMsg);       hCommPort := CreateFile(StrPCopy(CommPortName,'\\.\'+Copy(fCommPort,1,79)),             GENERIC_READ OR GENERIC_WRITE,             0,             nil,             OPEN_EXISTING,             FILE_FLAG_OVERLAPPED,0);       fActive := (hCommPort <> INVALID_HANDLE_VALUE);       if fActive then         begin           if not SetupComm(hCommPort,fRxQueueSize,fTxQueueSize) then             ProcessError(0111,GetLastError,'Error setup Queuesize',enError);           SetupDCB;           SetSignalDTR(dflt_DTRState);           SetSignalRTS(dflt_RTSState);           EnableEvents;         end       else         ProcessError(0112,GetLastError,'Error reopening Port',enError);     end; end;  // Internal method to enable all Events procedure TSerialPortNG.EnableEvents; begin   if not SetCommMask(hCommPort, EV_BREAK or EV_CTS or EV_DSR or EV_ERR or EV_RING or EV_RLSD or EV_RXCHAR or EV_RXFLAG or EV_TXEMPTY) then     ProcessError(0201,GetLastError,'Error activating CommEventMask',enError); end;  // Public method to cancel and  flush the receive buffer. procedure TSerialPortNG.ClearRxDQueue; begin   if fActive then     if not PurgeComm(hCommPort,  PURGE_RXABORT or PURGE_RXCLEAR) then       ProcessError(0301,GetLastError,'Error clearing RxD Queue',enError); end;  // Public method to cancel and flush the transmit buffer. procedure TSerialPortNG.ClearTxDQueue; begin   if fActive then     if not PurgeComm(hCommPort,  PURGE_TXABORT or PURGE_TXCLEAR) then       ProcessError(0401,GetLastError,'Error clearing TxD Queue',enError); end;  // Public method to Play with the RTS Line // It is an Error to work on this Line while in the Flowmode bmfOutxCtsFlow is set! procedure TSerialPortNG.SetSignalRTS(State : Boolean); begin   if fActive then     begin       if State then         begin           if not EscapeCommFunction(hCommPort,SETRTS) then             ProcessError(0501,GetLastError,'Error setting RTS',enError)         end       else         begin           if not EscapeCommFunction(hCommPort,CLRRTS) then             ProcessError(0502,GetLastError,'Error clearing RTS',enError)         end;       fRTSState := State;     end; end;  // Public method to Play with the DTR Line // It is an Error to work on this Line while in the Flowmode bmfOutxDtrFlow is set! procedure TSerialPortNG.SetSignalDTR(State : Boolean); begin   if fActive then     begin       if State then         begin           if not EscapeCommFunction(hCommPort,SETDTR) then             ProcessError(0601,GetLastError,'Error setting DTR',enError)         end       else         begin           if not EscapeCommFunction(hCommPort,CLRDTR) then             ProcessError(0602,GetLastError,'Error clearing DTR',enError)         end;       fDTRState := State;     end; end;  // Public method to set the break State procedure TSerialPortNG.SetSignalBREAK(State : Boolean); begin   if fActive then     begin       if State then         begin           if not SetCommBreak(hCommPort) then             ProcessError(0701,GetLastError,'Error setting BREAK State',enError)         end       else         begin           if not ClearCommBreak(hCommPort) then             ProcessError(0702,GetLastError,'Error clearing BREAK State',enError)         end;       fBREAKState := State;     end; end;  // Initialize the device control block. procedure TSerialPortNG.SetupDCB; var   MyDCB : TDCB;   MyCommTimeouts : TCommTimeouts; //  SDCB : array[0..79] of Char; begin   // The GetCommState function fills in a   // device-control block (a DCB structure)   // with the current control settings for   // a specified communications device.   // (Win32 Developers Reference)   // Get a default fill of the DCB.   if not GetCommState(hCommPort, MyDCB) then     begin       ProcessError(0801,GetLastError,'Error getting DCB from CommState',enError);       Exit;     end;    MyDCB.BaudRate := fBaudRate;   MyDCB.Flags := bmfBinary; //Must be set under Win32   if fParityType <> NOPARITY then // If a ParityType is selceted, set Paritybit automatic     MyDCB.Flags := MyDCB.Flags or bmfParity;   MyDCB.Parity := fParityType;   if fParityErrorReplacement then     MyDCB.Flags := MyDCB.Flags or bmfErrorChar;   MyDCB.Flags := MyDCB.Flags or fFlowControl;   if fStripNullChars then     MyDCB.Flags := MyDCB.Flags or bmfNull;   MyDCB.ErrorChar := fParityErrorChar;   MyDCB.EvtChar := fEventChar;   MyDCB.StopBits := fStopBits;   MyDCB.ByteSize := fDataBits;   MyDCB.XONChar := fXONChar;   MyDCB.XOFFChar := fXOFFChar;   MyDCB.XONLim := fRxQueueSize * fXONLimDiv div 100; // Send XOn if e.g fXONLimDiv = 33 -> 33% full   MyDCB.XOFFLim := fRxQueueSize * fXOFFLimDiv div 100;  // Send XOff if e.g fXOffLimDiv = 33 -> 100%-33%=67% Percent full   MyDCB.EOFChar := #0; //Ignored under Win32    // The SetCommTimeouts function sets   // the time-out parameters for all   // read and write operations on a   // specified communications device.   // (Win32 Developers Reference)   // The GetCommTimeouts function retrieves   // the time-out parameters for all read   // and write operations on a specified   // communications device.   GetCommTimeouts(hCommPort, MyCommTimeouts);   //Read Timeouts are disabled here, because they realized manually in the WorkThread   MycommTimeouts.ReadIntervalTimeout := MAXDWORD;   MycommTimeouts.ReadTotalTimeoutMultiplier := 0;   MycommTimeouts.ReadTotalTimeoutConstant := 0;   //Write Timeouts disable here   MycommTimeouts.WriteTotalTimeoutMultiplier := 0;   MycommTimeouts.WriteTotalTimeoutConstant := 0;   if not SetCommTimeouts(hCommPort, MyCommTimeouts) then       ProcessError(0802,GetLastError,'Error setting CommTimeout',enError);   if not SetCommState(hCommPort, MyDCB) then     ProcessError(0802,GetLastError,'Error setting CommState, 87 indicate that Parms are incorrect',enError); end;  // Public Send data method. procedure TSerialPortNG.SendData(Data : Pointer; Size : DWord); var MyCommTimeOuts : TCommTimeOuts; begin   if fSendInProgress then     begin       ProcessError(0901,0,'Msg, dont enter SendData while SendInProgress is set',enMsg);       Exit;     end   else     begin       GetCommTimeouts(hCommPort, MyCommTimeouts);       //Read Timeouts are disabled       MycommTimeouts.ReadIntervalTimeout := MAXDWORD;       MycommTimeouts.ReadTotalTimeoutMultiplier := 0;       MycommTimeouts.ReadTotalTimeoutConstant := 0;       //Write Timeouts calculated from the settings       MycommTimeouts.WriteTotalTimeoutMultiplier := 0;       MycommTimeouts.WriteTotalTimeoutConstant := ((fWTOCharDelayTime*Size) div 1000) + fWTOExtraDelayTime;       if not SetCommTimeouts(hCommPort, MyCommTimeouts) then           ProcessError(0902,GetLastError,'Error setting CommTimeout',enError);       BytesToWrite := Size;       if not WriteFile(hCommPort,                 Data^,                 Size,                 fWrittenBytes,                 @WriteOverlapped) then          begin            LastErr := GetLastError;            if LastErr <> ERROR_IO_PENDING then              begin                ProcessError(0903,LastErr,'Error writing Data',enError);                ResetOverlapped(WriteOverlapped);                fSendInProgress := False;              end            else              begin                WriteStartTime := GetTickCount;                fSendInProgress := True;              end;          end        else  // Write was done immidiatly          begin            if Assigned(fOnWriteDone) then              fOnWriteDone(Self);          end;      end; end;  // Public SendString Method procedure TSerialPortNG.SendString(S : String); begin   if Length(S) > 0 then     SendData(@S[1], Length(S)); end;  // Public NextClusterSize Method // Return the Number of Databytes // 0..MAXINT indicates that a Cluster is available, 0 = No Bytes, but an Error code // -1 not Cluster is available function TSerialPortNG.NextClusterSize : Integer; begin   EnterCriticalSection(CriticalSection);   try     if RxDClusterList.Count > 0 then       if RxDClusterList.Items[0] = Nil then           RxDClusterList.Pack;     if RxDClusterList.Count > 0 then       NextClusterSize := TSerialCluster(RxDClusterList.Items[0]).GetSize     else       NextClusterSize := -1;   finally     LeaveCriticalSection(CriticalSection);   end; end;  // Public NextClusterCCError Method // Returns the ErrorCode of the Next Cluster // Returns MAXDWORD if no Cluster in List function TSerialPortNG.NextClusterCCError : DWord; begin   EnterCriticalSection(CriticalSection);   try     if RxDClusterList.Count > 0 then       if RxDClusterList.Items[0] = Nil then           RxDClusterList.Pack;     if RxDClusterList.Count > 0 then       NextClusterCCError := TSerialCluster(RxDClusterList.Items[0]).GetCCError     else       NextClusterCCError := MAXDWORD;   finally     LeaveCriticalSection(CriticalSection);   end; end;  // Public Method to read and remove the next Cluster from the List // If no Cluster is avail the Method retuns NIL // Else, You have to deal with the Pointer, and Free him self function TSerialPortNG.ReadNextCluster(var ClusterSize : Integer; var CCError : DWord) : Pointer; var DataBuffer : Pointer; begin   EnterCriticalSection(CriticalSection);   try     if RxDClusterList.Count > 0 then       if RxDClusterList.Items[0] = Nil then           RxDClusterList.Pack;     if RxDClusterList.Count > 0 then       begin         CCError := TSerialCluster(RxDClusterList.Items[0]).GetCCError;         ClusterSize := TSerialCluster(RxDClusterList.Items[0]).GetSize;         GetMem(DataBuffer, ClusterSize);         TSerialCluster(RxDClusterList.Items[0]).GetData(DataBuffer);         TSerialCluster(RxDClusterList.Items[0]).Free;         RxDClusterList.Delete(0);         ReadNextCluster := DataBuffer;       end     else       begin         ClusterSize := -1;         CCError := MAXDWORD;         ReadNextCluster := Nil;       end;   finally     LeaveCriticalSection(CriticalSection);   end; end;  // Public Method to read and remove the next Cluster from the List // The Cluster is moved into a String function TSerialPortNG.ReadNextClusterAsString : String; begin   EnterCriticalSection(CriticalSection);   try     if RxDClusterList.Count > 0 then       if RxDClusterList.Items[0] = Nil then           RxDClusterList.Pack;     if RxDClusterList.Count > 0 then       begin         ReadNextClusterAsString := TSerialCluster(RxDClusterList.Items[0]).GetDataAsString;         TSerialCluster(RxDClusterList.Items[0]).Free;         RxDClusterList.Delete(0);       end     else       ReadNextClusterAsString := '';   finally     LeaveCriticalSection(CriticalSection);   end; end;  // Public Method to read and remove the next Cluster from the List // The Cluster is moved into "Dest". "Dest" should Point to enough Space to avoid // Exception Errors function TSerialPortNG.ReadNextClusterAsPChar(Dest : PChar) : PChar; begin   EnterCriticalSection(CriticalSection);   try     if Dest <> Nil then       begin         if RxDClusterList.Count > 0 then           if RxDClusterList.Items[0] = Nil then               RxDClusterList.Pack;         if RxDClusterList.Count > 0 then           begin             ReadNextClusterAsPChar := TSerialCluster(RxDClusterList.Items[0]).GetDataAsPChar(Dest);             TSerialCluster(RxDClusterList.Items[0]).Free;             RxDClusterList.Delete(0);           end         else           ReadNextClusterAsPChar := Nil;       end     else       ReadNextClusterAsPChar := Nil;   finally     LeaveCriticalSection(CriticalSection);   end; end;  // Private Method procedure TSerialPortNG.WorkThreadDone(Sender: TObject); begin   WorkThreadIsRunning := False; end;  // Public Method to fit the TimeOut Values to the current Baudrate // If the Property XTOAuto is true this method will be called from the SetBaud method procedure TSerialPortNG.XTODefault; var i : Integer;     NewXTO : DWord; begin   NewXTO := 1100;   for i := 0 to BaudRateCount-1 do     begin       if fBaudRate >= BaudRates[i] then         NewXTO := XTOCharDelayDef[i];     end;   SetRTOCharDelayTime(NewXTO);   SetWTOCharDelayTime(NewXTO); end;  // Saves all Setting into the Registry // e.g. WriteSettings('Software/DomIS','SerialNGAdvDemo') // will save to HKEY_CURRENT_USER\Software\DomIS\SerialAdvDemo procedure TSerialPortNG.WriteSettings(Regkey, RegSubKey : String);  var FIniFile : TRegIniFile; begin   FIniFile := TRegIniFile.Create(RegKey);   try     try     with FIniFile do       begin         WriteString(RegSubKey, 'CommPort', fCommPort);         WriteString(RegSubKey, 'BaudRate', IntToStr(fBaudRate));         WriteString(RegSubKey, 'ParityType', IntToStr(fParityType));         WriteString(RegSubKey, 'ParityErrorChar', fParityErrorChar);         WriteBool  (RegSubKey, 'ParityErrorReplacement', fParityErrorReplacement);         WriteString(RegSubKey, 'StopBits', IntToStr(fStopBits));         WriteString(RegSubKey, 'DataBits', IntToStr(fDataBits));         WriteString(RegSubKey, 'XONChar', fXONChar);         WriteString(RegSubKey, 'XOFFChar', fXOFFChar);         WriteString(RegSubKey, 'XONLimDiv', IntToStr(fXONLimDiv));         WriteString(RegSubKey, 'XOFFLimDiv', IntToStr(fXOFFLimDiv));         WriteString(RegSubKey, 'FlowControl', IntToStr(fFlowControl));         WriteBool  (RegSubKey, 'StripNullChars', fStripNullChars);         WriteString(RegSubKey, 'EventChar', fEventChar);         WriteString(RegSubKey, 'RTOCharDelayTime', IntToStr(fRTOCharDelayTime));         WriteString(RegSubKey, 'RTOExtraDelayTime', IntToStr(fRTOExtraDelayTime));         WriteString(RegSubKey, 'ClusterSize', IntToStr(fClusterSize));         WriteString(RegSubKey, 'RxQueueSize', IntToStr(fRxQueueSize));         WriteString(RegSubKey, 'TxQueueSize', IntToStr(fTxQueueSize));         WriteString(RegSubKey, 'WTOCharDelayTime', IntToStr(fWTOCharDelayTime));         WriteString(RegSubKey, 'WTOExtraDelayTime', IntToStr(fWTOExtraDelayTime));         WriteBool  (RegSubKey, 'XTOAuto', fXTOAuto);         WriteBool  (RegSubKey, 'RTSState', fRTSState);         WriteBool  (RegSubKey, 'DTRState', fDTRState);         WriteBool  (RegSubKey, 'BREAKState', fBREAKState);         WriteString(RegSubKey, 'ErrorNoise', IntToStr(fErrorNoise));         WriteBool  (RegSubKey, 'Active', FActive);         ProcessError(0501,0,'Settings saved',enMsg);       end;     except       ProcessError(0502,0,'Error saving Settings',enError);     end;   finally     FIniFile.Free;   end; end;  // Read all Settings from the Registry // e.g. ReadSettings('Software/DomIS','SerialNGAdvDemo') // will read from HKEY_CURRENT_USER\Software\DomIS\SerialAdvDemo procedure TSerialPortNG.ReadSettings(Regkey, RegSubKey : String); var FIniFile : TRegIniFile;     Activate : Boolean;     function CharFromStr(S : String):Char;     begin       if Length(S) > 0 then         CharFromStr := S[1]       else         CharFromStr := #0;     end;  begin   FIniFile := TRegIniFile.Create(RegKey);   try     try     with FIniFile do       begin         Activate := ReadBool(RegSubKey, 'Active', False); //Read the Active Flag into a save place         if Activate then         // The Port should be activated         // if the Port is the same as opened, the port stays open           CommPort := ReadString(RegSubKey, 'CommPort', dflt_CommPort)         else           begin           // The Port should be deactivated             Active := False; // Deactivate             fCommPort := ReadString(RegSubKey, 'CommPort', dflt_CommPort) //Store new name           end;         fBaudRate := StrToIntDef(ReadString(RegSubKey, 'BaudRate', ''),dflt_BaudRate);         fParityType := StrToIntDef(ReadString(RegSubKey, 'ParityType', ''), dflt_ParityType);         ParityErrorChar := CharFromStr(ReadString(RegSubKey, 'ParityErrorChar', dflt_ParityErrorChar));         fParityErrorReplacement := ReadBool(RegSubKey, 'ParityErrorReplacement', dflt_ParityErrorReplacement);         fStopBits := StrToIntDef(ReadString(RegSubKey, 'StopBits', ''), dflt_StopBits);         fDataBits := StrToIntDef(ReadString(RegSubKey, 'DataBits', ''), dflt_DataBits);         fXONChar := CharFromStr(ReadString(RegSubKey, 'XONChar', dflt_XONChar));         fXOFFChar := CharFromStr(ReadString(RegSubKey, 'XOFFChar', dflt_XOFFChar));         fXONLimDiv := StrToIntDef(ReadString(RegSubKey, 'XONLimDiv',''), dflt_XONLimDiv);         fXOFFLimDiv := StrToIntDef(ReadString(RegSubKey, 'XOFFLimDiv',''), dflt_XOFFLimDiv);         fFlowControl := StrToIntDef(ReadString(RegSubKey, 'FlowControl',''), dflt_FlowControl);         fStripNullChars := ReadBool(RegSubKey, 'StripNullChars', dflt_StripNullChars);         fEventChar := CharFromStr(ReadString(RegSubKey, 'EventChar', dflt_EventChar));         fRTOCharDelayTime := StrToIntDef(ReadString(RegSubKey, 'RTOCharDelayTime',''), dflt_RTOCharDelayTime);         fRTOExtraDelayTime := StrToIntDef(ReadString(RegSubKey, 'RTOExtraDelayTime',''), dflt_RTOExtraDelayTime);         fClusterSize := StrToIntDef(ReadString(RegSubKey, 'ClusterSize',''), dflt_ClusterSize);         fRxQueueSize := StrToIntDef(ReadString(RegSubKey, 'RxQueueSize',''), dflt_RxQueueSize);         fTxQueueSize := StrToIntDef(ReadString(RegSubKey, 'TxQueueSize',''), dflt_TxQueueSize);         fWTOCharDelayTime := StrToIntDef(ReadString(RegSubKey, 'WTOCharDelayTime',''), dflt_WTOCharDelayTime);         fWTOExtraDelayTime := StrToIntDef(ReadString(RegSubKey, 'WTOExtraDelayTime',''), dflt_WTOExtraDelayTime);         fXTOAuto := ReadBool(RegSubKey, 'XTOAuto', dflt_XTOAuto);         fRTSState := ReadBool(RegSubKey, 'RTSState', dflt_RTSState);         fDTRState := ReadBool(RegSubKey, 'DTRState', dflt_DTRState);         fBREAKState := ReadBool  (RegSubKey, 'BREAKState', dflt_BREAKState);         fErrorNoise := StrToIntDef(ReadString(RegSubKey, 'ErrorNoise',''), dflt_ErrorNoise);         Active := Activate; //After all force the new settings         ProcessError(0401,0,'Settings readed',enMsg);       end;     except       ProcessError(0402,0,'Error reading Settings',enError);     end;   finally     FIniFile.Free;   end; end;  procedure TSerialPortNG.WaitForThreadNotRunning(Counter : Integer); begin   while (Counter  > 0) and      (WorkThreadIsRunning) do     begin       Sleep(75);       Dec(Counter);     end; end;  // // WorkThread Definitions // The Workthread manage all the Work in the Background // - Checks wether the writing is done // - Checks if Data are received // - Checks the Status // - Calls the Events  // Saves the process error Variables procedure TWorkThread.SetProcessError(APlace, ACode : DWord; AMsg : String; ANoise : Byte); begin   Place := APlace;   Code := ACode;   Msg := AMsg;   Noise := ANoise; end;  // Calls the ProcessError Eventhandler procedure TWorkThread.ProcessError; begin   Owner.ProcessError(Place,Code,Msg,Noise); end;  // Create the Thread constructor TWorkThread.Create(AOwner : TSerialPortNG); begin   Owner := AOwner;   inherited Create(False); end;  // Events... procedure TWorkThread.RxClusterEvent; begin   if assigned(Owner.fOnRxClusterEvent) then     Owner.fOnRxClusterEvent(Owner); end; procedure TWorkThread.CommEvent; begin   Owner.fOnCommEvent(Owner); end; procedure TWorkThread.CommStatEvent; begin   Owner.fOnCommStat(Owner); end; procedure TWorkThread.BreakEvent; begin   Owner.fOnBreakEvent(Owner); end; procedure TWorkThread.CTSEvent; begin   Owner.fOnCTSEvent(Owner); end; procedure TWorkThread.DSREvent; begin   Owner.fOnDSREvent(Owner); end; procedure TWorkThread.LineErrorEvent; begin   Owner.fOnLineErrorEvent(Owner); end; procedure TWorkThread.RingEvent; begin   Owner.fOnRingEvent(Owner); end; procedure TWorkThread.RIEvent; begin   Owner.fOnRIEvent(Owner); end; procedure TWorkThread.RLSDEvent; begin   Owner.fOnRLSDEvent(Owner); end; procedure TWorkThread.RxCharEvent; begin   Owner.fOnRxCharEvent(Owner); end; procedure TWorkThread.RxEventCharEvent; begin   Owner.fOnRxEventCharEvent(Owner); end; procedure TWorkThread.TxQueueEmptyEvent; begin   Owner.fOnTxQueueEmptyEvent(Owner); end; procedure TWorkThread.WriteDone; begin   if Assigned(Owner.fOnWriteDone) then     Owner.fOnWriteDone(Owner); end;  procedure TWorkThread.ThreadSynchronize(Method: TThreadMethod); begin   if not Owner.fThreadQuietMode then     Synchronize(Method); end;   // // Workthread Maincycle procedure TWorkThread.Execute; var   WrittenBytes : DWORD;   BytesRead : DWORD;   CommStatus : TComStat;   CommErrorCode : DWORD;   CommEventFlags : DWORD;   ModemState : DWORD;   RetCode : DWord;   StartTime, TickTime : DWord;   ClusterData : Pointer;   Buffer : Pointer;   BufferSize : DWord;   WaitForReadEvent : Boolean;   WaitForCommEvent : Boolean;   HandleEvent : array[0..1] of DWord;   ActiveMode, TerminateMode : Boolean;   // The local Procedure evaluates the Events generated by the CommPort   // and calles the Events of the Mainprogram   procedure DoCommEvent;   begin     if Owner.ShutdownInProgress then Exit;     Owner.fCommEvent := CommEventFlags;     if (CommEventFlags and EV_BREAK) <> 0 then       if assigned(Owner.fOnBreakEvent) then          ThreadSynchronize(BreakEvent);     if (CommEventFlags and EV_CTS) <> 0 then       begin         if assigned(Owner.fOnCTSEvent) then           ThreadSynchronize(CTSEvent);       end;     if (CommEventFlags and EV_DSR) <> 0 then       begin         if assigned(Owner.fOnDSREvent) then           ThreadSynchronize(DSREvent);       end;     if (CommEventFlags and EV_ERR) <> 0 then       begin         if assigned(Owner.fOnLineErrorEvent) then           ThreadSynchronize(LineErrorEvent);       end;     if (CommEventFlags and EV_RING) <> 0 then       begin         if assigned(Owner.fOnRingEvent) then           ThreadSynchronize(RingEvent);       end;     if (CommEventFlags and EV_RLSD) <> 0 then       begin         if assigned(Owner.fOnRLSDEvent) then           ThreadSynchronize(RLSDEvent);       end;     if (CommEventFlags and EV_RXCHAR) <> 0 then       begin         if assigned(Owner.fOnRxCharEvent) then           ThreadSynchronize(RxCharEvent);       end;     if (CommEventFlags and EV_RXFLAG) <> 0 then       begin         if assigned(Owner.fOnRxEventCharEvent) then           ThreadSynchronize(RxEventCharEvent);       end;     if (CommEventFlags and EV_TXEMPTY) <> 0 then       begin         if assigned(Owner.fOnTxQueueEmptyEvent) then           ThreadSynchronize(TxQueueEmptyEvent);       end;     if CommEventFlags <> 0 then       if assigned(Owner.fOnCommEvent) then          ThreadSynchronize(CommEvent);   end;    // Fetch the ModemStatus and CommErrorCode and CommStatus and generate   // a CommStatEvent if something changed   procedure GetStatus;   var ExecDoCommEvent : Boolean;       ExecRIEvent : Boolean;       ClrCommErrDone : Boolean;   begin     ExecDoCommEvent := False;     ExecRIEvent := False;     if GetCommModemStatus(Owner.hCommPort,ModemState) then       begin        // There is a Bug in Win9x on signalizing the RING Event        // We catch this manually here        // The RingEvent is singnalize only on the falling edge of the RI!         if Owner.Platform = VER_PLATFORM_WIN32_WINDOWS then           begin             if ((ModemState and MS_RING_ON) = 0) and                ((Owner.fModemState and MS_RING_ON) <> 0) then               // The RingIndicator Line has changed and is now False               // generate Event               begin                 CommEventFlags := EV_RING;                 Owner.fRingState := (ModemState and MS_RING_ON) <> 0;                 ExecDoCommEvent := True;               end;           end;         if ((ModemState xor Owner.fModemState) and MS_RING_ON) <> 0 then           ExecRIEvent := True;         Owner.fModemState := ModemState; // Krystian from Poland suggest to add these 3 lines and got correct states // even if no Event is assigned.         Owner.fCTSState := (ModemState and MS_CTS_ON) <> 0;         Owner.fDSRState := (ModemState and MS_DSR_ON) <> 0;         Owner.fRLSDState := (ModemState and MS_RLSD_ON) <> 0;         Owner.fRingState := (ModemState and MS_RING_ON) <> 0;         if ExecRIEvent and assigned(Owner.fOnRIEvent) then           ThreadSynchronize(RIEvent);         if ExecDoCommEvent then           DoCommEvent;        end     else       begin         SetProcessError(9905,GetLastError,'Error getting ModemStatus',enError);         ThreadSynchronize(ProcessError);       end;     ClrCommErrDone := False;     repeat       if ClearCommError(owner.hCommPort, CommErrorCode, @CommStatus) then         begin           if (Owner.fCommError <> CommErrorCode) or              (Owner.fCommStateFlags <> CommStatus.Flags) or              (Owner.fCommStateInQueue <> CommStatus.cbInQue) or              (Owner.fCommStateOutQueue <> CommStatus.cbOutQue) then             begin               Owner.fCommError := CommErrorCode;               Owner.fCommStateFlags := CommStatus.Flags;               Owner.fCommStateInQueue := CommStatus.cbInQue;               Owner.fCommStateOutQueue := CommStatus.cbOutQue;               if Assigned(Owner.fOnCommStat) then                 ThreadSynchronize(CommStatEvent);             end           else             ClrCommErrDone := True;         end       else         begin           SetProcessError(9803,GetLastError,'Error ClearCommError',enError);           ThreadSynchronize(ProcessError);           ClrCommErrDone := True;         end     until ClrCommErrDone;   end;    // This local procedure checks if the Writing is done   procedure CheckWriter;   begin     if Owner.fSendInProgress then       begin         if GetOverlappedResult(Owner.hCommPort,Owner.WriteOverlapped,WrittenBytes, FALSE) then           begin             Owner.fWrittenBytes := WrittenBytes;             Owner.fSendInProgress := False;             if WrittenBytes <> Owner.BytesToWrite then               begin                 SetProcessError(9701,RetCode,'Error write TimeOut',enError);                 ThreadSynchronize(ProcessError);               end;             ThreadSynchronize(WriteDone);           end         else           begin             RetCode := GetLastError;             case RetCode of               ERROR_IO_INCOMPLETE :;               ERROR_IO_PENDING :                 begin                   TickTime := GetTickCount;                   if ((WrittenBytes*Owner.fWTOCharDelayTime)/1000+Owner.fWTOExtraDelayTime) < (Owner.WriteStartTime - TickTime) then                     begin                       Owner.fWrittenBytes := WrittenBytes;                       Owner.fSendInProgress := False;                       Owner.ResetOverlapped(Owner.WriteOverlapped);                       SetProcessError(9701,RetCode,'Error write TimeOut',enError);                       ThreadSynchronize(ProcessError);                       ThreadSynchronize(WriteDone);                     end;                 end;             else               // Its an Error!!!               Owner.fSendInProgress := False;               Owner.ResetOverlapped(Owner.WriteOverlapped);               SetProcessError(9702,RetCode,'Error getting Overlapped Result',enError);               ThreadSynchronize(ProcessError);               ThreadSynchronize(WriteDone);             end;           end;       end;   end;    //This procedure stores the received Cluster into the List   procedure DoRxClusterStore;   begin     if not Owner.ShutdownInProgress then       begin         if BytesRead > 0 then           begin             GetMem(ClusterData,BytesRead);             Move(Buffer^,ClusterData^,BytesRead);             Cluster := TSerialCluster.Create(ClusterData,BytesRead,CommErrorCode);           end         else            Cluster := TSerialCluster.Create(Nil,0,CommErrorCode);         // The Storing of the Cluster into the Queue is done a CriticalSection         EnterCriticalSection(Owner.CriticalSection);         try           Owner.RxDClusterList.Add(Cluster);         finally           //End of safe block           LeaveCriticalSection(Owner.CriticalSection);         end;         ThreadSynchronize(RxClusterEvent);       end;   end;    //Checks if Data is wainting in the RxDQueue and reads if Conditions are met   //is called only if no Overlapp is running   procedure ReadNoWait;   begin     if CommStatus.cbInQue = 0 then // No Char received       StartTime := GetTickCount // Remember this Time as a Startpoint     else // at least one Char was received       begin       // A Cluster is completed if one of the followoing conditions fit       // - Owner request reading now       // - cbInQue is greater than ClusterSize       // - (cbInQue *  fRTOCharDelayTime)/1000 + fRTOExtraDelayTime is greater than the elapsed Time       // - a (Line-) Error occoured         TickTime := GetTickCount;         if (Owner.fReadRequest) or            (CommStatus.cbInQue >= Owner.ClusterSize) or            (((CommStatus.cbInQue *  Owner.fRTOCharDelayTime)/1000 + Owner.fRTOExtraDelayTime) < (TickTime - StartTime)) or            ((CommErrorCode and (CE_RXOVER or CE_OVERRUN or CE_RXPARITY or CE_FRAME or CE_BREAK)) <> 0) then           begin             BufferSize := CommStatus.cbInQue;             GetMem(Buffer,BufferSize);             if ReadFile(owner.hCommPort,                                PChar(Buffer)^,                                BufferSize,                                BytesRead,                                @Owner.ReadOverlapped) then               begin //We have received something                 Owner.fReadRequest := False; // Reset the Requestflag                 DoRxClusterStore; // Store Data and fire Event...                 FreeMem(Buffer,BufferSize); // Free Buffer                 Buffer := Nil;                 StartTime := GetTickCount // Remember this Time as a Startpoint               end             else  // ReadFile was not successful, this may caused by the Overlapped function               begin                 RetCode := GetLastError;                 if RetCode = ERROR_IO_PENDING then // Yes, Reading is in Progress                   WaitForReadEvent := True                 else                   begin // Error while reading                     Owner.fReadRequest := False;                     FreeMem(Buffer,BufferSize);                     Buffer := Nil;                     SetProcessError(9804,RetCode,'Error reading Data',enError);                     ThreadSynchronize(ProcessError);                   end;               end;           end;       end;   end;    // Checks for new events   //is called only if no Overlapp is running   procedure CommEventNoWait;   begin     CommEventFlags := 0;     if WaitCommEvent(Owner.hCommPort,CommEventFlags,@Owner.StatusOverlapped) then       begin         GetStatus;  // Update Statusflags 25.3.2003         DoCommEvent; // Event Occours, fire Events       end     else       begin         RetCode := GetLastError;         if RetCode = ERROR_IO_PENDING then           WaitForCommEvent := True //Check the Overlapped.hEvent         else           begin             SetProcessError(9907,RetCode,'Error calling WaitCommEvent',enError);             ThreadSynchronize(ProcessError);           end;       end;   end;    // Checks for received Data while an Overlapp is running   procedure ProcessWaitForRead;   begin     if not GetOverlappedResult(Owner.hCommPort,Owner.ReadOverlapped,BytesRead, False) then       begin         RetCode := GetLastError;         if RetCode = ERROR_OPERATION_ABORTED then           SetProcessError(9907,RetCode,'Error read aborted',enError)         else           SetProcessError(9908,RetCode,'Error getting Overlappedresult',enError);         ThreadSynchronize(ProcessError);       end     else  // Successfull Overlapped read       begin         DoRxClusterStore; // Store Data and fire Event...         FreeMem(Buffer,BufferSize); // Free Buffer         Buffer := Nil;         StartTime := GetTickCount // Remember this Time as a Startpoint       end;     WaitForReadEvent := False;   end;    // Checks for new Events while an Overlapp is running   procedure ProcessWaitForComm;   begin     if (Owner.fActive) then       begin         GetStatus;         DoCommEvent;       end;     WaitForCommEvent := False;   end;   // Main Cycle of the Thread begin   StartTime := GetTickCount;   WaitForCommEvent := False;   WaitForReadEvent := False;   ActiveMode := Owner.fActive;   TerminateMode := Terminated;   while not TerminateMode do     begin       if ActiveMode then         begin           Owner.WorkThreadIsRunning := True;           if (Owner.fActive) then             GetStatus; // Picup several Information about the actual State of Com           CheckWriter; // Checks for pending Writeprocess           if (not WaitForReadEvent) and (Owner.fActive) then // Start new Action only if not deactivating             ReadNoWait; // Reads if avail, no waiting here           if not WaitForCommEvent and (Owner.fActive) then   // Start new Action only if not deactivating             CommEventNoWait; // Check for Events, no waiting here           // WaitForMultiple Events           if (WaitForReadEvent and WaitForCommEvent) then             begin               HandleEvent[0] := Owner.ReadOverlapped.hEvent;               HandleEvent[1] := Owner.StatusOverlapped.hEvent;               RetCode := WaitForMultipleObjects(2,@HandleEvent,False,75);               if (Owner.fActive) then                 GetStatus; // Picup several Information about the actual State of Com               case RetCode of               WAIT_OBJECT_0 :                 begin                   ProcessWaitForRead;                 end;               WAIT_OBJECT_0 + 1 :                 begin                   ProcessWaitForComm;                 end;               WAIT_TIMEOUT :                 begin                 end;               else                 SetProcessError(9911,RetCode,'Error getting Overlappedresult',enError);                 ThreadSynchronize(ProcessError);                 WaitForReadEvent := False;                 WaitForCommEvent := False;               end;             end           else if WaitForReadEvent then             begin               RetCode := WaitForSingleObject(Owner.ReadOverlapped.hEvent,75);               if (Owner.fActive) then                 GetStatus; // Picup several Information about the actual State of Com               case RetCode of               WAIT_OBJECT_0 :                 begin                   if (Owner.fActive) then                     ProcessWaitForRead;                 end;               WAIT_TIMEOUT :                 begin                 end;               else                 SetProcessError(9912,RetCode,'Error getting Overlappedresult',enError);                 ThreadSynchronize(ProcessError);                 WaitForReadEvent := False;               end;             end           else if WaitForCommEvent then// WaitForCommEvent             begin               RetCode := WaitForSingleObject(Owner.StatusOverlapped.hEvent,75);               if (Owner.fActive) then                 GetStatus; // Picup several Information about the actual State of Com               case RetCode of               WAIT_OBJECT_0 :                 begin                   ProcessWaitForComm;                 end;               WAIT_TIMEOUT :                 begin                 end;               else                 SetProcessError(9913,RetCode,'Error getting Overlappedresult',enError);                 ThreadSynchronize(ProcessError);                 WaitForCommEvent := False;               end;             end;           if not Owner.fActive then // The owner wants to deactivate the port             begin               if WaitForReadEvent then                 Owner.SetOverlapped(Owner.ReadOverlapped);               if WaitForCommEvent then                 begin                   SetCommMask(Owner.hCommPort,0);                   Owner.SetOverlapped(Owner.StatusOverlapped);                 end;               if (not WaitForCommEvent) and                  (not WaitForReadEvent) and                  (not Owner.fSendInProgress) then                 ActiveMode := False; // We do so if everything pending is finished             end;         end       else // not ActiveMode         begin           Owner.WorkThreadIsRunning := False;           ActiveMode := Owner.fActive;           Sleep(200); //prevent consuming 100% of cpu-time in inactive mode         end;       if Terminated and (not ActiveMode) then //No termination before deactivation         TerminateMode := True;     end; // while not Terminated   Owner.WorkThreadIsTerminated := True; end;  end. 
object Form1: TForm1   Left = 226   Top = 214   BorderIcons = [biSystemMenu, biMinimize]   BorderStyle = bsSingle   Caption = #1051#1086#1075#1080#1095#1077#1089#1082#1080#1081' '#1072#1085#1072#1083#1080#1079#1072#1090#1086#1088   ClientHeight = 473   ClientWidth = 607   Color = clBlack   Font.Charset = DEFAULT_CHARSET   Font.Color = clWindowText   Font.Height = -11   Font.Name = 'MS Sans Serif'   Font.Style = []   OldCreateOrder = False   OnClose = FormClose   OnCreate = FormCreate   PixelsPerInch = 96   TextHeight = 13   object SpeedButton1: TSpeedButton     Left = 536     Top = 352     Width = 65     Height = 41     OnClick = SpeedButton1Click   end   object SpeedButton2: TSpeedButton     Left = 432     Top = 352     Width = 65     Height = 41     OnClick = SpeedButton2Click   end   object Label1: TLabel     Left = 8     Top = 400     Width = 117     Height = 14     Caption = #1043#1083#1091#1073#1080#1085#1072' '#1087#1088#1077#1076#1087#1091#1089#1082#1086#1074#1086#1081     Color = clBlack     Font.Charset = DEFAULT_CHARSET     Font.Color = clWindow     Font.Height = -11     Font.Name = 'Arial'     Font.Style = []     ParentColor = False     ParentFont = False   end   object Label2: TLabel     Left = 8     Top = 416     Width = 67     Height = 14     Caption = #1088#1077#1075#1080#1089#1090#1088#1072#1094#1080#1080':'     Font.Charset = DEFAULT_CHARSET     Font.Color = clWindow     Font.Height = -11     Font.Name = 'Arial'     Font.Style = []     ParentFont = False   end   object Label3: TLabel     Left = 328     Top = 384     Width = 22     Height = 22     Caption = 'Hz'     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -19     Font.Name = 'Arial'     Font.Style = []     ParentFont = False   end   object Label4: TLabel     Left = 200     Top = 408     Width = 181     Height = 18     Caption = #1058#1072#1081#1084#1072#1091#1090' '#1086#1078#1080#1076#1072#1085#1080#1103' '#1087#1091#1089#1082#1072':'     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -16     Font.Name = 'Arial'     Font.Style = []     ParentFont = False   end   object Label5: TLabel     Left = 256     Top = 432     Width = 63     Height = 22     Caption = #1062#1080#1082#1083#1086#1074     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -19     Font.Name = 'Arial'     Font.Style = []     ParentFont = False   end   object Chart1: TChart     Left = 95     Top = 12     Width = 514     Height = 301     AllowPanning = pmHorizontal     AllowZoom = False     BackWall.Brush.Color = clBlack     BackWall.Color = clBlack     BackWall.Pen.Color = clWhite     Title.Brush.Color = clWhite     Title.Color = clWhite     Title.Frame.Color = clWhite     Title.Text.Strings = (       'TChart')     Title.Visible = False     BackColor = clBlack     BottomAxis.Automatic = False     BottomAxis.AutomaticMaximum = False     BottomAxis.AutomaticMinimum = False     BottomAxis.Axis.Color = clWhite     BottomAxis.Grid.Color = clWhite     BottomAxis.LabelsFont.Charset = DEFAULT_CHARSET     BottomAxis.LabelsFont.Color = clWhite     BottomAxis.LabelsFont.Height = -11     BottomAxis.LabelsFont.Name = 'Arial'     BottomAxis.LabelsFont.Style = []     BottomAxis.Maximum = 16.000000000000000000     BottomAxis.MinorGrid.Color = clWhite     BottomAxis.MinorTicks.Color = clWhite     BottomAxis.Ticks.Color = clWhite     BottomAxis.TicksInner.Color = clWhite     DepthAxis.Automatic = False     DepthAxis.AutomaticMaximum = False     DepthAxis.AutomaticMinimum = False     DepthAxis.Axis.Color = clWhite     DepthAxis.Grid.Color = clWhite     DepthAxis.LabelsFont.Charset = DEFAULT_CHARSET     DepthAxis.LabelsFont.Color = clWhite     DepthAxis.LabelsFont.Height = -11     DepthAxis.LabelsFont.Name = 'Arial'     DepthAxis.LabelsFont.Style = []     DepthAxis.Maximum = 500.000000000000000000     DepthAxis.Minimum = 16.000000000000000000     DepthAxis.MinorGrid.Color = clWhite     DepthAxis.MinorTicks.Color = clWhite     DepthAxis.Ticks.Color = clWhite     DepthAxis.TicksInner.Color = clWhite     DepthAxis.Title.Font.Charset = DEFAULT_CHARSET     DepthAxis.Title.Font.Color = clWhite     DepthAxis.Title.Font.Height = -11     DepthAxis.Title.Font.Name = 'Arial'     DepthAxis.Title.Font.Style = []     Frame.Color = clWhite     LeftAxis.Automatic = False     LeftAxis.AutomaticMaximum = False     LeftAxis.AutomaticMinimum = False     LeftAxis.Axis.Color = clWhite     LeftAxis.Grid.Color = clWhite     LeftAxis.Inverted = True     LeftAxis.Maximum = 8.000000000000000000     LeftAxis.MinorGrid.Color = clWhite     LeftAxis.MinorTicks.Color = clWhite     LeftAxis.Ticks.Color = clWhite     LeftAxis.TicksInner.Color = clSilver     Legend.Font.Charset = DEFAULT_CHARSET     Legend.Font.Color = clWhite     Legend.Font.Height = -11     Legend.Font.Name = 'Arial'     Legend.Font.Style = []     Legend.Frame.Color = clWhite     Legend.Visible = False     RightAxis.Axis.Color = clSilver     ScaleLastPage = False     TopAxis.Automatic = False     TopAxis.AutomaticMaximum = False     TopAxis.AutomaticMinimum = False     TopAxis.Axis.Color = clSilver     TopAxis.Grid.Color = clSilver     TopAxis.LabelsFont.Charset = DEFAULT_CHARSET     TopAxis.LabelsFont.Color = clWhite     TopAxis.LabelsFont.Height = -11     TopAxis.LabelsFont.Name = 'Arial'     TopAxis.LabelsFont.Style = []     TopAxis.Maximum = 16.000000000000000000     TopAxis.Minimum = 16.000000000000000000     View3D = False     BevelOuter = bvNone     Color = clBlack     TabOrder = 0     object Series1: TLineSeries       Marks.ArrowLength = 8       Marks.Visible = False       SeriesColor = clRed       Dark3D = False       Pointer.InflateMargins = True       Pointer.Style = psRectangle       Pointer.Visible = False       Stairs = True       XValues.DateTime = False       XValues.Name = 'X'       XValues.Multiplier = 1.000000000000000000       XValues.Order = loAscending       YValues.DateTime = False       YValues.Name = 'Y'       YValues.Multiplier = 1.000000000000000000       YValues.Order = loNone     end     object Series2: TLineSeries       Marks.ArrowLength = 8       Marks.Visible = False       SeriesColor = clGreen       Dark3D = False       Pointer.InflateMargins = True       Pointer.Style = psRectangle       Pointer.Visible = False       Stairs = True       XValues.DateTime = False       XValues.Name = 'X'       XValues.Multiplier = 1.000000000000000000       XValues.Order = loAscending       YValues.DateTime = False       YValues.Name = 'Y'       YValues.Multiplier = 1.000000000000000000       YValues.Order = loNone     end     object Series3: TLineSeries       Marks.ArrowLength = 8       Marks.Visible = False       SeriesColor = clYellow       Dark3D = False       Pointer.InflateMargins = True       Pointer.Style = psRectangle       Pointer.Visible = False       Stairs = True       XValues.DateTime = False       XValues.Name = 'X'       XValues.Multiplier = 1.000000000000000000       XValues.Order = loAscending       YValues.DateTime = False       YValues.Name = 'Y'       YValues.Multiplier = 1.000000000000000000       YValues.Order = loNone     end     object Series4: TLineSeries       Marks.ArrowLength = 8       Marks.Visible = False       SeriesColor = clBlue       Dark3D = False       Pointer.InflateMargins = True       Pointer.Style = psRectangle       Pointer.Visible = False       Stairs = True       XValues.DateTime = False       XValues.Name = 'X'       XValues.Multiplier = 1.000000000000000000       XValues.Order = loAscending       YValues.DateTime = False       YValues.Name = 'Y'       YValues.Multiplier = 1.000000000000000000       YValues.Order = loNone     end     object Series5: TLineSeries       Marks.ArrowLength = 8       Marks.Visible = False       SeriesColor = clWhite       Dark3D = False       Pointer.InflateMargins = True       Pointer.Style = psRectangle       Pointer.Visible = False       Stairs = True       XValues.DateTime = False       XValues.Name = 'X'       XValues.Multiplier = 1.000000000000000000       XValues.Order = loAscending       YValues.DateTime = False       YValues.Name = 'Y'       YValues.Multiplier = 1.000000000000000000       YValues.Order = loNone     end     object Series6: TLineSeries       Marks.ArrowLength = 8       Marks.Visible = False       SeriesColor = clGray       Dark3D = False       Pointer.InflateMargins = True       Pointer.Style = psRectangle       Pointer.Visible = False       Stairs = True       XValues.DateTime = False       XValues.Name = 'X'       XValues.Multiplier = 1.000000000000000000       XValues.Order = loAscending       YValues.DateTime = False       YValues.Name = 'Y'       YValues.Multiplier = 1.000000000000000000       YValues.Order = loNone     end     object Series7: TLineSeries       Marks.ArrowLength = 8       Marks.Visible = False       SeriesColor = clFuchsia       Dark3D = False       Pointer.InflateMargins = True       Pointer.Style = psRectangle       Pointer.Visible = False       Stairs = True       XValues.DateTime = False       XValues.Name = 'X'       XValues.Multiplier = 1.000000000000000000       XValues.Order = loAscending       YValues.DateTime = False       YValues.Name = 'Y'       YValues.Multiplier = 1.000000000000000000       YValues.Order = loNone     end     object Series8: TLineSeries       Marks.ArrowLength = 8       Marks.Visible = False       SeriesColor = clTeal       Dark3D = False       Pointer.InflateMargins = True       Pointer.Style = psRectangle       Pointer.Visible = False       Stairs = True       XValues.DateTime = False       XValues.Name = 'X'       XValues.Multiplier = 1.000000000000000000       XValues.Order = loAscending       YValues.DateTime = False       YValues.Name = 'Y'       YValues.Multiplier = 1.000000000000000000       YValues.Order = loNone     end   end   object ColorBox1: TColorBox     Left = 88     Top = 32     Width = 38     Height = 22     Selected = clGreen     Color = clBlack     ItemHeight = 16     TabOrder = 1   end   object ColorBox2: TColorBox     Left = 88     Top = 64     Width = 38     Height = 22     Selected = clGradientActiveCaption     Color = clBlack     ItemHeight = 16     TabOrder = 2   end   object ColorBox3: TColorBox     Left = 88     Top = 96     Width = 38     Height = 22     Selected = clRed     Color = clBlack     ItemHeight = 16     TabOrder = 3   end   object ColorBox4: TColorBox     Left = 88     Top = 128     Width = 38     Height = 22     Selected = clLime     Color = clBlack     ItemHeight = 16     TabOrder = 4   end   object ColorBox5: TColorBox     Left = 88     Top = 160     Width = 38     Height = 22     Selected = clYellow     Color = clBlack     ItemHeight = 16     TabOrder = 5   end   object ColorBox6: TColorBox     Left = 88     Top = 192     Width = 38     Height = 22     Selected = clBlue     Color = clBlack     ItemHeight = 16     TabOrder = 6   end   object ColorBox7: TColorBox     Left = 88     Top = 223     Width = 38     Height = 22     Selected = clFuchsia     Color = clBlack     ItemHeight = 16     TabOrder = 7   end   object ColorBox8: TColorBox     Left = 88     Top = 255     Width = 38     Height = 22     Selected = clAqua     Color = clBlack     ItemHeight = 16     TabOrder = 8   end   object ScrollBar1: TScrollBar     Left = 120     Top = 300     Width = 481     Height = 17     Max = 484     PageSize = 0     TabOrder = 9     OnChange = ScrollChange   end   object StaticText1: TStaticText     Left = 8     Top = 32     Width = 72     Height = 28     Caption = #1050#1072#1085#1072#1083' 1'     Color = clBlack     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -19     Font.Name = 'MS Sans Serif'     Font.Style = []     ParentColor = False     ParentFont = False     TabOrder = 10   end   object StaticText2: TStaticText     Left = 8     Top = 64     Width = 72     Height = 28     Caption = #1050#1072#1085#1072#1083' 2'     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -19     Font.Name = 'MS Sans Serif'     Font.Style = []     ParentFont = False     TabOrder = 11   end   object StaticText3: TStaticText     Left = 8     Top = 96     Width = 72     Height = 28     Caption = #1050#1072#1085#1072#1083' 3'     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -19     Font.Name = 'MS Sans Serif'     Font.Style = []     ParentFont = False     TabOrder = 12   end   object StaticText4: TStaticText     Left = 8     Top = 128     Width = 72     Height = 28     Caption = #1050#1072#1085#1072#1083' 4'     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -19     Font.Name = 'MS Sans Serif'     Font.Style = []     ParentFont = False     TabOrder = 13   end   object StaticText5: TStaticText     Left = 8     Top = 160     Width = 72     Height = 28     Caption = #1050#1072#1085#1072#1083' 5'     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -19     Font.Name = 'MS Sans Serif'     Font.Style = []     ParentFont = False     TabOrder = 14   end   object StaticText6: TStaticText     Left = 8     Top = 192     Width = 72     Height = 28     Caption = #1050#1072#1085#1072#1083' 6'     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -19     Font.Name = 'MS Sans Serif'     Font.Style = []     ParentFont = False     TabOrder = 15   end   object StaticText7: TStaticText     Left = 8     Top = 225     Width = 72     Height = 28     Caption = #1050#1072#1085#1072#1083' 7'     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -19     Font.Name = 'MS Sans Serif'     Font.Style = []     ParentFont = False     TabOrder = 16   end   object StaticText8: TStaticText     Left = 8     Top = 253     Width = 72     Height = 28     Caption = #1050#1072#1085#1072#1083' 8'     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -19     Font.Name = 'MS Sans Serif'     Font.Style = []     ParentFont = False     TabOrder = 17   end   object StaticText9: TStaticText     Left = 432     Top = 328     Width = 172     Height = 28     Caption = #1052#1072#1089#1096#1090#1072#1073#1080#1088#1086#1074#1072#1085#1080#1077     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -19     Font.Name = 'MS Sans Serif'     Font.Style = []     ParentFont = False     TabOrder = 18   end   object GroupBox1: TGroupBox     Left = 8     Top = 320     Width = 145     Height = 73     Caption = #1047#1072#1087#1091#1089#1082     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -19     Font.Name = 'MS Sans Serif'     Font.Style = []     ParentFont = False     TabOrder = 19     object RadioButton1: TRadioButton       Left = 8       Top = 24       Width = 134       Height = 17       Caption = #1055#1086' '#1087#1077#1088#1077#1076#1085#1077#1084#1091' '#1092#1088#1086#1085#1090#1091       Checked = True       Font.Charset = DEFAULT_CHARSET       Font.Color = clWhite       Font.Height = -11       Font.Name = 'MS Sans Serif'       Font.Style = []       ParentFont = False       TabOrder = 0       TabStop = True     end     object RadioButton2: TRadioButton       Left = 8       Top = 48       Width = 129       Height = 17       Caption = #1055#1086' '#1079#1072#1076#1085#1077#1084#1091' '#1092#1088#1086#1085#1090#1091       Font.Charset = DEFAULT_CHARSET       Font.Color = clWhite       Font.Height = -11       Font.Name = 'MS Sans Serif'       Font.Style = []       ParentFont = False       TabOrder = 1     end     object RadioButton3: TRadioButton       Left = 8       Top = 72       Width = 113       Height = 17       Caption = #1055#1086' '#1096#1072#1073#1083#1086#1085#1091       Enabled = False       Font.Charset = DEFAULT_CHARSET       Font.Color = clWhite       Font.Height = -11       Font.Name = 'MS Sans Serif'       Font.Style = []       ParentFont = False       TabOrder = 2       Visible = False     end   end   object ComboBox1: TComboBox     Left = 200     Top = 336     Width = 185     Height = 21     ItemHeight = 13     TabOrder = 20     Text = #1042#1099#1073#1086#1088' '#1087#1091#1089#1082#1086#1074#1086#1075#1086' '#1082#1072#1085#1072#1083#1072     Items.Strings = (       #1050#1072#1085#1072#1083' 1'       #1050#1072#1085#1072#1083' 2'       #1050#1072#1085#1072#1083' 3'       #1050#1072#1085#1072#1083' 4'       #1050#1072#1085#1072#1083' 5'       #1050#1072#1085#1072#1083' 6'       #1050#1072#1085#1072#1083' 7'       #1050#1072#1085#1072#1083' 8'       #1053#1077#1090)   end   object ComboBox2: TComboBox     Left = 200     Top = 360     Width = 185     Height = 21     ItemHeight = 13     TabOrder = 21     Text = #1042#1099#1073#1086#1088' '#1090#1072#1082#1090#1086#1074#1086#1075#1086' '#1075#1077#1085#1077#1088#1072#1090#1086#1088#1072     OnChange = ComboBox2Change     Items.Strings = (       '(clk/6)  1 228 800 Hz'       '(clk/8)     921 600 Hz'       '(clk/16)   460 800 Hz'       '(clk/32)   230 400 Hz'       '(clk/64)   115 200 Hz'       '(clk/128)   57 600 Hz'       '(clk/256)   28 800 Hz'       #1055#1088#1086#1080#1079#1074#1086#1083#1100#1085#1099#1081)   end   object BitBtn1: TBitBtn     Left = 432     Top = 408     Width = 169     Height = 41     Caption = #1047#1072#1087#1091#1089#1082     Font.Charset = DEFAULT_CHARSET     Font.Color = clWindowText     Font.Height = -19     Font.Name = 'MS Sans Serif'     Font.Style = []     ParentFont = False     TabOrder = 22     OnClick = BitBtn1Click   end   object TrackBar1: TTrackBar     Left = 0     Top = 432     Width = 113     Height = 45     Max = 100     SelStart = 100     TabOrder = 23     OnChange = TrackBar1Change   end   object Edit1: TEdit     Left = 120     Top = 432     Width = 33     Height = 24     Font.Charset = DEFAULT_CHARSET     Font.Color = clWindowText     Font.Height = -13     Font.Name = 'Courier New'     Font.Style = []     ParentFont = False     ReadOnly = True     TabOrder = 24     Text = '0'   end   object MaskEdit1: TMaskEdit     Left = 200     Top = 384     Width = 119     Height = 22     EditMask = '!99999;1; '     Font.Charset = DEFAULT_CHARSET     Font.Color = clWindowText     Font.Height = -11     Font.Name = 'Courier New'     Font.Style = []     MaxLength = 5     ParentFont = False     TabOrder = 25     Text = '    0'   end   object MaskEdit2: TMaskEdit     Left = 200     Top = 432     Width = 47     Height = 24     EditMask = '!99999;1; '     Font.Charset = DEFAULT_CHARSET     Font.Color = clWindowText     Font.Height = -13     Font.Name = 'Courier New'     Font.Style = []     MaxLength = 5     ParentFont = False     TabOrder = 26     Text = '65535'     OnChange = MaskEdit2Change   end   object SerialPortNG1: TSerialPortNG     CommPort = 'COM1'     BaudRate = 19200     RTOCharDelayTime = 570     WTOCharDelayTime = 570     ErrorNoise = 255     OnRxClusterEvent = SerialPortNG1RxClusterEvent   end end 
unit Unit1;  interface  uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs, TeEngine, Series, ExtCtrls, TeeProcs, Chart, StdCtrls, ComCtrls,   Buttons, ComDrv32, SerialNG, Mask, Math;  type   TForm1 = class(TForm)     Chart1: TChart;     Series1: TLineSeries;     Series2: TLineSeries;     Series3: TLineSeries;     Series4: TLineSeries;     Series5: TLineSeries;     Series6: TLineSeries;     Series7: TLineSeries;     Series8: TLineSeries;     ColorBox1: TColorBox;     ColorBox2: TColorBox;     ColorBox3: TColorBox;     ColorBox4: TColorBox;     ColorBox5: TColorBox;     ColorBox6: TColorBox;     ColorBox7: TColorBox;     ColorBox8: TColorBox;     StaticText1: TStaticText;     StaticText2: TStaticText;     StaticText3: TStaticText;     StaticText4: TStaticText;     StaticText5: TStaticText;     StaticText6: TStaticText;     StaticText7: TStaticText;     StaticText8: TStaticText;     ScrollBar1: TScrollBar;     SpeedButton1: TSpeedButton;     SpeedButton2: TSpeedButton;     StaticText9: TStaticText;     GroupBox1: TGroupBox;     RadioButton1: TRadioButton;     RadioButton2: TRadioButton;     RadioButton3: TRadioButton;     ComboBox1: TComboBox;     ComboBox2: TComboBox;     BitBtn1: TBitBtn;     SerialPortNG1: TSerialPortNG;     TrackBar1: TTrackBar;     Edit1: TEdit;     Label1: TLabel;     Label2: TLabel;     MaskEdit1: TMaskEdit;     Label3: TLabel;     Label4: TLabel;     MaskEdit2: TMaskEdit;     Label5: TLabel;     procedure FormCreate(Sender: TObject);     procedure ScrollChange(Sender: TObject);     procedure BitBtn2Click(Sender: TObject);     procedure SpeedButton1Click(Sender: TObject);     procedure SpeedButton2Click(Sender: TObject);     procedure FormClose(Sender: TObject; var Action: TCloseAction);     procedure BitBtn1Click(Sender: TObject);     procedure SerialPortNG1RxClusterEvent(Sender: TObject);     procedure TrackBar1Change(Sender: TObject);     procedure ComboBox2Change(Sender: TObject);     procedure MaskEdit2Change(Sender: TObject);   private     { Private declarations }     scale:word;     dwError:dword;     pName:PWideChar;     flag:byte;     function StrToIntM(str:string):dword;   public     { Public declarations }   end;    TArrBuf512 = array[0..511] of byte;  var   Form1: TForm1;  implementation  uses SerialNGBasic;  {$R *.dfm}  procedure TForm1.FormCreate(Sender: TObject); var   i:word;   s:string; begin   SerialPortNG1.Active := True;    scale := 500;   ScrollBar1.Visible := False;   Chart1.BottomAxis.Minimum := 0;   Chart1.BottomAxis.Maximum := scale;    Series1.Clear;   Series2.Clear;   Series3.Clear;   Series4.Clear;   Series5.Clear;   Series6.Clear;   Series7.Clear;   Series8.Clear;    for i := 0 to 500 do   begin     Series1.AddXY(i, ((i mod 1)*0.5)+0.25, '', ColorBox1.Selected);     Series2.AddXY(i, ((i mod 2)*0.5)+1.25, '', ColorBox2.Selected);     Series3.AddXY(i, ((i mod 2)*0.5)+2.25, '', ColorBox3.Selected);     Series4.AddXY(i, ((i mod 2)*0.5)+3.25, '', ColorBox4.Selected);     Series5.AddXY(i, ((i mod 2)*0.5)+4.25, '', ColorBox5.Selected);     Series6.AddXY(i, ((i mod 2)*0.5)+5.25, '', ColorBox6.Selected);     Series7.AddXY(i, ((i mod 2)*0.5)+6.25, '', ColorBox7.Selected);     Series8.AddXY(i, ((i mod 2)*0.5)+7.25, '', ColorBox8.Selected);   end; end;  procedure TForm1.ScrollChange(Sender: TObject); begin   Chart1.BottomAxis.Minimum := ScrollBar1.Position;   Chart1.BottomAxis.Maximum := ScrollBar1.Position + scale; end;  procedure TForm1.BitBtn2Click(Sender: TObject); begin    Close; end;  procedure TForm1.SpeedButton1Click(Sender: TObject); begin    if (scale < 500) then       scale := scale + 10;    if (scale = 500) then       ScrollBar1.Visible := False    else       ScrollBar1.Visible := True;    ScrollBar1.Max := 500 - scale;    if (ScrollBar1.Position > (500 - scale)) then       ScrollBar1.Position := (500 - scale);    Chart1.BottomAxis.Minimum := ScrollBar1.Position;   Chart1.BottomAxis.Maximum := ScrollBar1.Position + scale; end;  procedure TForm1.SpeedButton2Click(Sender: TObject); begin    if (scale > 0) then       scale := scale - 10;    if (scale = 500) then       ScrollBar1.Visible := False    else       ScrollBar1.Visible := True;    ScrollBar1.Max := 500 - scale;    Chart1.BottomAxis.Minimum := ScrollBar1.Position;   Chart1.BottomAxis.Maximum := ScrollBar1.Position + scale; end;  procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin    SerialPortNG1.Active := False; end;  procedure TForm1.BitBtn1Click(Sender: TObject); var    s:string; begin    if (ComboBox2.ItemIndex <> -1) and (ComboBox1.ItemIndex <> -1) then    begin    s := '    ';    s[1] := char($FF);    s[2] := char($AA);    s[3] := char($3A);    s[4] := char((((ComboBox1.ItemIndex shl 1) or byte(RadioButton2.Checked))or (ComboBox2.ItemIndex shl 5)));    SerialPortNG1.SendString(s);    flag := 1;    end    else       MessageBox(0, '���������� ������� ����� ��������� ������ � ������� �������� ���������!', '������', MB_OK or MB_ICONINFORMATION); end;  procedure TForm1.SerialPortNG1RxClusterEvent(Sender: TObject); var    i:integer;    n:integer;    p:^TArrBuf512;    size:integer;    error:DWord; begin   n := SerialPortNG1.NextClusterSize;   if n >= 0 then     begin        p := SerialPortNG1.ReadNextCluster(size, error);        if (flag=1) then        begin        Series1.Clear;        Series2.Clear;        Series3.Clear;        Series4.Clear;        Series5.Clear;        Series6.Clear;        Series7.Clear;        Series8.Clear;        for i := 0 to n do        begin           Series8.AddXY(i, -(((p^[i] shr 7) and 1)*0.5)+7.75, '', ColorBox8.Selected);           Series7.AddXY(i, -(((p^[i] shr 6) and 1)*0.5)+6.75, '', ColorBox7.Selected);           Series6.AddXY(i, -(((p^[i] shr 5) and 1)*0.5)+5.75, '', ColorBox6.Selected);           Series5.AddXY(i, -(((p^[i] shr 4) and 1)*0.5)+4.75, '', ColorBox5.Selected);           Series4.AddXY(i, -(((p^[i] shr 3) and 1)*0.5)+3.75, '', ColorBox4.Selected);           Series3.AddXY(i, -(((p^[i] shr 2) and 1)*0.5)+2.75, '', ColorBox3.Selected);           Series2.AddXY(i, -(((p^[i] shr 1) and 1)*0.5)+1.75, '', ColorBox2.Selected);           Series1.AddXY(i, -(( p^[i] and 1)*0.5)+0.75, '', ColorBox1.Selected);        end;        flag := 0;        end;    end; end; procedure TForm1.TrackBar1Change(Sender: TObject); begin    Edit1.Text := IntToStr(TrackBar1.Position); end;  procedure TForm1.ComboBox2Change(Sender: TObject); begin    if ComboBox2.ItemIndex = 7 then    begin       MaskEdit1.Visible := true;       Label3.Visible := true;       MaskEdit1.Text := '';    end    else    begin       MaskEdit1.Visible := False;       Label3.Visible := false;    end; end;  procedure TForm1.MaskEdit2Change(Sender: TObject); begin    if MaskEdit2.Text <> '' then       if StrToIntM(MaskEdit2.Text) > 65535 then          MaskEdit2.Text := '65535'; end;  function TForm1.StrToIntM(str:string):dword; var    i,num:integer; begin    num := 0;    if (length(str) > 0) and (length(str) < 6) then    for i := length(str) downto 1 do       if ((str[i] >= '0')and(str[i] <= '9')) then       begin          num := num + (byte(str[i])-byte('0'))*Round(Power(10,length(str)-i));       end;    StrToIntM := num; end;  end.    
object Form2: TForm2   Left = 291   Top = 205   AutoScroll = False   BorderIcons = [biSystemMenu, biMinimize]   Caption = #1043#1077#1085#1077#1088#1072#1090#1086#1088' '#1073#1072#1081#1090#1110#1074   ClientHeight = 473   ClientWidth = 607   Color = clBlack   Font.Charset = DEFAULT_CHARSET   Font.Color = clWindowText   Font.Height = -11   Font.Name = 'MS Sans Serif'   Font.Style = []   OldCreateOrder = False   OnCreate = Form2Create   PixelsPerInch = 96   TextHeight = 13   object Label1: TLabel     Left = 104     Top = 24     Width = 112     Height = 18     Caption = #1056#1077#1076#1072#1082#1090#1080#1088#1086#1074#1072#1090#1100     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -16     Font.Name = 'Arial'     Font.Style = []     ParentFont = False   end   object Label2: TLabel     Left = 104     Top = 56     Width = 121     Height = 18     Caption = #1050#1086#1083#1080#1095#1077#1089#1090#1074#1086' '#1073#1072#1081#1090     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -16     Font.Name = 'Arial'     Font.Style = []     ParentFont = False   end   object Label3: TLabel     Left = 104     Top = 88     Width = 82     Height = 18     Caption = #1053#1072#1095#1072#1083#1100#1085#1099#1081     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -16     Font.Name = 'Arial'     Font.Style = []     ParentFont = False   end   object Label4: TLabel     Left = 104     Top = 120     Width = 71     Height = 18     Caption = #1050#1086#1085#1077#1095#1085#1099#1081     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -16     Font.Name = 'Arial'     Font.Style = []     ParentFont = False   end   object ListBox1: TListBox     Left = 8     Top = 8     Width = 65     Height = 433     ItemHeight = 13     TabOrder = 0     OnClick = ListBoxClick   end   object RadioGroup1: TRadioGroup     Left = 408     Top = 16     Width = 185     Height = 105     Caption = #1043#1077#1085#1077#1088#1072#1094#1080#1103' '#1073#1072#1081#1090#1086#1074     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -16     Font.Name = 'Arial'     Font.Style = []     ItemIndex = 0     Items.Strings = (       #1062#1080#1082#1083#1080#1095#1077#1089#1082#1072#1103       #1056#1072#1079#1086#1074#1072#1103       #1055#1086#1096#1072#1075#1086#1074#1072#1103)     ParentFont = False     TabOrder = 1   end   object BitBtn1: TBitBtn     Left = 408     Top = 136     Width = 185     Height = 41     Caption = #1055#1091#1089#1082'/'#1064#1072#1075     Font.Charset = DEFAULT_CHARSET     Font.Color = clWindowText     Font.Height = -16     Font.Name = 'Arial'     Font.Style = [fsBold]     ParentFont = False     TabOrder = 2     OnClick = BitBtn1Click   end   object BitBtn2: TBitBtn     Left = 408     Top = 192     Width = 185     Height = 41     Caption = #1057#1090#1086#1087     Enabled = False     Font.Charset = DEFAULT_CHARSET     Font.Color = clWindowText     Font.Height = -16     Font.Name = 'Arial'     Font.Style = [fsBold]     ParentFont = False     TabOrder = 3     OnClick = BitBtn2Click   end   object CheckBox1: TCheckBox     Left = 8     Top = 448     Width = 537     Height = 17     Caption = #1056#1072#1073#1086#1090#1072' '#1075#1077#1085#1077#1088#1072#1090#1086#1088#1072' '#1089#1083#1086#1074' '#1080' '#1083#1086#1075#1080#1095#1077#1089#1082#1086#1075#1086' '#1072#1085#1072#1083#1080#1079#1072#1090#1086#1088#1072' '#1074' '#1087#1072#1088#1077     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -16     Font.Name = 'MS Sans Serif'     Font.Style = [fsBold]     ParentFont = False     TabOrder = 4     OnClick = CheckBox1Click   end   object GroupBox1: TGroupBox     Left = 96     Top = 192     Width = 281     Height = 153     Caption = #1056#1077#1078#1080#1084' '#1091#1089#1090#1072#1085#1086#1074#1082#1080' '#1095#1072#1089#1090#1086#1090#1099     Font.Charset = DEFAULT_CHARSET     Font.Color = clWhite     Font.Height = -16     Font.Name = 'Arial'     Font.Style = []     ParentFont = False     TabOrder = 5     object Label5: TLabel       Left = 192       Top = 56       Width = 18       Height = 18       Caption = 'Hz'       Enabled = False     end     object Label6: TLabel       Left = 192       Top = 112       Width = 18       Height = 18       Caption = 'Hz'     end     object RadioButton1: TRadioButton       Left = 16       Top = 24       Width = 113       Height = 17       Caption = #1042#1099#1073#1086#1088#1086#1095#1085#1099#1081       TabOrder = 0       OnClick = RadioButton1Click     end     object RadioButton2: TRadioButton       Left = 16       Top = 80       Width = 137       Height = 17       Caption = #1055#1088#1086#1080#1079#1074#1086#1083#1100#1085#1099#1081       Checked = True       TabOrder = 1       TabStop = True       OnClick = RadioButton2Click     end     object ComboBox1: TComboBox       Left = 40       Top = 48       Width = 145       Height = 26       Enabled = False       ItemHeight = 18       TabOrder = 2       Text = #1042#1099#1073#1086#1088' '#1095#1072#1089#1090#1086#1090#1099     end     object MaskEdit5: TMaskEdit       Left = 40       Top = 104       Width = 144       Height = 26       EditMask = '!999999;1; '       MaxLength = 6       TabOrder = 3       Text = '      '     end   end   object MaskEdit1: TMaskEdit     Left = 232     Top = 24     Width = 33     Height = 21     EditMask = 'aa;1;0'     MaxLength = 2     TabOrder = 6     Text = '  '     OnChange = MaskEdit1Change     OnKeyPress = MaskEdit1KeyPress   end   object MaskEdit2: TMaskEdit     Left = 232     Top = 56     Width = 33     Height = 21     EditMask = 'aaaa;1; '     MaxLength = 4     TabOrder = 7     Text = '1024'     OnChange = MaskEdit2Change     OnKeyPress = MaskEdit2KeyPress   end   object MaskEdit3: TMaskEdit     Left = 232     Top = 88     Width = 33     Height = 21     EditMask = 'aaa;1;0'     MaxLength = 3     TabOrder = 8     Text = '   '     OnChange = MaskEdit3Change     OnKeyPress = MaskEdit3KeyPress   end   object MaskEdit4: TMaskEdit     Left = 232     Top = 120     Width = 33     Height = 21     EditMask = 'aaa;1;0'     MaxLength = 3     TabOrder = 9     Text = '   '     OnChange = MaskEdit4Change     OnKeyPress = MaskEdit4KeyPress   end end 
unit Unit2;  interface  uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs, StdCtrls, ExtCtrls, Buttons, Mask;  type   TForm2 = class(TForm)     ListBox1: TListBox;     RadioGroup1: TRadioGroup;     BitBtn1: TBitBtn;     BitBtn2: TBitBtn;     CheckBox1: TCheckBox;     Label1: TLabel;     GroupBox1: TGroupBox;     RadioButton1: TRadioButton;     RadioButton2: TRadioButton;     ComboBox1: TComboBox;     Label5: TLabel;     Label6: TLabel;     MaskEdit1: TMaskEdit;     Label2: TLabel;     MaskEdit2: TMaskEdit;     MaskEdit3: TMaskEdit;     Label3: TLabel;     Label4: TLabel;     MaskEdit4: TMaskEdit;     MaskEdit5: TMaskEdit;     procedure RadioButton1Click(Sender: TObject);     procedure RadioButton2Click(Sender: TObject);     procedure ListBoxClick(Sender: TObject);     procedure Form2Create(Sender: TObject);     procedure CheckBox1Click(Sender: TObject);     procedure MaskEdit1KeyPress(Sender: TObject; var Key: Char);     procedure MaskEdit1Change(Sender: TObject);     procedure MaskEdit2KeyPress(Sender: TObject; var Key: Char);     procedure MaskEdit2Change(Sender: TObject);     procedure MaskEdit3KeyPress(Sender: TObject; var Key: Char);     procedure MaskEdit4KeyPress(Sender: TObject; var Key: Char);     procedure MaskEdit4Change(Sender: TObject);     procedure MaskEdit3Change(Sender: TObject);     procedure BitBtn1Click(Sender: TObject);     procedure BitBtn2Click(Sender: TObject);   private     { Private declarations }     index:integer;     count:integer;     buf:array[0..1023]of byte;     function StrToHex(str:string):integer;   public     { Public declarations }   end;  var   Form2: TForm2;  implementation  uses Unit1;  {$R *.dfm}  procedure TForm2.RadioButton1Click(Sender: TObject); begin    MaskEdit5.Enabled := false;    Label6.Enabled := false;    ComboBox1.Enabled := true;    Label5.Enabled := true; end;  procedure TForm2.RadioButton2Click(Sender: TObject); begin    ComboBox1.Enabled := false;    Label5.Enabled := false;    MaskEdit5.Enabled := true;    Label6.Enabled := true; end; procedure TForm2.ListBoxClick(Sender: TObject); var    s:string; begin    s := ListBox1.Items.ValueFromIndex[ListBox1.ItemIndex];    index := ListBox1.ItemIndex;    MaskEdit1.Text := s[4]+s[5]; end;  procedure TForm2.Form2Create(Sender: TObject); var    i,j:integer;    s,s1:string; begin    count := 1024;    index := 0;    ListBox1.Clear;    for i := 0 to count-1 do    begin       s := Format('%x',[i]);       for j := 1 to 3-length(s) do          s1 := s1 + '0';       for j := 1 to length(s) do          s1 := s1 + s[j];       ListBox1.Items.Add(s1+':00');       s1 := '';       buf[i] := 0;    end; end;  procedure TForm2.CheckBox1Click(Sender: TObject); begin    if (CheckBox1.Checked = True) then       Form1.Visible := true; end;  procedure TForm2.MaskEdit1KeyPress(Sender: TObject; var Key: Char); begin    if not(((Key >= '0') and (Key <= '9')) or           ((Key >= 'A') and (Key <= 'F')) or           ((Key >= 'a') and (Key <= 'f'))) then       Key := ' ';    if (Key >= 'a') and (Key <= 'f') then       Key := UpCase(Key) end;  procedure TForm2.MaskEdit1Change(Sender: TObject); var    s,s1,s2:string;    i:byte; begin    s1 := '';    s := Format('%x',[index]);    for i := 1 to 3-length(s) do       s1 := s1 + '0';    for i := 1 to length(s) do       s1 := s1 + s[i];     s2 := s1 + ':';     s1 := '';    s := Format('%x',[StrToHex(MaskEdit1.Text)]);    for i := 1 to 2-length(s) do       s1 := s1 + '0';    for i := 1 to length(s) do       s1 := s1 + s[i];     buf[index] := StrToHex(MaskEdit1.Text);    s2 := s2 + s1;    ListBox1.Items.Strings[index] := s2; end;  procedure TForm2.MaskEdit2KeyPress(Sender: TObject; var Key: Char); var    i,j:integer;    s,s1:string; begin       if not((Key >= '0') and (Key <= '9') or (Key = #13)) then          Key := ' ';       if Key = #13 then       begin          ListBox1.Clear;          for i := 0 to count-1 do          begin             s := Format('%x',[i]);             for j := 1 to 3-length(s) do                s1 := s1 + '0';             for j := 1 to length(s) do                s1 := s1 + s[j];             ListBox1.Items.Add(s1+':00');             s1 := '';          end;       end; end;  procedure TForm2.MaskEdit2Change(Sender: TObject); var    i:integer;    s,s1:string; begin    s1 := '';    s := MaskEdit2.Text;    if s <> '' then       for i := 1 to length(s) do          if s[i] <> ' ' then s1 := s1 + s[i];    if s1 <> '' then    begin       if (StrToInt(s1) > 1024) then       begin          MaskEdit2.Text := '1024';          count := 1024;       end;       count := StrToInt(s1);    end; end;  function TForm2.StrToHex(str:string):integer; var    i,num:integer; begin    num := 0;    if (length(str) > 0) and (length(str) < 5) then    for i := length(str) downto 1 do    begin       if ((str[i] >= '0')and(str[i] <= '9')) then          num := num + (byte(str[i])-byte('0'))shl(4*(length(str)-i));       if ((str[i] >= 'A')and(str[i] <= 'F')) then          num := num + (byte(str[i])-byte('A')+10)shl(4*(length(str)-i));       if ((str[i] >= 'a')and(str[i] <= 'f')) then          num := num + (byte(str[i])-byte('a')+10)shl(4*(length(str)-i));    end;    StrToHex := num; end;  procedure TForm2.MaskEdit3KeyPress(Sender: TObject; var Key: Char); begin    if not(((Key >= '0') and (Key <= '9')) or           ((Key >= 'A') and (Key <= 'F')) or           ((Key >= 'a') and (Key <= 'f'))) then       Key := ' ';    if (Key >= 'a') and (Key <= 'f') then       Key := UpCase(Key); end;  procedure TForm2.MaskEdit4KeyPress(Sender: TObject; var Key: Char); begin    if not(((Key >= '0') and (Key <= '9')) or           ((Key >= 'A') and (Key <= 'F')) or           ((Key >= 'a') and (Key <= 'f'))) then       Key := ' ';    if (Key >= 'a') and (Key <= 'f') then       Key := UpCase(Key); end;  procedure TForm2.MaskEdit4Change(Sender: TObject); begin    if MaskEdit4.Text <> '' then    begin       if StrToHex(MaskEdit4.Text) > count-1 then          MaskEdit4.Text := Format('%3x', [count-1]);       if StrToHex(MaskEdit4.Text) < StrToHex(MaskEdit3.Text) then          MaskEdit4.Text := MaskEdit3.Text;    end; end;  procedure TForm2.MaskEdit3Change(Sender: TObject); begin    if MaskEdit3.Text <> '' then    begin       if StrToHex(MaskEdit3.Text) > count-1 then          MaskEdit3.Text := Format('%3x', [count-1]);       if StrToHex(MaskEdit4.Text) < StrToHex(MaskEdit3.Text) then          MaskEdit3.Text := MaskEdit4.Text;    end; end;  procedure TForm2.BitBtn1Click(Sender: TObject); var    i:integer;    //a:array[1..] begin    BitBtn1.Enabled := False;    BitBtn2.Enabled := True;    //Form1.SerialPortNG1.SendData();    Form1.SerialPortNG1.SendData(@buf[StrToHex(MaskEdit3.Text)],StrToHex(MaskEdit4.Text)-StrToHex(MaskEdit3.Text)); end;  procedure TForm2.BitBtn2Click(Sender: TObject); begin    BitBtn1.Enabled := True;    BitBtn2.Enabled := False; end;  end. 
object Form3: TForm3   Left = 239   Top = 164   AutoScroll = False   BorderIcons = [biSystemMenu, biMinimize]   Caption = 'Form3'   ClientHeight = 287   ClientWidth = 509   Color = clBtnFace   Font.Charset = DEFAULT_CHARSET   Font.Color = clWindowText   Font.Height = -11   Font.Name = 'MS Sans Serif'   Font.Style = []   OldCreateOrder = False   Visible = True   PixelsPerInch = 96   TextHeight = 13   object Label1: TLabel     Left = 24     Top = 16     Width = 474     Height = 29     Caption = #1042#1110#1088#1090#1091#1072#1083#1100#1085#1080#1081' '#1074#1080#1084#1110#1088#1102#1074#1072#1083#1100#1085#1080#1081' '#1082#1086#1084#1087#1083#1077#1082#1089     Font.Charset = DEFAULT_CHARSET     Font.Color = clWindowText     Font.Height = -24     Font.Name = 'Arial'     Font.Style = [fsBold]     ParentFont = False   end   object BitBtn1: TBitBtn     Left = 16     Top = 64     Width = 153     Height = 41     Caption = #1051#1086#1075#1110#1095#1085#1080#1081' '#1072#1085#1072#1083#1110#1079#1072#1090#1086#1088     TabOrder = 0     OnClick = BitBtn1Click   end   object BitBtn2: TBitBtn     Left = 16     Top = 120     Width = 153     Height = 41     Caption = #1043#1077#1085#1077#1088#1072#1090#1086#1088' '#1073#1072#1081#1090     TabOrder = 1     OnClick = BitBtn2Click   end   object BitBtn3: TBitBtn     Left = 16     Top = 176     Width = 153     Height = 41     Caption = 'BitBtn3'     Enabled = False     TabOrder = 2   end   object BitBtn4: TBitBtn     Left = 16     Top = 232     Width = 153     Height = 41     Caption = 'BitBtn4'     Enabled = False     TabOrder = 3   end end 
unit Unit3;  interface  uses   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,   Dialogs, StdCtrls, Buttons;  type   TForm3 = class(TForm)     BitBtn1: TBitBtn;     BitBtn2: TBitBtn;     BitBtn3: TBitBtn;     BitBtn4: TBitBtn;     Label1: TLabel;     procedure BitBtn1Click(Sender: TObject);     procedure BitBtn2Click(Sender: TObject);   private     { Private declarations }   public     { Public declarations }   end;  var   Form3: TForm3;  implementation  uses Unit1, Unit2;  {$R *.dfm}  procedure TForm3.BitBtn1Click(Sender: TObject); begin    Form1.Visible := True; end;  procedure TForm3.BitBtn2Click(Sender: TObject); begin    Form2.Visible := true; end;  end. 
<AVRStudio><MANAGEMENT><ProjectName>111</ProjectName><Created>24-Dec-2008 16:50:50</Created><LastEdit>09-Feb-2009 02:47:50</LastEdit><ICON>208</ICON><ProjectType>0</ProjectType><Created>24-Dec-2008 16:50:50</Created><Version>4</Version><Build>4, 13, 0, 557</Build><ProjectTypeName>Atmel AVR Assembler</ProjectTypeName></MANAGEMENT><CODE_CREATION><ObjectFile>111.obj</ObjectFile><EntryFile>D:\_DISK C\diplom\main.asm</EntryFile><SaveFolder>D:\_DISK C\diplom\</SaveFolder></CODE_CREATION><DEBUG_TARGET><CURRENT_TARGET>AVR Simulator</CURRENT_TARGET><CURRENT_PART>ATmega8515</CURRENT_PART><BREAKPOINTS></BREAKPOINTS><IO_EXPAND><HIDE>false</HIDE></IO_EXPAND><REGISTERNAMES><Register>R00</Register><Register>R01</Register><Register>R02</Register><Register>R03</Register><Register>R04</Register><Register>R05</Register><Register>R06</Register><Register>R07</Register><Register>R08</Register><Register>R09</Register><Register>R10</Register><Register>R11</Register><Register>R12</Register><Register>R13</Register><Register>R14</Register><Register>R15</Register><Register>R16</Register><Register>R17</Register><Register>R18</Register><Register>R19</Register><Register>R20</Register><Register>R21</Register><Register>R22</Register><Register>R23</Register><Register>R24</Register><Register>R25</Register><Register>R26</Register><Register>R27</Register><Register>R28</Register><Register>R29</Register><Register>R30</Register><Register>R31</Register></REGISTERNAMES><COM>Auto</COM><COMType>0</COMType><WATCHNUM>0</WATCHNUM><WATCHNAMES><Pane0></Pane0><Pane1></Pane1><Pane2></Pane2><Pane3></Pane3></WATCHNAMES><BreakOnTrcaeFull>0</BreakOnTrcaeFull></DEBUG_TARGET><Debugger><modules><module></module></modules><Triggers></Triggers></Debugger><AvrAssembler><Folder>D:\_DISK C\diplom\</Folder><RelPath>main.asm</RelPath><EntryFile>D:\_DISK C\diplom\main.asm</EntryFile><IncludePath>F:\Program Files\Atmel\AVR Tools\AvrAssembler\Appnotes</IncludePath><V2IncludePath></V2IncludePath><V2Parameters></V2Parameters><FileType>I</FileType><ObjectName>111</ObjectName><Wrap>0</Wrap><ErrorAsWarning>0</ErrorAsWarning><MapFile>1</MapFile><ListFile>0</ListFile><Version1>0</Version1><PreCompile></PreCompile><PostCompile></PostCompile><SourceFiles>,</SourceFiles></AvrAssembler><AVRSimulator><FuseExt>0</FuseExt><FuseHigh>246</FuseHigh><FuseLow>96</FuseLow><LockBits>237</LockBits><Frequency>7372800</Frequency><ExtSRAM>0</ExtSRAM><SimBoot>1</SimBoot><SimBootnew>1</SimBootnew></AVRSimulator><ProjectIncludeDirs><Dirs><Dir>F:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes</Dir></Dirs></ProjectIncludeDirs><ProjectFiles><Files><Name>\main.asm</Name><Name>F:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m8515def.inc</Name></Files></ProjectFiles><IOView><usergroups/></IOView><Files><File00000><FileId>00000</FileId><FileName>main.asm</FileName><Status>257</Status></File00000></Files><Events><Bookmarks></Bookmarks></Events><Trace><Filters></Filters></Trace></AVRStudio> 
:020000020000FC :1000000010C000000000000000000000000006C258 :100010000000EDC100000000000000000000000032 :10002000000002E00EBF0FE50DBF0FE001BD00ECC8 :1000300005BF789414D202E009BF00E003BF222775 :10004000442700E007BB0FEF08BBA895413009F03B :10005000CDC1442708E10AB9C0E0DCE77FEF052FF6 :10006000007E06950695069506950695003069F57D :10007000052F0071E9F4052F0E70069511E0003090 :1000800019F0110F0A95D9F7052F017049F4A895B9 :1000900066B36123E1F7A89566B36123E1F308C075 :1000A000A89566B36123E1F3A89566B36123E1F7F0 :1000B00006B309937A95E1F77A9506B309937A9591 :1000C000E1F77A9506B3099379C1013089F5052FD7 :1000D0000071E9F4052F0E70069511E0003019F05B :1000E000110F0A95D9F7052F017049F4A89566B349 :1000F0006123E1F7A89566B36123E1F308C0A895F1 :1001000066B36123E1F3A89566B36123E1F706B313 :100110000993000000007A95D1F77A9506B3099308 :10012000000000007A95D1F77A9506B3099346C18D :100130000230A9F5052F0071E9F4052F0E70069520 :1001400011E0003019F0110F0A95D9F7052F017051 :1001500049F4A89566B36123E1F7A89566B36123D6 :10016000E1F308C0A89566B36123E1F3A89566B3EF :100170006123E1F706B3099313E01A95F1F7000044 :100180007A95C1F77A9506B3099313E01A95F1F7BA :1001900000007A95C1F77A9506B309930FC1033031 :1001A000B9F5052F0071E9F4052F0E70069511E0E1 :1001B000003019F0110F0A95D9F7052F017049F495 :1001C000A89566B36123E1F7A89566B36123E1F3CF :1001D00008C0A89566B36123E1F3A89566B36123CF :1001E000E1F706B3099318E01A95F1F70000000053 :1001F0007A95B9F77A9506B3099318E01A95F1F74D :10020000000000007A95D1F77A9506B30993D6C01D :100210000430A9F5052F0071E9F4052F0E7006953D :1002200011E0003019F0110F0A95D9F7052F017070 :1002300049F4A89566B36123E1F7A89566B36123F5 :10024000E1F308C0A89566B36123E1F3A89566B30E :100250006123E1F706B3099313E11A95F1F7000062 :100260007A95C1F77A9506B3099313E11A95F1F7D8 :1002700000007A95C1F77A9506B309939FC00530BF :10028000B9F5052F0071E9F4052F0E70069511E000 :10029000003019F0110F0A95D9F7052F017049F4B4 :1002A000A89566B36123E1F7A89566B36123E1F3EE :1002B00008C0A89566B36123E1F3A89566B36123EE :1002C000E1F706B3099318E21A95F1F70000000070 :1002D0007A95B9F77A9506B3099318E21A95F1F76A :1002E000000000007A95B9F77A9506B3099366C0C5 :1002F0000630A9F5052F0071E9F4052F0E7006955B :1003000011E0003019F0110F0A95D9F7052F01708F :1003100049F4A89566B36123E1F7A89566B3612314 :10032000E1F308C0A89566B36123E1F3A89566B32D :100330006123E1F706B3099313E51A95F1F700007D :100340007A95C1F77A9506B3099313E51A95F1F7F3 :1003500000007A95C1F77A9506B309932FC007304C :1003600009F042C0052F0071E9F4052F0E700695C3 :1003700011E0003019F0110F0A95D9F7052F01701F :1003800049F4A89566B36123E1F7A89566B36123A4 :10039000E1F308C0A89566B36123E1F3A89566B3BD :1003A0006123E1F706B309937A95E1F77A9506B3ED :1003B00009937A95E1F77A9506B30993C0E0DCE7F3 :1003C0000991A8955D9BFDCF0CB97A95C9F77A95EF :1003D0000991A8955D9BFDCF0CB97A95C9F7099154 :1003E000A8955D9BFDCF0CB908E90AB92ECE0F93F5 :1003F0000FB70F930CB1213059F00A3A59F405E0C8 :1004000003BF002702BF21E0C0E0DCE733270AEA90 :10041000099333950F910FBF0F9118950F931F9369 :100420000FB70F9300E003BFC0E0DCE7333089F47F :1004300009910A3A71F409910A3359F40991502F3C :1004400041E0C0E0DCE70027099309930993099391 :10045000099322270F910FBF1F910F91189508E95B :100460000AB906E000BD00E017E100BD19B901E0DE :10047000009300C00895F894A8955D9BFDCF0CB93A :0404800078940895CF :00000001FF 
cls @F:\avr\avreal\avreal32 +MEGA8515 -p1  -w -v -o1000  -fBODEN=1,BLEV=1,CKSEL=0,BRST=1,CKOPT=0,SUT=1,EESV=1,BLB0=1,BLB1=1,S8515C=0 @pause  
#include <m8515def.inc>  .def	tmp		    = r16		 .def	tmp1	    = r17 .def	RX_flag	    = r18 .def	RX_Counter  = r19 .def	RX_Complete = r20 .def	command		= r21 .def	tmp2		= r22 .def	tmp3		= r23  .equ	UC_REG = 0xC000  .equ	RX_Buffer = 0x7C00  .macro  USART_TRANSMITT_M utm_l0: 		wdr 		sbis	UCSRA, UDRE 		rjmp	utm_l0  		out		UDR, tmp .endm  .macro  WAIT_PUSK 		mov		tmp, command 		andi	tmp, 0b00010000 		brne	wp_l5  		mov		tmp, command 		andi	tmp, 0b00001110 		lsr		tmp  		ldi		tmp1, 1 wp_l0: 		cpi		tmp, 0 		breq	wp_l1 		lsl		tmp1 		dec		tmp 		brne	wp_l0  wp_l1: 		mov		tmp, command 		andi	tmp, 0b00000001 		brne	wp_l2  wp_l3: 		wdr 		in		tmp2, PINB 		and		tmp2, tmp1 		brne	wp_l3 wp_l4: 		wdr 		in		tmp2, PINB 		and		tmp2, tmp1 		breq	wp_l4  		rjmp	wp_l5 wp_l2: 		wdr 		in		tmp2, PINB 		and		tmp2, tmp1 		breq	wp_l2 wp_l6: 		wdr 		in		tmp2, PINB 		and		tmp2, tmp1 		brne	wp_l6 wp_l5:		 .endm  .macro ANALYZE_CLK_6 ac6_l0: 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp      // 2 cycle                               		dec		tmp3	     // 1 cycle 		brne	ac6_l0       // 2 cycles or  							 // 1 cycle 		dec		tmp3		 // 1 cycle ac6_l1: 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp		 // 2 cycle  		dec		tmp3		 // 1 cycle 		brne	ac6_l1       // 2 cycles  		dec		tmp3 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp		 // 2 cycle .endm  .macro ANALYZE_CLK_8 ac8_l0: 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp      // 2 cycle                  nop 				 // +2 cyle 		nop 		                      		dec		tmp3	     // 1 cycle 		brne	ac8_l0       // 2 cycles or  							 // 1 cycle 		dec		tmp3		 // 1 cycle ac8_l1: 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp		 // 2 cycle          nop 				 // +2 cyle 		nop  		dec		tmp3		 // 1 cycle 		brne	ac8_l1       // 2 cycles  		dec		tmp3 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp		 // 2 cycle .endm  .macro ANALYZE_CLK_16 ac16_l0: 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp      // 2 cycle  	    ldi		tmp1, 3      // +10 cyle ac16_l2: 	 	dec		tmp1 		brne	ac16_l2 		nop                               		dec		tmp3	     // 1 cycle 		brne	ac16_l0      // 2 cycles or  							 // 1 cycle 		dec		tmp3		 // 1 cycle ac16_l1: 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp		 // 2 cycle   	    ldi		tmp1, 3      // +10 cyle ac16_l3: 	 	dec		tmp1 		brne	ac16_l3 		nop  		dec		tmp3		 // 1 cycle 		brne	ac16_l1      // 2 cycles  		dec		tmp3 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp		 // 2 cycle .endm  .macro ANALYZE_CLK_32 ac32_l0: 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp      // 2 cycle  	    ldi		tmp1, 8      // +26 cyle ac32_l2: 	 	dec		tmp1 		brne	ac32_l2 		nop         nop 		                      		dec		tmp3	     // 1 cycle 		brne	ac32_l0      // 2 cycles or  							 // 1 cycle 		dec		tmp3		 // 1 cycle ac32_l1: 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp		 // 2 cycle  	    ldi		tmp1, 8      // +26 cyle ac32_l3: 	 	dec		tmp1 		brne	ac32_l3 		nop 		nop  		dec		tmp3		 // 1 cycle 		brne	ac32_l3      // 2 cycles  		dec		tmp3 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp		 // 2 cycle .endm  .macro ANALYZE_CLK_64 ac64_l0: 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp      // 2 cycle  	    ldi		tmp1, 19     // +58 cyle ac64_l2: 	 	dec		tmp1 		brne	ac64_l2 		nop                               		dec		tmp3	     // 1 cycle 		brne	ac64_l0      // 2 cycles or  							 // 1 cycle 		dec		tmp3		 // 1 cycle ac64_l1: 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp		 // 2 cycle  	    ldi		tmp1, 19     // +58 cyle ac64_l3: 	 	dec		tmp1 		brne	ac64_l3 		nop  		dec		tmp3		 // 1 cycle 		brne	ac64_l1      // 2 cycles  		dec		tmp3 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp		 // 2 cycle .endm  .macro ANALYZE_CLK_128 ac128_l0: 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp      // 2 cycle                               	    ldi		tmp1, 40     // +122 cyle ac128_l2: 	 	dec		tmp1 		brne	ac128_l2 		nop 		nop  		dec		tmp3	     // 1 cycle 		brne	ac128_l0     // 2 cycles or  							 // 1 cycle 		dec		tmp3		 // 1 cycle ac128_l1: 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp		 // 2 cycle  	    ldi		tmp1, 40     // +122 cyle ac128_l3: 	 	dec		tmp1 		brne	ac128_l3 		nop 		nop  		dec		tmp3		 // 1 cycle 		brne	ac128_l1     // 2 cycles  		dec		tmp3 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp		 // 2 cycle .endm  .macro ANALYZE_CLK_256 ac256_l0: 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp      // 2 cycle                               	    ldi		tmp1, 83     // +250 cyle ac256_l2: 	 	dec		tmp1 		brne	ac256_l2 		nop  		dec		tmp3	     // 1 cycle 		brne	ac256_l0     // 2 cycles or  							 // 1 cycle 		dec		tmp3		 // 1 cycle ac256_l1: 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp		 // 2 cycle  	    ldi		tmp1, 83     // +250 cyle ac256_l3: 	 	dec		tmp1 		brne	ac256_l3 		nop  		dec		tmp3		 // 1 cycle 		brne	ac256_l1     // 2 cycles  		dec		tmp3 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp		 // 2 cycle .endm  .macro ANALYZE_CLK_VN acv_l0: 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp      // 2 cycle                               		dec		tmp3	     // 1 cycle 		brne	acv_l0       // 2 cycles or  							 // 1 cycle 		dec		tmp3		 // 1 cycle acv_l1: 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp		 // 2 cycle  		dec		tmp3		 // 1 cycle 		brne	acv_l1       // 2 cycles  		dec		tmp3 		in		tmp, PINB    // 1 cycle 		st		Y+, tmp		 // 2 cycle .endm  .org 0 		rjmp	RESET 		nop;rjmp	INT0 		nop;rjmp	INT1 		nop;rjmp	TIMER1_CAPT 		nop;rjmp	TIMER1_COMPA 		nop;rjmp	TIMER1_COMPB 		nop;rjmp	TIMER1_OVF 		rjmp	TIMER0_OVF 		nop;rjmp	SPI_STC 		rjmp	USART_RXC 		nop;rjmp	USART_UDRE 		nop;rjmp	USART_TXC 		nop;rjmp	ANA_COMP 		nop;rjmp	INT2 		nop;rjmp	TIMER0_COMP 		nop;rjmp	EE_RDY 		nop;rjmp	SPM_RDY  RESET: ; set stack pointer to top of RAM 		ldi		tmp, high(RAMEND) 		out		SPH, tmp 		ldi		tmp, low(RAMEND) 		out		SPL, tmp  ; enable WDT with 2,1s timeout 		ldi		tmp, (1<<WDE)|(7<<WDP0) 		out		WDTCR, tmp  ; enable external SRAM 		ldi		tmp, (1<<SRE)|(1<<SRW10) 		out		MCUCR, tmp  ; enable interrupts 		sei  ; USART init 		rcall	USART_Init  // Unmask timer 0 overflov interrupt 		ldi		tmp, (1<<TOIE0) 		out		TIMSK, tmp  // Stop timer0 		ldi		tmp, 0b00000000 		out		TCCR0, tmp  		clr		RX_Flag 		clr		RX_Complete 		 		ldi		tmp, 0 		out		DDRB, tmp 		ldi		tmp, 0b11111111 		out		PORTB, tmp  loop: 		wdr 		cpi		RX_Complete, 1 		breq	c_l0 		rjmp	l0 c_l0: // reset RX_Complete 		clr		RX_Complete  // mask RXCIE 		ldi		tmp, (1<<TXEN) | (1<<RXEN)  		out		UCSRB, tmp  // reset RX_Buffer 		ldi		YL, low(RX_Buffer) 		ldi		YH, high(RX_Buffer)  		ldi		tmp3, 0xFF  // do command 		mov		tmp, command 		andi	tmp, 0b11100000 		lsr		tmp 		lsr		tmp 		lsr		tmp 		lsr		tmp 		lsr		tmp  		cpi		tmp, 0 		brne	dc_l0 		   WAIT_PUSK 		   ANALYZE_CLK_6 		   rjmp 	dc_end dc_l0: 		cpi		tmp, 1 		brne	dc_l1 		   WAIT_PUSK 		   ANALYZE_CLK_8 		   rjmp 	dc_end dc_l1: 		cpi		tmp, 2 		brne	dc_l2 		   WAIT_PUSK 		   ANALYZE_CLK_16 		   rjmp 	dc_end dc_l2: 		cpi		tmp, 3 		brne	dc_l3 		   WAIT_PUSK 		   ANALYZE_CLK_32 		   rjmp 	dc_end dc_l3: 		cpi		tmp, 4 		brne	dc_l4 		   WAIT_PUSK 		   ANALYZE_CLK_64 		   rjmp 	dc_end dc_l4: 		cpi		tmp, 5 		brne	dc_l5 		   WAIT_PUSK 		   ANALYZE_CLK_128 		   rjmp 	dc_end dc_l5: 		cpi		tmp, 6 		brne	dc_l6 		   WAIT_PUSK 		   ANALYZE_CLK_256 		   rjmp 	dc_end dc_l6: 		cpi		tmp, 7 		breq	cdc_unk 		rjmp	dc_unk cdc_unk: 		   WAIT_PUSK 		   ANALYZE_CLK_VN dc_end: /* // wait if need befor pusk 		WAIT_PUSK  // analyse and store (6 cycles) // clock time (1/7372800Mhz)*6 = 813,8ns 		ANALYZE_CLK_6 */ // reset RX_Buffer 		ldi		YL, low(RX_Buffer) 		ldi		YH, high(RX_Buffer)  // transmitt data  l1: 		ld		tmp, Y+ 		USART_TRANSMITT_M 		dec		tmp3 		brne	l1 		dec		tmp3 l2: 		ld		tmp, Y+ 		USART_TRANSMITT_M 		dec		tmp3 		brne	l2 		ld		tmp, Y+ 		USART_TRANSMITT_M  dc_unk: // unmask RXCIE 		ldi		tmp, (1<<TXEN) | (1<<RXEN) | (1<<RXCIE)  		out		UCSRB, tmp  l0: 		rjmp	loop  ///////////////////////////////////////////////////// // USART receive complete ISR USART_RXC: 		push	tmp 		in		tmp, SREG 		push 	tmp  // tmp <- RX 		in		tmp, UDR  // if (RX_Flag == 1) goto urxc_l0 		cpi		RX_Flag, 1 		breq	urxc_l0  // if (RX == AA)  		cpi		tmp, 0xAA 		brne	urxc_end	  // init timeout 		ldi		tmp, 0b00000101 		out		TCCR0, tmp 		clr		tmp 		out		TCNT0, tmp  // set recive_flag 		ldi		RX_Flag, 1  // reset RX_Buffer 		ldi		YL, low(RX_Buffer) 		ldi		YH, high(RX_Buffer) 		clr		RX_Counter  		ldi		tmp, 0xAA urxc_l0: // push RX to buffer 		st		Y+, tmp 		inc		RX_Counter  urxc_end: 		pop		tmp 		out		SREG, tmp 		pop		tmp 		reti  ///////////////////////////////////////////////////// // Timer0 overflow ISR TIMER0_OVF: 		push	tmp 		push	tmp1 		in		tmp, SREG 		push 	tmp  // Stop timer0 		ldi		tmp, 0b00000000 		out		TCCR0, tmp  // reset RX_Buffer 		ldi		YL, low(RX_Buffer) 		ldi		YH, high(RX_Buffer) 		 		cpi 	RX_Counter, 3 		brne	t0ovf_l0 		 		ld		tmp, Y+ 		cpi		tmp, 0xAA 		brne	t0ovf_l0  		ld		tmp, Y+ 		cpi		tmp, 0x3A 		brne	t0ovf_l0  		ld		tmp, Y+ 		mov		command, tmp  		ldi		RX_Complete, 1  //clear buffer 		ldi		YL, low(RX_Buffer) 		ldi		YH, high(RX_Buffer) 		clr		tmp 		st		Y+, tmp 		st		Y+, tmp 		st		Y+, tmp 		st		Y+, tmp 		st		Y+, tmp 						 t0ovf_l0: // clear recive_flag 		clr		RX_Flag  		pop		tmp    		out		SREG, tmp 		pop		tmp1 		pop		tmp 		reti  ///////////////////////////////////////////////////// // USART init routine // uses: tmp, tmp1 USART_Init: 		ldi		tmp, (1<<TXEN) | (1<<RXEN) | (1<<RXCIE)  		out		UCSRB, tmp 		ldi		tmp, (1<<UCSZ0) | (1<<UCSZ1) 		out		UCSRC, tmp 		ldi		tmp, 0 		ldi		tmp1, 23 		out		UBRRH, tmp 		out		UBRRL, tmp1		  		ldi		tmp, 0b00000001 		sts		UC_REG, tmp 		ret  ///////////////////////////////////////////////////// // USART transmit routine // uses: tmp USART_Transmit: 		cli ut_l0: 		wdr 		sbis	UCSRA, UDRE 		rjmp	ut_l0  		out		UDR, tmp  		sei 		ret 
program Project1;  uses   Forms,   Unit1 in 'Unit1.pas' {Form1},   Unit2 in 'Unit2.pas' {Form2},   Unit3 in 'Unit3.pas' {Form3};  {$R *.res}  begin   Application.Initialize;   Application.CreateForm(TForm3, Form3);   Application.CreateForm(TForm1, Form1);   Application.CreateForm(TForm2, Form2);   Application.Run; end. 
#### ###��##��##################�### ###��##��##################(### ###@#####################################�##�###��#�###�#�#��##���#���###�##�###��#�###�#�#��##���##1###############�33331##########��3333##########33333###########������###########33331##DD#######����##FvvD######���1#Gggfv@#####���1#&vvggd######��1#wwgbvt######��1wwwr"gf@#####��1wwwr"vv@#####��3#wr""gf@#####��3#wr""&f@#####���#ww"w""@######��1�wr'""@######��1��w""$#######��1rwr"�########��3#'w"/�#######��3#"ww$�########��##""##�#######��1#####�#######��1#####��######��3####���p######�31###��##�3333;�31###��##�33333��3###���#��333���3####��#���������####������������####������������#####�###############�#�#���#���#���#���#���#���##�� #�##?�##?�###�###�###�###�###�###�##?�##?�##?�###����������#��~#��>###?###?###?�##?�##?�##?����####0###��##M#A#I#N#I#C#O#N###########################  ######�#####


МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ

НАЦІОНАЛЬНИЙ ТЕХНІЧНИЙ УНІВЕРСИТЕТ

ХАРКІВСЬКИЙ ПОЛІТЕХНІЧНИЙ ІНСТИТУТ”

Факультет xxxx Кафедра Обчислювальна техніка та програмування__

Спеціальність Системне програмування xxxx___________

До захисту допускаю

Завідувач кафедри

________________проф._xxxxxxxx

(ініціали та прізвище)

_________________________________

(підпис, дата)

ДИПЛОМНИЙ ПРОЕКТ

Освітньо-каліфікаційного рівня спеціаліст__

Тема проекту: Віртуальний вимірювальний комплекс на базі учбового______ лабораторного стенду EV8031________________________________________

затверджена наказом по НТУ «ХПІ» від 21 листопада 2008 р. № xxxxx

Харків 2009

Найменування виробу,

об'єкту або теми

Найменування

документу

Фор-

мат

Кільк.

арк.

При-мітка







Документи загальні










Завдання

А4

2



Звіт

А4

91


















Програмні документи




Документи дипломного проекту

Технічне завдання

А4

8



Специфікація

А4

2



Текст програми

А4

48



Опис програми

А4

8



Керівництво оператора

А4

7








Плакати




Тема проекту


А1

1


Структурна схема стенду, та розподілення його ресурсів


А1

1


Результати роботи


А1

1


Протокол обміну з COM портом


А1

1


Формули для розрахунків


А1

1


Схема алгоритму


А4

8











XXXXX-23А 03077.13 ВД







Прізвище

Підп

Дата


Розроб.

Xxxxx



Віртуальний висірювальний комплекс на базі учбового лабораторного стенду EV8031


Відомість документів

Літ.

Аркуш

Аркушів

Перев.

Xxxxx




ДПС

1

1






НТУ «ХПІ»

Кафедра ОТП

Н. конт.

Xxxxx





Затв.

Домнін





НАЦІОНАЛЬНИЙ ТЕХНІЧНИЙ УНІВЕРСИТЕТ “ХПІ”

Факультет XX Кафедра Обчислювальна техніка та програмування_____________

Спеціальність Системне програмування xxx_

ЗАТВЕРДЖУЮ

Завідувач кафедри

_____________________________

(підпис, ініціали та прізвище)

ЗАВДАННЯ

на виконання дипломного проекту

освітньо-кваліфікаційного рівня спеціаліст__

Студенту ______________________________________________

1. Тема проекту Віртуальний вимірювальний комплекс на базі учбового лабораторного стенду EV8031__________________

2. Зміст завдання Розробка програмного забеспечення віртуального вимірювального комплексу, який містить логічний аналізатор та генератор слів. Інтерфейс користувача повинен надавати можливість налагодження швидкості, ввод та відображення данних, керування режимами пуску, остановом, запуском по каналу, режимами циклічної генерації, маштабуванням проаналізованої послідовності, наявність та керування глибиною передпускової реєстрації.

3. Вихідні дані для виконання проекту Апаратна частина – учбовий лабораторний стенд EV8031 з мікроконтролером AVR ATMega8515, зв’язок між ПК і апаратурою реалізувати за допомогою послідовного порту RS-232. Програмна частина повинна мати інтерфейс користувача, як у аналогічних віртуальних пристроїв програми Electronic Workbench. Мова програмування для ПК Delphi.

4. Скласти звіт і виконати необхідні документи (програмні, плакати) відповідно до плану виконання дипломної роботи

Програмні документи (текст програми, керівництво оператора, опис програми, пояснювальна записка)___

План виконання дипломного проекту

Етап

Найменування

Термін

виконання

Прізвище консультанта

1

Аналіз поставленої задачі.

05.09.2008

Xxxxx М.В.

2

Розробка архітектури системи.

10.09.2008

Xxxxx М.В.

3

Розробка структур та данних.

05.10.2008

Xxxxx М.В.

4

Ознайомлення з питаннями охорони праці

15.10.2008

Фомін А.Й.

5

Розробка бізнес-плану

11.11.2008

Погорєлов С.М.

6

Створення коду ПЗ

07.01.2009

Xxxxx М.В.

7

Тестування і налагодження системи

10.01.2009

Xxxxx М.В.

8

Оформлення пояснювальної записки

01.02.2009

Xxxxx М.В.

9

Підготовка плакатів та доповіді

07.02.2009

Xxxxx М.В.





Керівник ДП _______________________________М.В. Xxxxx___

(підпис і дата) (ініціали та прізвище)

Студент-дипломник _____________________________________

(підпис і дата) (ініціали та прізвище)

ВІРТУАЛЬНИЙ ВИМІРЮВАЛЬНИЙ КОМПЛЕКС НА БАЗІ УЧБОВОГО ЛАБОРАТОРНОГО СТЕНДУ EV8031

Специфікація

xxxxxxx03077-01

Аркушів _2_

Харків 2009

Позначення

Найменування

Примітка


Документація по комплексах


Xxxxx.03077-13 12 01-1

Текст програми


Xxxxx.03077-13 12 01-1-ЛЗ

Текст програми


Xxxxx.03077-13 34 01-1

Керівництво оператора


Xxxxx.03077-13 34 01-1-ЛЗ

Керівництво оператора


Xxxxx.03077-13 13 01-1

Опис програми


Xxxxx.03077-13 13 01-1-ЛЗ

Опис програми


ЗМІСТ

ЗМІСТ

ВСТУП

1 ПІДСТАВА ДЛЯ РОЗРОБКИ

2 ПРИЗНАЧЕННЯ РОЗРОБКИ

3 ВИМОГИ ДО ПРОГРАМНОГО ВИРОБУ

3.1 Вимоги до функціональних характеристик

3.2 Вимоги до надійності

3.3 Умови експлуатації

3.4 Вимоги до складу і параметрів технічних засобів

3.5 Вимоги до інформаційної та програмної сумістності

3.6 Вимоги до маркування й упакування

3.7 Вимоги до транспортування і зберігання

4 ВИМОГИ ДО ПРОГРАМНОЇ ДОКУМЕНТАЦІЇ

5 ТЕХНІКО-ЕКОНОМІЧНІ ПОКАЗНИКИ

6 СТАДІЇ ТА ЕТАПИ РОЗРОБКИ

7 ПОРЯДОК КОНТРОЛЮ І ПРИЙМАННЯ

ВСТУП

Данний програмний продукт є комплексом засобів, які дозволяють виконувати тестування цифрових пристроїв, за допомогою аналізу отриманої з них послідовності у відгук на подані тестові послідовності, за допомогою логічного аналізатора та генератора слів, відповідно.

Система, що розробляється, повинна мати зручний інтерфейс користувача, а зв’язок, зі стендом, повинен виконуватись за допомогою послідовного порту. Також, продукт повинен виглядати у вигляді готових модулів, для зручного запуску, або, у випадку ПЗ мікроконтролера, зручного завантаження стандартними засобами.

1 ПІДСТАВА ДЛЯ РОЗРОБКИ

Підставою для розробки є “завдання на виконання дипломного проекту”, видане викладачем кафедри “Обчислювальної техніки та програмування” xxxxxxxxxxxxxx 1xxx і затверджене кафедрою “Обчислювальна техніка та програмування”/протокол № 2/від 7.10.2008, а також наказом № xxxxxx по Національному технічному університету “Харківський політехнічний інститут” від 25.10.2008.

Найменування теми дипломного проекту:”Віртуальний вимірювальний комплекс на базі учбового лабораторного стенду EV8031”.

2 ПРИЗНАЧЕННЯ РОЗРОБКИ

Данний порограмний продукт призначений для налагодження різноманітних цифрових пристроїв, і має для цього декілька віртуальних пристоїв: логічний аналізатор та генератор слів. Подача тестової послідовності забеспечується генератором слів, а аналіз реакції пристрою – за допомогою логічного аналізатора.

Такий віртуальний комплекс дозволяє швидко і зручно налагодити необхідний цифровий пристрій, завдяки зручному інтерфейсу користувача, такому як у пакеті Electronic Workbench.

3 ВИМОГИ ДО ПРОГРАМНОГО ВИРОБУ

3.1 Вимоги до функціональних характеристик

Програмний продукт повинен забеспечувати наступні функціональні можливості:

Для ЛА:

- відображення сигналу на моніторі ПК у вигляді діаграм;

- дозволяти керування логічним аналізатором з ПК (через СОМ порт);

- можливість змінення масштабів по вісі часу ;

- зсув сигналу за часом;

  • зміна кольору сигналу;

  • можливість встановлення частоти реєстрації;

  • можливість встановлення передпускової реєстрації;

  • можливість встановлення типу сигналу запуску;

  • можливість встановлення каналу запуску;

Для ГC:

  • встановлення послідовності слів, які необхідно генерувати;

  • можливість встановлення частоти генерації;

  • можливість встановлення типу генерації: циклічний, одноразовий, пошаговий;

  • можливість керування запуском та зупенненям;

  • можливість перемикання ГС та ЛА у парний режим роботи.

3.2 Вимоги до надійності

Програмний вироб повинен забеспечувати виключення тупікових ситуацій в роботі. При обриві лінії звязку послідовного інтерфейсу програма повинна видати повідомлення про відсутність звязку з пристроєм.

3.3 Умови експлуатації

Програмний продукт “Віртуальний вимірювальний комплекс” повинен безперебійно функціонувати в нормальних умовах експлуатації:

  • температура навколишнього середовища від 5 до 35°С;

  • вібрації, зовнішні магнітні, радіаційні і електричні поля не повинні перевищувати норми.

Для нормальної експлуатації системи необхідні початкові знання по експлуатації ПЕОМ.

Вимоги до рівня кваліфікації користувача – мінімальні знання спілкування з Windows-вікнами ПЕОМ.

3.4 Вимоги до складу і параметрів технічних засобів

Для функціонування програмного виробу необхідний ПЕОМ IBM PC AT/ATX з центральним процессором не нижче Pentium !!! або його аналогом, наявність послідовного COM порту.

3.5 Вимоги до інформаційної та програмної сумістності

При написанні програми повинні бути використані можливості які надає операційна система Windows. Програма повинна корректно працювати під керуванням Windows2000/XP.

Для написання модулів віртуального вимірювального комплексу повинна бути використана мова програмування Delphi 7.

3.6 Вимоги до маркування й упакування

На початку кожного файлу вихідних текстів програми записувати наступну інформацію:

  • імя данного файлу: __________________.____.;

  • функціональне призначення: ______(у проекті)________;

  • файл створений для дипломного проекта захисту кваліфікації фахівця

  • зафахом : Системне програмування

  • тема проекту : Віртуальний вимірювальний комплекс на базі учбового лабораторного стенду EV8031;

  • керівник : М.І. Скородєлов, викладач кафедри ОТП;

  • розробник : О.О. Ісмаілов, студент групи КІТ23а;

  • рік розробки : 2008.

На захисті надати файли програми (проекту) в розпакованому вигляді і упаковані zip або rar архіватором.

3.7 Вимоги до транспортування і зберігання

Транспортування результатів проектування може здійснюватися за допомогою будь-яких доступних носіїв: CD-R, CD-RW, Flash-RAM, HDD.

Берегти на накопичувачах сумістно: файли початкових текстів розробки, виконуваний файл, допоміжні файли і файли документів проекту.

4 ВИМОГИ ДО ПРОГРАМНОЇ ДОКУМЕНТАЦІЇ

Програмна документація програмного продукту “Віртуальний вимірювальний комплекс на базі учбового лабораторного стенду” повинна мітстити наступні документи:

  1. Специфікація;

  2. Текст програми(мікроконтроллера, і ПК);

  3. Опис програми;

  4. Керівництво оператора.

Додаткові вимоги до програмної.

Розробити Звіт про виконання дипломного проекту. У документі Звіт виклад основних розділів дипломного проекту повинен займали не менше 60 сторінок(без урахування розділів по економіці, охорони праці та додатків).

5 ТЕХНІКО-ЕКОНОМІЧНІ ПОКАЗНИКИ

Техніко-економічні показники повинні бути визначені в процессі розробки і зазначені у відповідному розділі звіту про виконання дипломного проекту.

6 СТАДІЇ ТА ЕТАПИ РОЗРОБКИ

Розробка програмного продукту відповідає стадії робочого проекту. Етапи розробки виконують в наступному порядку:

  • отримання завдання;

  • збір початкових матеріалів;

  • огляд літератури й обгрунтування необхідності розробки;

  • визначення областей застосування;

  • розробка технічного завдання;

  • техніко-економічне обгрунтування розробки;

  • розробка алгоритму розвязання задачі;

  • розробка структури програмного продукту;

  • визначення конфігурації програмних засобів;

  • розробка пояснювальної записки(розділу або розділів Звіту);

  • програмування і налагодження програмного продукту;

  • розробка програмних документів;

  • тестування програмного продукту;

  • коректування програми та програмних документів за результатами тестування.

7 ПОРЯДОК КОНТРОЛЮ І ПРИЙМАННЯ

При прийманні дипломної роботи перевіряється:

  1. Комплектність, зміст та оформлення документації згідно розділу 4 цього документу.

  2. Відповідність програмного продукту згідно вимогам до програмного продукту розділу 3 цього документу.

РЕФЕРАТ

Звіт про ДП: 93 стр., 31 рис., 12 табл., 24 джерела

КЛЮЧОВІ СЛОВА: віртуальні пристрої, логічні аналізатори, генератор слів, учбово-лабораторний стенд EV8031.

У данній роботі розглянуте створення программного забеспечення таких віртуальних пристроїв, як:

  • Логічний аналізатор;

  • Генератор слів.

Та обєднання їх у віртуальний вимірювальний комплекс на базі учбового лабораторного стенду.

Розроблено алгоритм і программа реалізації завдання. Чітко сформульовані основні проблеми, існуючі при розробці таких комплексів, та визначені нові підхіди для їх вирішення.

Розглянуті питання охорони праці й навколишнього середовища, проведена техніко-економічна оцінка роботи. На підставі аналізу результатів зроблені висновки й рекомендації для подальшої роботи в данному напрямку.

РЕФЕРАТ

Отчёт по ДП: 93 стр., 31 рис., 12 табл., 24 источника

КЛЮЧЕВЫЕ СЛОВА: виртуальные приборы,логические анализаторы, генератор слов, учебно-лабораторный стенд EV8031.

В данной работе рассматривается создание программного обеспечения таких виртуальных приборов, как:

  • Логический анализатор;

  • Генератор слов.

И объединения их в виртуальный измерительный комплекс на базе учебно-лабораторного стенда.

Разработан алгоритм и программа реализации задания. Четко сформулированы основные проблемы, существующие при разработке таких комплексов, и указаны пути их решения.

Рассмотрены вопросы охраны труда и окружающей среды, проведена технико-экономическая оценка работы. На основе анализа результатов сделаны выводы и рекомендации для дальнейшей работы в данном направлении.

ABSTRACT

Report on DP: 93 page, 31 fig., 12 tables., 24 source

KEYWORDS: virtual devices, logic analyzers, generator of words, educational laboratory stand EV8031.

Creation of software of such virtual devices is examined in this work, as:

- Logic analyzer;

- Generator of words.

And associations them in a virtual measuring complex on the base of educational laboratory stand.

An algorithm and program of realization of task is developed. Basic problems, existing at development of such complexes, are expressly formulated, and the ways of their decision are indicated.

The questions of labour and environment protection are considered, the technical and economic estimation of work is conducted. On the basis of analysis of results conclusions and recommendations are done for further work in this direction.

ЗМІСТ

РЕФЕРАТ

ВСТУП

1 ВИБІР ТА ОБҐРУНТУВАННЯ ОСНОВНИХ ТЕХНІЧНИХ РІШЕНЬ

1.1. Аналіз вихідного технічного завдання та постановка задачі

1.2.Огляд і аналіз аналогічних пристроїв

1.2.1. Портативні вимірювальні комплекси на базі дискретних спеціалізованих приладів

1.2.2. Спеціалізовані мікропроцесорні прилади

1.2.3. Прилади за технологією «віртуальні інструменти»

1.2.3.1. Віртуальні прилади фірми «Белвар»

1.2.3.2. Віртуальні прилади фірми «Omega»

1.2.3.3. Віртуальні прилади фірми «National Instruments»

1.3 Порівняльний аналіз та висновки

1.3.1 Короткі висновки 40

1.4. Зв'язок ВВК з IBM PC

1.4.1 Вибір інтерфейсу зв'язку

2 ОБЗОР АПАРАТНОЇ ЧАСТИНИ

2.1 Лабораторный стенд EV8031

2.1.1 Системний контроллер

2.1.2 Зовнішня пам’ять ОЗП

2.1.3 Порти вводу/виводу

2.1.4 Порт послідовної передачі данних

2.1.5 Мікроконтроллер

2.2 Мікроконтроллер ATMega8515

2.2.1 Архітектура AVR

2.2.2 Розподілення пам’яті мікроконтролера

2.2.3 Порти вводу виводу

Рис. 7 Блок схема порта вводу/виводу

2.2.4 Переривання та обробка переривань

2.2.5 Таймери

2.2.6 Послідовний приємопередавач USART

3 РОЗРОБКА ПРОГРАМНОГО ЗАБЕСПЕЧЕННЯ

3.1 Розробка програмного забеспечення мікроконтроллера

3.1.1 Розробка логічного аналізатора

3.1.2 Розробка генератора слів

3.1.3 Розробка алгоритму приємо передавача

3.1.4 Розробка головного циклу програми

3.2 Розробка програмного забеспечення ПК

3.2.1 Розробка інтерфейсу логічного аналізатора

Рис. 18 Інтерфейс користувача логічного аналізатора

3.2.2 Розробка інтерфейсу генератора слів

Рис. 19 Інтерфейс користувача генератору слів

3.2.3 Розробка інтерфейсу прийому/передачі

3.2.3 Розробка алгоритму програми

4 ТЕСТУВАННЯ ПРОГРАМНОГО ЗАБЕСПЕЧЕННЯ

5 БІЗНЕС-ПЛАН

5.1 Доцільність виробництва продукту

5.2 Опис характеристик продукту

5.2.1 Найменування та призначення

5.2.2 Загальні параметри продукту

5.3 Оцінка витрат на розробку

5.3.1 Визначення потреби у матеріальних та трудових ресурсах

5.4 Розрахунок витрат та договірної ціни продукту

5.5 Розрахунок витрат на тиражування

5.6 Аналіз стратегії маркетингу

5.6.1 Схема просування товару

5.6.2 Стимулювання продажу

5.6.3 Організація реклами та витрати на неї

5.7 Розробка фінансового плану

5.8 Висновки

6 ОХОРОНА ПРАЦІ ТА НАВКОЛИШНЬОГО СЕРЕДОВИЩА

6.1 Загальні питання охорони праці

6.2 Характеристика виробничого середовища приміщення, де виконується проектна робота

6.3 Аналіз небезпечних і шкідливих факторів

6.4 Виробнича санітарія

6.4.1 Метереологічні умови

6.4.2 Забезпечення виробничого освітлення

6.4.3 Шум

6.4.4 Випромінювання вiд екрана

6.5 Техніка безпеки

6.6 Пожежна безпека

6.7 Охорона навколишнього середовища

6.8 Висновок

ВИСНОВКИ

ВСТУП

Будь-який IBM-сумісний персональний компютер (ПК), навіть той що декілька років простояв на полиці за непотрібністю, може перетворитися в дуже добрий віртуальний прилад або цілий вимірювальний комплекс. Для цього потрібно лише підключити до ПК один або декілька не дуже складних зовнішніх пристроїв або плат розширення. При цьому весь інтелектуальний потенциал комп’ютера можна використати для побудови програмної частини приладу, за рахунок якої і будуть реалізовуватися всі його основні функціональні можливості. Віртуальний прилад, таким чином, представляє собою більш чи менш складне програмне забеспечення, яке встановлюється на ПК, та деякого інтерфейсного пристрою (ІП) який дозволяє сполучити ПК з джерелами та приймачами інформації.

Можна разраховувати на те, що віртуальний прилад надає користувачеві набагато більш широкі можливості в порівнянні з класичним вимірювальним приладом, який має той же рівень технічних характеристик.

У даному дипломному проекті як раз і розглядається можливість створення віртуального вимірювального комплексу: логічного аналізатору та генератору слів.

Реальні форми сигналів, діючих, наприклад, на системних шинах, не грають істотної ролі. Важливі тільки їхні логічні стани в ті моменти часу, коли вони сприймаються приладом і містять необхідну інформацію.

Такий комплекс може використовуватися в якості універсального вимірювального приладу, призначеного для запам’ятовування та слідкування за системними сигналами, що надходять на його входи в вигляді «чистих» двійкових сигналів та зберігати їх в своїй внутрішній цифровій пам'яті при налагодженні функціональних вузлів і пристроїв різних апаратних засобів обчислювальної техніки (периферійних пристроїв і т.п.), мікропроцесорних і мікроконтролерних систем різного призначення, радіотехнічних систем і пристроїв, засобів телекомунікації і т.д.

Такий віртуальний вимірювальний комплекс може замінити собою цілий комплект рiзноманiтних вимiрювальних приладiв.

Він дозволяє виконувати наступні дії:

  • реєстрації послідовності логічних станів водночас і синхронно в багатьох точках схеми та протягом значного часового інтервалу;

  • реєстрації станів контрольних точок в деякому інтервалі часу, що передує вибраній оператором події;

  • оперативного подання результатів вимірів в різноманітних форматах, зручних для оператора та що не відрізняються від основних форм документування, таких, наприклад, як шістнадцятирічний формат, двійковий формат, дизасемблерний формат та інші.

Розробці такого віртуального вимірювального комплексу і присвячений даний дипломний проект.

1 ВИБІР ТА ОБҐРУНТУВАННЯ ОСНОВНИХ ТЕХНІЧНИХ РІШЕНЬ

1.1. Аналіз вихідного технічного завдання та постановка задачі

Пристрій, що розробляється в даному дипломному проекті – віртуальний вимірювальний комплекс (ВВК): логічний аналізатор. Такий ВВК може використовуватися в якості універсального вимірювального приладу, призначеного для для запам’ятовування та слідкування за системними сигналами, що надходять на його входи в вигляді «чистих» двійкових сигналів та зберігати їх в своїй внутрішній цифровій пам'яті при налагодженні функціональних вузлів і пристроїв різних апаратних засобів обчислювальної техніки (периферійних пристроїв і т.п.), мікропроцесорних і мікроконтролерних систем різного призначення, радіотехнічних систем і пристроїв, засобів телекомунікації і т.д. Такий ВВК може замінити собою цілий комплект вимірювальних приладів.

Саме через його універсальність, мобільність та легкість у використанні, а також відносно не високу ціну, цей ВВК пропонується для використання у лабораторіях ВУЗу при проведенні лабораторних робіт з таких дисциплін, як „Комп’ютерна електроніка”, „Комп’ютерна схемотехніка”, „Периферійні пристрої” та інші.

Розглянувши весь спектр лабораторних робіт, що проводяться по цих предметах, можна визначити основні технічні вимоги до віртуального вимірювального комплексу: логічного аналізатору, які є достатніми, для того, щоб цей ВВК можна було використовувати при проведенні цих лабораторних робіт. Ці технічні вимоги приведені нижче.

Розроблювальний ВВК повинний мати наступні характеристики:

- У режимі логічного аналізатору:

  • Кількість каналів – 8;

  • Кількість станів, що реєструються – 1024;

  • Тактовий генератор – внутрішній з змінною частотою або зовнішній;

  • Запуск – за позитивним або негативним перепадом на одній з 8-ми вхідних ліній.

  • Глибина передпускової реєстрації – задається програмно.

  • Елементна база – однокриштальний мікроконтролер типу ATMega8515.

Конструктивне виконання – зовнішній пристрій, що підключається до ПК через інтерфейс RS232;

Також, віртуальний вимірювальний комплекс: логічний аналізатор повинен дозволяти у інтерфейсі користувача відображати часові діаграми на екрані ПК. Програма візуалізації має дозволяти виконувати масштабування та скролінг цих діаграм, обирати їх колір, користуватися різноманітними настройками.

З погляду розроблювача такий ВВК – це нестандартний периферійний пристрій, що передає оброблений сигнал на персональний комп'ютер (ПК) для його остаточного аналізу і відображення. Програмні засоби ВВК при цьому повинні забезпечити максимально зручний і звичний для користувача режим введення і відображення інформації: повинний мати вікно, у якому можливо задати параметри і побачити результат (діаграму сигналу).

Процедура взаємодії користувача з ВВК полягає в наступному: користувач, за допомогою спеціального меню, задає настроювання приладу і режим його роботи.

Таким чином загальна задача, яка сформульована в початковому технічному завданні, може бути розбита на окремі функціональні задачі:

  • Апаратна частина яка приймає і перетворить аналогові сигнали в цифрові;

  • Програмне забезпечення пристрою: містить у собі питання побудови інтерфейсу і сервісних програм;

  • Організація зв'язку розроблювального пристрою з комп'ютером;

Для того щоб перейти до розгляду кожної функціональної задачі окремо необхідно розглянути питання, що стосуються пристрою у цілому. Також необхідно розглянути варіанти побудови пристроїв такого типу.

1.2.Огляд і аналіз аналогічних пристроїв

При пошуку складних несправностей в дискретних пристроях виникає необхідність одночасного спостереження декількох сигналів, однократних і аперіодичних, поведінки системи в моменти часу, попередні якій-небудь події або наступні за ним. Такі можливості надає логічний аналізатор - прилад для збору і аналізу даних про реальні умови роботи дискретних пристроїв.

Логічний аналізатор (ЛА) являє собою комбінацію багатоканального реєстратора двійкових сигналів, побудованого на базі швидкодіючого ЗП з розвиненою системою управління процесом запису даних, і екранного пульта-дисплея, що відображає записану в ЗП інформацію в формі, найбільш зручній для її аналізу.

Розрізнюють два типи логічних аналізаторів: аналізатори логічних станів і аналізатори тимчасових діаграм.

Аналізатори логічних станів фіксують стани контрольних точок схеми, що перевіряється під час тактових сигналів, що задаються пристроєм, що перевіряється, і записують процес зміни станів синхронно з його роботою.

Аналізатори тимчасових діаграм фіксують стани контрольних точок схеми, що перевіряється в моменти часу, які задаються незалежно працюючим тактовим внутрішнім генератором аналізатора.

Стани контрольних точок фіксуються в дискретні моменти часу (при подачі тактових сигналів) в двійковій формі; 0- при відсутності сигналу, 1-при його наявності.

Логічні аналізатори мають два основних режими: реєстрації і відображення.

Реєстрацією називається процес запису стану сигналів, що поступають по вхідних каналах аналізатора, в його запам'ятовуючі пристрої. Реєстрація починається по сигналу запуску реєстрації, який може бути або зовнішнім сигналом, або кодовим словом, або послідовністю кодових слів.

Відображенням називається процес індикації на екрані електронно-променевої трубки тимчасових діаграм або логічних станів, записаної в ЗП в процесі реєстрації.

Для установки режиму, способу запуску реєстрації, відображення, а також кодових слів запуску реєстрації на панелі управління є перемикачі і гнізда для підключення зовнішніх сигналів.

Оскільки в режимі реєстрації процес запису сигналів в ЗП ЛА йде відповідно до вибраної тактової частоти, сигнали, які за часом коротше чергового тактового періоду і з'являються після тактового сигналу, не будуть записані, хоч і можуть спричинити неясну зміну станів асинхронної логіки. Для виявлення подібної ситуації деякі ЛА мають режим фіксації перешкод. Цей режим не дозволяє виміряти ширину короткого сигналу, однак вказує на його наявність і тимчасове положення. Основними характеристиками ЛА є:

1. число каналів одночасної реєстрації станів сигналів;

2. рівні вхідних логічних сигналів;

3. глибина реєстрації, т.е максимальна кількість запам'ятовувань каналу інформації;

4. максимальна частота реєстрації, що визначає мінімальний інтервал часу між двома послідовними відліками станів вхідних сигналів.

Глибина реєстрації визначається місткістю ЗП, а максимальна частота реєстрації - швидкодією ЗП аналізатора.

Аналізатори, що Випускаються в цей час мають від 8 до 48 каналів реєстрації, частоту реєстрації від 20 до 200 МГц, глибину реєстрації від 64 до 2048 біт на каналі.

Процес реєстрації в ЛА може бути початий при появі на входах:

спеціально заданого зовнішнього сигналу;

заданої кодової комбінації (слово стану) сигналів ;

заданої послідовності кодових комбінацій.

Існують наступні способи запуску реєстрації: прямий, затриманий і з попередньою установкою.

При прямому запуску сигнал запуску відразу включає процес реєстрації, а при затриманому - через певний час, що задається числом тактів затримки. При запуску з попередньою установкою аналізатор реєструє стани в контрольних точках пристрою, що діагностується незалежно від сигналу запуску і дозволяє зберегти і видати на відображення дані, які були записані за N тактів до появи сигналу і М-N.

В даний час створення багатоцільових, портативних вимірювальних комплексів йде по трьох напрямках:

  • На базі дискретних спеціалізованих приладів;

  • Спеціалізовані мікропроцесорні прилади;

  • Прилади за технологією "віртуальні інструменти";

Розглянемо ці напрямки більш докладно:

1.2.1. Портативні вимірювальні комплекси на базі дискретних спеціалізованих приладів

Як правило, зараз будь-який пристойний прилад має інтерфейс підключення до комп'ютера й таким образом з'являється можливість створення багатоцільових вимірювальних комплексів, у яких здійснюється взаємозалежне керування роботою приладів, де частина необхідних функцій обробки сигналів здійснюється окремими приладами (у межах закладених у них можливостей), частина функцій разом з вихідними даними приладів передається керуючому комп'ютеру. При такому способі з'являється можливість створення дійсно досить багатофункціональних вимірювальних комплексів. Про портативність подібних комплексів можна говорити, звичайно, з великою натяжкою, хіба тільки в тім смислі, що в принципі вони є переносними.

О промисловому (захищеному) виконанні говорити не приходиться. Вартість висока, надійність низька (велика кількість складових), функціональні можливості фіксовані й обмежені можливостями комплектуючих приладів. Модернізація й адаптація до об'єктів діагностики - дорогі, трудомісткі, у більшості випадків повною мірою просто нездійсненні. Використовуються, в основному, для оснащення лабораторних установок, проведення НИР ОКР і ін.

1.2.2. Спеціалізовані мікропроцесорні прилади

Аналізатори-збирачі. На сьогоднішній день це досить широка номенклатура приладів як вітчизняного, так і імпортного виробництва. Прилади дійсно портативні, багатоцільові, можуть бути у захищеному виконанні аж до забезпечення вимог по іскровзривобезпеки. В останній якості практично не мають альтернативи, але у всіх інших випадках на сьогоднішній день це вже далеко не кращий шлях рішення подібних задач. Справа в тім, що подібні прилади у всіх випадках являють собою, по суті, спеціалізовані "саморобні" портативні комп'ютери з убудованими пристроями вводу-виводу даних і унікальним програмним забезпеченням фірми-виробника. У кожного виробника подібні прилади є зовсім унікальними як по виконанню "у залізі", так і по програмному забезпеченні. Як комп'ютери, по більшості своїх технічних параметрів і сервісних можливостей вони не йдуть ні в яке порівняння з "звичайними" сучасними портативними комп'ютерами, тим більше з темпами їхнього безупинного удосконалювання і зниження вартості. Вартість приладів досить висока і на практиці може збільшуватися (навіть у рази) за рахунок комплектації відповідним програмним забезпеченням. Вартість програмного забезпечення практично завжди порівнянна з вартістю "заліза", а іноді і перевершує його. У цілому можна сказати так: річ гарна, іноді незамінна, але в більшості випадків далеко не краща на сьогоднішній день.

1.2.3. Прилади за технологією «віртуальні інструменти»

Формально термін означає "удавані прилади", власне кажучи, функціонально, це, звичайно, зовсім дійсні прилади і віртуальність їх складається тільки в тім, що окремо, як звичні дискретні прилади "у залізі" вони дійсно не існують. Реалізуються апаратно-програмним шляхом і базуються на трьох основних складовим:

  • Обчислювальні й апаратні можливості сучасних комп'ютерів, для переносних приладів - це Notebook;

  • Спеціалізовані мови програмування для задач обробки й аналізу сигналів;

  • Апаратні пристрої вводу-виводу спеціально розроблені для роботи під керуванням програм, написаних на вищезгаданих спеціалізованих мовах програмування.

Одне з найбільш вдалих і отримавших дуже широке поширення в усьому світі пропозицій по практичній реалізації даної технології створення приладів - апаратні пристрої вводу-виводу і спеціалізована мова графічного програмування LabVIEW фірми National Instruments, США. Обширнейшая бібліотека стандартних функцій обробки сигналів і створення інтерфейсу для користувача (вид приладу на моніторі), налагоджені драйвери взаємодії з апаратними пристроями, величезна номенклатура самих пристроїв вводу-виводу в сполученні з можливостями сучасних комп'ютерів дозволяють при мінімально можливих на сьогоднішній день витратах створювати в дуже короткий термін будь-які складні прилади, причому дуже високої якості. Це обумовлено тим, що всі основні складові подібного приладу (комп'ютер, системне ПО, пристрій вводу-виводу) - це фірмові вироби масового виробництва, протестовані виготовлювачем і гарантовані для забезпечення, що сопрягаются по всім необхідним параметрам, найбільш повного використання всіх можливостей кожного з названих компонентів. При цьому всі основні компоненти безупинно удосконалюються по своїх функціональних і технічних параметрах з повним збереженням наступності з попередніми версіями. Наприклад, раз уже створений в остаточному виді прилад можна переустановити на іншій, більш сучасний комп'ютер і він відразу почне працювати, наприклад, більш швидко без яких-небудь переробок самої програми приладу. З погляду габаритів приладів, навіть теоретично немає нічого рівного, оскільки в габаритах, наприклад, одна сучасного Notebook може бути реалізоване практично необмежена кількість різних приладів. З цим же зв'язані і вартісні показники подібних приладів. Наприклад, навіть один прилад типу стандартного вузькополосного спектроаналізатору у віртуальному виконанні буде коштувати в 1.5-2 рази дешевше, ніж у традиційному дискретному. З огляду на те, що за технологією віртуальних приладів у рамках разових витрат "на залізо" може бути реалізоване (і так на практиці завжди і відбувається) безліч приладів, вартість подібного рішення стає просто несоизмеримо малої в порівнянні з іншими способами реалізації. Оскільки технологія "віртуальних приладів" являє собою зовсім нову і, можна сказати, революційну технологію в приладобудуванні, вона дозволяє сполучити такі якості, що у процесі удосконалювання традиційних приладів, як правило, сполучити неможливо: краще, дешевше, швидше, надійніше. Розглянемо даний тип приладів більш докладно.

1.2.3.1. Віртуальні прилади фірми «Белвар»

Ця фірма пропонує користувачам цифрові логічні аналізатори у вигляді невеликих приставок до персонального комп'ютера. Наприклад АКС-3161, це професійна модель віртуального 16 – канального логічного аналізатору з частотою дискретизації 200МГц, виконана у вигляді приставки до ПК та підключається до LPT-порту комп’ютера. Має гнучки можливості захвату та відображення цифрового потоку даних, широкими можливостями по роботі з зовнішньою тактовою частотою. Має наступні технічні параметри:

  • Внутришні частоти дискретизаії 1,25 кГц...200 МГц (17 ступенів)

  • 16 каналів

  • Буфер даних 131000 виборок на канал

  • Режими запуску: по шаблону; по фронту; безперервний

  • Цифровий регістратор: від 4 секунд до 1 часу

  • Порогова напруга 1,0...2,4 В

  • Споживча потужність 4,5 Вт (800 мВт у режимі очікування)

  • Нестабільність частоти дискретизації 0,01%

  • Вхідна напруга 0...7 В макс.

  • Вхідна ширина смуги частот 40 МГц

  • Вхідний імпеданс 100 кОм/8 пФ

  • Габаритні розміри 150х86х26 мм

Зовнішній вигляд цього логічного аналізатору приведений на рис. 1.1

Рисунок 1.1 Зовнішній вигляд приставки до комп'ютера АСК-3161

Нижче на рис. 1.2 приведено вікно програми інтерфейсу користувача з діаграмою сигналів.

Рисунок 1.2 Вид деяких вікон ПО приставки до комп'ютера АСК-3161

АКС-3162 – віртуальний 16-канальний логічний аналізатор виконаний у вигляді плати розширення в ISA-слот комп’ютера та працює разом з осцилографічною плотою АСК-3101. Єдине для обох плат програмне забезпечення дозволяє синхронізувати і бачити на екрані одночасно 2 канали аналогової та 16 каналів цифрової інформації. Сполучення аналогових та цифрових функцій дозволяє використовувати систему як осцилограф змішаних сигналів для пошуку аналогових перешкод у цифрових схемах, аналізу фронтів, логічних рівнів та ін.

АКС-3162 має наступні технічні параметри:

  • 16 каналів

  • Мінімальний період виборок: 50 нс у реальному часі

  • Максимальний період виборок 2,5 мс

  • Запуск: будь-яка комбінація логічних рівнів на вході аналізатору, або синхронізуючий сигнал з плати осцилографу

  • Можливість запису до запускаючої події 7872 відліку

  • Довжина запису 8000 відліків на кожний канал

  • Вхідний імпеданс 1 МОм/30 пФ

  • Рівень спарцьовування запуску обираємий: ТТЛ або КМОП

Зовнішній вигляд цього логічного аналізатору приведений на рис. 1.3

Рисунок 1.3 Зовнішній вигляд приставки до комп'ютера АСК-3162

Нижче на рис. 1.4 приведено вікно програми інтерфейсу користувача з діаграмою сигналів.

Рисунок 1.4 Вид деяких вікон ПО приставки до комп'ютера АСК-3162

АКС-3166 – це більш потужний логічний аналізатор, має наступні технічні характеристики:

  • 16 каналів

  • Діапазон частот дискретизації 2 кГц…200 МГц

  • Довжина запису 2М слова на канал

  • Регулювання розміру предзапису та постзапису

  • Діапазон установки порогів спрацьовування по входах ±2,5 В с дискретністю 20 мВ

  • Режими запуску: при наявності шаблону даних, по тривалості шаблону даних, по фронту будь-якого біта даних, за шаблоном даних та/або по фронту будь-якого біту даних у різноманітних комбінаціях

  • Інтерфейс зв’язку з комп’ютером USB 1.1 або LPT (EPP)

  • Професійні вимірювальні щупи дозволяють легко і швидко здійснити підключення до контактів аналізуємої плати

Цей логічний аналізатор призначений для аналізу потоку цифрових даних одночасно по 16 каналам з частотою дискретизації до 200 МГц, а також може бути використаний у якості цифрового регістратору даних. Буфер 2М виборок на канал дозволяє забезпечити високу точність часових вимірів достатньо тривалих потоків даних. Гнучкий набір варіантів синхронізації та шаблонів запуску дозволяє визначити різноманітні збої у потоці даних, що приводять до порушення роботи апаратури. Даний аналізатор забезпечує нормальну роботу з апаратурою, яка має різні логічні порогові рівні вхідних сигналів, тому що пороги обираються користувачем.

Інтерфейс користувача програми складається з набору робочих панелей (вікон). Кожна панель має набір керуючих елементів (КЕ), які дозволяють користувачу впливати на роботу програми та індикаторів, що відображають необхідну інформацію. Більшість цих елементів є частиною стандартного інтерфейсу Windows і не потребують спеціальних пояснень по їх використанню.

Зовнішній вигляд цього логічного аналізатору приведений на рис. 1.5

Рисунок 1.5 Зовнішній вигляд приставки до комп'ютера АСК-3166

Для керування програмою користувач може також використовувати команди спливаючього меню головної панелі. АКС-3166 має зрозумілий та зручний інтерфейс, котрий може налагоджуватися користувачем. Нижче на рис. 1.6 приведено вікно програми інтерфейсу користувача з діаграмою сигналів.

Рисунок 1.6 Вид деяких вікон ПО приставки до комп'ютера АСК-3166

1.2.3.2. Віртуальні прилади фірми «Omega»

Логический анализатор Omega – Logic : використовується для запису аналізу послідовних та паралельних потоків обміну, а також генерації заданих цифрових послідовностей. Збудований на основі базового блоку Omega. Завдяки використанню ПЛІС пристрій має недосяжну для мікроконтролерних аналогів швидкодію та точність обробки даних. 4 режими запису дозволяють оптимально використовувати внутрішню пам’ять аналізатора. Наявність різноманітних вбудованих та користувальницьких засобів аналізу сигналів дає можливість швидко та ефективно оброблювати великі об’єми інформації. Цей аналізатор має наступні технічні параметри:

  • Логічний аналізатор:

  • Кількість каналів: 2, 4, 8

  • Об’єм внутрішньої пам’яті: 128 КБайт (опціонально 512K)

  • Режими запису: нормальний, адаптивний, дельта, з зовнішньою синхронізацією.

  • Максимальна частота запису: 20 МГц.

  • Стабільність задаючього генератора: +/-100ppm (опціонально +/-25ppm)

  • Аналізатор протоколів: I2C, MicroWire, SPI, RS232, 1Wire, CAN ...

  • Налагодження режимів відображення інформації (двійковий, десятковий, шістнадцятковий, символьний).

  • Вбудована макромова аналізу і генерації послідовностей.

  • Збереження даних у файли різних форматів.

  • Генератор: 8 каналів, 128 КБайт пам’яті, максимальна частота - 20 МГц, однократний та циклічний режим.

  • Логічний пробник - 16 каналів.

  • Електричні параметри (з адаптером LA16):

  • - Вхідний опір - 100 кОм

  • - Вихідний опір - 100 Ом

  • - Вхідна ємність - 10 пФ (без кабелю)

  • - Напруга порогового рівня - 1.4В (TTL)

1.2.3.3. Віртуальні прилади фірми «National Instruments»

Ця фірма є розробником технології віртуальних приладів – революційної концепції, що змінила підхід та методику проведення вимірів та розробки систем автоматизації. Максимально використовуючи можливості комп’ютерів та сучасних інформаційних технологій, віртуальні прилади дозволили збільшити продуктивність і знизити собівартість рішень за рахунок використання гнучкого та простого у освоєнні програмного забезпечення, такого як середовище графічного програмування LabVIEW, а також модульного обладнання, такого як, наприклад, модулі стандарту PXI, призначеного для збору даних та керуванням приладами.

Розглядаючи новітні прилади збору даних цієї фірми, можна виділити наступні: це універсальній зовнішній пристрій збору даних USB 6008/6009, а також внутрішні плати збору даних М серії, що мають стандартній та поширений для звичайних ПК швидкий інтерфейс РСІ.

Розглянемо тепер більш детально технічні характеристики цих приладів:

USB 6008/6009 зображено на рис. 1.7.

  • 8 каналів аналогового вводу, з дозволом 12 або 14 біт, частота оцифровки до 48 кГц;

  • Гвитові термінали для підключення датчиків;

  • Швидке plug-and-play підключення до ПК;

  • Драйвери для ОС Windows, Mac OS X та Linux;

  • Багатофункціональний ввід/вивід для проведення збору та збереження даних;

  • Живлення по шині USB;

  • Безкоштовне ПО для збору та збереження даних.

Рисунок 1.7 Зовнішній вигляд приставки до комп'ютера USB 6008/6009

Плати збору даних М серії зображено на рис. 1.8.

  • До 32 аналогових входів, 4 виходів та 48 цифрових ліній;

  • Дозвіл до 18 розрядів;

  • Програмує мий вхідний діапазон;

  • Аналоговий вивід до 2,8 МГц (16 розрядів);

  • Високошвидкісний (до 10 МГц) ввід/вивід цифрових сигналів;

  • У 5 разів покращена точність вимірів за рахунок нелінійної калібрування в усіх діапазонах;

  • Повна підтримка LabVIEW та інструментального драйверу NI-DAQmx.

Рисунок 1.8 Зовнішній вигляд плати збору даних М серії

LabVIEW являє собою високоефективне середовище графічного програмування, у якому можна створювати гнучкі та масштабовані прикладні програми вимірів, керування та тестування з мінімальними часовими та грошовими затратами. Приклад прикладної програми вимірів, створеної у LabVIEW зображено на рис.1.9.

Рисунок 1.9 Зовнішній вигляд вікон прикладної програми вимірів,

створеної у LabVIEW

LabVIEW сполучає у собі гнучкість традиційної мови програмування з інтерактивною технологією Експрес ВП, яка включає у себе автоматичне створення коду, використання помічників при конфігуруванні вимірів, шаблони прикладних програм та Експрес ВП, що налагоджуються. Завдяки цим особливостям, і експерти можуть легко та швидко створювати прикладні програми у LabVIEW.

1.3 Порівняльний аналіз та висновки

Задачу реалізації ВВК аналогічного розроблювальному, можна вирішити декількома шляхами:

За допомогою спеціалізованих плат (реалізація на «твердій» логіці). Даний спосіб дозволяє мінімізувати як розміри, так і вартість апаратної частини, але при цьому зростають вимоги до ПК, тому що на нього лягає вся обробка вхідного сигналу.

За допомогою плат на «програмувальній» логіці. Даний спосіб дозволяє не тільки передбачити захист плати від позамежного рівня вхідного сигналу, але і перекласти частину його обробки на мікроконтролер плати, що дозволяє розвантажити ПК.

1.3.1 Короткі висновки

Як видно з приведеного порівняння реалізація ВВК за допомогою «твердої» логіки приводить до значно менших грошових витрат, але при цьому і швидкість роботи усього ВВК, і можливість використовувати ПК у багатозадачном режимі різко знижуються через велику кількість обчислень, що виконує ПК. Приймаючи це до уваги, у процесі дипломного проектування був розроблений ВВК на «програмувальній» логіці, що дозволило в значній мірі розвантажити ПК, і значно зменшити число даних для обміну, тому що вся попередня обробка сигналу виконується мікроконтролером.

1.4. Зв'язок ВВК з IBM PC

Підключення ВВК до ПК можна здійснити використовуючи будь-який убудований інтерфейс. Коротке порівняння деяких з них приведено в табл. 1.

Таблиця 1.

Порівняння методів підключення ВIК


Системна магістраль ISA

Інтерфейс
Centronics

Інтерфейс
RS-232C

Швидкість обміну

Висока (до 5 Мбайт/с і вище)

до 100 Кбайт/с

115200 Кбiт/с

Довжина і тип лінії зв'язку з комп'ютером

Вбудовані ПС (лінія зв'язку відсутня)

До 2 м, багатопровідний кабель

До 15м, одиночний провід

Складність вузлів сполучення з ПК

Від малої до середньої

Від малої до середньої

Від середньої до високої

Додатковий конструктив

Не потрібний

Потрібний

Потрібний

Зовнішнє джерело живлення

Не потрібне

Потрібне

Потрібне

Формат і розрядність даних

Паралельний,
16 розрядів

Паралельний,
8 розрядів

Послідовний

Необхідність наявності драйвера

+

+

-

Кількість ПС, що підключаються до ПК

До 6

1

1

З погляду розроблювального ВВК найбільш привабливим виглядає інтерфейс RS-232.

1.4.1 Вибір інтерфейсу зв'язку

У розроблювальному ВВК зв'язок пристрою з ПК буде здійснюватися за допомогою COM порту (інтерфейс RS-232). Даний вид зв'язку дозволяє забезпечити достатню для роботи ВВК швидкість і при цьому є найбільш зручним з погляду ПО, тому що не вимагає спеціального драйвера. Розглянемо цей інтерфейс більш докладно.

2 ОБЗОР АПАРАТНОЇ ЧАСТИНИ

2.1 Лабораторный стенд EV8031


Рис. 1 Блок схема стенду EV8031

Вся логіка стенду реалізована на програмуємій логічній мікросхемі EPM7128STC100. Системний контроллер керує режимами роботи, виробу керуючих сигналів на ОЗП, регістри защіпки, динамічним світлодіодним індикатором, клавіатурою.

2.1.1 Системний контроллер

Системний контроллер зв’язаний з мікроконтроллером за допомогою шини данних AD0..7 та старших 4-х біт адресу A12..15. Коли мікроконтроллер виконує операцію читання/запису данних у зовнішню пам’ять спочатку на лінії AD0..7(мультиплексується із A0..7 на момент синхроімпульсу лінії ALE) та лінії A8..15 виводиться адрес комірки, молодші 8 біт та старші – відповідно. Після закінчення синхроімпульсу ALE на лініях AD0..7 з’являється 8 біт данних. Коли старший біт адресу дорівнює 1, системний контроллер залишає лінію nRCS у високому стані, і старші 4 біта адресу, разом із молодшим байтом адресу, який надійшов по лініям AD0..7 у період синхроімпульсу, тепер керують адресою пристрою котрому надсилається керуючий байт. Перелік адрес за якими розташовані керуючі слова пристроїв наданий у таблиці 2.1.

Таблиця 2.1.

Адрес

Тип цикла

B7

B6

B5

B4

B3

B2

B1

B0

Имя

Порты периферийных устройств

8xx0

Запись

[Порт A]

PA_REG

8xx1

Запись

[Порт B]

PB_REG

8xx2

Запись

[Порт C]

PC_REG

8xx3

Запись

x

x

x

x

x

TRISC

x

x

TRIS

ЖКИ

8xx4

Запись

Регистр команд ЖК индикатора

LCD_CMD

8xx5

Запись

Регистр данных ЖК индикатора

LCD_DATA

Последовательный порт

9xxx

Чтение

CTS

DSR

DCD

RI

KL3

KL2

KL1

KL0

US_REG

Cxx0

Запись

x

x

X

x

DTR

RTS

CFG1

CFG0

UC_REG

Индикатор и светодиоды

Axx0

Запись

[Регистр индикатора 0]

DISPLAY[0]

Axx1

Запись

[Регистр индикатора 1]

DISPLAY[1]

Axx2

Запись

<зарезервировано>

DISPLAY[2]

Axx3

Запись

<зарезервировано>

DISPLAY[3]

Axx4

Запись

DP3

DP2

DP1

DP0

BL3

BL2

BL1

BL0

DC_REG

Axx5

Запись

<зарезервировано>

EDC_REG

Axx6

Запись

LED7

LED6

LED5

LED4

LED3

LED2

LED1

LED0

LED_REG

Управление работой

Axx7

Запись

x

x

X

x

x

x

x

RUN

SYS_CTL












Совместимые регистры

Bxx0

Запись

[Регистр индикатора 1]

DISPLAYB












2.1.2 Зовнішня пам’ять ОЗП

Коли старший 15 біт адресу дорівнює 0 системний контроллер встановлює лінію вибору кристаллу ОЗП – nRCS у низький логічний рівень, а лінії nRRD та nRWR повторюють стани ліній nRD та nWR відповідно. Лінія RA14 повторює лінію A14 тільки у тому випадку якщо вибраний режим роботи стенда із мікроконтроллером AVR. У випадку роботи із мікроконтроллером 80C51 лінією буде керувати системний контроллер перші 16кбайт – коди інструкцій программи, другі 16кбайт – данні.

2.1.3 Порти вводу/виводу

Стенд має три 8-ми бітних портів вводу/виводу PORTA(лінії PA0..7), PORTB(лінії PB0..7), PORTC(лінії PC0..7). Порти PORTA та PORTB виконані на регістрах защіпках і працюють тільки на виход, а PORTC – у системному контроллері і може працювати як на вход так і на виход. Коли мікроконтроллер записує байт по адресу 8xx0(xне впливають і можуть бути будь якими), системний контроллер встановлює лінію PACLK у високий стан. Регістр защіпка запам’ятовує лінії AD0..7 та повторює іх стан на своїх вихідних лініях – PA0..7. Аналогічно отримується доступ до портів PORTB та PORTC але доступ виконується за адресами 8xx1 та 8хх2 відповідно. За адресою 8хх3 знаходиться байт керування режимом роботи на вхід або на вихід, за відповідає біт 2. Якщо він дорівнює 0 порт працює на вхід, якщо 1 на вихід.

2.1.4 Порт послідовної передачі данних

Модуль послідовного зв’язку створений на мікросхемі приймача 1489, передавача 74НС04, мултиплексора каналу передачі (усередині системного контроллеру). Вибор каналу послідовної передачі забеспечується сигналами CFG1,CFG0 за адресою 9001h(см. таблицу 1). Програмне встановлення сигналів CFG0 у ‘1’, а CFG1 у ’0’ формує вибір додаткового каналу послідовної передачі данних, гніздо X12. Додатковий послідовний канал має повний набір сигналів інтерфейсу RS-232C. Сам пристрій який реалізує послідовну прийом/передачу знаходиться у мікроконтроллері і називається UART або USART, його лінії RxD, TxD зв’язані із системним контроллером, а він в свою чергу може комутувати їх на 3 напрямки:COM1, COM2, RS485.

2.1.5 Мікроконтроллер

Стенд підтримує 2 типи мікроконтроллерів: мікроконтроллер AT89C51 із ядром і8031, та ATMega8515 із AVR ядром який і розглядається у данному документі. Для перемиканням між режимами підтримки першого або другого мікроконтроллеру, системний контроллер має лінію Х9(0 – AVR, 1 - i8031).

2.2 Мікроконтроллер ATMega8515

КМОП мікроконтроллер АТ8515 реалізований за AVR RISC архітектурою (Гарвардська архітектура із роздільною пам’яттю та роздільними шинами для пам’яті програм та даних) та сумісний за похідним кодом і тактуванню із 8-ми розрядними мікроконтролерами родини FVR. Виконуючи команди за один тактовий цикл, він забезпечує могутню систему команд із 32-ма 8-розрядними регістрами загального призначення та конвеєрне звернення до памяті програм. Шість із 32 регістрів можуть використовуватись як три 16-розрядних регістра-вказіника при косвенній адресації простору памяті. Виконання відносних переходів та команд виклику реалізується із прямою адресацією усіх 4К адресного простору. Адреса периферійних функцій міститься у просторі памяті вводу/виводу. Архітектура ефективно підтримує як мови високого рівня, так і програми на мовах асемблеру.

2.2.1 Архітектура AVR

Мікроконтроллер має 32 регістри загального призначення які безпосередньо підключені до АЛУ, це дозволяє виконувати більшість команд за один такт. Мікроконтроллер має 8 кбайт неодноразово-програмуємої пам’яті программ, 512 байт внутрішнього ПЗП, 512 байт внутрішнього ОЗП та інтерфейс який дозволяє розширити ций обєм завдяки підключенню зовнішнього ОЗП, 4 – 8-ми бітних порта та 1 – 3-х бітний порт, 1 – 8-ми бітний таймер та 1 – 16 – бітний таймер, які мають зовнішні лінії синхронізації, переривання за переповненням та зрівненням. Також мікроконтроллер має зовнішні переривання, послідовний програмуємий приемопередавач, програмуємий “WatchDog” таймер із окремим RC-генератором, порт SPI та три програмуємі режими роботи єнергосбереження.

Рис 1. Блок схема мікроконтроллеру ATMega8515

2.2.2 Розподілення пам’яті мікроконтролера

Розподілення памяті мікроконтроллера показано на рис. 2.

Внутрішній ОЗП мікроконтроллеру розташований за адресою 0060h та закінчується 025Fh. Починаючи з адреси 0260h до FFFFh можна адресувати зовнішню пам’ять. На рис. 3 надана структурна схема підключення зовнішнього ОЗП до мікроконтроллеру.

Рис 2. Розподілення пам’яті мікроконтроллера.

Внутрішній ОЗП мікроконтроллеру розташований за адресою 0060h та закінчується 025Fh. Починаючи з адреси 0260h до FFFFh можна адресувати зовнішню пам’ять. На рис. 3 надана структурна схема підключення зовнішнього ОЗП до мікроконтроллеру.

Рис. 3 Структурна схема підключення ОЗП до мікроконтроллера

На відміну від внутрішньої памяті доступ до зовнішньої триває довше на 1 такт(або на 2 такти у залежності від налаштовувань). На рис. 4 подана

часова діаграма доступу до зовнішньої памяті:

Рис. 4 Часова діаграма доступу до зовнішньої памяті.

Робота зовнішнього СОЗП(SRAM) налаштовується за допомогою регістру MCUCR рис 5.

Рис. 5 Опис полів регістру MCUCR

Робота зовнішнього SRAM дозволяється встановленням біту SRE у регістрі MCUCR. За зрівняннями зі зверненням до внутрішньої памяті даних, звернення до зовнішньої памяті потребує додаткового циклу на кожний байт. Це означає, що для виконання команд LD, ST, LDS, STS, PUSH та POP потрібен додатковий тактовий цикл. Якщо стек розташований у зовнішній SRAM, то для переривання, виклику підпрограм та вертання потрібно буде два додаткових цикла, оскільки в стеку буде зберігатися та відновлятися двубайтовий лічильник команд. Якщо інтерфейс із зовнішньою пам’яттю використовується із станом чекання, то на кожний байт необхідно ще два додаткових тактових цикла. Це призводить до наступного ефекту. Командам пересилання даних необхідно два додаткових тактових цикла, тоді для обробки переривання, виклику підпрограми та при вертанні з підпрограми потрібно на чотири тактових циклу більше, ніж це вказано в описі системи команд.

Встановлений у 1 біт SRE дозволяє звернення до зовнішнього SRAM даних та переводить роботу портів А, С, ліній WR та RD на виконання альтернативної функції, також змінюється напрямок роботи портів. Після встановлення SRE у 0 звертання до зовнішньої памяті недозволяється, а напрямок роботи портів встановлюється у читання.

При встановленому у 1 SRW до циклу звертання до зовнішнього SRAM дозволяється один цикл чекання. При скиданні у 0 біті SRW звертання до зовнішнього SRAM виконується за 3 цикли. См. рис. 4 Цикл та звернення до зовнішнього SRAM без стану очікування, та рис. 6 із станом очікування.

Рис.6 Звернення до зовнішньої SRAM зі станом очікування

2.2.3 Порти вводу виводу

Порти вводу/виводу можуть робити на вхід та на вихід. За це відповідає відповідний регістр напрямку DDRx(x-назва порту A, B…). Також порт має регістр стану PORTx запис данних у який відображається на порт, якщо порт знаходиться у режимі видачі. А якщо порт працює у режимі читання цей регістр вмикає/вимикає підтягуючі резистори. Для читання порту використовується регістр PINx. Також більшість портів мають альтернативні функції і коли порт іх виконує, відповідні регістри DDRx, PORTx та PINx не впливають на роботу порта. На рис. 7 зображена блок-схема порта який немає альтернативної функції.

Рис. 7 Блок схема порта вводу/виводу

2.2.4 Переривання та обробка переривань

Найважливіша характеристика будьякого мікроконтроллера це - час відгуку на переривання. Відгук на виконання усіх дозволених переривань AVR складає мінімум 4 тактових цикла. Впродовж 4 тактових циклів вміст лічильника команд(2 байта) зберігається у стек, та вказівник стеку зменшується на 2. Вектор вказує перехід на підпрограму обробки переривання та цей перехід займає 3 тактових цикла. Якщо переривання виникає за час виконання багатоциклової команди, то команда закінчує виконання, а потім обслуговується переривання. Вертання з підпрограми обробки переривання (як і виклик підпрограми) займає 4 тактових цикла. Впродовж цих 4 циклів стан лічильника команд (2 байта) відновляється зі стеку та вказівник стеку збільшується на 2. Коли мікроконтроллер виходить з перервання, він завжди вертається у основну програму та виконує ще одну команду, перш ніж почати обслуговувати якесь відкладене переривання.

Відзначимо, що регістр статусу SREG не обробляється апаратними можливостями AVR, ані для переривань, ані для підпрограм.

При обробці підпрограм переривань, які потребують збереження SREG, збереження потрібно виконувати програмними засобами користувача. Для переривань, які запускаються статичними подіями (наприклад співпадання вмісту регістру зрівняння 1А із станом таймеру/лічильника1). Прапорець переривання встановлюється у момент виникнення події. Якщо прапорець скинутий, але умови виникнення переривання продовжують існувати, прапорець не буде встановлюватись до тих пір, доки ця подія не виникне знову.

2.2.5 Таймери

Мікроконтроллер має один 8-розрядний та один 16-розрядний таймери лічильники. Вони можуть тактуватися, як від внутрішнього, так і від зовнішнього генератора. Блок схеми таймерів зображена на рис. 8 та рис. 9. Кожний таймер має свій окремий попередній дільник із чотирма ступенями ділення: CK/8, CK/64, CK/256, CK/1024, де CK – це вхідний тактовий сигнал. Цей тактовий сигнал, за замовчуванням, з’єднаний із головним тактовим сигналом системи. Обидва таймери мають загальний регістр стану таймерів, у якому зберігаються такі прапори стану, як: переповнення, співпадання за зрівненням та захвату події. Встановлення дозволення/недозволення переривань виконується у регістрі масок переривань таймерів/лічільників TIMSK. При тактуванні таймеру/лічильника від зовнішнього генератора цей сигнал синхронізується із тактовою частотою CPU. Для запеспечення правильної синхронізації зовнішнього сигналу необхідно, щоб мінімальний час між двома вхідними тактовими тактовими циклами був не менш одного циклу внутрішнього тактового сигналу CPU. Зовнішній тактовий сигнал синхронізується за підніманням фронту внутрішнього тактового сигналу CPU. Точність таймерів росте зі зменшенням коєфіцієнту попереднього ділення. Аналогічним чином, високий коефіцієнт попереднього ділення зручно використовувати при реалізації функцій із низькою швидкістю виконання, або точної синхронізації рідко виникаючих дій. Оба таймери підтримують зрівнення.

2.2.6 Послідовний приємопередавач USART

Блок-схема передавача USART показана на рис. 10. Передача данних починається записом передаваємих данних у регістр данних I/O USART(UDR). Дані пересилаються з UDR у зсувний регісир передачі у наступних випадках:

  • Новий символ записаний в UDR після того, як був виданий з регістру стоповий біт попереднього символа. Зсувний регістр завантажується миттєво.

Рис. 8 Блок схема 8-ми бітного таймеру мікроконтроллеру

Рис.9 блок-схема 16-бітного таймеру мікроконтроллера

Рис. 10 Блок-схема послідовного приємопередавача

Якщо з 10 або 11-розрядного зсувного регістру видана вся інформація(зсувний регістр передачі пустий), дані з UDR надсилаються у зсувний регістр. У цей час встановлюється біт UDRE(USART Data Register Empty) регістру статуса USART(UCSRA). При встановленому у стан 1 біті UDRE USART готовий прийняти наступний символ. Запис в UDR очищує біт UDRE. У цей самий час, коли дані пересилаються з UDR у 10(11)-розрядний зсувний регістр, біт 0 зсувного регістру скидається у стан 0(стан 0-стартовий біт), а біт 9 та 10 встановлюється у стан 1(стан 1 – стоповий біт). Також приємопередавач має налаштування для організації приємопередавача 9 бітних символів, налаштувати швидкість передачі можна за допомогою спеціального бод-генератора. Бод-генератор представляє собою дільник, генеруючий імпульси передачі із частотою, яка визначається виразом:


Де BAUDчастота в бодах, Foscчастота тактового генератору CPU, UBRRвміст регістру UBRRH та UBRRL. Для того, щоб можна було точно обирати усі швидкості прийому/передачі потрібно використовувати спеціальні частоти. Прийом виконується асинхронно, коли регістр данних заповнюється прийнятим байтом у регістрі UCSRA встановлюється біт RXC. Також USART підтримує обробку переривань по прийому та по передачі. Більш детальна інформація знаходиться у даташиті, який можна знайти на сайті виробника http:\\www.atmel.com.

3 РОЗРОБКА ПРОГРАМНОГО ЗАБЕСПЕЧЕННЯ

3.1 Розробка програмного забеспечення мікроконтроллера

Розробка програмного забеспечення мікроконтроллера починається із розподілення його ресурсів для створення ПО в цілому. Оскільки мікроконтроллер використовується у складі стенда, треба взяти на увагу ресурси, які займає стенд, і оскільки він представляє собою закінчений пристрій, треба знайти вільні ресурси, які можна використовувати, без внесення змін у схему або монтажу печатної плати. На рис. 11 зображена принципова схема стенду. Стенд має два роз’єма розширення, один системний(X1) другий періферцйний(X10). Періферійний має 2 порта які працюють на вихід, 1 порт мікроконтроллера який просто виведений на разєм розширення і 1 порт який реалізований у системному контроллері. Для реалізації логічного аналізатора можна використати порт мікроконтроллера, який виведений на розєм розширення, а для реалізації генератора слів можна використати порт А стенду. Схема розподілення ресурсів стенду показана на рис. 12.



Рис. 12 Схема розподілення ресурсів стенду

3.1.1 Розробка логічного аналізатора

Найпростіший алгоритм, за яким можна зробити реестрацію вхідної послідовності, це лінійна послідовність команд, які читають порт та запам’ятовують данні у регістри. Всьго у мікроконтроллера ATMega8515 32 регістри, тому алгоритм дозволяє прочитати та зберегти 32 стани порту, а так як команда читання порту у регістр(in R0, PINB) займає 1 такт, такий код виконується із максимальною швидкістю. Швидкість буде дорівнювати швидкості тактового генератору мікроконтроллера – 7 372 800 Гц.










Рис 13. Блок схема алгоритму найшвидшої реестрації

Наступний алгоритм менш швидкий але дозволяє зареєструвати 512 станів вхідної послідовності. Він аналогічний попередньому тільки після кожної команди читання порту додається команда збереження у память. Швидкість виконання такого алгоритму дорівнює 7 372 800/3 = 2 457 600 Гц. Незважаючи на швидкісь код такого алгоритму займає багато памяті програм.

Наступний алгоритм дозволяє зареєструвати 1024 стани вхідної послідовності, але має ще менш швидкі характеристики, та займає ще більший об’єм програмної пам’яті мікроконтроллера. Швидкість такого алгоритму 7 372 800/5 = 1 474 560 Гц.

Наступний алгоритм виконує аналогічні дії попередньому але займає набагато менше пам’яті программ. Він складається із 4-ох послідовно розташованих однакових циклів. Це зв’язано з тим, що для підсумку необхідної кількості операцій використовується однобайтовий лічильник. 1024/256 = 4 послідовно розташованих циклів. Швидкість такого алгоритму 7 372 800/8 = 921 600 Гц. Для того щоб зменшити об’єм коду потрібно використати 2-ох байтовий лічильник, але тоді швидкість зменшиться до 7 372 800/9 = 819 200 Гц.

Можна піти іншим шляхом. 1024 у HEX коді це 0400h. А якщо початкова адреса памяті данних буде кратною 0100h, для перевірки того, що цикл був виконаний 1024 рази потрібно перевіряти тільки старший байт адреси.

Наступний алгоритм реалізує передпускову реєстрацію. Оскільки невідомо, коли зявиться необхідна зміна стану пускового каналу, необхідно постійно реєструвати вхідну послідовність. Память у такому разі треба використовувати по кільцю рис. 15.

Коли виникає необхідна зміна стану пускового каналу, починається відлік зареєстрованих станів, він дорівнює:

1024 – [глибина передпускової реєстрації] (байт)








Рис. 14 Блок схема алгоритму реєстрації, яка виконується за допомогою циклів





Рис. 15 Використання памяті по кільцю

Коли вказівник стає на адрес 0700h, вказівник перенаправляється на адресу 0300h і реєстрація продовжується доки кількість зареєстрованих байт не дорівнюватиме 1024. Якщо зміна стану довго не відбувається мікроконтроллер увійде до вічного циклу тому передбачено перевірку на прийом команди “СТОП. Також алгоритм реалізує керування швидкістю реєстрації. Оскільки для виконання затримки використовується таймер, для перевірки переповнення таймеру треба читати регістр стану, потім перевіряти чи виникла подія. Якщо подія виникла – скинути подію і перезапустити таймер, а інакще – перейти на читання регістру стану таймеру і т.д. Це призводить до того, що реакція на таймер буде залежити від швидкості, яка некратна швидкості 1 циклу перевірки таймеру на наявність події. Але з аналізу лабораторного практикуму необхідні швидкості реєстрації дорівнюють 50 гц тому розбіжність в декілька тактів не буде впливати на зареєстровану послідовність.

Всі алгоритми підпрограм аналізу знаходяться у додатках.

3.1.2 Розробка генератора слів

Генератор слів повинен використовувати порт А стенду. Доступ до цього порту можна отримати тільки завдяки звертанню до пам’яті, за адресою 8000h, це виконується за 4 такти. Можна налагодити мікроконтроллер для того, щоб виконувати доступ за 3 такти, а ле для роботи із памятю потрібно знову переналогодити мікроконтроллер на 4 такти. А операції переналагоджування займуть 2 такти, це призведе до зменшення швидкості алгоритму.

Найшвидший і невеликий за обсягом програмного коду алгоритм читання з памяті та видачі у порт зображений на рис. 16


Рис 16. Блок схема алгоритму генератора слів(швидкий варіант)

Цей алгоритм не надає змогу змінювати швидкість генератору, та може працювати тільки у режимі одноразової генерації.

Наступний алгоритм дозволяє виконувати всі три режими: циклічний, одноразовий та шаговий; для перших двох дозволяє міняти швидкість генерації. Швидкість цього алгоритму набагато менша ніж у попередньому випадку, але відповідає технічному завданню. На початку алгоритму налагоджується початкова адреса ГС, потім перевіряється необхідність запуску таймера(пошаговий режим не використовує таймер). Далі йде тіло циклу, умова виходу з якого це, кінець виданих данних, або натиснення кнопки стоп у режимі цикл. Алгоритм зображений на рис. 17.




Рис. 17 Блок схема алгоритму генератора слів(повнофункціональний варіант)

3.1.3 Розробка алгоритму приємо передавача

Звязок забеспечується за допомогою синхронного/асинхронного приємо передавача RS-232. Але оскільки мікроконтроллер працює від блоку живлення 5 вольт, для звязку з ПК необхідний перетворювач рівня сигналів(рівень сигналів RS-232 – +/-12 В). Цей перетворювач існує на платі стенду. Тому для налагодження роботи із портом достатньо настроїти стенд записавши за адресою С000h число 1, це вибір другого режиму роботи послідовного порта(див. Табл. 1).

Пристрій USART має сигнали RXD та TXD, сигнал прийому та передачі відповідно. Пристрій підтримує стандартні швидкості і налашьовується за допомогою регістру UBRR. Оскільки периферія мікроконтроллеру тактується від загального тактового генератору, то швидкість передавання може бути із похибкою. Для того, щоб похибки не було у тактовому генераторі використовують спеціальні кварци із частотами кратними швидкостям передачі. Стенд EV8031 має кварц із частотою 7,3728 МГц, що відповідає 0%-ній похибці на усіх швидкостях.

Алгоритм налагодження USART складається з налагодження режиму роботи USART. Це поперше кількість стартових, стопових біт, перевірка на додавання або недодавання, кількість інформаційних біт, дозволити/ заборонити прийом і дозволити/заборонити передачу, дозволити/ заборонити обробку переривань за закінченням приймання або за закінченням передавання. Далі налагоджується швидкість записом у регістр UBRR обчисленого або взятого із таблицї даташиту [1]. У пороцессі розробки була знайдена помилка в роботі мікроконтроллера: він пошкоджує данні регістру UBRR, при виконнанні запису у інші регістри, які відносяться до налагоджування USART. Було прийнято рішення встановлювати швидкість USART останньою операцією його налагодження. В нашому випадку перевірка за додатними/недотаними числами не використовується, кількість інформаціонних біт – 8, 1 стартовий та 1 стоповий біт. Для початку передавання у порт данних необхідно зачекати доки попередній сеанс передачі закінчиться. Це виконується перевіркою біта UDRE регістру UCSRA. Далі для початку передавання байту потрібно записати його у регістр UDR. Після цього USART у фоновому режимі починає передачу і зупиняється коли байт переданий.

Для передачі масиву данних необхідно виконувати такі сеанси для кожного байту масиву.

Прийом по USART більш складний за передачу. Справа у тому, що прийом повинен бути у фоновому режимі, інакше це треба буде робити у головному циклі програми. Після прийому першого байту, треба чекати і приймати байти тільки на час називаємий таймаут, інакше якщо зв’язок раптом обірветься, або прийнятий байт буде результатом завади на лінії передачі, мікроконтроллер увійде у бекінечний цикл(зависання програми). Для цього USART має переривання RXC(Recieve complete). Коли байт надходить до рнгістру UDR спрацьовує переривання, мікроконтроллер починає виконувати обробник переривання. У обробнику перевіряється наявність першого байту команди, і якщо перший байт вірний, наступного разу виконується ініціалізація таймеру на час таймауту(цей час обчислюєтся згідно зі швидкістю прийому/передачі і кількості приймаємих байт) і піднімається прапорець, згідно з яким починається налаштовування приймаємих байт у пам’яті. Прийом продовжується доки не спрацює переривання за таймером, налаштованим на час таймауту. Обробник переривання таймеру зупиняє відлік і виконує діагностику прийнятої послідовності. Згідно з нею налаштовуються відповідні регістри, флаги і обчислюється код за яким виконується перехід до необхідного алгоритму.

3.1.4 Розробка головного циклу програми

У головному циклі програми виконується перевірка на наявність прийнятої послідовності. Якщо послідовність була прийнята і розпізнана як придатна до виконання виконується налаштовування необхідних пристроїв мікроконтроллера і перехід до необхідної підпрограми. Після виконання необхідного коду у випадку логічного аналізатора виконується передача зареєстрованих данних, у разі генератора слів відповідь, що код виконаний.

3.2 Розробка програмного забеспечення ПК

Розробка програмного забезпечення ПК починається з вибору мови програмування, та визначення, які ресурси комп’ютера і ОС необхідні для реалізації програми. Тому, для розробки програмного забеспечення була обрана мова програмування Delphi 7, а для звертання до ком порту використаний компонент SerialNG. Код цього компонента відкритий, не забороняється його використання у комерційних проектах. Також для відображення проаналізованих данних використаний стандартний компонент Chart, він дозволяє створювати графіки, та налагоджувати способ виводу. Інщі компоненти використані у програмі є загальновідомими і опис іхнього призначення можна знайти у [3].

3.2.1 Розробка інтерфейсу логічного аналізатора

Рис. 18 Інтерфейс користувача логічного аналізатора

Розробка прграмного забеспечення для ПК починається із розробки інтер фейсу користувача. Інтерфейс логічного аналізатора повинен мати елементи керування вибором частоти, вибором пкскового каналу і виглядом сиглалу запуску(за підвищенням або спадом). Головне, користувачеві повинно бути надано діаграму усіх 8-ми каналів за часом, та елементи, які дозволяють виконувати зручний перегляд та пошук необхідних послідовностей. Загальний вигляд розробленого інтерфейсу наданий на рис. 18.

3.2.2 Розробка інтерфейсу генератора слів

Інтерфейс користувача генератору слів повинен мати елементи керування режимом роботи генератора: циклічний, одноразовий та шаговий. Також він повинен дозволяти змінювати швидкість генерації, запускати та зупиняти генерацію. Головним елементом інтерфейсу генератора, є список вводу необхідної послідовності. Він повинен передбачати помилки при вводі шістнадцятирічних чисел, та налаштовуванню діапазонів. Загальний вигляд інтерфейсу користувача зображений на рис. 19.

Рис. 19 Інтерфейс користувача генератору слів

Також мова інтерфейсу яка була використана це російська.

3.2.3 Розробка інтерфейсу прийому/передачі

В усіх випадках, зв’язок виконаний через COM порт. Як і випадку із мікроконтроллером, необхідно спочатку налагодити порт. Сучасні ОС не дозволяють отримувати безпосередній доступ до портів вводу виводу, метою цього є боротьба за беспеку. Але вони надають спеціальні функції для реалізації таких дій. В данному випадку була обрана ОС Windows 2000 або XP. Вона має необхідний обсяг сервісних функцій для реалізації данної дії, їх називають API. Але при розробці за допомогою API виникли деякі проблеми. Більшість яких була звязана із великим обсягом часу для розробки стійкого коду роботи із послідовним портом. Були отримані деякі показники, але програма приймала сбійні байти, і інколи зависала. Тому було прийнято рішення використати компонент. Delphi дозволяє створювати і використовувати візуальні компоненти. Ці компоненти спрощують програмування, якщо при розробці непотрібні нестандартні компоненти, але незабороняється іх створювати або встановлювати. В інтернеті можна знайти безліч похідних кодів і багато з них можна використовувати вільно. Одним з таких компонентів є компонент SerialNG. Оскільки останнім часом велика кількість файлів “мігрує з серверу на сервер, місце знаходження данного компоненту не вказується, але його назви достатньо для пошуку за допомогою відомих пошукових серверів(також не приводиться у цілях реклами). Цей компонент дозволяє візуально налагодити роботу із послідовним портом і нескладний у використанні.

3.2.3 Розробка алгоритму програми

Загальний алгорим за яким працює програма наданий у додатках. Текст програми не містить складних алгоритмів. Можна тільки зазначити, що для фільтрації вводу були використані перехоплювачі повідомлень WM_KEYPRESSED. Обробники таких перехоплювачів змінюють код отриманого символу на неіснуючий, якщо символ виходить за рамки встановлені при розробці обробника. Оскільки код виконаний у вигляді одного програмного модуля, проблем із використанням COM порту не виникає. Треба зазначити, що доступ який надає ОС Windows 2000/XP до порту є монопольним, і якщо на момент виконання данної програми будуть використовуватись інщі програми, які отримують доступ до COM порту, доступ залишиться тільки у вашої програми. Навпаки ж якщо якась з сторонніх програм виконується і доступ до порту належить їй, данна програма не зможе отримати доступ.

4 ТЕСТУВАННЯ ПРОГРАМНОГО ЗАБЕСПЕЧЕННЯ

При тестуванні програмного забеспечення були використані сторонні програмні та апаратні засоби. Одними з таких засобів є монітор послідовних портів wTerm.(рис. 20) Він надає зручний інтерфейс для контролю, передачі, та прийманню данних за допомогою послідовних портів. Перший тест це реакція на команди які надходять із інтерфейсу користувача до стенду. Для цього треба спочатку перевірити стенд. За допомогою wTerm в порт передається необхідна послідовність керуючих слів, якщо стенд прийняв послідовність і працює правильно він повинен у відповідь передати відповідь + 1024 байти проаналізованих данних. Для перевірки правильноі працездатності інтерфейсу користувача потрідно з’єднати 2 порти ПК нульмодумним кабелем(прийом передача - схрещені), і wTerm настроїти на роботу із портом COM2. Якщо після натиснення кнопки запуску логічного аналізатора у вікні прийому wTerm з’явиться необхідна послідовність, можна спробувати передати логічному аналізатору відповідь у форматі керуючі слова + 1024 байти данних. Якщо данні зявляться у елементі перегляду логічних станів логічного аналізатору можна візуально перевірити іх на достовірність. Аналогічни чином перевіряється генератор слів, тільки для аналізу видаваємих данних використовується осцилограф або ЛА стороннього виробництва. Остаочна перевірка закінчується повноцінною працездатністю програмного забеспечення. Стенд підєднується до порту COM1 і за допомогою генератору сигналів стороннього виробництва перевіряється працездатність ЛА, аналогічно перевіряється ГС, і останній режим – ЛА+ГС можна перевірити з’єднавши шину ЛА і шину ГС перемичками. Після генерації у пошаговому режимі сгенерована послідовність повинна зявлятись у вікні логічного аналізатора.

Остаточна перевірку можна виконати за допомогою генератору сигналів послідовно змцнюючи частоту генерації, таким чином намагаючись зняти реальні технічні показники системи. Але показники які необхідні для проведення лабораторних робіт за аналізом вхідного завдання повністю відповідають показникам працесдатності системи.

Рис. 20 Загальний вигляд монітору послідовного порту wTerm

5 БІЗНЕС-ПЛАН

Резюме

В даному бізнес-плані розглядається можливість реалізації програмного продукту “Віртуальний вимірювальний комплекс”. Даний проект має потребу у інвестиції 1800 грн. Передбачається, що кошти для інвестиції будуть взяті з власного рахунку розробників даного програмного продукту. Розробка програмного продукту триватиме 4 місяці, в ній будуть задіяні 2 спеціаліста, а саме: керівник проекту та програміст. Також буде найнятий інженер для тиражування програмного продукту. Розробка програмного продукту “Віртуальний вимірювальний комплекс” буде вестися на власному комп’ютері розробників, тому кошти для оренди комп’ютеру не потрібні.

В даному бізнес-проекті обрана спрощена форма оподаткування – єдиний податок по ставці 10%. Передбачається, що проект окупиться в перший же рік його реалізації. Потенційними покупцями даного програмного продукту можуть бути:

а) Будинки відпочинку, пансіонати і готелі, підприємства громадського харчування на Чорному й Азовському морях. Для цієї групи потенційних споживачів автономне безперебійне постачання гарячою водою дозволить підвищити рівень обслуговування відпочиваючих. Особлива привабливість гелиосистем для цієї групи клієнтів обумовлена тим, що їхня діяльність протікає в основному в літній період, що є найбільш сприятливим для роботи таких систем. статистичних даних показав, що на Україні функціонує більше 3000 будинків відпочинку й санаторіїв. Для великих пансіонатів і будинків відпочинку час функціонування не обмежується тільки літнім періодом. Тому для них більше кращими будуть двоконтурні системи, що працюють в автоматичному режимі. Для невеликих туристичних баз і кемпінгів, що працюють тільки в літній період, будуть кращими економічної термосифонної системи.

б) Фермерські господарства, селянські садиби, міське населення яке має дачі, для яких використання гелиосистем для одержання гарячої води є комерційно привабливим. Економічний аналіз показує, що якщо підігрів води вироблятися за рахунок електроенергії, то при існуючій собівартості електроенергії на Україні 0.03$/кВт*година матеріальні витрати на придбання колекторів окупаються за 3 роки, якщо вартість теплового колектора не вище 150$/м2. Аналіз статистичних показав, що на Україні функціонує 32400 фермерських господарств, близько 15.9 мільйона чоловік живе в селах і селах і кожна десята міська родина має дачну ділянку. Для структур ці господарства функціонуючих тільки в літній період будуть становити інтерес економічні одноконтурні термосифонні системи гарячого водопостачання й сонячні сушарки.

в) Громадян зі статком вище за середнє частки, що мають, будинку. Аналіз статистичних даних показав, що таких людей на Україні більше 100 000 чоловік (їхній щомісячний доход перевищує 500$). Для цієї категорії громадян, по міркуваннях забезпечення європейського рівня життя, для незалежності від можливих перебоїв із централізованим постачанням гарячою водою буде привабливим закупити системи сонячних колекторів, що працюють в автоматичному режимі. Прямим підтвердженням привабливості для населення автономних енергетичних систем є успішна реалізація десятками фірм на Україні електронагрівників води. Ціна електронагрівника становить 150-200$, витрати на оплату споживаної електроенергії для гарячого водопостачання родини з 4 чоловік становлять 1$ у день. Істотним недоліком цих систем є те, що вони функціонують тільки при подачі електроенергії. На Україні крім проблеми з постачанням гарячою водою гостро коштує проблема електропостачання. З метою економії практикується відключення електроенергії по кілька разів у добу протягом декількох годин. Таким чином, електронагрівники не в змозі забезпечити дійсно автономне постачання гарячою водою.

г) Будівельних фірм які займаються будівлею елітного житла. Такі фірми будуть постійними клієнтами на ринку гелиосистем. Використання гелиосистем дозволить підвищити не тільки якісні показники комфортності житла, але і його престижність за рахунок наближення до західних стандартів. Аналіз статистичних даних показав, що на Україні працює більше сотні будівельних компаній зазначеного вище профілю. Для таких будівельних фірм уже на стадії проектування житла може бути передбачено, що гаряче водопостачання буде здійснюватися на базі двоконтурних гелиосистем працюючих безперебійно в автоматичному режимі

Ціна нашого програмного продукту, який розроблюється, буде дорівнювати 3540 грн. Прибуток з однієї копії програмного продукту складатиме 590 грн. Передбачається, що в перший рік прибуток складатиме 112690 грн. Аналогів програмного продукту “ Віртуальний вимірювальний комплекс ” на ринку СНД та у країнах ближнього зарубіжжя немає.

5.1 Доцільність виробництва продукту

Мета розробки програмного продукту “Віртуальний вимірювальний комплекс ” полягає в тому, що сучасні установи все більше використовують комп’ютерні програмні продукти з діагностичною метою. Для забезпечення точності і логічності при встановленні вольт-амперних характеристик потрібен математичний підхід.

5.2 Опис характеристик продукту

5.2.1 Найменування та призначення

Програмний продукт має назву “ Віртуальний вимірювальний комплекс ”. Система проста у використанні й інтуїтивно зрозуміла користувачеві.

Розроблений програмний продукт може бути використаний при перетворенні сонячної енергії у електричну.

5.2.2 Загальні параметри продукту

Функціонування продукту повністю забезпечується стандартною конфігурацією IBM PC/AT сумісних персональних ЕОМ, наявністю процесора CPU-Intel Pentium II, Pentium III або його аналогів AMD К6, AMD K7 і вище з об’ємом оперативної пам’яті 32 Мб, наявністю відеоадаптеру SVGA та накопичувачу на жорсткому магнітному диску об’ємом не менш ніж 400 Мб.

Програмний продукт призначений для праці в середовищі WIN32 для операційної системи Microsoft Windows 98 і вище.

5.3 Оцінка витрат на розробку

5.3.1 Визначення потреби у матеріальних та трудових ресурсах

У таблиці 5.1 приведені витрати на матеріали при розробці програмного продукту.

Таблиця 5.1 - Покупні матеріали при розробці даного продукту

Матеріали

Кількість,шт.

Вартість, грн.

Загальна вартість, грн.

Призначення

Дискети

2

3,00

6,00

Збереження програми

Папір

200

0,03

6,00

Роздруківка вихідних текстів

Література


5


0,00

0,00

Уся література була узята в бібліотеці.

Тонер для принтера

2

8,00

16,00

Роздруківка документації

Сумарна вартість, грн.

28,00

Перелік спеціалістів для реалізації проекту приведений у таблиці 5.2.

Таблиця 5.2 - Перелік спеціалістів для реалізації проекту

Спеціаліст

Кількість, чол.

Призначення

Керівник проекту

1

Консультації

Програміст

1

Напис програмного продукту

Інженер

1

Тиражування

Розрахуємо розмір оплати спеціалістів.

Трудовитрати в людино-днях обчислюється по формулі:

Т = Тофаспод, (5.1)

де Тоф – трудомісткість вивчення опису задачі та формулювання її постановки;

Та – трудомісткість на розробку алгоритму програми;

Тс – трудомісткість на складання схеми алгоритму;

Тп – трудомісткість на розробку програми;

То – трудомісткість на налагодження програми;

Тд – трудомісткість на оформлення документації.

Трудовитрати всіх видів визначаються через умовну кількість операторів (Q) програми, що обчисляються по формулі:

, (5.2)

де q – передбачувана кількість команд програми;

К – коефіцієнт складності програми (для рішення задач у реальному часі – 1,5);

Р – коефіцієнт корекції програми (від 0,4 до 0,8); n – кількість корекцій програми.

У даному програмному комплексі передбачуване число команд програми – 450. Приймаємо коефіцієнт складності програми К=1,5. При наладці програми, можливо, буде зроблено 6 корекцій, з них 4 з коефіцієнтом 0,7 і 2 з коефіцієнтом 0,3. Виходячи з цих даних, можна обчислити умовну кількість операторів програми:

Q = 450*1,5*(4*0,7+2*0,3) = 2295 умовних операторів.

Трудомісткість на вивчення опису програми і формулювання її постановки визначаємо по формулі:

, (5.3)

де Vоф – індивідуальна продуктивність виконавця (команд/години);

дані о продуктивності виконавця приведені у таблиці 6.3;

Ккв – коефіцієнт кваліфікації виконавця; v – коефіцієнт, що враховує якість опису (0,9-1,0), в нашому випадку даний коефіцієнт буде дорівнювати 1.

Таблиця 5.3 - Дані о продуктивності виконавця

Вигляд роботи

Продуктивність команд/години

Вивчення опису задачі, формулювання постановки задачі.

80

Розробка алгоритмів рішення задачі

20

Складання схеми програми

15

Розробка програми

20

Наладка програми

5

Оформлення документації

20

Коефіцієнт кваліфікації залежить від стажу роботи й дорівнює:

до 2-х років – 0.8;

від 2-х до 3-х років – 1.0;

від 3-х до 5-ти років – 1.2;

від 5-ти до 7-ми років – 1.4.

У нашому випадку коефіцієнт кваліфікації буде дорівнювати – 1,4.

Трудовитрати на інші види робіт розраховуємо по формулі:

, (5.4)

де i – вигляд роботи;

Vi – продуктивність виконавця (таблиця 6.3).

Зробимо розрахунок трудовитрат, який представлений в таблиці 5.4.

Таблиця 5.4 - Розрахунок трудовитрат

Вид роботи

Розрахункова кількість людино-діб

Вивчення опису задачі, формулювання постановки задачі

Тоф =2,56

Розробка алгоритмів рішення задачі

Та = 10,25

Складання схеми програми

Тс = 13,66

Розробка програми

Тп =10,25

Наладка програми

То = 40,98

Оформлення документації

Тд =10,25

Разом:

Т =87,95

Зарплату розробникам можна полічити виходячи з місячного окладу розробника і терміну, необхідного для розробки програмного продукту. Термін розробки визначається виходячи з 22 робочих днів в місяць:

Тм = Т/22 =87,95/22 = 3,99 місяця.

Розрахунок витрат на основну заробітну плату зображений в таблиці 5.5.

Пайова участь керівника проекту дорівнює 20 % від посадового окладу.

Для подальшої реалізації програмного продукту потрібно найняти інженера й встановити йому відрядну заробітну плату у розмірі 1 грн. за створення однієї копії.

Додаткова заробітна плата (Здоп.) вміщує до себе доплати, надбавки, гарантійні і компенсаційні виплати, передбачені законодавством.

Додаткову заробітну плату приймаємо 10 % від Зосн

Таблиця 5.5 - Розрахунок заробітної плати

Посада

Оклад, грн.

Кіл-ть, людин.

Час зайн-сті, міс.

Заробітна плата за місяць, грн.

Основна заробітна плата, грн.

Керівник проекту

300

1

4

300*0.2=60

1200*0.2=240

Програміст

200

1

4

200

800

Разом

260

1040

Таким чином додаткова заробітна плата буде дорівнювати 1040*0,1=104 грн.

5.4 Розрахунок витрат та договірної ціни продукту

При розрахунку експлуатаційних витрат необхідно визначити час налагодження програми (Тмв) на ЕОМ по наступній формулі:

, (5.5)

де m – витрати машинного часу на налагодження однієї команди (год.).

В дипломному проекті m прийнято рівним одній хвилині.

Після розрахунку Тмв буде дорівнювати

Тмв=2295/84 » 27

Вартість машинного часу визначається по наступній формулі:

Змв = См.ч·Тм.в, (5.6)

де Смч – вартість однієї машино-години, з розрахунку 1 грв за 1 год.

Таким чином вартість машинного часу буде дорівнювати Змв = 27 грв.

До відрахувань на соціальні заходи відносяться:

– відрахування на державне (обов’язкове) соціальне страхування, включаючи і відрахування на обов'язкове медичне страхування, що разом складає 2,5 % від Зосн+Здоп. Відрахування на соціальне страхування складає (1040+104)*0,025=28,60 грн.

– відрахування на державне (обов’язкове) пенсійне страхування (у Пенсійний фонд) складає 32 % від Зосн+Здоп. Відрахування на пенсійне страхування складає (1040+104)*0,32=366,08 грн.

– відрахування у Фонд сприяння зайнятості населення – 2.5 % від Зосн+Здоп. Відрахування у Фонд сприяння зайнятості населення складає (1040+104)*0,025=28,60 грн.

Відрахування на страхування від травматизму – 0,85% від Зосн.+Здоп. Дане відрахування складає (1040+104)*0,0085=9,724 грн.

Разом, відрахування на соціальні заходи складають 37,85% від Зосн. +Здоп. Відрахування на соціальні заходи складають (1040+104)*0,3785=433 грн.

До накладних витрат відносяться витрати на повне відновлення і капітальний ремонт Основного фонду (амортизаційні відрахування), орендна плата, вартість машинного часу, витрати на енергію і т.д. У даній роботі накладні витрати приймаються в розмірі 70 % від Зосн. Накладні витрати 1040*0,7=728 грн.

На підставі проведених розрахунків складаємо розрахунок витрат та договірної ціни програмного продукту, що приведений у таблиці 6.6. Необхідно врахувати те, що розрахунок витрат та договірної ціни проводиться для 100 копій програмного продукту. З цього приводу для розрахунку витрат на 1 копію програмного продукту – суму витрат необхідно поділити на 100.

Таблиця 5.6 - Розрахунок витрат та договірної ціни програмного продукту

Найменування статті витрат

Сума, грн.

1. Вартість матеріалів і покупних виробів

28,00

2. Основна заробітна плата

1040,00

3. Додаткова заробітна плата

104,00

4. Відрахування на соціальні заходи

433,00

5. Накладні витрати

728,00

6. Вартість машинного часу

27,00

7. Кошторисна вартість (сума пунктів з 1 по 6)

2360,00

8. Прибуток (25% від пункту 7)

590,00

9. Ціна розроблювача (сума пунктів 7, 8)

2950,00

10. ПДВ (20% від пункту 9)

590,00

11. Ціна продажу (сума пунктів 9, 10)

3540,00

5.5 Розрахунок витрат на тиражування

Витрати на тиражування розраховуються наступним чином:

Зтир=См.ч·Тк+Зд+Зи, (5.7)

де Тк – час копіювання системи (1 копія – 0,034 год);

Зд – вартість дискети (1 дискета –3,0 грн.);

Зи – зарплата інженера (1 грн. – 1 копія);

Смч – вартість однієї машино-години (1 грн.).

Витрати на тиражування однієї копії складуть:

Зтир=1*0,034+3,0+1=4,034 грн.

5.6 Аналіз стратегії маркетингу

Стратегія маркетингу є одним з основних техніко-економічних обґрунтувань програмного продукту, що розробляється. При освоєнні ринку підприємство використовує масовий, диференційований або цільовий маркетинг. У залежності від результатів проведеної сегментації ринку підприємство вибирає стратегію маркетингу, розробляє комплекс заходів щодо її реалізації.

Диференційований маркетинг передбачає вихід відразу на декілька сегментів ринку; розробляється відразу декілька комплексів маркетингу стосовно до кожного сегмента і прикладеної споживачам моделі виробу.

Підприємства з обмеженими ресурсами використовують, як правило, стратегію цільового маркетингу, особливо при достатній місткості вибраного сегмента і відсутності великого числа конкурентів. В нашому випадку найкраще вибрати диференційований або цільовий маркетинг.

5.6.1 Схема просування товару

Структура прямих каналів збуту підприємства, що пропонує продукт, включає наступні підрозділи:

– відділ збуту;

– збутові філіали;

– збутові контори підприємства.

Виробник, організуючі реалізацію своєї продукції через збутові філіали, домагається ряду переваг. За допомогою прямих контактів з споживачами через свій збутовий персонал, що звичайно є в складі збутового філіалу, він може провести більш концентровані і своєчасні заходи щодо просування своєї продукції. Реалізація програмного продукту може відбуватися як безпосередньо через виробника, так і через незалежних посередників (дистриб’юторів). Дистриб’ютори поділяються на наступні групи:

– функціонально – спеціалізовані дистриб’ютори;

– дистриб'ютори з товарною спеціалізацією;

– багато товарні дистриб’ютори.

Цінність оптового посередника для виробника продукції багато в чому залежить від того, як до цього посередника відносяться споживачі. Оптовий посередник, як правило, має можливість поставити вироби споживачеві швидше, ніж виробник, так як його склад звичайно привернений до підприємства споживача ближче, ніж філіал збутового органу виробника.

Послуги посередника сприяють також скороченню витрат на матеріально – технічне забезпечення і обробку облікової документації. У деяких випадках загальні витрати споживача на придбання виробів у посередника будуть нижчими, ніж у разі придбання його у виробника, який призначає ціну без урахування транспортування і страхування. Посередник же доставляє виріб споживачеві власним транспортом, включаючи вартість доставки відразу в ціну, що вигідніше споживачеві.

Програмний продукт “ Віртуальний вимірювальний комплекс ” може продаватися як безпосередньо споживачеві, так і через посередників.

5.6.2 Стимулювання продажу

Стимулювання збуту – це цілеспрямована діяльність підприємства по сприянню потенційним споживачам у виборі і придбанні продукції, що випускається ним або по створенню позитивної думки про неї.

Комплекс маркетингового стимулювання вміщує до себе крім рекламної діяльності наступні методи впливу на процес збуту виробів і послуг:

– персональний продаж;

– формування позитивної громадської думка про продукцію підприємства;

– економічне стимулювання збуту.

У нашому випадку найбільш підходять перший і останній методи, тобто персональний продаж та економічне стимулювання збуту.

Розглянемо їх детальніше.

Персональне (особисте) рекламування передбачає безпосередній контакт представника підприємства з споживачем продукції. У ході персонального продажу представник виробника допомагає споживачеві краще засвоїти переваги і вигоди виробу, що пропонується і переконує останнього придбати його або підтримати торгову марку виробника при спілкуванні з іншими споживачами.

Методами економічного стимулювання, що будуть доречними в нашому випадку, є:

- установка програмного продукту;

- повна технічна підтримка в течії року і консультації.

5.6.3 Організація реклами та витрати на неї

Рекламна діяльність становить важливу і невід’ємну частину загальної системи заходів маркетингу. Головна функція реклами полягає в індивідуалізації виробу, що рекламується, тобто виділенні його з маси конкуруючих на основі виділення якої-небудь відмітної властивості.

Шляхом формування попиту реклама активно впливає на виробництво і сприяє досягненню найбільш ефективних комерційних результатів на ринку. Рекламна діяльність підлегла загальним цілям і стратегії маркетингу, зокрема сприяє підготовці ринку до появи нового товару, підтримує початок продажу, їх розширення, досягнення максимальних об'ємів ринку, забезпечує додатковий продаж продукції в період заключної фази життєвого циклу виробу.

Рекламою для даного програмного продукту стане стаття у журналі “Радіохоббі”.

Вартість розміщення статті в даному виданні становить 60 грн.

5.7 Розробка фінансового плану

Мета даного розділу узагальнити матеріали попередніх розділів та представити їх у вартісному виразі.

В цьому розділі створюються карти прогнозу руху готівки для 1, 2 і 3-го років реалізації програмного продукту “ Віртуальний вимірювальний комплекс ”. Для першого року реалізації карта прогнозів складена на місяць, для другого по кварталах, для третього загалом на рік. У карти прогнозу вноситься графа “готівка”, тобто різниця між прибутками і сумою витрат. За допомогою цих карт будується таблиця прибутків та витрат. Карти прогнозів готівки для 1, 2 і 3-го років реалізації програмного продукту “ Віртуальний вимірювальний комплекс ” представлені, відповідно, в таблицях 6.7, 6.8 і 6.9. Рух готівки

Таблиця 5.7 - Карта руху готівки за перший рік реалізації

Прибуток, витрати

Сума, грн. по місяцях

Всього

Місяць

січень

лютий

берез

квіт

трав

черв

липень

серп

верес

жовт

лист

груд


Обсяг продаж ПП

0

0

0

5

9

10

12

15

25

31

38

46

191

Прибуток від реалізації

0

0

0

2950

5310

5900

7080

8850

14750

18290

22420

27140

112690

П

О

С

Т

І

Й

Н

І

З/п. Керівн., програм..

260

260

260

260

0,0

0,0

0,0

0,0

0,0

0,0

0,0

0,0

1040


Накл.

витр.

182

182

182

182

0,0

0,0

0,0

0,0

0,0

0,0

0,0

0,0

728


Страх. Внесок

108,25

108,25

108,25

108,25

0,0

0,0

0,0

0,0

0,0

0,0

0,0

0,0

433


Всього

550,25

550,25

550,25

550,25

0,0

0,0

0,0

0,0

0,0

0,0

0,0

0,0

2201

З

М

І

Н

Н

І

Витр. Тираж

0,0

0,0

0,0

20,17

36,306

40,34

48,408

60,51

100,85

125,054

153,292

185,564

770,494


Витр.

рекл.

0,0

0,0

60

0,0

0,0

0,0

0,0

0,0

0,0

0,0

0,0

0,0

60


Вартість машинного часу

27

27

27

27

0,0

0,0

0,0

0,0

0,0

0,0

0,0

0,0

108


Податки (10% прибутка)

0

0

0

295,0

531,0

590,0

708,0

885,0

1475,0

1829,0

2242,0

2714,0

11269,0


Всього

27

27

87

342,17

567,306

530,34

756,408

945,51

1575,85

1954,054

2395,292

2899,564

12207,494

Таблиця 5.8 - Карта руху готівки за другий рік реалізації

Прибуток та витрати

Сума, грн.

Всього


I кв.

II кв.

III кв.

IV кв.


Об’єм реалізованого продукту

50

55

60

65

220

Прибуток від реалізації

29500

32450

35400

38350

129800

Постійні витрати

Зарплата керівника

0

0

0

0

0


Накладні витрати

0

0

0

0

0


Страхові внески

0

0

0

0

0


Всього

0

60

0

0

60

Змінні витрати

Витрати на тираж

201,7

221,87

242,04

262,21

887,48


Витрати на рекламу

0

60

0

0

60


Податки

2950

3245

3540

3835

12980


Всього





13927,48

Таблиця 5.9 - Карта руху готівки за третій рік реалізації

Прибуток та витрати

Сума, грн.

Об’єм реалізованого продукту

350

Прибуток від реалізації

206500

Постійні витрати

Зарплата керівника

0


Накладні витрати

0


Страхові внески

0


Всього

60

Змінні витрати

Витрати на тираж

1411,9


Витрати на рекламу

60


Податки

20650


Всього

22121,9

За результатами розрахунків складаємо таблицю прибутків і витрат (табл. 5.10).

Таблиця 5.10 - Прибутки та витрати

Назва показнику

Сума, грн.

Всього


1 рік

2 рік

3 рік


Кількість продаж

191

220

350

761

Прибуток від продаж

112690

129800

206500

448990

Пост. Витр.

Зарплата (осн+дод)

1144

0

0

1144


Відчислення на соціальні заходи:

433

0

0

433


Вартість матеріалів

28

0

0

28


Накладні витрати при реалізації

728

0

0

728

Змін.

Витр.

Витрати на рекламу

60

60

60

180


Вартість машинного часу

108

0

0

108


Тиражування

770,494

887,48

1411,9

3069,874


Податок

11269

12980

20650

44899

Всього

14432,494

13927,48

22121,9

50481,874

Чистий” прибуток

98257,506

115872,52

184378,1

398508,126

Визначимо точку беззбитковості – це такий обсяг продаж, при котрому окупаються всі витрати.

Аналітично вона визначається по формулі:

Тб=(Зпост+Зр)/(Цед-Зпер), (5.8)

де Зпост – постійні витрати на строк реалізації ПП (грн.);

Зр – витрати на розробку ПП (грн.);

Цед – ціна одиниці продукції (грн.);

Зпер – змінні витрати на одиницю продукції.

Зпост та Зпер визначаються з таблиці прибутків та витрат (табл. 5.10). Зпост вміщує до себе заробітну плату на строк розробки програмного продукту, відчислення на соціальне страхування та накладні витрати. Зпер вміщує до себе вартість машинного часу, витрати на тиражування, витрати на рекламу на строк реалізації програмного продукту. Витрати на розробку програмного продукту складаються з витрат на матеріали, що необхідні при розробці програмного продукту й складають 28 грн. Зпост дорівнює 2305 грн. Зпер дорівнює 3357,874 грн. Ціна одиниці продукту дорівнює 3540,00 грн. Таким чином точка беззбитковості буде дорівнювати наступному значенню:

Тб=(2305+28)/(3540-3357,874)= 13

Графік беззбитковості зображений на рисунку 5.1.









Рис.5.1. Графік беззбитковості.

5.8 Висновки

Проведений аналіз дозволяє зробити висновок про доцільність розробки і продажу програмного продукту “ Віртуальний вимірювальний комплекс ” на ринку.

Собівартість продукту становить 3540 грн., а прибуток – 590 грн. за одиницю програмного продукту.

Максимальна ціна розробленого програмного продукту дорівнює:

Цmax=1.2·(Ccc+1.3·П) = 1,2·(3540+1,3*590)= 5168,4 грн.

Мінімальна ціна розробленого програмного продукту дорівнює:

Цmin=1.2·(Зтирад+1.3·П)=1,2·(4,034+0+1,3·590)= 925,2408 грн.

Виходячи з отриманих результатів, установимо ціну продажу без обліку ПДВ. Ціна програмного продукту знаходиться в межах:

925,2408 грн. <= Цпрод <= 5168,4 грн.

Приймаємо ціну продажу програмного продукту рівної 3540 грн.

За перший рік планується реалізувати 191 одиницю продукції, за другий – 220, за третій – 350. Завдяки розрахунку точці беззбитковості було визначено обсяг продаж, при котрому окупуються усі витрати, він дорівнює 13 програмним продуктам. Потенційними покупцями даного програмного продукту можуть бути різноманітні споживачі електроенергії, та користувачі ЕОМ, що будуть зацікавлені цим програмним продуктом. Рекламу даного програмного продукту планується проводить завдяки спеціалізованому журналу “Радіохоббі” у вигляді статті, в якій буде описано всі можливості даного програмного продукту.

6 ОХОРОНА ПРАЦІ ТА НАВКОЛИШНЬОГО СЕРЕДОВИЩА

В даному розділі дипломного проекту на тему Віртуальний вимірювальний комплекс на базі учбового лабораторного стенду EV8031 ” розглядаються питання створення оптимальних умов роботи оператора, користувачів розробляємого програмного продукту.

6.1 Загальні питання охорони праці

Охорона праці - це система правових, соціально-економічних, організаційно-технічних, санітарно-гігієнічних і лікувально-профілактичних заходів та засобів, спрямованих на збереження життя, здоров'я і працездатності людини у процесі трудової діяльності.

Завдання охорони праці – звести до мінімуму імовірність ураження або занедужання працюючого з одночасним створенням комфортних умов при максимальній продуктивності праці.

Для даного етапу реалізації програмного продукту питання охорони праці розглядаються щодо умов роботи оператора та науковця при дослідженні.

6.2 Характеристика виробничого середовища приміщення, де

виконується проектна робота

Приміщення міститься на третьому поверсі триповерхового будинку.

Площа приміщення повинна розраховуватись у відповідності з наступними вимогами: на одне робоче місце повинно відводитися 6 м2, об’єм 20 м3. Комп’ютери повинні розміщуватися на відстані не менше 1 м від стін. Відстань між боковими поверхнями комп’ютерів не повинна бути менше 1,2 м. Відстань між тильною поверхнею одного комп’ютера та екраном іншого – 2,5 м.

Категорія будинку за пожежонебезпекою – категорія В [6]. До цієї категорії належать приміщення, в яких знаходяться тверді пальні речовини та матеріали (при запаленні стороннім джерелом продовжують горіти після його зникнення).

Клас приміщення за пожежонебезпекою П-IІа [6].

Ступінь вогнестійкості будівельних конструкцій триповерхового будинку з категорією пожежонебезпеки В – I та II [6].

Клас приміщення за ступенем небезпеки ураження електричним струмом – приміщення з підвищеною небезпекою, тому що в ньому є можливість одночасного дотику людини до маючих з’єднання з землею металоконструкцій будинку, технологічним апаратом, механізмом та ін. з одного боку, та до металевих конструкцій – з іншого [7].

Помешкання повинно бути світлим, сухим i теплим. Підлоги роблять рівними, без вибоїв, щільними, мають не слизьку i зручну для чищення поверхню, i утримуються в чистоті. Радіатори i трубопроводи опалювальної i водопровідної систем обладнуються діелектриками (дерев’яними i т.д.) i закриваються огородженнями. Не можна застосовувати огородження з шаруватого паперового пластика i т.п.

Характеристика електричної мережі, що живить електроустаткування, приміщення: перемінний струм, частота 50 Гц, напруга 220 В, режим нейтралі – глухозаземлена нейтраль, споживча потужність комп’ютера 300 Вт.

6.3 Аналіз небезпечних і шкідливих факторів

У відповідності до ГОСТ 12.0.003–74 [9] при розробці системи, що виконується на комп’ютері, на людину впливають небезпечні та шкідливі фактори, перелік яких приведений в таблиці 7.1.

Таблиця 6.1 – Перелік небезпечних та шкідливих факторів

Найменування небезпечного та шкідливого фактора

Джерело виникнення фактора

Характер дії на людину

Нормируване значення фактора

Нормативний доку-мент

Продовження таблиці 6.1

1

2

3

4

5

1. Підвищений рівень іонізуючих випромінювань в робочій зоні

Екрани та інші по-верхні ЕОМ

Мутагенні процеси, що виникли все-редені орга-нізму

Кількість в 1см3 повітря: позитивних іонів Ф=1500..3000, легких негативних іонів Ф=3000..5000

[10]

2. Рентгенівське м’яке випроміню-вання

Монітор (ЕПТ)

Мутагенні процеси, що виникли все-редені орга-нізму

На відстані 5 см від екрану рівень випрмінювання не повинен перевіщу-вати 100 мкр/г

[11]

3. Пряма та від-бита блискість

Невірне розташу-вання ПК

Перевтома зорового аналізатору

Покажчик Р=0

[12]

1

2

3

4

5

4. Підвищений рівень статичної електрики

Діалект-рична по-верхя ком-п’ютера, джерела живлення

Ураження струмом

Е≤20 кВ/м

[13]

5.Підвищена або знижена темпе-ратура повітря

Підвищена:

недолік провітрюва-ності примі-щення, від-сутність кондиціоне-рів;

Знижена:

погана опа-люваність приміщення

Порушення терморегуля-ції організму

t=22..24°C

[14]

6. Підвищений рівень шуму на робочому місці

Друкарська техніка,вен-тиляція, ос-вітлюваль-ний прилад

Загальна втома орга-нізму

L≤50 дБА

[15]

7.Недолік при-роднього освіт-лення

Невірне розташу-вання моні-тору, вікон-них прорізів

Стомлення зорового аналізатору

КПО не нижче 1,5%

[12]

8.Підвищена яскравість світла

Невірне розташу-вання моні-тору

Стомлення зорового аналізатору

В=100 кд/м2

[11]

9.Знижена контрасність

Якість монітору

Стомлення зорового аналізатору

= 0,9%

В0 – яскравість об’єкту, Вф – яскравість фону

[11]

10.Підвищене значення напруги в електричному ланцюгу

Електрична,апаратура

Ураження електричним струмом

I=0,6 мА

[18]

11. Підвищена пульсація світ-лового потоку

Лампи ден-ного світла, монітор ЕОМ

Стомлення зору

Кп=5%

[11]

12. Виробничий пил

Статична електрика, накопичена на поверхні комп’ютера

Подразнення

слизової оболонки

ПДК=4мг/м3

[14]

13. Статична напруга

Постійна поза сидін-ня

М’язова вто-ма

Зниження стати-чної витривалості на 40%

[11]

14.Розумова перенапруга

Труднощі виробничо-го завдання

Загальне фі-зичне стом-лення, зни-ження праце-здатності

Зниження витри-валості до вихід-ного 40-50%

[11]

15. Перенапруга зорових аналі-заторів

Монітор ЕОМ

Загальне фі-зичне стом-лення

Подовження часу реакції на світло та звук 40-50%

[11]

6.4 Виробнича санітарія

Працівники обчислювального центра піддаються впливові шкідливих і небезпечних факторів виробничого середовища, електромагнітних полів, статичної електрики, шумів .

Оператори зазнають психоемоційної напруги.

6.4.1 Метереологічні умови

Метеорологічні умови на виробництві або мікроклімат визначають наступні параметри: температура (°C), рухливість (м/с), відносна вологість повітря (%) і інтенсивність теплового випромінювання.

З урахуванням параметрів мікроклімату метеоумови в приміщенні поділяються на оптимальні та допустимі.

У відповіді до ГОСТ 12.1.005–88 [14] встановлюються оптимальні умови, при виборі яких враховується пора року та категорія роботи.

За затратами енергії розробка програмного продукту є легкою фізичною роботою (сидяча робота, не потребує фізичного напруження) – категорія 1а.

Але дипломна робота характеризується напруженою розумовою працею. Тому обрані оптимальні параметри мікроклімату, що наведені у таблиці 6.2.

Таблиця 6.2 – Оптимальні праметри мікроклімату

Категорія роботи по енергозатратам

Пора року

Температура повітря, °С

Відносна вологість повітря,%

Швидкість руху повітря,

м/с

легка 1а

Холодна

22-24

40-60

0,1


Тепла

23-25



Приміщення обладнане системами централізованого опалення (загальне парове), кондиціювання повітря та штучною припливно-витяжною вентиляцією відповідно до СНиП 2.04.05-91 [17].

6.4.2 Забезпечення виробничого освітлення

При освітленні виробничих приміщень використовується природне освітлення, створюване світлом неба (пряме та відбите) , штучне, здійснюване електричними лампами, та комбіноване.

Природне освітлення підрозділяють на бічне, верхнє, комбіноване.

В приміщенні використовується бічне природне освітлення, що здійснюється крізь бічні вікна. Воно повинне забезпечувати коефіцієнт природної освітленності (КПО) не нижче 1,5% [12].

Нормовані значення КПО для будинків, розташованих у IV поясі світлового клімату визначаються за формулою:

(6.1)

де – значення КПО для III поясу світлового клімату складає 1,5%,

m – коефіцієнт світлового клімату (для міста Харкова m=0,9%),

c – коефіцієнт сонячності клімату (с=1).

=1,5*0,9*1=1,35%

Загальне освітлення повинно бути рівномірним.

Штучне освітлення приміщення з робочими місцями, обладнаними відеотерміналами ЕОМ загального та персонального користування, має бути обладнане системою загального рівномірного освітлення. Даний вид штучного освітлення і використовується на моєму робочому місці.

Дані по нормах освітлення для створення умов нормальної роботи середньої точності містяться у таблиці 6.3.

Таблиця 6.3 – Характеристика виробничого освітлення

Точність зорової роботи

Міні-маль-ний розмір об’єк-ту

Розряд зорової роботи

Під-роз-ряд зоро-вої праці

Кон-раст об’єк-ту фо-ну

Харак-терис-тика фону

Нормоване значення освітлення







Природ-не

Штучне







,%

,%

Lmin, лк

Тип ламп

Середня точність

0,5..1

IV

В

Се-ред-ній

Серед-ня

1,5

1,35

500

Га-зо-роз-ряд-ні

Комфортні умови зорової роботи забезпечуються.

Загальне освітлення має бути виконане у вигляді суцільних або переривчатих ліній світильників, що розміщуються збоку від робочих місць (переважно зліва) паралельно лінії зору працівників. Допускається застосувати світильники таких класів світлорозподілу:

- світильники прямого світла - П;

- переважно прямого світла - Н;

- переважно відбитого світла - В.

При розташуванні відеотерміналів ЕОМ за периметром приміщення лінії світильників штучного освітлення повинні розміщуватися локально над робочими місцями.

Для загального освітлення необхідно застосовувати світильники із розсіювачами та дзеркальними екранними сітками або віддзеркалювачами, укомплектовані високочастотними пускорегулювальними апаратами (ВЧ ПРА). Допускається застосовувати світильники без ВЧ ПРА тільки при використанні моделі з технічною назвою "Кососвіт". Застосування світильників без розсіювачів та екранних сіток забороняється.

Як джерело світла при штучному освітленні повинні застосовуватися, як правило, люмінесцентні лампи типу ЛБ. При обладнанні відбивного освітлення у виробничих та адміністративно-громадських приміщеннях можуть застосовуватися метало галогенові лампи потужністю до 250 Вт. Допускається у світильниках місцевого освітлення застосовувати лампи розжарювання.

Яскравість світильників загального освітлення в зоні кутів промінювання від 50 до 90 відносно вертикалі в подовжній і поперечній площинах повинна складати не більше 200кд/м2 , а захисний кут світильників повинен бути не більшим за 40.

Коефіцієнт запасу (Кз) відповідно до СНиП 11-4-79 [12] для освітлювальної установки загального освітлення слід приймати рівним 1.4.

Коефіцієнт пульсації повинен не перевищувати 5% і забезпечуватися застосуванням газорозрядних ламп у світильниках загального і місцевого освітлення. При відсутності світильників з ВЧ ПРА лампи багатолампових світильників або розташовані поруч світильники загального освітлення необхідно підключати до різних фаз трифазної мережі.

Рівень освітленості на робочому столі в зоні розташування документів має бути в межах 300-500 лк. У разі неможливості забезпечити даний рівень освітленості забезпечити даний рівень освітленості системою загального освітлення допускається застосування світильників місцевого освітлення, але при цьому не повинно бути відблисків на поверхні та збільшення освітленості екрану більше ніж 300 лк.

Світильники місцевого освітлення повинні мати напівпрозорий відбивач світла з захисним кутом не меншим за 40 .

Необхідно передбачити обмеження прямої блискості від джерела природного та штучного освітлення, при цьому яскравість поверхонь, що світяться (вікна, джерела штучного світла) і перебувають у полі зору, повинна бути не більшою за 200 кд/м2.

Необхідно обмежувати відбиту блискість шляхом правильного вибору типів світильників та розміщенням робочих місць відносно джерел природного та штучного освітлення. При цьому яскравість відблисків на екрані відеотермінала на повинна перевищувати 40 кд/м2, яскравість стелі при застосуванні системи відбивного освітлення не повинна перевищувати 200 кд/м2.

Необхідно передбачити нерівномірність розподілу яскравості в полі зору осіб, що працюють з відеотерміналом, при цьому відношення значень яскравості робочих поверхонь не повинно перевищувати 3:1, а робочих поверхонь і навколишніх предметів (стіни, обладнання) - 5:1.

Необхідно використовувати систему вимикачів, що дозволяє регулювати інтенсивність штучного освітлення залежно від інтенсивності природного, а також дозволяє освітлювати тільки потрібні для роботи зони приміщення.

Для забезпечення нормованих значень освітлення в приміщеннях з відеотерміналами ЕОМ загально та персонального користування необхідно очищати віконне скло та світильники не рідше ніж 2 рази на рік, та своєчасно проводити заміну ламп, що перегоріли.

Виробничі приміщення, в яких розташовані ЕОМ, не повинні межувати з приміщеннями, де рівні шуму та вібрації перевищують норму (механічні цехи, майстерні тощо).

6.4.3 Шум

У приміщеннях з ЕОМ рівні звукового тиску, рівні звуку та еквівалентні рівні звуку на робочих місцях повинні відповідати вимогам ГОСТ 12.1.003-83 ССБТ [15] ”Шум. Общие требования безопасности", СН 3223-85 "Санітарні норми допустимих рівнів шуму на робочих місцях з урахуванням напруженості та тяжкості праці", затверджених Міністерством охорони здоров'я України. Рівні шуму на робочих місцях осіб, що працюють з відеотерміналами та ЕОМ, визначені ДСанПІН 3.3.2-007-98[19]

Для забезпечення нормативних рівнів шуму у виробничих приміщеннях та на робочих місцях застосовуються шумопоглинальні засоби, вибір яких обґрунтовується спеціальними інженерно-акустичними розрахунками.

Як засоби шумопоглинання повинні застосовуватися негорючі або важкогорючі спеціальні перфоровані плити, панелі, мінеральна вата з максимальним коефіцієнтом звукопоглинання в межах частот 31.-8000 Гц, або інші матеріали аналогічного призначення, дозволені для оздоблення приміщень органами державного санітарно-епідеміологічного нагляду. Крім того, необхідно застосовувати підвісні стелі з аналогічними властивостями.

6.4.4 Випромінювання вiд екрана

ВДТ генерує декілька типів випромінювання, у тому числі: гамма тормозне, рентгенівське, радіочастотне, мікроволнове, видиме, ультрафіолетове й інфрачервоне випромінювання. Рівні цих випромінювань не перевищують діючих норм.

Вимоги щодо допустимих значень неіонізуючого електромагнітного випромінювання:

напруженість електромагнітного поляна відстані 50 см. Навкруги ВДТ за електричною складовою не повинна перевищувати:

у діапазоні частот 5 Гц - 2 кГц – 25 В/м,

у діапазоні частот 2 кГц - 400 кГц – 2,5 В/м,

щільність магнітного потоку не повинна перевищувати:

у діапазоні частот 5 Гц - 2 кГц – 250 нТл,

у діапазоні частот 2 кГц - 400 кГц – 25 нТл,

поверхневий електростатичний потенціал не повинен перевищувати 500 В.

Конструктивне рішення екрана дисплея таке, що рентгенівське випромінювання від екрана на відстані 10 см не перевищує 100 мкР/г [19].

У помешканнях із дисплеями необхідно контролювати аероіонізацію. У таблиці 6.4 наведені рівні іонізації повітря робочої зони обчислювального центру (ОЦ).

Таблиця 6.4 - Рівні іонізації повітря робочої зони ОЦ

Рівні

Кількість іонів в 1 см повітря



n+

n-

Мінімально необхідні

400

600

Оптимальні

1500-3000

3000-5000

Максимально допустимі

50000

50000

Варто враховувати, що м'яке рентгенівське випромінювання, що виникає при напрузі на аноді 20-22 кВ, а також напруга на струмоведучих ділянках схеми викликає іонізацію повітря з утворенням позитивних іонів, що вважаються несприятливими для людини.

6.5 Техніка безпеки

Тому що лабораторія, де знаходяться ЕОМ, не є помешканням із підвищеним утриманням механічних, теплових або радіаційних небезпек, але є споживачем електричної енергії (трифазна мережа перемінного струму напругою 220 В та частотою 50 Гц), то в даному помешканні є небезпека поразки людини електричним струмом. Тому при розгляді питань техніки безпеки обмежимося розглядом електробезпеки.

Передбачено такі міри електробезпеки:

– конструктивні заходи електробезпеки;

– схемно-конструктивні заходи електробезпеки;

– експлуатаційні заходи електробезпеки.

Конструктивні заходи безпеки спрямовані на запобігання можливості дотику людини до струмоведучих частин.

Для усунення можливості дотику оператора до струмоведучих частин, усі рубильники встановлені в закритих корпусах, усі струмоведучі частини поміщені в захисний корпус або мають захисний прошарок ізоляції, що виключає можливість дотику до них, застосовується блоковий монтаж. Живлячий електричний ланцюг має ізоляцію, виконану відповідно до ГОСТ 14254-80 [20]. Ступінь захисту устаткування відповідає IР44

(де 4 захист від твердих тіл розміром більш 1 мм; 4 – захист від бризок) відповідно до ПУЭ-87 [7].

Відповідно до ГОСТ 12.2.007.0-75* [21] приймаємо I клас захисту від поразки електричним струмом обслуговуючого персоналу тому, що комп'ютер має робочу ізоляцію й елементи занулення.

Схемно-конструктивні заходи електробезпеки забезпечують безпеку дотику людини до металевих не струмоведучих частин електричних апаратів при випадковому пробої їхньої ізоляції і виникнення електричного потенціалу на них.

Живлення здійснюється від трьох провідної мережі: фазовий дріт, нульовий робочий дріт, нульовий захисний дріт.

Тому що напруга менше 1000 В, але більше 42 В, то відповідно до ГОСТ 12.1.030-81* [22] із метою захисту від поразки електричним струмом застосовуємо занулення, тому що лабораторія є помешканням із підвищеною небезпекою поразки людини електричним струмом, так як можливий одночасний дотик людини до металоконструкцій будинків і т.п., що мають з’єднання з землею з одного боку, і до металевих корпусів електронного устаткування – з іншого.

Занулення – навмисне електричне з’єднання з нульовим захисним провідником металевих не струмоведучих частин, що можуть виявитися під напругою.

Принцип дії занулення – перетворення пробою на корпус в однофазне коротке замикання з метою викликати великий струм, здатний забезпечити спрацьовування захисту і тим самим автоматично відключити ушкоджену установку від живлячої мережі. Таким захистом є: плавкі запобіжники, що здійснюють захист одночасно від струмів короткого замикання і перевантаження.

Занулення потребує наявності в мережі нульового дроту, глухого заземлення нейтралі джерела струму і повторного заземлення нульового дроту (рис. 6.1).

Рис. 6.1. Принципова схема занулення

1 - корпус електроустановки;

2 - апарати захисту від струмів КЗ (запобіжники);

Ro - опір заземлення середньої точки обмотки джерела струму;

Rп - опір повторного заземлювача нульового захисного провідника;

Iк - струм короткого замикання;

Iн - частина струму короткого замикання, що протікає через нульовий захисний провідник;

Iз - частина струму короткого замикання, що протікає через землю.

По засобу захисту від поразки електричним струмом проектована система відноситься до I класу відповідно до ГОСТ 12.2.007.0-75* [21].

Призначення елементів занулення:

– призначення нульового захисного провідника – забезпечити необхідне для відключення установки значення струму однофазного короткого замикання шляхом створення для цього струму ланцюга з малим опором;

– призначення заземлення середньої точки – зниження напруги занулених корпусів (а отже, нульового захисного провідника) щодо землі до безпечного значення при замиканні фази на землю;

– призначення повторного заземлення захисного провідника – зниження напруги щодо землі занулених конструкцій у період замикання фази на корпус як при справній схемі занулення, так і у випадку обриву нульового захисного дроту.

Таким чином, занулення здійснює дві захисних дії – швидке автоматичне відключення ушкодженої установки від живлячої мережі і зниження напруги занулених металевих не струмоведучих частин, що виявилися під напругою, щодо землі.

Первинним джерелом живлення ПЕОМ є трьохпровідна мережа: фазовий дріт, нульовий робочий дріт, нульовий захисний дріт. Електроживлення здійснюється від електроустановки (трансформатора) із регульованою напругою під навантаженням. Напруга мережі подається в розподільну шафу.

У помешканні лабораторії прокладена шина повторного захисного заземлення (заземлюєчий провідник) виконана відповідно до ГОСТ 12.1.030 81* [22], що металево з’єднується з заземленою нейтраллю електроустаткування.

Опір заземлюючого пристрою, до якого приєднана нейтраль, не більш 0,6 Ом. Шина повторного захисного заземлювача доступна для огляду.

Для роботи з пристроями під високою напругою необхідні наступні запобіжні заходи:

– не підключати і не відключати рознімання кабелів при напрузі мережі;

– технічне обслуговування і ремонтні роботи допускається виробляти тільки при виключеному живленні мережі;

– до роботи допускаються особи, які навчені і які мають групи допуску до роботи на машинах відповідно до ПУЭ-87 [7].

6.6 Пожежна безпека

Пожежна безпека – стан об'єкта при якому із установленою ймовірністю виключається можливість виникнення і розвитку пожежі, а також забезпечується захист матеріальних цінностей.

Причинами, що можуть викликати пожежу в розглянутому

помешканні, є:

– несправність електропроводки і приладів;

– коротке замикання електричних ланцюгів;

– перегрів апаратури;

– блискавка.

Помешкання обчислювального центру по пожежній безпеці відноситься до категорії В відповідно до ОНТП-24-86 [6], тому що в обігу знаходяться тверді спалимі речовини і матеріали. Ступінь вогнестійкості будинку – II відповідно до СНиП 2.01.02-85 [8], клас помешкання по пожежній небезпеці П-IIа, відповідно до ПУЭ-87 [7].

Пожежна безпека відповідно до ГОСТ 12.1.004-91 [16] забезпечується системами запобігання пожежі, пожежного захисту, організаційно-технічними заходами.

Система запобігання пожежі:

– контроль і профілактика ізоляції;

– наявність плавких вставок і запобіжників в електронному устаткуванні;

– для захисту від статичної напруги використовується заземлення;

– захист від блискавок будівель і устаткування.

Для даного класу будівель і місцевості із середньою грозовою діяльністю 10 і більш грозових годин у рік, тобто для умов м. Харкова встановлена III категорія захисту від блискавок.

Ступінь захисту відповідному класу помешкання П II-а IР44 для устаткування і IР2Х для світильників.

Система пожежного захисту:

– аварійне відключення і переключення апаратури;

– наявність первинних засобів пожежегасіння, вогнегасників ОП-5, тому що вуглекислота має погану електропровідність, або порошкових вогнегасників;

– система оповіщення, світлова і звукова сигналізація;

– захист легкозаймистих частин устаткування, конструкцій захисними матеріалами;

– використання негорючих матеріалів для акустичної обробки стін і стель;

– у помешканнях, де немає робочого персоналу, встановлена автоматична система пожежного захисту.

Для успішної евакуації персоналу при пожежі розміри дверей робочого помешкання повинні бути наступними: ширина дверей не менше 1,5 м., висота дверей не менше 2,0 м., ширина коридору 1,8 м.; робоче помешкання повинно мати два виходи; відстань від найбільше віддаленого робочого місця не повинне перевищувати 100 м.

Організаційні заходи пожежної профілактики:

– навчання персоналу правилам пожежної безпеки;

– видання необхідних інструкцій і плакатів, плану евакуації персоналу у випадку пожежі.

Будівля обчислювального центру відповідає вимогам пожежної безпеки.

6.7 Охорона навколишнього середовища

При вирішенні технічних задач необхідно приділяти особливу увагу питанню взаємодії виробничої середи з навколишньою природною середою. Результат хозяйственної діяльності людини сказується вже не тільки в локальному, але й у регіональному, а у ряді випадків і глобальному масштабах. Охорона навколишнього середовища становиться важливою соціальною та економічною проблемою.

На порозі ІІІ тисячоліття людство знаходиться з досить суперечливим надбанням. З одного боку-бурхливі темпи загальнолюдського прогресу, а з другого-його негативні наслідки прямо протилежної спрямованості. Останні проявляються, насамперед, у надмірному забрудненні навколишнього середовища й інтенсивній його деградації.

В законі Украйни про охорону навколишнього середовища регламентується «Законом про охорону навколишнього природного середовища, 1991р. При виконанні дипломної роботи утворюються тверді побутові відходи (папір, канцелярські вироби та інші), а також комп’ютерні та інші види організаційної техніки, яка відпрацювала свій термін. Вони повинні утилізовуватися на полігонах твердих побутових відходів з максимальним використанням в якості вторинних ресурсів.

6.8 Висновок

Дотримання наведених в таблицях 6.1, 6.2, 6.3 нормативних значень параметрів шкідливих та небезпечних факторів, оптимальних параметрів мікроклімату, норм освітлення дозволить забезпечити безпечні умови праці користувача ЕОМ.

СПИСОК ДЖЕРЕЛ ІНФОРМАЦІЇ

  1. Datasheet ATMega8515 www.atmel.com.

  2. Техническое описание стенда EV8031.

  3. М.Е. Фленов, Библія програміста (Delphi), Москва, 2008, 349с.

  4. Стив Тейксейра, Ксавье Пачеко, Borland Delphi 6. Руководство разработчика, Питер, 2008, 1120с.

  5. Парижский С.М., Delphi. Только практика, Питер, 2008, 208 с.

  6. ОНТП-24-86, МВД СССР. "Общесоюзные нормы технологического проектирования. Определение категорий зданий и сооружений по взрывопожарной и пожарной опасности. " - М.: 1986.

  7. ПУЭ-87 . Правила установки электроустройств. М.:Энергоатомиздат 1987г.

  8. СНиП 2.01.02-85. " Строительные нормы и правила. Противопожарные нормы проектирования зданий и сооружений" -М.:Стройиздат.,1986 р.

  9. 12.0.003–74* “ССБТ. Опасные и вредные производственные факторы. Классификация.” 1978 (с 01.01.76). Переиздание (сентябрь 1999 г.) с Изменением № 1, утвержденным в октябре 1978 г. (ИУС 11-78).

  10. СН 2152-80 "Санітарно-гігієнічні норми допустимих рівнів іонізації повітря виробничих та громадських приміщень"

  11. ДНАОП 0.00 – 1.31 – 99. Правила охорони праці під час експлуатації електронно-обчислювальних машин.

  12. СНиП 11-4-79 " Строительные нормы и правила. Естественное и искусственное освещение"-М.:Стройиздат.,1980 р.

  13. ГОСТ 12.1.045 "ССБТ. Электростатические поля. Допустимые уровни на рабочих местах и требования к проведению контроля"

  14. ГОСТ 12.1.005-88 "ССБТ Общие санитарно-гигиенические требования к воздуху рабочей зоны"-Введ. 01.01.89.

  15. ГОСТ 12.1.003-83 "ССБТ Шум. Общие требования безопасности"-Введ. 01.07.84.

  16. ГОСТ 12.1.004-91." ССБТ. Пожарная безопасность. Общие требования".  Введ. 01.07.92.

  17. СНиП 2.04.05-91 " Строительные нормы и правила. Отопление, вентиляция и кондиционирование воздуха"-М.:Стройиздат.,1987 р.

  18. ГОСТ 12.1.038-82 "ССБТ Электробезопасность. Предельно-допустимые уровни напряжения прикосновения и токов". -Введ. 01.07.83.

  19. ДСанПіН З.З.2. 007 1998. Державні санітарні правила і норми роботи з візуальними дисплейним терміналами електронно-обчислювальних машин.

  20. ГОСТ 14254-80. Электрооборудование напряжением до 1000 В. Оболочки. Степени защиты.  Введ. 01.01.81.

  21. ГОСТ 12.2.007.0-75*. ССБТ. Изделия электротехнические. Общие требования безопасности.  Введ. 01.01.78.

  22. ГОСТ 12.1.030-81*. ССБТ. Электробезопасность. Защитное заземление. Зануление.  Введ. 01.07.82.

  23. Перерва П.Г. Управление промышленным маркетингом. Харьков, Основа, 1993.

  24. Современный маркетинг / под ред. Е.К.Хруцкого. – М.: Прогресс, 1991.

ВИСНОВКИ

У ході виконання научно дослідницької роботи були розглянуті основні технічні характеристики лабораторного стенду EV8031, а також розглянутий лабораторний практикум з курсу мікроконтроллерних систем.

У ході роботи були розглянуті основні характеристики та ресурси мікроконтроллера ATMega8515 та стенду EV8031. Були обчислені його швидкістні характеристики, які необхідні для розробки віртуального вимірювального комплексу.

Було зясовано, що дуже складно побудувати такі пристрої як логічний аналізатор та генератор слів на програмній базі мікроконтроллеру. Але отримані характеристики повністю вдовільнили постановлену задачу.

Одночасний доступ двох програм до послідовного поорту неможливий, тому для вирішення задачі було прийнято рішення обьєднати дві програми у один програмний модуль, але з двома вікнами, для зручності у користуванні.

Побудова інтерфейсу була взята із багатовідомої системи моделювання електронних пристроїв Electronic Workbench, де є аналогічні віртуальні пристрої.

У результаті тестування створеного програмного забеспечення, були отримані вдовільні показники. Як було зазначено вище, використання таймеру не призводить до великоі похибки при вимірюванні на швидкості вхідної послідовності 50Гц.

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ

НАЦІОНАЛЬНИЙ ТЕХНІЧНИЙ УНІВЕРСИТЕТ

ХАРКІВСЬКИЙ ПОЛІТЕХНІЧНИЙ ІНСТИТУТ”

Кафедра: Обчислювальна техніка та програмування

ЗАТВЕРДЖУЮ

Завідуючий кафедрою ОТП

__________ /xxxx.А./

"___" __________ 2009р.

ВІРТУАЛЬНИЙ ВИМІРЮВАЛЬНИЙ КОМПЛЕКС НА БАЗІ УЧБОВОГО ЛАБОРАТОРНОГО СТЕНДУ EV8031

Текст програми

ЛИСТ ЗАТВЕРДЖЕННЯ

xxxx.03077-01 12 01-1-ЛЗ



РОЗРОБНИКИ

Керівник проекту

_____________/xxx./

_____”_________2009р.

Виконавець

Студент групи x

/xxxxxx./

_____”____________2009р.


Харків 2009

ЗАТВЕРДЖЕНО

xxx.03077-01 12 01-1-ЛЗ

ВІРТУАЛЬНИЙ ВИМІРЮВАЛЬНИЙ КОМПЛЕКС НА БАЗІ УЧБОВОГО ЛАБОРАТОРНОГО СТЕНДУ EV8031

Текст програми

xxxxx.03077-01 12 01-1

Аркушів _48_

Харків 2009

ЗМІСТ

1 ТЕКСТ ПРОГРАМНОГО ЗАБЕСПЕЧЕННЯ ПК

1.1 Текст програмного модуля логічного аналізатора, Unit1.pas

2 Тексти програмного модуля генератора слів, Unit2.pas

3 Текст програмного модуля головного вікна ВВК, , Unit3.pas

2 ТЕКСТ ПРОГРАМНОГО ЗАБЕСПЕЧЕННЯ МК

2.1 Текст програмного забеспечення ВВК мікроконтроллера, main.asm

1 ТЕКСТ ПРОГРАМНОГО ЗАБЕСПЕЧЕННЯ ПК

1.1 Текст програмного модуля логічного аналізатора, Unit1.pas

Ім’я данного файлу : Unit1.pas

Функціональне призначення : програмне забеспечення ПК, модуль логічного аналізатора

Файл створений для дипломного проекта захисту кваліфікації фахівця

За фахом : Системне програмування;

Тема проекту : Віртуальний вимірювальний комплекс на базі учбового лабораторного стенду;

Керівник : М.В. Скородєлов, викладач кафедри ОТП;

Розробник : О.О. Ісмаілов, студент групи КІТ-23а;

Рік розробки : 2009.

unit Unit1;

interface

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, TeEngine, Series, ExtCtrls, TeeProcs, Chart, StdCtrls, ComCtrls, Buttons, ComDrv32, SerialNG, Mask, Math;

type TForm1 = class(TForm)

Chart1: TChart;

Series1: TLineSeries;

Series2: TLineSeries;

Series3: TLineSeries;

Series4: TLineSeries;

Series5: TLineSeries;

Series6: TLineSeries;

Series7: TLineSeries;

Series8: TLineSeries;

ColorBox1: TColorBox;

ColorBox2: TColorBox;

ColorBox3: TColorBox;

ColorBox4: TColorBox;

ColorBox5: TColorBox;

ColorBox6: TColorBox;

ColorBox7: TColorBox;

ColorBox8: TColorBox;

StaticText1: TStaticText;

StaticText2: TStaticText;

StaticText3: TStaticText;

StaticText4: TStaticText;

StaticText5: TStaticText;

StaticText6: TStaticText;

StaticText7: TStaticText;

StaticText8: TStaticText;

ScrollBar1: TScrollBar;

SpeedButton1: TSpeedButton;

SpeedButton2: TSpeedButton;

StaticText9: TStaticText;

GroupBox1: TGroupBox;

RadioButton1: TRadioButton;

RadioButton2: TRadioButton;

RadioButton3: TRadioButton;

ComboBox1: TComboBox;

ComboBox2: TComboBox;

BitBtn1: TBitBtn;

SerialPortNG1: TSerialPortNG;

TrackBar1: TTrackBar;

Edit1: TEdit;

Label1: TLabel;

Label2: TLabel;

MaskEdit1: TMaskEdit;

Label3: TLabel;

Label4: TLabel;

MaskEdit2: TMaskEdit;

Label5: TLabel;

procedure FormCreate(Sender: TObject);

procedure ScrollChange(Sender: TObject);

procedure BitBtn2Click(Sender: TObject);

procedure SpeedButton1Click(

Sender: TObject);

procedure SpeedButton2Click(Sender: TObject);

procedure FormClose(Sender: TObject; var Action: TCloseAction);

procedure BitBtn1Click(Sender: TObject);

procedure SerialPortNG1RxClusterEvent(Sender: TObject);

procedure TrackBar1Change(Sender: TObject);

procedure ComboBox2Change(Sender: TObject);

procedure MaskEdit2Change(Sender: TObject);

private

{ Private declarations }

scale:word;

dwError:dword;

pName:PWideChar;

flag:byte;

function StrToIntM(str:string):dword;

public

{ Public declarations }

end;

TArrBuf512 = array[0..511] of byte;

Var Form1: TForm1;

implementation

uses SerialNGBasic;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);

var

i:word;

s:string;

begin

SerialPortNG1.Active := True;

scale := 500;

ScrollBar1.Visible := False;

Chart1.BottomAxis.Minimum := 0;

Chart1.BottomAxis.Maximum := scale;

Series1.Clear;

Series2.Clear;

Series3.Clear;

Series4.Clear;

Series5.Clear;

Series6.Clear;

Series7.Clear;

Series8.Clear;

for i := 0 to 500 do

begin

Series1.AddXY(i, ((i mod 1)*0.5)+0.25, '', ColorBox1.Selected);

Series2.AddXY(i, ((i mod 2)*0.5)+1.25, '', ColorBox2.Selected);

Series3.AddXY(i, ((i mod 2)*0.5)+2.25, '', ColorBox3.Selected);

Series4.AddXY(i, ((i mod 2)*0.5)+3.25, '', ColorBox4.Selected);

Series5.AddXY(i, ((i mod 2)*0.5)+4.25, '', ColorBox5.Selected);

Series6.AddXY(i, ((i mod 2)*0.5)+5.25, '', ColorBox6.Selected);

Series7.AddXY(i, ((i mod 2)*0.5)+6.25, '', ColorBox7.Selected);

Series8.AddXY(i, ((i mod 2)*0.5)+7.25, '', ColorBox8.Selected);

end;

end;

procedure TForm1.ScrollChange(Sender: TObject);

begin

Chart1.BottomAxis.Minimum := ScrollBar1.Position;

Chart1.BottomAxis.Maximum := ScrollBar1.Position + scale;

end;

procedure TForm1.BitBtn2Click(Sender: TObject);

begin

Close;

end;

procedure TForm1.SpeedButton1Click(Sender: TObject);

begin

if (scale < 500) then

scale := scale + 10;

if (scale = 500) then

ScrollBar1.Visible := False

else

ScrollBar1.Visible := True;

ScrollBar1.Max := 500 - scale;

if (ScrollBar1.Position > (500 - scale)) then

ScrollBar1.Position := (500 - scale);

Chart1.BottomAxis.Minimum := ScrollBar1.Position;

Chart1.BottomAxis.Maximum := ScrollBar1.Position + scale;

end;

procedure TForm1.SpeedButton2Click(Sender: TObject);

begin

if (scale > 0) then

scale := scale - 10;

if (scale = 500) then

ScrollBar1.Visible := False

else

ScrollBar1.Visible := True;

ScrollBar1.Max := 500 - scale;

Chart1.BottomAxis.Minimum := ScrollBar1.Position;

Chart1.BottomAxis.Maximum := ScrollBar1.Position + scale;

end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);

begin

SerialPortNG1.Active := False;

end;

procedure TForm1.BitBtn1Click(Sender: TObject);

var

s:string;

begin

if (ComboBox2.ItemIndex <> -1) and (ComboBox1.ItemIndex <> -1) then

begin

s := ' ';

s[1] := char($FF);

s[2] := char($AA);

s[3] := char($3A);

s[4] := char((((ComboBox1.ItemIndex shl 1) or byte(RadioButton2.Checked))or (ComboBox2.ItemIndex shl 5)));

SerialPortNG1.SendString(s);

flag := 1;

end

else

MessageBox(0, 'Необходимо указать номер пускового канала и выбрать тактовый генератор!', 'Ошибка', MB_OK or MB_ICONINFORMATION);

end;

procedure TForm1.SerialPortNG1RxClusterEvent(

Sender: TObject);

var

i:integer;

n:integer;

p:^TArrBuf512;

size:integer;

error:DWord;

begin

n := SerialPortNG1.NextClusterSize;

if n >= 0 then

begin

p := SerialPortNG1.ReadNextCluster(size, error);

if (flag=1) then

begin

Series1.Clear;

Series2.Clear;

Series3.Clear;

Series4.Clear;

Series5.Clear;

Series6.Clear;

Series7.Clear;

Series8.Clear;

for i := 0 to n do

begin

Series8.AddXY(i, -(((p^[i] shr 7) and 1)*0.5)+7.75, '', ColorBox8.Selected);

Series7.AddXY(i, -(((p^[i] shr 6) and 1)*0.5)+6.75, '', ColorBox7.Selected);

Series6.AddXY(i, -(((p^[i] shr 5) and 1)*0.5)+5.75, '', ColorBox6.Selected);

Series5.AddXY(i, -(((p^[i] shr 4) and 1)*0.5)+4.75, '', ColorBox5.Selected);

Series4.AddXY(i, -(((p^[i] shr 3) and 1)*0.5)+3.75, '', ColorBox4.Selected);

Series3.AddXY(i, -(((p^[i] shr 2) and 1)*0.5)+2.75, '', ColorBox3.Selected);

Series2.AddXY(i, -(((p^[i] shr 1) and 1)*0.5)+1.75, '', ColorBox2.Selected);

Series1.AddXY(i, -(( p^[i] and 1)*0.5)+0.75, '', ColorBox1.Selected);

end;

flag := 0;

end;

end;

end;

procedure TForm1.TrackBar1Change(Sender: TObject);

begin

Edit1.Text := IntToStr(TrackBar1.Position);

end;

procedure TForm1.ComboBox2Change(Sender: TObject);

begin

if ComboBox2.ItemIndex = 7 then

begin

MaskEdit1.Visible := true;

Label3.Visible := true;

MaskEdit1.Text := '';

end

else

begin

MaskEdit1.Visible := False;

Label3.Visible := false;

end;

end;

procedure TForm1.MaskEdit2Change(Sender: TObject);

begin

if MaskEdit2.Text <> '' then

if StrToIntM(MaskEdit2.Text) > 65535 then

MaskEdit2.Text := '65535';

end;

function TForm1.StrToIntM(str:string):dword;

var

i,num:integer;

begin

num := 0;

if (length(str) > 0) and (length(str) < 6) then

for i := length(str) downto 1 do

if ((str[i] >= '0')and(str[i] <= '9')) then

begin

num := num +

(byte(str[i])-byte('0'))*

Round(Power(10,length(str)-i));

end;

StrToIntM := num;

end;

end.

2 Тексти програмного модуля генератора слів, Unit2.pas

Ім’я данного файлу : Unit2.pas

Функціональне призначення : програмне забеспечення ПК, модуль генератора слів

Файл створений для дипломного проекта захисту кваліфікації фахівця

За фахом : Системне програмування;

Тема проекту : Віртуальний вимірювальний комплекс на базі учбового лабораторного стенду;

Керівник : М.В. Скородєлов, викладач кафедри ОТП;

Розробник : О.О. Ісмаілов, студент групи КІТ-23а;

Рік розробки : 2009.

unit Unit2;

interface

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Buttons, Mask;

type TForm2 = class(TForm)

ListBox1: TListBox;

RadioGroup1: TRadioGroup;

BitBtn1: TBitBtn;

BitBtn2: TBitBtn;

CheckBox1: TCheckBox;

Label1: TLabel;

GroupBox1: TGroupBox;

RadioButton1: TRadioButton;

RadioButton2: TRadioButton;

ComboBox1: TComboBox;

Label5: TLabel;

Label6: TLabel;

MaskEdit1: TMaskEdit;

Label2: TLabel;

MaskEdit2: TMaskEdit;

MaskEdit3: TMaskEdit;

Label3: TLabel;

Label4: TLabel;

MaskEdit4: TMaskEdit;

MaskEdit5: TMaskEdit;

procedure RadioButton1Click(Sender: TObject);

procedure RadioButton2Click(Sender: TObject);

procedure ListBoxClick(Sender: TObject);

procedure Form2Create(Sender: TObject);

procedure CheckBox1Click(Sender: TObject);

procedure MaskEdit1KeyPress(Sender: TObject; var Key: Char);

procedure MaskEdit1Change(Sender: TObject);

procedure MaskEdit2KeyPress(Sender: TObject; var Key: Char);

procedure MaskEdit2Change(Sender: TObject);

procedure MaskEdit3KeyPress(Sender: TObject; var Key: Char);

procedure MaskEdit4KeyPress(Sender: TObject; var Key: Char);

procedure MaskEdit4Change(Sender: TObject);

procedure MaskEdit3Change(Sender: TObject);

procedure BitBtn1Click(Sender: TObject);

procedure BitBtn2Click(Sender: TObject);

private

{ Private declarations }

index:integer;

count:integer;

buf:array[0..1023]of byte;

function StrToHex(str:string):integer;

public

{ Public declarations }

end;

var Form2: TForm2;

implementation

uses Unit1;

{$R *.dfm}

procedure TForm2.RadioButton1Click(Sender: TObject);

begin

MaskEdit5.Enabled := false;

Label6.Enabled := false;

ComboBox1.Enabled := true;

Label5.Enabled := true;

end;

procedure TForm2.RadioButton2Click(Sender: TObject);

begin

ComboBox1.Enabled := false;

Label5.Enabled := false;

MaskEdit5.Enabled := true;

Label6.Enabled := true;

end;

procedure TForm2.ListBoxClick(Sender: TObject);

var

s:string;

begin

s:=

ListBox1.Items.ValueFromIndex[ListBox1.ItemIndex];

index := ListBox1.ItemIndex;

MaskEdit1.Text := s[4]+s[5];

end;

procedure TForm2.Form2Create(Sender: TObject);

var

i,j:integer;

s,s1:string;

begin

count := 1024;

index := 0;

ListBox1.Clear;

for i := 0 to count-1 do

begin

s := Format('%x',[i]);

for j := 1 to 3-length(s) do

s1 := s1 + '0';

for j := 1 to length(s) do

s1 := s1 + s[j];

ListBox1.Items.Add(s1+':00');

s1 := '';

buf[i] := 0;

end;

end;

procedure TForm2.CheckBox1Click(Sender: TObject);

begin

if (CheckBox1.Checked = True) then

Form1.Visible := true;

end;

procedure TForm2.MaskEdit1KeyPress(Sender: TObject; var Key: Char);

begin

if not(((Key >= '0') and (Key <= '9')) or

((Key >= 'A') and (Key <= 'F')) or

((Key >= 'a') and (Key <= 'f'))) then

Key := ' ';

if (Key >= 'a') and (Key <= 'f') then

Key := UpCase(Key)

end;

procedure TForm2.MaskEdit1Change(Sender: TObject);

var

s,s1,s2:string;

i:byte;

begin

s1 := '';

s := Format('%x',[index]);

for i := 1 to 3-length(s) do

s1 := s1 + '0';

for i := 1 to length(s) do

s1 := s1 + s[i];

s2 := s1 + ':';

s1 := '';

s := Format('%x',[StrToHex(MaskEdit1.Text)]);

for i := 1 to 2-length(s) do

s1 := s1 + '0';

for i := 1 to length(s) do

s1 := s1 + s[i];

buf[index] := StrToHex(MaskEdit1.Text);

s2 := s2 + s1;

ListBox1.Items.Strings[index] := s2;

end;

procedure TForm2.MaskEdit2KeyPress(Sender: TObject; var Key: Char);

var

i,j:integer;

s,s1:string;

begin

if not((Key >= '0') and (Key <= '9') or

(Key = #13)) then

Key := ' ';

if Key = #13 then

begin

ListBox1.Clear;

for i := 0 to count-1 do

begin

s := Format('%x',[i]);

for j := 1 to 3-length(s) do

s1 := s1 + '0';

for j := 1 to length(s) do

s1 := s1 + s[j];

ListBox1.Items.Add(s1+':00');

s1 := '';

end;

end;

end;

procedure TForm2.MaskEdit2Change(Sender: TObject);

var

i:integer;

s,s1:string;

begin

s1 := '';

s := MaskEdit2.Text;

if s <> '' then

for i := 1 to length(s) do

if s[i] <> ' ' then s1 := s1 + s[i];

if s1 <> '' then

begin

if (StrToInt(s1) > 1024) then

begin

MaskEdit2.Text := '1024';

count := 1024;

end;

count := StrToInt(s1);

end;

end;

function TForm2.StrToHex(str:string):integer;

var

i,num:integer;

begin

num := 0;

if (length(str) > 0) and (length(str) < 5) then

for i := length(str) downto 1 do

begin

if ((str[i] >= '0')and(str[i] <= '9')) then

num := num + (byte(str[i])-byte('0'))shl(4*(length(str)-i));

if ((str[i] >= 'A')and(str[i] <= 'F')) then

num := num + (byte(str[i])-byte('A')+10)shl(4*(length(str)-i));

if ((str[i] >= 'a')and(str[i] <= 'f')) then

num := num + (byte(str[i])-byte('a')+10)shl(4*(length(str)-i));

end;

StrToHex := num;

end;

procedure TForm2.MaskEdit3KeyPress(Sender: TObject; var Key: Char);

begin

if not(((Key >= '0') and (Key <= '9')) or

((Key >= 'A') and (Key <= 'F')) or

((Key >= 'a') and (Key <= 'f'))) then

Key := ' ';

if (Key >= 'a') and (Key <= 'f') then

Key := UpCase(Key);

end;

procedure TForm2.MaskEdit4KeyPress(Sender: TObject; var Key: Char);

begin

if not(((Key >= '0') and (Key <= '9')) or

((Key >= 'A') and (Key <= 'F')) or

((Key >= 'a') and (Key <= 'f'))) then

Key := ' ';

if (Key >= 'a') and (Key <= 'f') then

Key := UpCase(Key);

end;

procedure TForm2.MaskEdit4Change(Sender: TObject);

begin

if MaskEdit4.Text <> '' then

begin

if StrToHex(MaskEdit4.Text) > count-1 then

MaskEdit4.Text := Format('%3x', [count-1]);

if StrToHex(MaskEdit4.Text) < StrToHex(MaskEdit3.Text) then

MaskEdit4.Text := MaskEdit3.Text;

end;

end;

procedure TForm2.MaskEdit3Change(Sender: TObject);

begin

if MaskEdit3.Text <> '' then

begin

if StrToHex(MaskEdit3.Text) > count-1 then

MaskEdit3.Text := Format('%3x', [count-1]);

if StrToHex(MaskEdit4.Text) < StrToHex(MaskEdit3.Text) then

MaskEdit3.Text := MaskEdit4.Text;

end;

end;

procedure TForm2.BitBtn1Click(Sender: TObject);

var

i:integer;

//a:array[1..]

begin

BitBtn1.Enabled := False;

BitBtn2.Enabled := True;

//Form1.SerialPortNG1.SendData();

Form1.SerialPortNG1.SendData(@buf[StrToHex(MaskEdit3.Text)],StrToHex(MaskEdit4.Text)-StrToHex(MaskEdit3.Text));

end;

procedure TForm2.BitBtn2Click(Sender: TObject);

begin

BitBtn1.Enabled := True;

BitBtn2.Enabled := False;

end;

end.

3 Текст програмного модуля головного вікна ВВК, , Unit3.pas

Ім’я данного файлу : Unit3.pas

Функціональне призначення : програмне забеспечення ПК, модуль головного вікна ВВК

Файл створений для дипломного проекта захисту кваліфікації фахівця

За фахом : Системне програмування;

Тема проекту : Віртуальний вимірювальний комплекс на базі учбового лабораторного стенду;

Керівник : М.В. Скородєлов, викладач кафедри ОТП;

Розробник : О.О. Ісмаілов, студент групи КІТ-23а;

Рік розробки : 2009.

unit Unit3;

interface

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons;

type TForm3 = class(TForm)

BitBtn1: TBitBtn;

BitBtn2: TBitBtn;

BitBtn3: TBitBtn;

BitBtn4: TBitBtn;

Label1: TLabel;

procedure BitBtn1Click(Sender: TObject);

procedure BitBtn2Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var Form3: TForm3;

implementation

uses Unit1, Unit2;

{$R *.dfm}

procedure TForm3.BitBtn1Click(Sender: TObject);

begin

Form1.Visible := True;

end;

procedure TForm3.BitBtn2Click(Sender: TObject);

begin

Form2.Visible := true;

end;

end.

2 ТЕКСТ ПРОГРАМНОГО ЗАБЕСПЕЧЕННЯ МК

2.1 Текст програмного забеспечення ВВК мікроконтроллера, main.asm

Ім’я данного файлу : main.asm

Функціональне призначення : програмне забеспечення ПК, модуль логічного аналізатора

Файл створений для дипломного проекта захисту кваліфікації фахівця

За фахом : Системне програмування;

Тема проекту : Віртуальний вимірювальний комплекс на базі учбового лабораторного стенду;

Керівник : М.В. Скородєлов, викладач кафедри ОТП;

Розробник : О.О. Ісмаілов, студент групи КІТ-23а;

Рік розробки : 2009.

#include <m8515def.inc>

.def tmp = r16

.def tmp1 = r17

.def RX_flag = r18

.def RX_Counter = r19

.def RX_Complete = r20

.def command = r21

.def tmp2 = r22

.def tmp3 = r23

.equ UC_REG = 0xC000

.equ RX_Buffer = 0x7C00

.macro USART_TRANSMITT_M

utm_l0:

wdr

sbis UCSRA, UDRE

rjmp utm_l0

out UDR, tmp

.endm

.macro WAIT_PUSK

mov tmp, command

andi tmp, 0b00010000

brne wp_l5

mov tmp, command

andi tmp, 0b00001110

lsr tmp

ldi tmp1, 1

wp_l0:

cpi tmp, 0

breq wp_l1

lsl tmp1

dec tmp

brne wp_l0

wp_l1:

mov tmp, command

andi tmp, 0b00000001

brne wp_l2

wp_l3:

wdr

in tmp2, PINB

and tmp2, tmp1

brne wp_l3

wp_l4:

wdr

in tmp2, PINB

and tmp2, tmp1

breq wp_l4

rjmp wp_l5

wp_l2:

wdr

in tmp2, PINB

and tmp2, tmp1

breq wp_l2

wp_l6:

wdr

in tmp2, PINB

and tmp2, tmp1

brne wp_l6

wp_l5:

.endm

.macro ANALYZE_CLK_6

ac6_l0:

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

dec tmp3 // 1 cycle

brne ac6_l0 // 2 cycles or

// 1 cycle

dec tmp3 // 1 cycle

ac6_l1:

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

dec tmp3 // 1 cycle

brne ac6_l1 // 2 cycles

dec tmp3

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

.endm

.macro ANALYZE_CLK_8

ac8_l0:

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

nop // +2 cyle

nop

dec tmp3 // 1 cycle

brne ac8_l0 // 2 cycles or

// 1 cycle

dec tmp3 // 1 cycle

ac8_l1:

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

nop // +2 cyle

nop

dec tmp3 // 1 cycle

brne ac8_l1 // 2 cycles

dec tmp3

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

.endm

.macro ANALYZE_CLK_16

ac16_l0:

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

ldi tmp1, 3 // +10 cyle

ac16_l2:

dec tmp1

brne ac16_l2

nop

dec tmp3 // 1 cycle

brne ac16_l0 // 2 cycles or

// 1 cycle

dec tmp3 // 1 cycle

ac16_l1:

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

ldi tmp1, 3 // +10 cyle

ac16_l3:

dec tmp1

brne ac16_l3

nop

dec tmp3 // 1 cycle

brne ac16_l1 // 2 cycles

dec tmp3

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

.endm

.macro ANALYZE_CLK_32

ac32_l0:

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

ldi tmp1, 8 // +26 cyle

ac32_l2:

dec tmp1

brne ac32_l2

nop

nop

dec tmp3 // 1 cycle

brne ac32_l0 // 2 cycles or

// 1 cycle

dec tmp3 // 1 cycle

ac32_l1:

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

ldi tmp1, 8 // +26 cyle

ac32_l3:

dec tmp1

brne ac32_l3

nop

nop

dec tmp3 // 1 cycle

brne ac32_l3 // 2 cycles

dec tmp3

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

.endm

.macro ANALYZE_CLK_64

ac64_l0:

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

ldi tmp1, 19 // +58 cyle

ac64_l2:

dec tmp1

brne ac64_l2

nop

dec tmp3 // 1 cycle

brne ac64_l0 // 2 cycles or

// 1 cycle

dec tmp3 // 1 cycle

ac64_l1:

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

ldi tmp1, 19 // +58 cyle

ac64_l3:

dec tmp1

brne ac64_l3

nop

dec tmp3 // 1 cycle

brne ac64_l1 // 2 cycles

dec tmp3

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

.endm

.macro ANALYZE_CLK_128

ac128_l0:

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

ldi tmp1, 40 // +122 cyle

ac128_l2:

dec tmp1

brne ac128_l2

nop

nop

dec tmp3 // 1 cycle

brne ac128_l0 // 2 cycles or

// 1 cycle

dec tmp3 // 1 cycle

ac128_l1:

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

ldi tmp1, 40 // +122 cyle

ac128_l3:

dec tmp1

brne ac128_l3

nop

nop

dec tmp3 // 1 cycle

brne ac128_l1 // 2 cycles

dec tmp3

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

.endm

.macro ANALYZE_CLK_256

ac256_l0:

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

ldi tmp1, 83 // +250 cyle

ac256_l2:

dec tmp1

brne ac256_l2

nop

dec tmp3 // 1 cycle

brne ac256_l0 // 2 cycles or

// 1 cycle

dec tmp3 // 1 cycle

ac256_l1:

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

ldi tmp1, 83 // +250 cyle

ac256_l3:

dec tmp1

brne ac256_l3

nop

dec tmp3 // 1 cycle

brne ac256_l1 // 2 cycles

dec tmp3

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

.endm

.macro ANALYZE_CLK_VN

acv_l0:

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

dec tmp3 // 1 cycle

brne acv_l0 // 2 cycles or

// 1 cycle

dec tmp3 // 1 cycle

acv_l1:

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

dec tmp3 // 1 cycle

brne acv_l1 // 2 cycles

dec tmp3

in tmp, PINB // 1 cycle

st Y+, tmp // 2 cycle

.endm

.org 0

rjmp RESET

nop;rjmp INT0

nop;rjmp INT1

nop;rjmp TIMER1_CAPT

nop;rjmp TIMER1_COMPA

nop;rjmp TIMER1_COMPB

nop;rjmp TIMER1_OVF

rjmp TIMER0_OVF

nop;rjmp SPI_STC

rjmp USART_RXC

nop;rjmp USART_UDRE

nop;rjmp USART_TXC

nop;rjmp ANA_COMP

nop;rjmp INT2

nop;rjmp TIMER0_COMP

nop;rjmp EE_RDY

nop;rjmp SPM_RDY

RESET:

; set stack pointer to top of RAM

ldi tmp, high(RAMEND)

out SPH, tmp

ldi tmp, low(RAMEND)

out SPL, tmp

; enable WDT with 2,1s timeout

ldi tmp, (1<<WDE)|(7<<WDP0)

out WDTCR, tmp

; enable external SRAM

ldi tmp, (1<<SRE)|(1<<SRW10)

out MCUCR, tmp

; enable interrupts

sei

; USART init

rcall USART_Init

// Unmask timer 0 overflov interrupt

ldi tmp, (1<<TOIE0)

out TIMSK, tmp

// Stop timer0

ldi tmp, 0b00000000

out TCCR0, tmp

clr RX_Flag

clr RX_Complete

ldi tmp, 0

out DDRB, tmp

ldi tmp, 0b11111111

out PORTB, tmp

loop:

wdr

cpi RX_Complete, 1

breq c_l0

rjmp l0

c_l0:

// reset RX_Complete

clr RX_Complete

// mask RXCIE

ldi tmp, (1<<TXEN) | (1<<RXEN)

out UCSRB, tmp

// reset RX_Buffer

ldi YL, low(RX_Buffer)

ldi YH, high(RX_Buffer)

ldi tmp3, 0xFF

// do command

mov tmp, command

andi tmp, 0b11100000

lsr tmp

lsr tmp

lsr tmp

lsr tmp

lsr tmp

cpi tmp, 0

brne dc_l0

WAIT_PUSK

ANALYZE_CLK_6

Rjmp dc_end

dc_l0:

cpi tmp, 1

brne dc_l1

WAIT_PUSK

ANALYZE_CLK_8

Rjmp dc_end

dc_l1:

cpi tmp, 2

brne dc_l2

WAIT_PUSK

ANALYZE_CLK_16

Rjmp dc_end

dc_l2:

cpi tmp, 3

brne dc_l3

WAIT_PUSK

ANALYZE_CLK_32

Rjmp dc_end

dc_l3:

cpi tmp, 4

brne dc_l4

WAIT_PUSK

ANALYZE_CLK_64

Rjmp dc_end

dc_l4:

cpi tmp, 5

brne dc_l5

WAIT_PUSK

ANALYZE_CLK_128

Rjmp dc_end

dc_l5:

cpi tmp, 6

brne dc_l6

WAIT_PUSK

ANALYZE_CLK_256

Rjmp dc_end

dc_l6:

cpi tmp, 7

breq cdc_unk

rjmp dc_unk

cdc_unk:

WAIT_PUSK

ANALYZE_CLK_VN

dc_end:

/*

// wait if need befor pusk

WAIT_PUSK

// analyse and store (6 cycles)

// clock time (1/7372800Mhz)*6 = 813,8ns

ANALYZE_CLK_6

*/

// reset RX_Buffer

ldi YL, low(RX_Buffer)

ldi YH, high(RX_Buffer)

// transmitt data

l1:

ld tmp, Y+

USART_TRANSMITT_M

Dec tmp3

brne l1

dec tmp3

l2:

ld tmp, Y+

USART_TRANSMITT_M

Dec tmp3

brne l2

ld tmp, Y+

USART_TRANSMITT_M

dc_unk:

// unmask RXCIE

ldi tmp, (1<<TXEN)|(1<<RXEN)|(1<<RXCIE)

out UCSRB, tmp

l0:

rjmp loop

////////////////////////////////////////////////////

// USART receive complete ISR

USART_RXC:

Push tmp

in tmp, SREG

push tmp

// tmp <- RX

in tmp, UDR

// if (RX_Flag == 1) goto urxc_l0

cpi RX_Flag, 1

breq urxc_l0

// if (RX == AA)

cpi tmp, 0xAA

brne urxc_end

// init timeout

ldi tmp, 0b00000101

out TCCR0, tmp

clr tmp

out TCNT0, tmp

// set recive_flag

ldi RX_Flag, 1

// reset RX_Buffer

ldi YL, low(RX_Buffer)

ldi YH, high(RX_Buffer)

clr RX_Counter

ldi tmp, 0xAA

urxc_l0:

// push RX to buffer

st Y+, tmp

inc RX_Counter

urxc_end:

pop tmp

out SREG, tmp

pop tmp

reti

////////////////////////////////////////////////////

// Timer0 overflow ISR

TIMER0_OVF:

Push tmp

Push tmp1

In tmp, SREG

push tmp

// Stop timer0

ldi tmp, 0b00000000

out TCCR0, tmp

// reset RX_Buffer

ldi YL, low(RX_Buffer)

ldi YH, high(RX_Buffer)

cpi RX_Counter, 3

brne t0ovf_l0

ld tmp, Y+

cpi tmp, 0xAA

brne t0ovf_l0

ld tmp, Y+

cpi tmp, 0x3A

brne t0ovf_l0

ld tmp, Y+

mov command, tmp

ldi RX_Complete, 1

//clear buffer

ldi YL, low(RX_Buffer)

ldi YH, high(RX_Buffer)

clr tmp

st Y+, tmp

st Y+, tmp

st Y+, tmp

st Y+, tmp

st Y+, tmp

t0ovf_l0:

// clear recive_flag

clr RX_Flag

pop tmp

out SREG, tmp

pop tmp1

pop tmp

reti

////////////////////////////////////////////////////

// USART init routine

// uses: tmp, tmp1

USART_Init:

Ldi tmp, (1<<TXEN) | (1<<RXEN) | (1<<RXCIE)

Out UCSRB, tmp

Ldi tmp, (1<<UCSZ0) | 1<<UCSZ1)

Out UCSRC, tmp

Ldi tmp, 0

Ldi tmp1, 23

Out UBRRH, tmp

Out UBRRL, tmp1

Ldi tmp, 0b00000001

Sts UC_REG, tmp

ret

////////////////////////////////////////////////////

// USART transmit routine

// uses: tmp

USART_Transmit:

cli

ut_l0:

wdr

sbis UCSRA, UDRE

rjmp ut_l0

out UDR, tmp

sei

ret

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ

НАЦІОНАЛЬНИЙ ТЕХНІЧНИЙ УНІВЕРСИТЕТ

ХАРКІВСЬКИЙ ПОЛІТЕХНІЧНИЙ ІНСТИТУТ”

Кафедра: Обчислювальна техніка та програмування

ЗАТВЕРДЖУЮ

Завідуючий кафедрою ОТП

__________ /xxxx./

"___" __________ 2009р.

ВІРТУАЛЬНИЙ ВИМІРЮВАЛЬНИЙ КОМПЛЕКС НА БАЗІ УЧБОВОГО ЛАБОРАТОРНОГО СТЕНДУ EV8031

Опис програми

ЛИСТ ЗАТВЕРДЖЕННЯ

xxxxx.03077-01 13 01-1-ЛЗ



РОЗРОБНИКИ

Керівник проекту

/xxxxxxxxx./

_____”____________2009р.

Виконавець

студент групи xxxxx

/xxxx./

_____”_______________2009р.


Харків 2009

ЗАТВЕРДЖЕНО

xxx.03077-01 13 01-1-ЛЗ

ВІРТУАЛЬНИЙ ВИМІРЮВАЛЬНИЙ КОМПЛЕКС НА БАЗІ УЧБОВОГО ЛАБОРАТОРНОГО СТЕНДУ EV8031

Опис програми

xxxx.03077-01 13 01-1

Листів _8_

Харків 2009

АНОТАЦІЯ

Даний документ містить у собі опис програми, методів та алгоритмів, що використовуються, опис потреб та особливостей функціонування продукту, розробленого у межах дипломного проектування “віртуального вимірювального комплексу”. Система призначена для тестування різноманітних цифрових пристроїв.

ABSTRACT

The given document contains the description of programs, methods and algorithms which were used. It describes the requirements and peculiarities of operation of the product developed within the framework of degree projection of a virtual analyze complex. The program implementation of the methods of analysis of self-descriptiveness and diagnostics.

ЗМІСТ

1. ЗАГАЛЬНІ ВІДОМОСТІ

1.1 Позначення і найменування програми

1.2 Програмне забезпечення, необхідне для функціонування програми

1.3 Обрана мова програмування

2. ФУНКЦІОНАЛЬНЕ ПРИЗНАЧЕННЯ

2.1 Призначення програми

2.2 Функціональні обмеження

3. ОПИС ЛОГІЧНОЇ СТРУКТУРИ ПРОГРАМИ

3.1 Алгоритм програми

4. ВИКОРИСТАНІ ТЕХНІЧНІ ЗАСОБИ

5. ВИКЛИК І ЗАВАНТАЖЕННЯ

5.1 Виклик програми

5.2 Точки входу в програму

5.3 Використання оперативної пам’яті

6. ВХІДНІ ДАНІ ПРОГРАМИ

7. ВИХІДНІ ДАНІ ПРОГРАМИ

1. ЗАГАЛЬНІ ВІДОМОСТІ

1.1 Позначення і найменування програми

Програмний продукт має найменування „Віртуальний вимірювальний пристрій ”. Відповідно головний завантажувальний модуль системи має назву “BBK.exe”(складається с перших букв слів імені продукту), головний модуль також підключає додаткові функціональні модулі, які виконують окремі функції. Це такі модулі:

  • Модуль, який предоставляє користувачу вибір необхідних віртуальних пристроїв;

  • Модуль, який предоставляє інтерфейс користувача логічного аналізатора;

  • Модуль який предоставляє інтерфейс генератора слів.

1.2 Програмне забезпечення, необхідне для функціонування програми

Для функціонування програми необхідні:

  • операційна система Windows2000/XP.

1.3 Обрана мова програмування

При виборі комп’ютерної техніки доцільно використовувати IBM-сумісні системи через їхнє велике поширення і доступність. На комп’ютерах цієї серії найбільш поширені операційні системи Microsoft Windows NT/2000/XP. Тому реалізація програми була здійсннена для операційних систем Microsoft Windows 2000/XP на IBM-сумісних комп’ютерах.

Існує досить багато сучасних середовищ і мов програмування. При обиранні мови програмування були розглянуті декіка важливих факторів, які повинні як найбільше відповідати висунутим до продукту вимогам.

Вимоги до програмного продукту:

  • зручний інтерфейс з користувачем;

  • простота використання, не вимагаючи спеціального навчання користувача;

  • наочність вихідних даних;

  • обробка великих структур даних;

  • вимоги до середовища розробки;

  • простота програмування;

  • великий набір компонентів;

  • зручний інтерфейс середовища;

  • можливість створення зручного інтерфейсу;

  • невисокі вимоги до обладнання;

  • простота налагодження програм.

Враховуючи всі вищенаведені вимоги к мовам програмування, було прийнято рішення для створення системи використовувати наступні мови програмування:

  • програмне забеспечення ПК – Delphi 7;

  • програмне забеспечення МК – AVRStudio;

  • Завантаження пошивки до мікроконтроллеру AVReal32.

2. ФУНКЦІОНАЛЬНЕ ПРИЗНАЧЕННЯ

2.1 Призначення програми

Програмний продукт призначений для налагодження різноманітних цифрових пристроїв. А також отримання проаналізованих данних тестуємого пристрою(логічний аналізатор), після подачі на нього тестової послідовності(генератор слів).

2.2 Функціональні обмеження

Програмний продукт відповідає поставленим до нього вимогам і у межах обумовлених ними не має функціональних обмежень.

3. ОПИС ЛОГІЧНОЇ СТРУКТУРИ ПРОГРАМИ

3.1 Алгоритм програми

Розроблене програмне забезпечення функціонує за наступним загальним алгоритмом: cтворюється головне вікно програми на якому розташовані елементи керування. Програма складається з троьох вікон. Перше вікно дозволяє обирати необхідний віртуальний пристрій. Друге і третє вікно – інтерфейс користувача логічного аналізатора та генератора слів. Обидва вікна очікують налаштовувань пристрою, та оброблюють елементи керування. Елемент керування запуском та зупинненням виконує передачу введених налаштовувань, за допомогою інтерфейса користувача, і передає налаштовування і данні за допомогою COM порту у мікроконтроллер. Після цього програма очікує прийом відповіді. Після прийому відповіді переходить у обробку елементів керування.

4. ВИКОРИСТАНІ ТЕХНІЧНІ ЗАСОБИ

Для роботи програмного продукту необхідна IBM PC/AT сумісна персональна ЕОМ, наявність процесору Pentium II 433МГц та вище з обсягом оперативної пам’яті 128Мб або більше, наявністю відео адаптеру VGA або SVGA, а також послідовного приємопередавача СОМ порта або RS-232.

Необхідний об’єм на жорсткому диску 5 Мб для продукту.

При розробці використовувалася ПЕОМ з наступними параметрами: Pentium Tualatin, 512 Мб RIMM ОЗП, жорсткий диск ємністю 80 Гб, відеокарта GeForce2 MX 400 32Мб.

5. ВИКЛИК І ЗАВАНТАЖЕННЯ

5.1 Виклик програми

Програмне запеспечення ПК інсталляції не потребує, потрібно тільки зробити копію програмного модуля у зручне місце, і завантажувати стандартними засобами операційної системи.

Програмне забеспечення мікроконтроллера потребує наявності встановленого пакету внутрішньосистемного програматору AVReal32. Також на момент програмування цільова ситема повинна бути підєднана спеціальним кабелем – програматором, також цільва система повинна бути підключена до блоку живлення(допускається живлення від USB). Програмування починається запуском спеціально підготовленого *.bat файлу.яки містить командну строку із необхідними налаштовуваннями програмування цілевої системи. Файл який містить завантажувальний код має розширення *.hex.

5.2 Точки входу в програму

Точкою входу до будь-якого з модулів програми є запуск головного модуля „ВВК.ехе”, що здійснює створення головного вікна програми, де є можливість обирати подальші дії.

5.3 Використання оперативної пам’яті

Програмний продукт потребує менше 5 Мб оперативної пам’яті.

6. ВХІДНІ ДАНІ ПРОГРАМИ

Вхідними даними програмного забеспечення ПК є налаштовування користувача, і у разі використання логічного аналізатору прийняті по COM порту данні. Вхідними данними програмного забеспечення мікроконтроллера є прийняті команди і у разі режиму генератору слів прийнята послідовність данних по COM порту.

7. ВИХІДНІ ДАНІ ПРОГРАМИ

Вихідними даними програмного забеспечення ПК є налаштовування користувача, і у разі використання генератору слів передаваємі по COM порту данні. Вихідними данними програмного забеспечення мікроконтроллера є прередаваємі відповіді і у разі режиму логічного аналізатора передаваєма послідовність проаналізованих данних по COM порту.

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ

НАЦІОНАЛЬНИЙ ТЕХНІЧНИЙ УНІВЕРСИТЕТ

ХАРКІВСЬКИЙ ПОЛІТЕХНІЧНИЙ ІНСТИТУТ”

Кафедра: Обчислювальна техніка та програмування

ЗАТВЕРДЖУЮ

Завідуючий кафедрою ОТП

__________ /xxxxxxxx./

"___" __________ 2009р.

ВІРТУАЛЬНИЙ ВИМІРЮВАЛЬНИЙ КОМПЛЕКС НА БАЗІ УЧБОВОГО ЛАБОРАТОРНОГО СТЕНДУ EV8031

Керівництво оператора

ЛИСТ ЗАТВЕРДЖЕННЯ

xxxxx.03077-01 34 01-1-ЛЗ



РОЗРОБНИКИ

Керівник проекту

_ _________ /xxxxx./

_____”_______________2009р.

Виконавець

студент групи xx-23а

/xxxxxxxx./

_____”_______________2009р.


Харків 2009

ЗАТВЕРДЖЕНО

xxxxxxxxxxxxxxxxxxxx

ВІРТУАЛЬНИЙ ВИМІРЮВАЛЬНИЙ КОМПЛЕКС НА БАЗІ УЧБОВОГО ЛАБОРАТОРНОГО СТЕНДУ EV8031

Керівництво оператора

xxxxxxx.03077-01 34 01-1

Аркушів

Харків 2009

АНОТАЦІЯ

Документ «Керівництво оператора» містить інформацію для перевірки, забезпечення функціонування й налаштовування системи «Віртуальний вимірювальний комплекс». У даному документі зазначені відомості про програмний продукт, його призначення й умови застосування, характеристика, установка, звернтання до програми.

ABSTRACT

Document «Guidance of operator» contains information for verification, providing of functioning and tuning of the system «Virtual measuring complex». In this document the noted information is about a software product, his setting and terms of application, description, setting, zverntannya to the program.

ЗМІСТ

1 ПРИЗНАЧЕННЯ ПРОГРАМНОГО ПАКЕТУ

2 УМОВИ ВИКОНАННЯ

3 ЗАВАНТАЖЕННЯ ПРОЕКТУ

4 ПОВІДОМЛЕННЯ ОПЕРАТОРУ

1 ПРИЗНАЧЕННЯ ПРОГРАМНОГО ПАКЕТУ

Програмний продукт призначений для налагодження різноманітних цифрових пристроїв. А також отримання проаналізованих данних тестуємого пристрою(логічний аналізатор), після подачі на нього тестової послідовності(генератор слів).

2 УМОВИ ВИКОНАННЯ

Нормальна робота з данним програмним продуктом можлива лише на комп’ютерах IBM PC/AT(чи сумісному з ним) серії не нижче Pentium !!!, з операційною системою Microsoft Windows 2000/XP.

Для нормального функціонування програмного продукту необхідна наявність таких характеристик:

  • SVGA відеоадаптер не менше 1024х768х32;

  • Жорсткий диск;

  • Пам’ять(бажано не нижче 128Мб);

  • Маніпулятор типу “миша”;

  • Клавіатура;

  • COM – порт.

3 ЗАВАНТАЖЕННЯ ПРОЕКТУ

Щоб завантажити програму, необхідно запустити файл BBK.exe. Після цього перед користувачем з’являється вікно(рис. 3.1) із чотирма кнопками. Дві зних залишені для розширення програмного забеспечення: генератор сигналу вільної форми та осцилограф. А інші дві дозволяють викликати додаткові вікна: логічний аналізатор(рис. 3.2) та генератор слів(рис. 3.3).

Рис 3.1 Головне віко віртуального вимірювального пристрою

Рис 3.2 Вікно логічного аналізатора

Рис 3.3 Вікно генератора слів

Інтерфейс складається з трьох вікон. Перше – головне вікно дозволяє відкривати вікна необхідних пристроїв. Вікна працюють як по одинці так і разом у залежності від налагодження.

Логічний аналізатор(рис.3.2) має наступні елементи керування:

  • керування кольором кожного з восьми сигналів;

  • змінення масштабу відображеного сигналу;

  • перегляд сигналу за допомогою полоси зсуву;

  • керування типом запуску якщо вибраний запус по каналу;

  • вибір запуску за необхідним каналом, або невикористовувати;

  • вибір глибини передпускової реєстрації;

  • вибір швидкості реєстрації данних з переліку або вільно;

  • запуск аналізатора;

  • останов аналізатора на випадок очікування пуску, який довго не наступає.

Генератор слів(рис. 3.3) має наступні елементи керування:

  • керування вводом необхідних послідовностей;

  • керування кількістю необхідних слов;

  • керування діапазоном з якого по який генерувати;

  • керування режимами роботи: циклічна генерація, одноразова, шагова.

  • Пуск генерації, або шаг;

  • Останов генерації у випадку наприклад циклічної генерації;

  • Керування швидкістю генерації з переліку а також вільно;

  • Режим роботи генератора слів та логічного аналізатора у парі.

4 ПОВІДОМЛЕННЯ ОПЕРАТОРУ

Програма виключає введення невірних даних у поля ввода, таким чином там де очікується ввід шістнадцятирічного числа можливо ввести твльки цифри від 0 до 9 та символи від a до f і, якщо символи вводяться у нижньому регістрі вводу, програма автоматично переводить іх до верхнього регістру. Також блокуються деякі несумісні операції, для того, щоб не дозволити користувачеві виконувати неможливі або невірні дії. Також виконується перевірка на наявність налаштовування обов’язкоаих параметрів, інакше виводиться повідомлення у якому зазначене виконання обов’язкових дій.








@F:\avr\avreal\avreal32 +MEGA8515  -p1 -e -w -v -o1000 -c 111.hex @pause 
� #TSERIALNGBASICDLG#0#####TPF0#TSerialNGBasicDLG#SerialNGBasicDLG#Left#�##Top#�##BorderStyle##bsDialog#Caption##Serial Basic Settings ClientHeight#�##ClientWidth#�##Color#	clBtnFace Font.Charset# ANSI_CHARSET Font.Color# clWindowText#Font.Height#�	Font.Name##Arial Font.Style###OldCreateOrder	#Position##poScreenCenter#Scaled# PixelsPerInch#x TextHeight####TBevel#Bevel1#Left# #Top# #Width#Z##Height#o#Shape##bsFrame###TLabel#Label3#Left###Top###Width###Height###Caption##&Port FocusControl##CBPort###TLabel#Label4#Left#�##Top###Width#4#Height###Caption#	&Baudrate FocusControl##CBBaud###TLabel#Label5#Left###Top#Q#Width#0#Height###Caption#	&Databits FocusControl##CBData###TLabel#Label6#Left#�##Top#Q#Width###Height###Caption##&Stop FocusControl##CBStop###TLabel#Label7#Left###Top#1#Width#"#Height###Caption##Pari&ty FocusControl##CBParity###TLabel#Label8#Left#�##Top#1#Width#B#Height###Caption# &Flowcontrol FocusControl##CBFlow##	TComboBox#CBPort#Left#9#Top###Width#h#Height###Style##csDropDownList ItemHeight## Items.Strings###COM1##COM2##COM3##COM4##COM5##COM6##COM7##COM8##TabOrder####	TComboBox#CBBaud#Left#�##Top###Width#i#Height###Style##csDropDownList ItemHeight## Items.Strings###110##300##600##1200##2400##4800##9600##14400##19200##38400##56000##57600##115000##128000##256000##TabOrder####	TComboBox#CBData#Left#P#Top#Q#Width#Q#Height###Style##csDropDownList ItemHeight## Items.Strings###4 Bit##5 Bit##6 Bit##7 Bit##8 Bit##TabOrder####	TComboBox#CBStop#Left#�##Top#Q#Width#i#Height###Style##csDropDownList ItemHeight## Items.Strings##	1 Bit (*)##1,5 Bits##2 Bits##TabOrder####	TComboBox#CBParity#Left#9#Top#1#Width#h#Height###Style##csDropDownList ItemHeight## Items.Strings###None (*)##Odd##Even##Mark##Space##TabOrder####	TComboBox#CBFlow#Left#�##Top#1#Width#i#Height###Style##csDropDownList ItemHeight## Items.Strings###None (*)##XOn-XOff##RTS-CTS##DSR-DTR##TabOrder#####TButton#OKBtn#Left#q##Top# #Width#]#Height###Caption##OK#Default	#ModalResult###TabOrder#####TButton	CancelBtn#Left#q##Top#/#Width#]#Height###Cancel	#Caption##Cancel#ModalResult###TabOrder#####
Додати в блог або на сайт

Цей текст може містити помилки.

Programming, computers, informatics and cybernetics | Graduation
911.6кб. | download | скачати

© Усі права захищені
написати до нас