Диплом на тему Віртуальний вимірювальний комплекс на базі учбового лабораторного стенду EV 8031
Работа добавлена на сайт bukvasha.net: 2015-06-30Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
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¤cy_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¤cy_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 М.В.
Керівник ДП _______________________________М.В. Xxxxx___ (підпис і дата) (ініціали та прізвище) Студент-дипломник _____________________________________ (підпис і дата) (ініціали та прізвище)
ВІРТУАЛЬНИЙ ВИМІРЮВАЛЬНИЙ КОМПЛЕКС НА БАЗІ УЧБОВОГО ЛАБОРАТОРНОГО СТЕНДУ EV8031 Специфікація xxxxxxx03077-01 Аркушів _2_ Харків 2009
ЗМІСТ ЗМІСТ ВСТУП 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 Умови експлуатації Програмний продукт “Віртуальний вимірювальний комплекс” повинен безперебійно функціонувати в нормальних умовах експлуатації:
Для нормальної експлуатації системи необхідні початкові знання по експлуатації ПЕОМ. Вимоги до рівня кваліфікації користувача – мінімальні знання спілкування з Windows-вікнами ПЕОМ. 3.4 Вимоги до складу і параметрів технічних засобів Для функціонування програмного виробу необхідний ПЕОМ IBM PC AT/ATX з центральним процессором не нижче Pentium !!! або його аналогом, наявність послідовного COM порту. 3.5 Вимоги до інформаційної та програмної сумістності При написанні програми повинні бути використані можливості які надає операційна система Windows. Програма повинна корректно працювати під керуванням Windows2000/XP. Для написання модулів віртуального вимірювального комплексу повинна бути використана мова програмування Delphi 7. 3.6 Вимоги до маркування й упакування На початку кожного файлу вихідних текстів програми записувати наступну інформацію:
На захисті надати файли програми (проекту) в розпакованому вигляді і упаковані zip або rar архіватором. 3.7 Вимоги до транспортування і зберігання Транспортування результатів проектування може здійснюватися за допомогою будь-яких доступних носіїв: CD-R, CD-RW, Flash-RAM, HDD. Берегти на накопичувачах сумістно: файли початкових текстів розробки, виконуваний файл, допоміжні файли і файли документів проекту. 4 ВИМОГИ ДО ПРОГРАМНОЇ ДОКУМЕНТАЦІЇ Програмна документація програмного продукту “Віртуальний вимірювальний комплекс на базі учбового лабораторного стенду” повинна мітстити наступні документи:
Додаткові вимоги до програмної. Розробити Звіт про виконання дипломного проекту. У документі Звіт виклад основних розділів дипломного проекту повинен займали не менше 60 сторінок(без урахування розділів по економіці, охорони праці та додатків). 5 ТЕХНІКО-ЕКОНОМІЧНІ ПОКАЗНИКИ Техніко-економічні показники повинні бути визначені в процессі розробки і зазначені у відповідному розділі звіту про виконання дипломного проекту. 6 СТАДІЇ ТА ЕТАПИ РОЗРОБКИ Розробка програмного продукту відповідає стадії робочого проекту. Етапи розробки виконують в наступному порядку:
7 ПОРЯДОК КОНТРОЛЮ І ПРИЙМАННЯ При прийманні дипломної роботи перевіряється:
РЕФЕРАТ Звіт про ДП: 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. Аналіз вихідного технічного завдання та постановка задачі Пристрій, що розробляється в даному дипломному проекті – віртуальний вимірювальний комплекс (ВВК): логічний аналізатор. Такий ВВК може використовуватися в якості універсального вимірювального приладу, призначеного для для запам’ятовування та слідкування за системними сигналами, що надходять на його входи в вигляді «чистих» двійкових сигналів та зберігати їх в своїй внутрішній цифровій пам'яті при налагодженні функціональних вузлів і пристроїв різних апаратних засобів обчислювальної техніки (периферійних пристроїв і т.п.), мікропроцесорних і мікроконтролерних систем різного призначення, радіотехнічних систем і пристроїв, засобів телекомунікації і т.д. Такий ВВК може замінити собою цілий комплект вимірювальних приладів. Саме через його універсальність, мобільність та легкість у використанні, а також відносно не високу ціну, цей ВВК пропонується для використання у лабораторіях ВУЗу при проведенні лабораторних робіт з таких дисциплін, як „Комп’ютерна електроніка”, „Комп’ютерна схемотехніка”, „Периферійні пристрої” та інші. Розглянувши весь спектр лабораторних робіт, що проводяться по цих предметах, можна визначити основні технічні вимоги до віртуального вимірювального комплексу: логічного аналізатору, які є достатніми, для того, щоб цей ВВК можна було використовувати при проведенні цих лабораторних робіт. Ці технічні вимоги приведені нижче. Розроблювальний ВВК повинний мати наступні характеристики: - У режимі логічного аналізатору:
Конструктивне виконання – зовнішній пристрій, що підключається до ПК через інтерфейс 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. Прилади за технологією «віртуальні інструменти» Формально термін означає "удавані прилади", власне кажучи, функціонально, це, звичайно, зовсім дійсні прилади і віртуальність їх складається тільки в тім, що окремо, як звичні дискретні прилади "у залізі" вони дійсно не існують. Реалізуються апаратно-програмним шляхом і базуються на трьох основних складовим:
Одне з найбільш вдалих і отримавших дуже широке поширення в усьому світі пропозицій по практичній реалізації даної технології створення приладів - апаратні пристрої вводу-виводу і спеціалізована мова графічного програмування LabVIEW фірми National Instruments, США. Обширнейшая бібліотека стандартних функцій обробки сигналів і створення інтерфейсу для користувача (вид приладу на моніторі), налагоджені драйвери взаємодії з апаратними пристроями, величезна номенклатура самих пристроїв вводу-виводу в сполученні з можливостями сучасних комп'ютерів дозволяють при мінімально можливих на сьогоднішній день витратах створювати в дуже короткий термін будь-які складні прилади, причому дуже високої якості. Це обумовлено тим, що всі основні складові подібного приладу (комп'ютер, системне ПО, пристрій вводу-виводу) - це фірмові вироби масового виробництва, протестовані виготовлювачем і гарантовані для забезпечення, що сопрягаются по всім необхідним параметрам, найбільш повного використання всіх можливостей кожного з названих компонентів. При цьому всі основні компоненти безупинно удосконалюються по своїх функціональних і технічних параметрах з повним збереженням наступності з попередніми версіями. Наприклад, раз уже створений в остаточному виді прилад можна переустановити на іншій, більш сучасний комп'ютер і він відразу почне працювати, наприклад, більш швидко без яких-небудь переробок самої програми приладу. З погляду габаритів приладів, навіть теоретично немає нічого рівного, оскільки в габаритах, наприклад, одна сучасного Notebook може бути реалізоване практично необмежена кількість різних приладів. З цим же зв'язані і вартісні показники подібних приладів. Наприклад, навіть один прилад типу стандартного вузькополосного спектроаналізатору у віртуальному виконанні буде коштувати в 1.5-2 рази дешевше, ніж у традиційному дискретному. З огляду на те, що за технологією віртуальних приладів у рамках разових витрат "на залізо" може бути реалізоване (і так на практиці завжди і відбувається) безліч приладів, вартість подібного рішення стає просто несоизмеримо малої в порівнянні з іншими способами реалізації. Оскільки технологія "віртуальних приладів" являє собою зовсім нову і, можна сказати, революційну технологію в приладобудуванні, вона дозволяє сполучити такі якості, що у процесі удосконалювання традиційних приладів, як правило, сполучити неможливо: краще, дешевше, швидше, надійніше. Розглянемо даний тип приладів більш докладно. 1.2.3.1. Віртуальні прилади фірми «Белвар» Ця фірма пропонує користувачам цифрові логічні аналізатори у вигляді невеликих приставок до персонального комп'ютера. Наприклад АКС-3161, це професійна модель віртуального 16 – канального логічного аналізатору з частотою дискретизації 200МГц, виконана у вигляді приставки до ПК та підключається до LPT-порту комп’ютера. Має гнучки можливості захвату та відображення цифрового потоку даних, широкими можливостями по роботі з зовнішньою тактовою частотою. Має наступні технічні параметри:
Зовнішній вигляд цього логічного аналізатору приведений на рис. 1.1 Рисунок 1.1 Зовнішній вигляд приставки до комп'ютера АСК-3161 Нижче на рис. 1.2 приведено вікно програми інтерфейсу користувача з діаграмою сигналів. Рисунок 1.2 Вид деяких вікон ПО приставки до комп'ютера АСК-3161 АКС-3162 – віртуальний 16-канальний логічний аналізатор виконаний у вигляді плати розширення в ISA-слот комп’ютера та працює разом з осцилографічною плотою АСК-3101. Єдине для обох плат програмне забезпечення дозволяє синхронізувати і бачити на екрані одночасно 2 канали аналогової та 16 каналів цифрової інформації. Сполучення аналогових та цифрових функцій дозволяє використовувати систему як осцилограф змішаних сигналів для пошуку аналогових перешкод у цифрових схемах, аналізу фронтів, логічних рівнів та ін. АКС-3162 має наступні технічні параметри:
Зовнішній вигляд цього логічного аналізатору приведений на рис. 1.3 Рисунок 1.3 Зовнішній вигляд приставки до комп'ютера АСК-3162 Нижче на рис. 1.4 приведено вікно програми інтерфейсу користувача з діаграмою сигналів. Рисунок 1.4 Вид деяких вікон ПО приставки до комп'ютера АСК-3162 АКС-3166 – це більш потужний логічний аналізатор, має наступні технічні характеристики:
Цей логічний аналізатор призначений для аналізу потоку цифрових даних одночасно по 16 каналам з частотою дискретизації до 200 МГц, а також може бути використаний у якості цифрового регістратору даних. Буфер 2М виборок на канал дозволяє забезпечити високу точність часових вимірів достатньо тривалих потоків даних. Гнучкий набір варіантів синхронізації та шаблонів запуску дозволяє визначити різноманітні збої у потоці даних, що приводять до порушення роботи апаратури. Даний аналізатор забезпечує нормальну роботу з апаратурою, яка має різні логічні порогові рівні вхідних сигналів, тому що пороги обираються користувачем. Інтерфейс користувача програми складається з набору робочих панелей (вікон). Кожна панель має набір керуючих елементів (КЕ), які дозволяють користувачу впливати на роботу програми та індикаторів, що відображають необхідну інформацію. Більшість цих елементів є частиною стандартного інтерфейсу Windows і не потребують спеціальних пояснень по їх використанню. Зовнішній вигляд цього логічного аналізатору приведений на рис. 1.5 Рисунок 1.5 Зовнішній вигляд приставки до комп'ютера АСК-3166 Для керування програмою користувач може також використовувати команди спливаючього меню головної панелі. АКС-3166 має зрозумілий та зручний інтерфейс, котрий може налагоджуватися користувачем. Нижче на рис. 1.6 приведено вікно програми інтерфейсу користувача з діаграмою сигналів. Рисунок 1.6 Вид деяких вікон ПО приставки до комп'ютера АСК-3166 1.2.3.2. Віртуальні прилади фірми «Omega» Логический анализатор Omega – Logic : використовується для запису аналізу послідовних та паралельних потоків обміну, а також генерації заданих цифрових послідовностей. Збудований на основі базового блоку Omega. Завдяки використанню ПЛІС пристрій має недосяжну для мікроконтролерних аналогів швидкодію та точність обробки даних. 4 режими запису дозволяють оптимально використовувати внутрішню пам’ять аналізатора. Наявність різноманітних вбудованих та користувальницьких засобів аналізу сигналів дає можливість швидко та ефективно оброблювати великі об’єми інформації. Цей аналізатор має наступні технічні параметри:
1.2.3.3. Віртуальні прилади фірми «National Instruments» Ця фірма є розробником технології віртуальних приладів – революційної концепції, що змінила підхід та методику проведення вимірів та розробки систем автоматизації. Максимально використовуючи можливості комп’ютерів та сучасних інформаційних технологій, віртуальні прилади дозволили збільшити продуктивність і знизити собівартість рішень за рахунок використання гнучкого та простого у освоєнні програмного забезпечення, такого як середовище графічного програмування LabVIEW, а також модульного обладнання, такого як, наприклад, модулі стандарту PXI, призначеного для збору даних та керуванням приладами. Розглядаючи новітні прилади збору даних цієї фірми, можна виділити наступні: це універсальній зовнішній пристрій збору даних USB 6008/6009, а також внутрішні плати збору даних М серії, що мають стандартній та поширений для звичайних ПК швидкий інтерфейс РСІ. Розглянемо тепер більш детально технічні характеристики цих приладів: USB 6008/6009 зображено на рис. 1.7.
Рисунок 1.7 Зовнішній вигляд приставки до комп'ютера USB 6008/6009 Плати збору даних М серії зображено на рис. 1.8.
Рисунок 1.8 Зовнішній вигляд плати збору даних М серії LabVIEW являє собою високоефективне середовище графічного програмування, у якому можна створювати гнучкі та масштабовані прикладні програми вимірів, керування та тестування з мінімальними часовими та грошовими затратами. Приклад прикладної програми вимірів, створеної у LabVIEW зображено на рис.1.9.
Рисунок 1.9 Зовнішній вигляд вікон прикладної програми вимірів, створеної у LabVIEW LabVIEW сполучає у собі гнучкість традиційної мови програмування з інтерактивною технологією Експрес ВП, яка включає у себе автоматичне створення коду, використання помічників при конфігуруванні вимірів, шаблони прикладних програм та Експрес ВП, що налагоджуються. Завдяки цим особливостям, і експерти можуть легко та швидко створювати прикладні програми у LabVIEW. 1.3 Порівняльний аналіз та висновки Задачу реалізації ВВК аналогічного розроблювальному, можна вирішити декількома шляхами: За допомогою спеціалізованих плат (реалізація на «твердій» логіці). Даний спосіб дозволяє мінімізувати як розміри, так і вартість апаратної частини, але при цьому зростають вимоги до ПК, тому що на нього лягає вся обробка вхідного сигналу. За допомогою плат на «програмувальній» логіці. Даний спосіб дозволяє не тільки передбачити захист плати від позамежного рівня вхідного сигналу, але і перекласти частину його обробки на мікроконтролер плати, що дозволяє розвантажити ПК. 1.3.1 Короткі висновки Як видно з приведеного порівняння реалізація ВВК за допомогою «твердої» логіки приводить до значно менших грошових витрат, але при цьому і швидкість роботи усього ВВК, і можливість використовувати ПК у багатозадачном режимі різко знижуються через велику кількість обчислень, що виконує ПК. Приймаючи це до уваги, у процесі дипломного проектування був розроблений ВВК на «програмувальній» логіці, що дозволило в значній мірі розвантажити ПК, і значно зменшити число даних для обміну, тому що вся попередня обробка сигналу виконується мікроконтролером. 1.4. Зв'язок ВВК з IBM PC Підключення ВВК до ПК можна здійснити використовуючи будь-який убудований інтерфейс. Коротке порівняння деяких з них приведено в табл. 1. Таблиця 1. Порівняння методів підключення ВIК
З погляду розроблювального ВВК найбільш привабливим виглядає інтерфейс 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.
|
ЖКИ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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 у зсувний регісир передачі у наступних випадках:
Рис. 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 - Покупні матеріали при розробці даного продукту
Перелік спеціалістів для реалізації проекту приведений у таблиці 5.2. Таблиця 5.2 - Перелік спеціалістів для реалізації проекту
Розрахуємо розмір оплати спеціалістів. Трудовитрати в людино-днях обчислюється по формулі: Т = Тоф+Та+Тс+Тп+То+Тд, (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 - Дані о продуктивності виконавця
Коефіцієнт кваліфікації залежить від стажу роботи й дорівнює: – до 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 - Розрахунок трудовитрат
Зарплату розробникам можна полічити виходячи з місячного окладу розробника і терміну, необхідного для розробки програмного продукту. Термін розробки визначається виходячи з 22 робочих днів в місяць: Тм = Т/22 =87,95/22 = 3,99 місяця. Розрахунок витрат на основну заробітну плату зображений в таблиці 5.5. Пайова участь керівника проекту дорівнює 20 % від посадового окладу. Для подальшої реалізації програмного продукту потрібно найняти інженера й встановити йому відрядну заробітну плату у розмірі 1 грн. за створення однієї копії. Додаткова заробітна плата (Здоп.) вміщує до себе доплати, надбавки, гарантійні і компенсаційні виплати, передбачені законодавством. Додаткову заробітну плату приймаємо 10 % від Зосн Таблиця 5.5 - Розрахунок заробітної плати
Таким чином додаткова заробітна плата буде дорівнювати 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 - Розрахунок витрат та договірної ціни програмного продукту
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 - Карта руху готівки за перший рік реалізації
| 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 - Прибутки та витрати
Назва показнику
Визначимо точку беззбитковості – це такий обсяг продаж, при котрому окупаються всі витрати. Аналітично вона визначається по формулі: Тб=(Зпост+Зр)/(Цед-Зпер), (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.4 Виробнича санітарія Працівники обчислювального центра піддаються впливові шкідливих і небезпечних факторів виробничого середовища, електромагнітних полів, статичної електрики, шумів . Оператори зазнають психоемоційної напруги. 6.4.1 Метереологічні умови Метеорологічні умови на виробництві або мікроклімат визначають наступні параметри: температура (°C), рухливість (м/с), відносна вологість повітря (%) і інтенсивність теплового випромінювання. З урахуванням параметрів мікроклімату метеоумови в приміщенні поділяються на оптимальні та допустимі. У відповіді до ГОСТ 12.1.005–88 [14] встановлюються оптимальні умови, при виборі яких враховується пора року та категорія роботи. За затратами енергії розробка програмного продукту є легкою фізичною роботою (сидяча робота, не потребує фізичного напруження) – категорія 1а. Але дипломна робота характеризується напруженою розумовою працею. Тому обрані оптимальні параметри мікроклімату, що наведені у таблиці 6.2. Таблиця 6.2 – Оптимальні праметри мікроклімату
Приміщення обладнане системами централізованого опалення (загальне парове), кондиціювання повітря та штучною припливно-витяжною вентиляцією відповідно до СНиП 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 – Характеристика виробничого освітлення
Комфортні умови зорової роботи забезпечуються. Загальне освітлення має бути виконане у вигляді суцільних або переривчатих ліній світильників, що розміщуються збоку від робочих місць (переважно зліва) паралельно лінії зору працівників. Допускається застосувати світильники таких класів світлорозподілу: - світильники прямого світла - П; - переважно прямого світла - Н; - переважно відбитого світла - В. При розташуванні відеотерміналів ЕОМ за периметром приміщення лінії світильників штучного освітлення повинні розміщуватися локально над робочими місцями. Для загального освітлення необхідно застосовувати світильники із розсіювачами та дзеркальними екранними сітками або віддзеркалювачами, укомплектовані високочастотними пускорегулювальними апаратами (ВЧ ПРА). Допускається застосовувати світильники без ВЧ ПРА тільки при використанні моделі з технічною назвою "Кососвіт". Застосування світильників без розсіювачів та екранних сіток забороняється. Як джерело світла при штучному освітленні повинні застосовуватися, як правило, люмінесцентні лампи типу ЛБ. При обладнанні відбивного освітлення у виробничих та адміністративно-громадських приміщеннях можуть застосовуватися метало галогенові лампи потужністю до 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 - Рівні іонізації повітря робочої зони ОЦ
Варто враховувати, що м'яке рентгенівське випромінювання, що виникає при напрузі на аноді 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 нормативних значень параметрів шкідливих та небезпечних факторів, оптимальних параметрів мікроклімату, норм освітлення дозволить забезпечити безпечні умови праці користувача ЕОМ. СПИСОК ДЖЕРЕЛ ІНФОРМАЦІЇ
ВИСНОВКИ У ході виконання научно дослідницької роботи були розглянуті основні технічні характеристики лабораторного стенду EV8031, а також розглянутий лабораторний практикум з курсу мікроконтроллерних систем. У ході роботи були розглянуті основні характеристики та ресурси мікроконтроллера ATMega8515 та стенду EV8031. Були обчислені його швидкістні характеристики, які необхідні для розробки віртуального вимірювального комплексу. Було з’ясовано, що дуже складно побудувати такі пристрої як логічний аналізатор та генератор слів на програмній базі мікроконтроллеру. Але отримані характеристики повністю вдовільнили постановлену задачу. Одночасний доступ двох програм до послідовного поорту неможливий, тому для вирішення задачі було прийнято рішення обь’єднати дві програми у один програмний модуль, але з двома вікнами, для зручності у користуванні. Побудова інтерфейсу була взята із багатовідомої системи моделювання електронних пристроїв Electronic Workbench, де є аналогічні віртуальні пристрої. У результаті тестування створеного програмного забеспечення, були отримані вдовільні показники. Як було зазначено вище, використання таймеру не призводить до великоі похибки при вимірюванні на швидкості вхідної послідовності 50Гц. МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ НАЦІОНАЛЬНИЙ ТЕХНІЧНИЙ УНІВЕРСИТЕТ “ХАРКІВСЬКИЙ ПОЛІТЕХНІЧНИЙ ІНСТИТУТ” Кафедра: “Обчислювальна техніка та програмування” “ЗАТВЕРДЖУЮ” Завідуючий кафедрою ОТП __________ /xxxx.А./ "___" __________ 2009р. ВІРТУАЛЬНИЙ ВИМІРЮВАЛЬНИЙ КОМПЛЕКС НА БАЗІ УЧБОВОГО ЛАБОРАТОРНОГО СТЕНДУ EV8031 Текст програми ЛИСТ ЗАТВЕРДЖЕННЯ xxxx.03077-01 12 01-1-ЛЗ
Харків 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-ЛЗ
Харків 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 Програмне забезпечення, необхідне для функціонування програми Для функціонування програми необхідні:
1.3 Обрана мова програмування При виборі комп’ютерної техніки доцільно використовувати IBM-сумісні системи через їхнє велике поширення і доступність. На комп’ютерах цієї серії найбільш поширені операційні системи Microsoft Windows NT/2000/XP. Тому реалізація програми була здійсннена для операційних систем Microsoft Windows 2000/XP на IBM-сумісних комп’ютерах. Існує досить багато сучасних середовищ і мов програмування. При обиранні мови програмування були розглянуті декіка важливих факторів, які повинні як найбільше відповідати висунутим до продукту вимогам. Вимоги до програмного продукту:
Враховуючи всі вищенаведені вимоги к мовам програмування, було прийнято рішення для створення системи використовувати наступні мови програмування:
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-ЛЗ
Харків 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. Для нормального функціонування програмного продукту необхідна наявність таких характеристик:
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##### 2. Реферат на тему Working Women Essay Research Paper Working WomenJasleen 3. Диплом на тему Психологические особенности развития речи у реб нка до тр х лет в семье 4. Реферат Декларация Бальфура 1917 года 5. Сочинение на тему С Есенин Анна Снегина 6. Реферат Явление монетаризма в экономике 7. Реферат Общие положения криминалистической тактики 2 8. Реферат Вплив естетичного виховання на реабілітацію вихованців допоміжної школи 9. Реферат Дауна болезнь 10. Реферат на тему Государственная регистрация выпуска ценных бумаг при учреждении акционерного общества |