{ Контроллер масс-спектрометра МИ1201-АГМ } {--------------------------------------------------------------------------- The control units for mass-spectrometer MI1201-AGM (c) Copyright Aleksandrov O.E., 1998 Модуль управления масс-спектрометром МИ1201-АГМ (c) Собственность Александрова О.Е., 1998 Molecular Physics department 620002, Екатеринбург, К-2 USTU, Ekaterinsburg, K-2, 620002 УГТУ, RUSSIA Кафедра молекулярной физики phone 75-48-39 тел. 75-48-39 E-mail: aleks@dpt.ustu.ru ----------------------------------------------------------------------------} Unit c_MI1201; {$X+ - разрешение вызова функций как процедур} INTERFACE USES MiscFunc, c_Ctrl, c_Ctrl1, c_Bus, c_Roll, c_CVF, c_Panel, c_ISSB, c_Count, c_Volts, MassClbr, MItypes; const cCalibrateDelayTime=200; cCalibrateRetryCount=100; cSwitchesSetTimeOut=3000; { время ожидания включения/выключения блоков } cParameterFileHeader='Control module for MI-1201 AGM saved parameters'+^M^J^M^J#$00; type { Коды ошибок } tErrorCodes=({$I C_ErrCds.Inc}, { общие коды } {Инициализация Init} ecFailInit_MoreThenOneController, ecFailInit_ctrlBus, ecFailInit_ctrlISSB, ecFailInit_ctrlPanel, ecFailInit_ctrlVolts, ecFailInit_ctrlCount, ecFailInit_ctrlRoll, ecFailInit_ctrlCVF, {Инициализация-exInit} ecFailExInit_ctrlBus, ecFailExInit_ctrlISSB, ecFailExInit_ctrlPanel, ecFailExInit_ctrlVolts, ecFailExInit_ctrlCount, ecFailExInit_ctrlRoll, ecFailExInit_ctrlCVF, { Переключения Вкл./Выкл.} ecFail_ctrlPanel_CurBlocks, ecFail_ctrlISSB_CurFlags, ecFail_ctrlPanel_CurInOutOpen, ecFail_ctrlCVF_CurRegime, ecFail_ctrlISSB_exCurBeam, ecFail_ctrlPanel_Blocks, ecFail_ctrlPanel_exSetValves, ecFail_ctrlPanel_InOutOpen, ecFail_ctrlCVF_Regime, ecFail_ctrlISSB_exBeam, ecFail_exSwitchesSet, { Переключения ИСТОЧНИКА газа} ecFail_ctrlPanel_exCurSource, ecFail_ctrlPanel_exIntelliSource, ecFail_ctrlPanel_exSource, ecFail_InvalidValves, { Управление магнитом } ecInvalidCalibrationParameters, ecFail_ctrlRoll_exScroll, { Измерение напряжений } ecFail_ctrlVolts_exVoltage, { Счет ионов } ecFail_ctrlCount_exStartOrRead, ecFail_ctrlCount_exStart, ecFail_ctrlCount_exRead, { Измерение ионного тока } ecFail_ctrlCVF_exGetData, ecFail_ctrlCVF_exStart, ecFail_ctrlCVF_exRead, ecFail_ctrlCVF_exCalibration, { Задание напряжений источника ионов } ecFail_ctrlISSB_exSetValue, ecFail_ctrlISSB_exResetValue, ecFail_ctrlPanel_exSetValue, { Аварийные сигналы } ecFail_ctrlISSB_exCurFlags, ecIsPowerON_Fail, { Cамотестирование } ecScrolIsUnoperational, ecVoltageIsUnoperational, ecCVF_Is_Unoperational, { Сохранение конфигурации } ecBusDataSaveFail, ecISSBDataSaveFail, ecCVFDataSaveFail, ecPanelDataSaveFail, ecCountDataSaveFail, ecVoltsDataSaveFail, ecRollDataSaveFail, ecBusDataRestoreFail, ecISSBDataRestoreFail, ecCVFDataRestoreFail, ecPanelDataRestoreFail, ecCountDataRestoreFail, ecVoltsDataRestoreFail, ecRollDataRestoreFail, ecDataSaveFileWrite, ecDataSaveFileRead, ecDataSaveFileInavalidFile, {Эмулятор} ecEmulatorNotFound, ecBadControllerState); tFlag=(fInitDone, fDone, fSetNoErrorCall, fAtLeastOneGetPNCDone, fAtLeastOneGetICountDone, fPNCCalibrationUisMeasured ); tFlags=set of tFlag; { дополнительный контроль над проведением инициализации MI1201 и субконтроллеров } tFeature=(XffRollFastExInit, ffSkipValvesExInit, ffSkipValvesExDone, ffSkipExDoneAtAll, ffRestoreBlocksState, ffUseEmulator); tFeatures=set of tFeature; const cAllControllers=[Low(tController)..High(tController)]; type tChannelStrName=string[16]; tSignalTransform=(fUseMkVolts, fDoNormalization); tSignalTransforms=set of tSignalTransform; tEmergencyFlag=(efFlagsUnavailable, efCatodBurnOUT, efOverload); tEmergencyFlags=set of tEmergencyFlag; tPorts=record {не используются} end; tIntelliSourceFlag=(fIntelliSourceError, fPressureDown, fNoPressureChange, fPressureUp); { !!! первые 6 устройств чувствительны к порядку} tDevice=(IonizationVoltage, EmissionCurrent, ExtractingVoltage, FocusingVoltage, CorrectionX, CorrectionZ, SEM_Voltage, UnknownDevice); tDevices=set of tDevice; const cDeviceName:array[tDevice] of string[30]=( 'напряжение ионизации', 'ток эмиссии', 'вытягивающее напряжение', 'фокусирующее напряжение', 'коррекция X', 'коррекция Z', 'напряжение на ВЭУ', '?' ); type tData=record Flags:tFlags; MassCalibration:tMassCalibration; IMChCalibration:tMassCalibration; SignalChannel:tChannel; Features:tFeatures; CalibratePNCDelayTime,CalibratePNCRetryCount:word; SwitchesSetTimeOut:word; DoNotExInit:tControllers; DoNotExDone:tControllers; DoNotTest:tControllers; SignalTransformationFlags:tSignalTransforms; xxxIMCh0:tMkVolts; U0,U1:tMkVolts; {Напряжения калибровки ПНЧ} PNCZeroLevels:tSignalsVArray; end; tTmpData=record LastSignals:tSignals; LastSignalsNorm:tNormalizedSignals; LastSignalsV:tSignalsV; InactiveControllers:tControllers; end; { ОСНОВНОЙ ОБЪЕКТ ---- Контроллер уровня 2 ---- масс-спектрометр МИ1201-АГМ } tPCtrl=^tCtrl; tCtrl=object(c_Ctrl1.tCtrl) { Контроллеры уровня 1 } ctrlISSB: c_ISSB.tCtrl; { контроллер Блока питания источника ионов АК2} ctrlPanel:c_Panel.tCtrl; { контроллер Пульта управления АК3} ctrlVolts:c_Volts.tCtrl; { контроллер Напряжений АК5} ctrlCount:c_Count.tCtrl; { контроллер Счетчика ионов АК7} ctrlRoll: c_Roll.tCtrl; { контроллер Магнита АК8} ctrlCVF: c_CVF.tCtrl; { контроллер ПНЧ АК9} function Name:tName; virtual; { Инициализация} constructor InitDefault; constructor Init(Ports:tPorts); procedure exInit; virtual; // procedure exReInit; virtual; procedure exSelfTest; { Все тесты } procedure exDone; virtual; destructor Done; function CompletelyInitiated:boolean; function OperationTime:tTiks; { Сохранение/восстановление состояния контроллера } function DataSize:word; // function Save(var DataPtr:pointer):boolean; // function exRestore(var DataPtr:pointer):boolean; function SaveToFile(const FName:PChar):boolean; // procedure exRestoreFromFile(const FName:string); function Save(var DataPtr:pointer):boolean; function Restore(var DataPtr:pointer):boolean; function SaveToFileX(const FName:PChar):boolean; function RestoreFromFile(const FName:string):boolean; procedure SpecialFeaturesSet(x:tFeatures); procedure SpecialFeaturesGet(var x:tFeatures); procedure SkipMaskSetForExInit(x:tControllers); procedure SkipMaskGetForExInit(var x:tControllers); procedure SkipMaskSetForTest(x:tControllers); { Текстовые сообщения о длительных операциях. Процедура должна перехватываться обработчиком сообщений, иначе ничего не делает. } procedure ProgressMessage(const Msg:string); virtual; { Обработка ошибок } function ErrorMessage(en:tErrorCode):string; virtual; function ErrorMessageCurrent:string; function ErrorMessagesFromSubControllers:string; procedure SetErrorCode(ErrCode:tErrorCode); procedure SetNoError; virtual; { Возвращает список контроллеров в которых возбуждена ошибка} procedure ErrorGetCtrlsWith(var c:tControllers); function ErrorGetFirstCtrlWith:tController; function ErrorCodeFromSubCtrl(c:tController):word; { Задержка на Time миллисекунд } procedure Delay(Time:word); { Методы управления магнитным полем } procedure MassCalibrationSet(M0,K:tMass); procedure MassCalibrationGet(var M0,K:tMass); function Mass2Counter(x:tMass):tMagnetCounter; // function ValidMass(x:tMass):boolean; procedure MassCalibrationSetCurrentMass(m:tMass); procedure MassCalibrationSetCurrentCounter(c:tCounter); procedure MassCalibrationGetEx(var MassCalibr:tMassCalibration); function MassCalibrationSetEx(const MassCalibr:tMassCalibration):boolean; function MassCalibrationPtr:tPMassCalibration; procedure IMChCalibrationSet(M0,K:tMass); procedure IMChCalibrationGet(var M0,K:tMass); function IMCh2Mass(x:tMkVolts):tMass; function IMCh2Counter(x:tMkVolts):tMagnetCounter; function IMChValid(x:tMkVolts):boolean; function exIMCh_Mass:tMass; function exIMChCalibrationDeltaOrigin:tCounter; procedure exIMChCalibrationRefineOrigin; procedure exIMChCalibrationCalculate(dC:tCounter); procedure exIMChCalibrationCalculateDefault; { изменяет магнитное поле ОТНОСИТЕЛЬНО ТЕКУЩЕГО ПОЛОЖЕНИЯ на Shift импульсов контроллера магнита } function exScroll(Shift:tMagnetCounter):tMagnetCounter; function exScrollEx(Shift:tMagnetCounter):boolean; { изменяет магнитное поле АБСОЛЮТНО устанавливая счетчик импульсов контроллера магнита на Сounter} procedure exJumpTo(C:tMagnetCounter); function exJumpToEx(C:tMagnetCounter):boolean; { возвращает текущее значение для счетчика импульсов } function Counter:tMagnetCounter; { возвращает TRUE, если допустимое значение для счетчика импульсов } function Counter2Mass(x:tMagnetCounter):tMass; { изменяет магнитное поле АБСОЛЮТНО для установки на массу иона Mass (!!! требует задания калибровки SetMassCalibration) } procedure exJumpToMass(M:tMass); function exJumpToMassEx(M:tMass):boolean; { возвращает массу иона для установленного магнитного пол (!!!требует задания калибровки SetMassCalibration)} function Mass:tMass; function MassMax:tMass; function MassMin:tMass; function MassValid(M:tMass):boolean; { Методы Вкл./Выкл. БЛОКОВ и информация о состоянии БЛОКОВ} procedure exSwitchesSet(ASwitches:tSwitches); procedure exSwitchesGet(var ASwitches:tSwitches); procedure exSwitchTurnON(ASwitch:tSwitch); procedure exSwitchTurnOFF(ASwitch:tSwitch); function exSwitchesIs(ASwitches:tSwitches):boolean; function exSwitchesIsON(ASwitches:tSwitches):boolean; function exSwitchesIsOFF(ASwitches:tSwitches):boolean; function exSwitchIsON(ASwitch:tSwitch):boolean; procedure SwitchesSetTimeOutSet(ATimeOut:word); function SwitchesSetTimeOut:word; function exSwitchesWait(Switches:tSwitches):boolean; function exSwitchesWaitMask(Switches,SwitchesMask:tSwitches):boolean; function exSwitchesWaitMaskEx(Switches,SwitchesMask:tSwitches; STimeOut:word):boolean; { Методы Вкл./Выкл. ИСТОЧНИКА пробы и информация о текущем ИСТОЧНИКЕ} { Открытие клапана } procedure exSourceSet(x:tSource); { Открытый клапан } function exSource:tSource; { Открытие клапана и возврат анализа результата открытия клапана DeltaOfAllCounters = [все активные счетчики ПНЧ до открытия] - [все активные счетчики ПНЧ после открытия]; DelayTime = задержка [мс], до открытия и после открытия.} procedure exSourceIntelliSet(x:tSource; DelayTime:word; var DeltaOfAllCounters:tGeneralSignalData); { Методы Вкл./Выкл. клапанов магистралей и информация о текущем состоянии } { Открытие клапана } procedure exValvesSetOpen(x:tValves); { Открытый клапан } procedure exValvesGetOpen(var x:tValves); { Методы измерения напряжений } { возвращает напряжение в точке x [10е-6 Вольт] или [микроВольт] c ожиданием стабильности показаний за период DelayTime [мс] и повтором попытки не более RetryCount раз. Если DelayTime=0 или RetryCount <= 1, проводится только одно считываие данных } function exVoltage:tMkVolts; procedure exVoltageSelectChannel; procedure VoltageChannelSet(x:tVoltageChannel); function VoltageChannel:tVoltageChannel; procedure VoltageReadParametersSet(DelayTime:word; RetryCount:word); procedure VoltageReadParametersGet(var DelayTime:word; var RetryCount:word); { Методы получения данных измерений } {считывание обобщенного канала - запуск измерения и возврат данных } function exSignal:tGeneralSignalData; {считывание обобщенного канала - возврат данных последнего измерения } function Signal:tGeneralSignalData; function SignalEx(cl:tChannel):tGeneralSignalData; function SignalNorm:tNormalizedSignalData; function SignalNormEx(cl:tChannel):tNormalizedSignalData; function SignalV:double; function SignalVEx(cl:tChannel):double; {запуск измерения на ВСЕХ каналах} procedure exSignalsStart; {состояние готовности ВСЕХ каналов } function exSignalsReady:boolean; {ожидание готовности ВСЕХ каналов (просто задержка на время интегрирования сигнала)} procedure exSignalsWait; procedure SignalsWait; {ожидание готовности, считывание данных со ВСЕХ каналов и возврат данных} procedure exSignalsRead(var Signals:TSignals); procedure exSignalsVRead(var Signals:TSignalsV); procedure exSignalsNormRead(var Signals:TNormalizedSignals); {запуск измерения, ожидание готовности, считывание данных со ВСЕХ каналов и возврат данных} procedure exSignalsGet(var Signals:TSignals); procedure exSignalsNormGet(var Signals:TNormalizedSignals); procedure exSignalsVGet(var Signals:TSignalsV); {возврат данных последнего измерения для ВСЕХ каналов} procedure SignalsGet(var Signals:TSignals); procedure SignalsVGet(var Signals:TSignalsV); procedure SignalsNormGet(var Signals:TNormalizedSignals); procedure exSignalsZeroLevelsMeasureEx(ChannelsSet:tChannels); procedure exSignalsZeroLevelsMeasure; procedure SignalsZeroLevelsGet(var ZLs:tSignalsVArray); procedure SignalsZeroLevelsSet(const ZLs:tSignalsVArray); function SignalZeroLevelGet(cl:tChannel):double; procedure SignalZeroLevelSet(cl:tChannel; ZL:double); {установка единого времени интегрирования для всех каналов} procedure IntegrationTimeSet(t:word); function IntegrationTime:word; function IntegrationTimeGetAndSet(t:word):word; function IntegrationTimeMax:word; {установка обобщенного канала для получения данных } procedure SignalChannelSet(u:tChannel); function SignalChannel:tChannel; function SignalChannelName:tChannelStrName; {установка времени интегрирования обобщенного } procedure IntegrationTimeForChannelSet(t:word); procedure IntegrationTimeForChannelSetEx(u:tChannel; t:word); function IntegrationTimeForChannelGet:word; function IntegrationTimeForChannelGetEx(u:tChannel):word; {установка типа преобразования данных канала } procedure SignalTransformFlagsSet(x:tSignalTransforms); function SignalTransformFlagsIn(x:tSignalTransform):boolean; procedure SignalTransformFlagsInclude(x:tSignalTransform); procedure SignalTransformFlagsExclude(x:tSignalTransform); procedure SignalTransformFlagsGet(var x:tSignalTransforms); { Калибрует ПНЧ } procedure exCalibrate; procedure exCalibrateEx(ChannelSet:tChannels); procedure exCalibrateFast; procedure CalibrateSetDelayTime(x:word); procedure CalibrateSetRetryCount(x:word); function CalibrateDelayTime:word; function CalibrateRetryCount:word; function CalibrateValid:boolean; { Методы управления напряжениями источника } { устанавливают } procedure exDeviceUSet(Device:tDevice; Value:longint); procedure exDeviceCounterSet(Device:tDevice; Value:word); procedure exDeviceReset(Device:tDevice); { возвращают установки } function DeviceU(Device:tDevice):longint; function DeviceCounter(Device:tDevice):word; { возвращают параметры } function DeviceUMax(Device:tDevice):longint; function DeviceUMin(Device:tDevice):longint; function DeviceUStep(Device:tDevice):longint; function DeviceCounterMax(Device:tDevice):word; function DeviceIndicator(Device:tDevice):integer; { Методы получения аварийных сигналов } procedure exEmergencyFlagsGet(var x:tEmergencyFlags); { катод НЕ сгорел } function exCatodOK:boolean; { катод сгорел } function exCatodBurnOUT:boolean; { перегрузка питания источника ионов } function exOverload:boolean; { Возвращает результат проверки наличия СЕТИ (220В) - включенн ли прибор } function exIsPowerON:boolean; procedure exDetectCtrl(var x:tCtrlAlive); virtual; private prCtrlBus:c_Bus.tCtrl; { контроллер ВВОДА/ВЫВОДА в порты } prData:tData; { данные подлежащие сохранению } prTmpData:tTmpData; { данные НЕподлежащие сохранению } // t0,t1,t2,t3,t4:longint; { методы самотестирования } procedure exTestRoll; procedure exTestVolts; procedure exTestCVF; { методы инициализации } procedure exInitBus{(Reinit:boolean)}; procedure exInitPanel{(Reinit:boolean)}; procedure exInitISSB{(Reinit:boolean)}; procedure exInitCount{(Reinit:boolean)}; procedure exInitCVF{(Reinit:boolean)}; procedure exInitVolts{(Reinit:boolean)}; procedure exInitRoll{(Reinit:boolean)}; procedure InactiveCtrlInclude(c:tController); procedure InactiveCtrlExclude(c:tController); function InactiveCtrl(c:tController):boolean; { Считает количество импульсов от ионов за период IntegrationTime [по умолч. мс]} function exIonCounterGet:tGeneralSignalData; procedure IonCounterIntegrationTimeSet(x:word); function IonCounterIntegrationTime:word; { Считает количество импульсов (пропорциональное ионному току) за период Time [мс] на всех активных ЭМУ и ВЭУ, запоминает данные } procedure exPNCDataGet; procedure PNCIntegrationTimeSet(x:word); function PNCIntegrationTime:word; { Возвращает количество импульсов (пропорциональное ионному току) со счетчика Channel (данные последнего вызова exGetPNCData)} function PNC(Channel:c_CVF.tChannel):tGeneralSignalData; { Возвращает напряжение пропорциональное ионному току (мкВ) со счетчика Channel (данные последнего вызова exGetPNCData). Требует калибровки exCalibrate } function PNC_U(Channel:c_CVF.tChannel):tGeneralSignalData; { Возвращает напряжение пропорциональное ионному току (В) со счетчика Channel (данные последнего вызова exGetPNCData). Требует калибровки exCalibrate } function PNC_V(Channel:c_CVF.tChannel):double; end; IMPLEMENTATION USES MI1201AGM_Emulator_DLL_Headers, DataSave, {$IfNDef Seg16}Windows{$EndIf}; const { Переменные для блокировки инициализации второго экземпляра контроллера } SingleControllerLock:word=0; SingleControllerPtr:pointer=NIL; cDefaultPorts:tPorts=({не используются}); procedure Switches2CVFRegime(x:tSwitches; var y:c_CVF.tRegime); begin y:=[]; if fCVF_Base0 in x then Include(y, frsBaseIsZero); if fCVF_InputEMU in x then Include(y, frsInputIsEMU); if fCVF_DoNotInvertInput in x then Include(y, frsDoNotInvertSignal); end; procedure CVFRegimeAdd2Switches(x:c_CVF.tRegime; var y:tSwitches); begin if frsBaseIsZero in x then Include(y, fCVF_Base0); if frsInputIsEMU in x then Include(y, fCVF_InputEMU); if frsDoNotInvertSignal in x then Include(y, fCVF_DoNotInvertInput); end; procedure CVFRegime2Switches(x:c_CVF.tRegime; var y:tSwitches); begin y:=[]; CVFRegimeAdd2Switches(x,y); end; procedure Switches2PanelBlocks(x:tSwitches; var y:c_Panel.tBlocks); begin y:=[]; if fBPGI in x then Include(y, c_Panel.fBPGI); if f10kV in x then Include(y, c_Panel.f10kV); if fSEM in x then Include(y, c_Panel.fSEM); if fValvesControl in x then Include(y, c_Panel.fValvesControl); end; procedure PanelBlocksAdd2Switches(x:c_Panel.tBlocks; var y:tSwitches); begin { прием с аппратуры БПГИ if c_Panel.fBPGI in x then Include(y, fBPGI);} { прием с аппратуры БПГИ if c_Panel.f10kV in x then Include(y, f10kV);} if c_Panel.fSEM in x then Include(y, fSEM); if c_Panel.fValvesControl in x then Include(y, fValvesControl); end; procedure PanelBlocks2Switches(x:c_Panel.tBlocks; var y:tSwitches); begin y:=[]; PanelBlocksAdd2Switches(x,y); end; procedure ISSBCtrlFlagsAdd2Switches(x:tCtrlFlags; var y:tSwitches); begin if fBPGI_On in x then Include(y, fBPGI); if f10kV_On in x then Include(y, f10kV); if not (fBeam_Off in x) then Include(y, fCVF_Beam); end; procedure ISSBCtrlFlags2Switches(x:tCtrlFlags; var y:tSwitches); begin y:=[]; ISSBCtrlFlagsAdd2Switches(x,y); end; function Channel2CVFChannel(ch:tChannel):c_CVF.tChannel; begin Channel2CVFChannel:=1; if ch in [PNC1..PNC5] then Channel2CVFChannel:=Ord(ch)+1 else if ch = PNC_SEM then Channel2CVFChannel:=9 else RunError(201); end; procedure ChannelsToCVFChannel(ChannelSet:tChannels; var schls:C_CVF.tChannels); var c:tChannel; begin schls:=[]; for c:=PNC1 to PNC_SEM do if c in ChannelSet then begin Include(schls,Channel2CVFChannel(c)); end; end; {------------------------------------------------------------------------} { Инициализация (без ввода/вывода в порты)} constructor tCtrl.Init(Ports:tPorts); const cMsgInit='Инициализация... '; var ch:tChannel; begin ProgressMessage(cMsgInit); Inc(SingleControllerLock); if (SingleControllerPTR<>@Self) and (SingleControllerLock<>1) then begin Dec(SingleControllerLock); SetErrorCode(tErrorCode(ecFailInit_MoreThenOneController)); Exit; end; SingleControllerPTR:=@Self; Inherited Init; prData.Flags:=[]; SkipMaskSetForExInit([]); SkipMaskSetForTest([]); SpecialFeaturesSet([]); MassCalibrationSet(0, 1.288E-9); IMChCalibrationSet(-324.9, 5.086E-7); SignalChannelSet(PNC1); CalibrateSetDelayTime(cCalibrateDelayTime); CalibrateSetRetryCount(cCalibrateRetryCount); SwitchesSetTimeOutSet(cSwitchesSetTimeOut); SignalTransformFlagsSet([]); MarkTime; prTmpData.InactiveControllers:=[]; prTmpData.LastSignals.Count:=Succ(Ord(High(ch))); for ch:=Low(ch) to High(ch) do begin prTmpData.LastSignals.Signals[ch]:=0; prTmpData.LastSignalsV.Signals[ch]:=0.0; prData.PNCZeroLevels[ch]:=0.0; end; prTmpData.LastSignalsV.Count:=Succ(Ord(High(ch))); { ProgressMessage(cMsgInit+'Контроллер ВВОДА/ВЫВОДА...');} prCtrlBus.InitDefault; { контроллер ВВОДА/ВЫВОДА в порты } if (prCtrlBus.Error) then begin SetErrorCode(tErrorCode(ecFailInit_ctrlBus)); end; { ProgressMessage(cMsgInit+'Контроллер пульта управления...');} ctrlPanel.InitDefault(prCtrlBus); { контроллер Пульта управления АК3} if (ctrlPanel.Error) then begin SetErrorCode(tErrorCode(ecFailInit_ctrlPanel)); end; { ProgressMessage(cMsgInit+'Контроллер блока питания источника ионов...');} ctrlISSB.InitDefault(prCtrlBus); { контроллер Блока питания источника ионов АК2} if (ctrlISSB.Error) then begin SetErrorCode(tErrorCode(ecFailInit_ctrlISSB)); end; { ProgressMessage(cMsgInit+'Контроллер электромагнита...');} ctrlRoll.InitDefault(prCtrlBus); { контроллер Магнита АК8} if (ctrlRoll.Error) then begin SetErrorCode(tErrorCode(ecFailInit_ctrlRoll)); end; { ProgressMessage(cMsgInit+'Контроллер измерения напряжений...');} ctrlVolts.InitDefault(prCtrlBus); { контроллер Напряжений АК5} if (ctrlVolts.Error) then begin SetErrorCode(tErrorCode(ecFailInit_ctrlVolts)); end; { ProgressMessage(cMsgInit+'Контроллер счетчика ионов...');} ctrlCount.InitDefault(prCtrlBus); { контроллер Счетчика ионов АК7} if (ctrlCount.Error) then begin SetErrorCode(tErrorCode(ecFailInit_ctrlCount)); end; { ProgressMessage(cMsgInit+'Контроллер ПНЧ...');} ctrlCVF.InitDefault(prCtrlBus); { контроллер ПНЧ АК9} if (ctrlCVF.Error) then begin SetErrorCode(tErrorCode(ecFailInit_ctrlCVF)); end; { ProgressMessage(cMsgInit);} if NoError then begin Include(prData.Flags, fInitDone); end; ProgressMessage(''); end; constructor tCtrl.InitDefault; begin Init(cDefaultPorts); end; function tCtrl.OperationTime:tTiks; var t,tx:tTiks; begin t:=Inherited OperationTime; tx:=ctrlISSB.OperationTime; if tx>t then t:=tx; tx:=ctrlPanel.OperationTime; if tx>t then t:=tx; tx:=ctrlVolts.OperationTime; if tx>t then t:=tx; tx:=ctrlCount.OperationTime; if tx>t then t:=tx; tx:=ctrlRoll.OperationTime; if tx>t then t:=tx; tx:=ctrlCVF.OperationTime; if tx>t then t:=tx; OperationTime:=t; end; destructor tCtrl.Done; begin if NotInitialized then Exit; ProgressMessage('Деинициализация...'); Inherited Done; Include(prData.Flags,fDone); if SingleControllerLock=1 then begin Dec(SingleControllerLock); end; ProgressMessage(''); end; function tCtrl.CompletelyInitiated:boolean; begin CompletelyInitiated:=IsExInitDone; end; function tCtrl.SaveToFile(const FName:PChar):boolean; (* type tByteArray=array[1..$FFFF] of Byte; tPtrByteArray=^tByteArray; var f:File; procedure xBlockWrite(const BlockToWrite; BlockSize:word); var sz:integer; begin BlockWrite(f,BlockToWrite,BlockSize,sz); if BlockSize<>sz then begin SetErrorCode(tErrorCode(ecDataSaveFileWrite)); end; end; var p,pD:tPtrByteArray; *) begin (* if NoError then begin GetMem(p, DataSize); pD:=p; Save(Pointer(pD)); if NoError then begin Assign(f,FName); Rewrite(f,1); xBlockWrite(cParameterFileHeader,Length(cParameterFileHeader)); if NoError then begin xBlockWrite(p^,DataSize); end; Close(f); end; FreeMem(p, DataSize); end; SaveToFile:=NoError;*) if NoError then begin SaveToFile:=SaveToFileX(FName); end else begin SaveToFile:=FALSE; end; end; (*procedure tCtrl.exRestoreFromFile; type tByteArray=array[1..$FFFF] of Byte; tPtrByteArray=^tByteArray; var f:File; procedure xBlockRead(var BlockToReadTo; BlockSize:word); var sz:integer; begin BlockRead(f,BlockToReadTo,BlockSize,sz); if BlockSize<>sz then begin SetErrorCode(tErrorCode(ecDataSaveFileREAD)); end; end; var p,pD:tPtrByteArray; {sz:integer;} Header:array[1..Length(cParameterFileHeader)] of Char; begin CheckExInitDone; if NoError then begin GetMem(p, DataSize); pD:=p; Assign(f,FName); Reset(f,1); xBlockRead(Header, SizeOf(Header)); if NoError then begin if Header=cParameterFileHeader then begin xBlockRead(p^,DataSize); if NoError then begin exRestore(Pointer(pD)); end; end else begin SetErrorCode(tErrorCode(ecDataSaveFileInavalidFile)); end; end; Close(f); FreeMem(p, DataSize); end; end; *) function tCtrl.SaveToFileX(const FName:PChar):boolean; type tByteArray=array[1..$FFFF] of Byte; tPtrByteArray=^tByteArray; var f:File; function xBlockWrite(const BlockToWrite; BlockSize:word):boolean; var sz:integer; begin BlockWrite(f,BlockToWrite,BlockSize,sz); xBlockWrite:=BlockSize=sz; end; var p,pD:tPtrByteArray; begin SaveToFileX:=FALSE; GetMem(p, DataSize); pD:=p; if Save(Pointer(pD)) then begin Assign(f,FName); Rewrite(f,1); if xBlockWrite(cParameterFileHeader,Length(cParameterFileHeader)) then begin SaveToFileX:=xBlockWrite(p^,DataSize); end; Close(f); end; FreeMem(p, DataSize); end; function tCtrl.RestoreFromFile(const FName:string):boolean; type tByteArray=array[1..$FFFF] of Byte; tPtrByteArray=^tByteArray; var f:File; function xBlockRead(var BlockToReadTo; BlockSize:word):boolean; var sz:integer; begin BlockRead(f,BlockToReadTo,BlockSize,sz); xBlockRead:=BlockSize=sz; end; var p,pD:tPtrByteArray; Header:array[1..Length(cParameterFileHeader)] of Char; begin RestoreFromFile:=False; GetMem(p, DataSize); pD:=p; Assign(f,FName); Reset(f,1); if xBlockRead(Header, SizeOf(Header)) then begin if Header=cParameterFileHeader then begin if xBlockRead(p^,DataSize) then begin RestoreFromFile:=Restore(Pointer(pD)); end; end; end; Close(f); FreeMem(p, DataSize); end; function tCtrl.Name; begin Name:='MI1201AGM'; end; (*function tCtrl.exRestore(var DataPtr:pointer):boolean; begin exRestore:=False; CheckExInitDone; if Error then Exit; if NoError then begin prCtrlBus.exRestore(DataPtr); if prCtrlBus.IsExInitDone and prCtrlBus.Error then SetErrorCode(tErrorCode(ecBusDataRestoreFail)); end; if NoError then begin ctrlPanel.exRestore(DataPtr); if ctrlPanel.IsExInitDone and ctrlPanel.Error then SetErrorCode(tErrorCode(ecPanelDataRestoreFail)); end; if NoError then begin ctrlISSB.exRestore(DataPtr); if ctrlISSB.IsExInitDone and ctrlISSB.Error then SetErrorCode(tErrorCode(ecISSBDataRestoreFail)); end; if NoError then begin ctrlCount.exRestore(DataPtr); if ctrlCount.IsExInitDone and ctrlCount.Error then SetErrorCode(tErrorCode(ecCountDataRestoreFail)); end; if NoError then begin ctrlCVF.exRestore(DataPtr); if ctrlCVF.IsExInitDone and ctrlCVF.Error then SetErrorCode(tErrorCode(ecCVFDataRestoreFail)); end; if NoError then begin ctrlVolts.exRestore(DataPtr); if ctrlVolts.IsExInitDone and ctrlVolts.Error then SetErrorCode(tErrorCode(ecVoltsDataRestoreFail)); end; if NoError then begin ctrlRoll.exRestore(DataPtr); if ctrlRoll.IsExInitDone and ctrlRoll.Error then SetErrorCode(tErrorCode(ecRollDataRestoreFail)); end; if NoError then begin Inherited exRestore(DataPtr); RestoreData(DataPtr, prData, SizeOf(prData)); // prData.InactiveControllers:=[]; end; exRestore:=NoError; end; *) (*function tCtrl.Save(var DataPtr:pointer):boolean; begin if NoError then begin prCtrlBus.Save(DataPtr); if prCtrlBus.Error then SetErrorCode(tErrorCode(ecBusDataSaveFail)); end; if NoError then begin ctrlPanel.Save(DataPtr); if ctrlPanel.Error then SetErrorCode(tErrorCode(ecPanelDataSaveFail)); end; if NoError then begin ctrlISSB.Save(DataPtr); if ctrlISSB.Error then SetErrorCode(tErrorCode(ecISSBDataSaveFail)); end; if NoError then begin ctrlCount.Save(DataPtr); if ctrlCount.Error then SetErrorCode(tErrorCode(ecCountDataSaveFail)); end; if NoError then begin ctrlCVF.Save(DataPtr); if ctrlCVF.Error then SetErrorCode(tErrorCode(ecCVFDataSaveFail)); end; if NoError then begin ctrlVolts.Save(DataPtr); if ctrlVolts.Error then Self.SetErrorCode(tErrorCode(ecVoltsDataSaveFail)); end; if NoError then begin ctrlRoll.Save(DataPtr); if ctrlRoll.Error then Self.SetErrorCode(tErrorCode(ecRollDataSaveFail)); end; if NoError then begin Inherited Save(DataPtr); StoreData(DataPtr, prData, SizeOf(prData)); end; Save:=NoError; end; *) function tCtrl.Restore(var DataPtr:pointer):boolean; begin Restore:=False; if prCtrlBus.Restore(DataPtr) then if ctrlPanel.Restore(DataPtr) then if ctrlISSB.Restore(DataPtr) then if ctrlCount.Restore(DataPtr) then if ctrlCVF.Restore(DataPtr) then if ctrlVolts.Restore(DataPtr) then if ctrlRoll.Restore(DataPtr) then if Inherited Restore(DataPtr) then Restore:=RestoreDataEx(DataPtr, prData, SizeOf(prData)); end; function tCtrl.Save(var DataPtr:pointer):boolean; begin Save:=FALSE; if prCtrlBus.Save(DataPtr) then if ctrlPanel.Save(DataPtr) then if ctrlISSB.Save(DataPtr) then if ctrlCount.Save(DataPtr) then if ctrlCVF.Save(DataPtr) then if ctrlVolts.Save(DataPtr) then if ctrlRoll.Save(DataPtr) then if Inherited Save(DataPtr) then Save:=StoreDataEx(DataPtr, prData, SizeOf(prData)); end; function tCtrl.DataSize:word; begin DataSize:=Inherited DataSize + DataSave.SizeOfData(SizeOf(prData))+ prCtrlBus.DataSize+ ctrlISSB.DataSize+ ctrlPanel.DataSize+ ctrlVolts.DataSize+ ctrlCount.DataSize+ ctrlRoll.DataSize+ ctrlCVF.DataSize; end; procedure tCtrl.ProgressMessage( const Msg:string); begin { пустышка - должен быть перекрыт } end; procedure tCtrl.Delay(time:word); begin prCtrlBus.Delay(time); end; procedure tCtrl.SkipMaskSetForExInit; begin prData.DoNotExInit:=x; end; procedure tCtrl.SkipMaskGetForExInit(var x:tControllers); begin x:=prData.DoNotExInit; end; procedure tCtrl.SkipMaskSetForTest; begin prData.DoNotTest:=x; end; {------------------------------------------------------------------------} { Установка параметров (без ввода/вывода в порты)} procedure tCtrl.SpecialFeaturesSet(x:tFeatures); begin prData.Features:=x; // ctrlRoll.FastExInitSet((XffRollFastExInit in x)); ctrlPanel.FlagSet(c_Panel.fSkipValvesClosingOnExInit,(ffSkipValvesExInit in x)); ctrlPanel.FlagSet(c_Panel.fSkipValvesClosingOnExDone,(ffSkipValvesExDone in x)); ctrlPanel.FlagSet(c_Panel.fBlocksRestoreOnExInit,(ffRestoreBlocksState in x)); end; procedure tCtrl.SpecialFeaturesGet(var x:tFeatures); begin x:=prData.Features-[ffRestoreBlocksState,ffSkipValvesExInit,ffSkipValvesExDone]; if ctrlPanel.FlagState(c_Panel.fSkipValvesClosingOnExInit) then begin Include(x, ffSkipValvesExInit); end; if ctrlPanel.FlagState(c_Panel.fSkipValvesClosingOnExDone) then begin Include(x, ffSkipValvesExDone); end; if ctrlPanel.FlagState(fBlocksRestoreOnExInit) then begin Include(x, ffRestoreBlocksState); end; end; (*procedure tCtrl.MassCalibrationSet(M1:tMass; Cnt1:longint; M2:tMass; Cnt2:longint); begin with prData do begin MassCalibration.SetCalibration(M1,Cnt1); MassCalibration.Refine(M2,Cnt2); if (MassCalibration.GetMass(2)>=M2) or (MassCalibration.GetCount(2)>=Cnt2) then begin SetErrorCode(tErrorCode(ecInvalidCalibrationParameters)); end; end; end; *) procedure tCtrl.MassCalibrationSetCurrentMass(m:tMass); var c:tCounter; begin prData.MassCalibration.Set_M0(0); prData.MassCalibration.Set_dC(0); c:=Mass2Counter(m); ctrlRoll.CounterRefine(c); prData.MassCalibration.CalculateAndSet_dC(c,m); end; procedure tCtrl.MassCalibrationSetCurrentCounter(c:tCounter); begin ctrlRoll.CounterRefine(c); end; procedure tCtrl.MassCalibrationSet; begin with prData do begin MassCalibration.Set_M0(M0); MassCalibration.Set_K(K); end; end; procedure tCtrl.MassCalibrationGet; begin with prData do begin M0:=MassCalibration.Get_M0; K:=MassCalibration.Get_K; end; end; procedure tCtrl.MassCalibrationGetEx(var MassCalibr:tMassCalibration); begin MassCalibr:=prData.MassCalibration; end; function tCtrl.MassCalibrationSetEx(const MassCalibr:tMassCalibration):boolean; begin if MassCalibr.Valid then begin prData.MassCalibration:=MassCalibr; MassCalibrationSetEx:=TRUE; end else begin MassCalibrationSetEx:=FALSE; end; end; function tCtrl.MassCalibrationPtr:tPMassCalibration; begin MassCalibrationPtr:=@prData.MassCalibration; end; function tCtrl.Mass2Counter(x:tMass):tMagnetCounter; begin Mass2Counter:=prData.MassCalibration.Mass2Counter(x); end; function tCtrl.MassValid; begin MassValid:=prData.MassCalibration.ValidMass(m); end; function tCtrl.Counter2Mass(x:tMagnetCounter):tMass; begin Counter2Mass:=prData.MassCalibration.Counter2Mass(x); end; procedure tCtrl.IMChCalibrationSet; begin with prData do begin IMChCalibration.Set_M0(0); IMChCalibration.Set_K(K); IMChCalibration.Set_dC(M0); end; end; procedure tCtrl.IMChCalibrationGet; begin with prData do begin // M0:=IMChCalibration.BaseCalibrationGetOrigin; M0:=IMChCalibration.Get_dC; K:=IMChCalibration.Get_K; end; end; function tCtrl.IMCh2Counter(x:tMkVolts):tMagnetCounter; begin IMCh2Counter:=Mass2Counter(IMCh2Mass(x)); end; function tCtrl.IMCh2Mass(x:tMkVolts):tMass; begin IMCh2Mass:=prData.IMChCalibration.Counter2Mass(x); end; function tCtrl.IMChValid; begin IMChValid:=(Low(tCounter)IMCh2 then begin prData.IMChCalibration.BaseCalibrationCalculate(IMCh1,IMCh2,C1,C2); end; exJumpTo(OldC); VoltageChannelSet(OldChl); exVoltageSelectChannel; end; end; procedure tCtrl.IntegrationTimeForChannelSet(t:word); begin IntegrationTimeForChannelSetEx(SignalChannel, t); end; procedure tCtrl.IntegrationTimeForChannelSetEx(u:tChannel; t:word); begin if u=IonCounter then begin IonCounterIntegrationTimeSet(t); end else begin PNCIntegrationTimeSet(t); end; end; function tCtrl.IntegrationTimeForChannelGet:word; begin IntegrationTimeForChannelGet:=IntegrationTimeForChannelGetEx(SignalChannel); end; function tCtrl.IntegrationTimeForChannelGetEx(u:tChannel):word; begin if u=IonCounter then begin IntegrationTimeForChannelGetEx:=IonCounterIntegrationTime; end else begin IntegrationTimeForChannelGetEx:=PNCIntegrationTime; end; end; procedure tCtrl.SignalTransformFlagsSet; begin prData.SignalTransformationFlags:=x; end; function tCtrl.SignalTransformFlagsIn; begin SignalTransformFlagsIn:=x in prData.SignalTransformationFlags; end; procedure tCtrl.SignalTransformFlagsInclude; begin Include(prData.SignalTransformationFlags,x); end; procedure tCtrl.SignalTransformFlagsExclude; begin Exclude(prData.SignalTransformationFlags,x); end; procedure tCtrl.SignalTransformFlagsGet; begin x:=prData.SignalTransformationFlags; end; procedure tCtrl.SignalChannelSet; begin prData.SignalChannel:=u; end; function tCtrl.SignalChannel; begin SignalChannel:=prData.SignalChannel; end; {------------------------------------------------------------------------} { Чтение текущих значений параметров (без ввода/вывода в порты)} (*procedure tCtrl.GetMassCalibration(var M1:tMass; var Cnt1:longint; var M2:tMass; var Cnt2:longint); begin with prData do begin M1:=MassCalibration.GetMass(1); M2:=MassCalibration.GetMass(2); Cnt1:=MassCalibration.GetCount(1); Cnt2:=MassCalibration.GetCount(2); end; end; *) function tCtrl.Mass; begin Mass:=Counter2Mass(ctrlRoll.Counter); end; function tCtrl.MassMax:tMass; begin MassMax:=100000; end; function tCtrl.MassMin:tMass; begin MassMin:=0; end; procedure tCtrl.VoltageReadParametersSet(DelayTime:word; RetryCount:word); begin ctrlVolts.RetryDelay(DelayTime); ctrlVolts.RetryCount(RetryCount); end; procedure tCtrl.VoltageReadParametersGet(var DelayTime:word; var RetryCount:word); begin DelayTime:=ctrlVolts.CurRetryDelay; RetryCount:=ctrlVolts.CurRetryCount; end; function tCtrl.CalibrateValid:boolean; begin CalibrateValid:=ctrlCVF.CalibrationValid; end; {------------------------------------------------------------------------} { Вспомогательные функции (без ввода/вывода в порты)} procedure tCtrl.SetNoError; begin prCtrlBus.SetNoError; ctrlISSB.SetNoError; ctrlPanel.SetNoError; ctrlVolts.SetNoError; ctrlCount.SetNoError; ctrlRoll.SetNoError; ctrlCVF.SetNoError; inherited SetNoError; Include(prData.Flags, fSetNoErrorCall); end; procedure tCtrl.SetErrorCode; begin Inherited SetErrorCode(ErrCode); if tErrorCodes(ErrCode)=ecAbort then begin ctrlCVF.SetErrorCode(ErrCode); ctrlCount.SetErrorCode(ErrCode); ctrlRoll.SetErrorCode(ErrCode); ctrlISSB.SetErrorCode(ErrCode); ctrlPanel.SetErrorCode(ErrCode); ctrlVolts.SetErrorCode(ErrCode); prCtrlBus.SetErrorCode(ErrCode); end; end; procedure tCtrl.ErrorGetCtrlsWith; begin c:=[]; if (prCtrlBus.Error) {and (prCtrlBus.ErrorCode <> Word(ecNotInitialized))} then Include(c, Bus); if (ctrlISSB.Error) {and (ctrlISSB.ErrorCode <> Word(ecNotInitialized))} then Include(c, ISSB); if (ctrlPanel.Error) {and (ctrlPanel.ErrorCode <> Word(ecNotInitialized))} then Include(c, Panel); if (ctrlVolts.Error) {and (ctrlVolts.ErrorCode <> Word(ecNotInitialized))} then Include(c, Volts); if (ctrlCount.Error) {and (ctrlCount.ErrorCode <> Word(ecNotInitialized))} then Include(c, Count); if (ctrlRoll.Error) {and (ctrlRoll.ErrorCode <> Word(ecNotInitialized))} then Include(c, Roll); if (ctrlCVF.Error) {and (ctrlCVF.ErrorCode <> Word(ecNotInitialized))} then Include(c, CVF); end; function tCtrl.ErrorGetFirstCtrlWith; var cs:tControllers; c:tController; begin ErrorGetFirstCtrlWith:=None; ErrorGetCtrlsWith(cs); for c:=Low(c) to High(c) do begin if c in cs then begin ErrorGetFirstCtrlWith:=c; Exit; end; end; end; function tCtrl.ErrorCodeFromSubCtrl; var ctrls:tControllers; begin ErrorGetCtrlsWith(ctrls); ErrorCodeFromSubCtrl:=0; if Bus in ctrls then ErrorCodeFromSubCtrl:=prCtrlBus.ErrorCode else if ISSB in ctrls then ErrorCodeFromSubCtrl:=ctrlISSB.ErrorCode else if Panel in ctrls then ErrorCodeFromSubCtrl:=ctrlPanel.ErrorCode else if Volts in ctrls then ErrorCodeFromSubCtrl:=ctrlVolts.ErrorCode else if Count in ctrls then ErrorCodeFromSubCtrl:=ctrlCount.ErrorCode else if Roll in ctrls then ErrorCodeFromSubCtrl:=ctrlRoll.ErrorCode else if CVF in ctrls then ErrorCodeFromSubCtrl:=ctrlCVF.ErrorCode; end; function tCtrl.ErrorMessagesFromSubControllers; var ctrls:tControllers; msg:string; const cLF=#13' '; begin ErrorGetCtrlsWith(ctrls); msg:='Субконтроллеры:'; if Bus in ctrls then msg:=msg+cLF+'Шина: ' +prCtrlBus.CurErrorMessage+'.'; if ISSB in ctrls then msg:=msg+cLF+'БПГИ: ' +ctrlISSB.CurErrorMessage+'.'; if Panel in ctrls then msg:=msg+cLF+'Панель упр.: ' +ctrlPanel.CurErrorMessage+'.'; if Volts in ctrls then msg:=msg+cLF+'Изм. напряжений: '+ctrlVolts.CurErrorMessage+'.'; if Count in ctrls then msg:=msg+cLF+'Счет.ионов: ' +ctrlCount.CurErrorMessage+'.'; if Roll in ctrls then msg:=msg+cLF+'Эл.магнит: ' +ctrlRoll.CurErrorMessage+'.'; if CVF in ctrls then msg:=msg+cLF+'ПНЧ: ' +ctrlCVF.CurErrorMessage+'.'; ErrorMessagesFromSubControllers:=msg; end; function tCtrl.ErrorMessage(en:tErrorCode):string; var EMsg:string; begin case tErrorCodes(en) of {Инициализация Init} ecFailInit_MoreThenOneController: EMsg:='Попытка инициализировать ВТОРОЙ контроллер MI1201'; ecFailInit_ctrlBus: EMsg:='Ошибка инициализации программы контроллера ввода/вывода'; ecFailInit_ctrlISSB: EMsg:='Ошибка инициализации программы контроллера блока питания источника ионов'; ecFailInit_ctrlPanel: EMsg:='Ошибка инициализации программы контроллера панели управления'; ecFailInit_ctrlVolts: EMsg:='Ошибка инициализации программы контроллера измерения напряжений'; ecFailInit_ctrlCount: EMsg:='Ошибка инициализации программы контроллера счетчика ионов'; ecFailInit_ctrlRoll: EMsg:='Ошибка инициализации программы контроллера магнита'; ecFailInit_ctrlCVF: EMsg:='Ошибка инициализации программы контроллера ПНЧ'; {Инициализация-exInit} ecFailExInit_ctrlBus: EMsg:='Ошибка инициализации оборудования контроллера ввода/вывода'; ecFailExInit_ctrlISSB: EMsg:='Ошибка инициализации оборудования контроллера блока питания источника ионов. Возможно не включен выключатель'+ ' "Сеть" на панели'; ecFailExInit_ctrlPanel: EMsg:='Ошибка инициализации оборудования контроллера панели управления'; ecFailExInit_ctrlVolts: EMsg:='Ошибка инициализации оборудования контроллера измерения напряжений'; ecFailExInit_ctrlCount: EMsg:='Ошибка инициализации оборудования контроллера счетчика ионов'; ecFailExInit_ctrlRoll: EMsg:='Ошибка инициализации оборудования контроллера магнита'; ecFailExInit_ctrlCVF: EMsg:='Ошибка инициализации оборудования контроллера ПНЧ'; { Переключения Вкл./Выкл.} ecFail_ctrlPanel_CurBlocks: EMsg:='Ошибка чтения состояния вкл/выкл. блоков контроллера панели управления'; ecFail_ctrlISSB_CurFlags: EMsg:='Ошибка чтения флагов состояния контроллера блока питания источника ионов'; ecFail_ctrlPanel_CurInOutOpen: EMsg:='Ошибка чтения состояния откр/закр. клапанов магистралей контроллера панели управления'; ecFail_ctrlCVF_CurRegime: EMsg:='Ошибка чтения режима контроллера ПНЧ'; ecFail_ctrlISSB_exCurBeam: EMsg:='Ошибка чтения состояния луча контроллера блока питания источника ионов'; ecFail_ctrlPanel_Blocks: EMsg:='Ошибка установки состояния вкл/выкл. блоков'; ecFail_ctrlPanel_exSetValves: EMsg:='Ошибка установки состояния откр/закр. клапанов'; ecFail_ctrlPanel_InOutOpen: EMsg:='Ошибка установки состояния откр/закр. клапанов магистралей контроллера панели управления'; ecFail_ctrlCVF_Regime: EMsg:='Ошибка установки режима контроллера ПНЧ'; ecFail_ctrlISSB_exBeam: EMsg:='Ошибка установки состояния луча контроллера блока питания источника ионов'; ecFail_exSwitchesSet: EMsg:='Ошибка переключения блоков - не удалось переключить за время ожидания'; { Переключения ИСТОЧНИКА газа} ecFail_ctrlPanel_exCurSource: EMsg:='Ошибка чтения состояния вкл/выкл. клапанов источника контроллера панели управления'; ecFail_ctrlPanel_exIntelliSource: EMsg:='Ошибка установки состояния вкл/выкл. клапанов источника контроллера панели управления'; ecFail_ctrlPanel_exSource: EMsg:='Ошибка установки состояния вкл/выкл. клапанов источника контроллера панели управления'; { Управление магнитом } ecInvalidCalibrationParameters: EMsg:='Ошибочные параметры калибровки массы. Должно быть M1s*SwitchesMask) and ti.NotIntervalEnd do begin Delay(5); exSwitchesGet(s); end; exSwitchesWaitMaskEx:=NoError and (Switches=s*SwitchesMask); end; function tCtrl.exSwitchesWaitMask(Switches,SwitchesMask:tSwitches):boolean; begin exSwitchesWaitMask:=exSwitchesWaitMaskEx(Switches,SwitchesMask,SwitchesSetTimeOut); end; function tCtrl.exSwitchesWait(Switches:tSwitches):boolean; begin exSwitchesWait:=exSwitchesWaitMaskEx(Switches,[Low(tSwitch)..High(tSwitch)],SwitchesSetTimeOut); end; procedure tCtrl.exSwitchTurnON(ASwitch:tSwitch); var xs:tSwitches; begin CheckExInitDone; exSwitchesGet(xs); If (NoError) and not (ASwitch in xs) then begin Include(xs,ASwitch); exSwitchesSet(xs); end; end; procedure tCtrl.exSwitchTurnOFF(ASwitch:tSwitch); var xs:tSwitches; begin CheckExInitDone; exSwitchesGet(xs); If (NoError) and (ASwitch in xs) then begin Exclude(xs,ASwitch); exSwitchesSet(xs); end; end; procedure tCtrl.exSourceSet(x:tSource); begin CheckExInitDone; If NoError then begin if not InactiveCtrl(Panel) then ctrlPanel.exSourceSet(x); if ctrlPanel.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlPanel_exSource)); end; end; end; procedure tCtrl.exSourceIntelliSet(x:tSource; DelayTime:word; var DeltaOfAllCounters:tGeneralSignalData); var c:tGeneralSignalData; begin CheckExInitDone; DeltaOfAllCounters:=0; If NoError then begin if exSource<>sCloseAll then begin exSourceSet(sCloseAll); If Error then Exit; Delay(DelayTime); end; c:=ctrlCVF.CurAverageOverActiveChannels; if ctrlPanel.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlPanel_exIntelliSource)); Exit; end; exSourceSet(x); If Error then Exit; Delay(DelayTime); c:=(c-ctrlCVF.CurAverageOverActiveChannels); if ctrlPanel.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlPanel_exIntelliSource)); Exit; end; DeltaOfAllCounters:=c; end; end; function ValidValves(x:tValves):boolean; var i:word; j:tValve; begin i:=0; for j:=vSample1 to vPumping do begin if j in x then Inc(i); end; ValidValves:=(i<=1); end; procedure Valves2SrcAndLines(x:tValves; var s:tSource; var ls:c_Panel.tValves); begin if vSample1 in x then s:=sSample1 else if vSample2 in x then s:=sSample2 else if vStandard1 in x then s:=sStandard1 else if vStandard2 in x then s:=sStandard2 else if vStandard3 in x then s:=sStandard3 else if vStandard4 in x then s:=sStandard4 else if vPumping in x then s:=sPumping else s:=sCloseAll; ls:=[]; if vLineOut1 in x then Include(ls,c_Panel.fLine1Out); if vLineOut2 in x then Include(ls,c_Panel.fLine2Out); if vLineIn1 in x then Include(ls,c_Panel.fLine1In); if vLineIn2 in x then Include(ls,c_Panel.fLine2In); end; procedure SrcAndLines2Valves(s:tSource; ls:c_Panel.tValves; var x:tValves); begin x:=[]; if s=sSample1 then Include(x, vSample1) else if s=sSample1 then Include(x, vSample2) else if s=sStandard1 then Include(x, vStandard1) else if s=sStandard2 then Include(x, vStandard2) else if s=sStandard3 then Include(x, vStandard3) else if s=sStandard4 then Include(x, vStandard4) else if s=sPumping then Include(x, vPumping); if c_Panel.fLine1Out in ls then Include(x,vLineOut1); if c_Panel.fLine2Out in ls then Include(x,vLineOut2); if c_Panel.fLine1In in ls then Include(x,vLineIn1); if c_Panel.fLine2In in ls then Include(x,vLineIn2); end; procedure tCtrl.exValvesSetOpen(x:tValves); var s:tSource; ls:c_Panel.tValves; begin CheckExInitDone; If NoError then begin if ValidValves(x) then begin Valves2SrcAndLines(x, s,ls); if not InactiveCtrl(Panel) then begin ctrlPanel.exSourceSet(s); ctrlPanel.exInOutOpenSet(ls); end; if ctrlPanel.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlPanel_exSetValves)); end; end else begin SetErrorCode(tErrorCode(ecFail_InvalidValves)); end; end; end; { Чтение текущих значений параметров } procedure tCtrl.exSwitchesGet(var ASwitches:tSwitches); var r:c_CVF.tRegime; b:c_Panel.tBlocks; i:tCtrlFlags; begin CheckExInitDone; ASwitches:=[]; If NoError then begin if not InactiveCtrl(Panel) then ctrlPanel.exBlocksONGet(b) else b:=[]; if ctrlPanel.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlPanel_CurBlocks)); Exit; end; ctrlCVF.CurRegime(r); if ctrlCVF.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlCVF_CurRegime)); Exit; end; CVFRegimeAdd2Switches(r, ASwitches); PanelBlocksAdd2Switches(b, ASwitches); if not InactiveCtrl(ISSB) then begin ctrlISSB.exCurFlags(i) end else i:=[]; if ctrlISSB.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlISSB_CurFlags)); Exit; end; ISSBCtrlFlagsAdd2Switches(i,ASwitches); end; end; function tCtrl.exSwitchIsON(ASwitch:tSwitch):boolean; var xs:tSwitches; begin exSwitchIsON:=False; exSwitchesGet(xs); If NoError then begin exSwitchIsON:=(ASwitch in xs); end; end; function tCtrl.exSwitchesIs(ASwitches:tSwitches):boolean; var xs:tSwitches; begin exSwitchesGet(xs); If NoError then begin exSwitchesIs:=(ASwitches=xs); end else begin exSwitchesIs:=FALSE; end; end; function tCtrl.exSwitchesIsON(ASwitches:tSwitches):boolean; var xs:tSwitches; begin exSwitchesGet(xs); If NoError then begin exSwitchesIsON:=(ASwitches=xs*ASwitches); end else begin exSwitchesIsON:=FALSE; end; end; function tCtrl.exSwitchesIsOFF(ASwitches:tSwitches):boolean; var xs:tSwitches; begin exSwitchesGet(xs); If NoError then begin exSwitchesIsOFF:=(xs*ASwitches=[]); end else begin exSwitchesIsOFF:=TRUE; end; end; function tCtrl.exSource:tSource; begin if Error then begin exSource:=sBad; end else begin if not InactiveCtrl(Panel) then exSource:=ctrlPanel.exSource else exSource:=sCloseAll; if ctrlPanel.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlPanel_exCurSource)); end; end; end; procedure tCtrl.exValvesGetOpen(var x:tValves); var s:tSource; ls:c_Panel.tValves; begin x:=[]; if Error then Exit; if not InactiveCtrl(Panel) then begin s:=ctrlPanel.exSource; ctrlPanel.exInOutOpenGet(ls); end else begin s:=sCloseAll; ls:=[]; end; if ctrlPanel.NoError then begin SrcAndLines2Valves(s,ls, x); end else begin SetErrorCode(tErrorCode(ecFail_ctrlPanel_exCurSource)); end; end; function tCtrl.exVoltage:tMkVolts; begin CheckExInitDone; exVoltage:=0; If NoError then begin if InactiveCtrl(Panel) then begin exVoltage:=0; end else begin exVoltage:=ctrlVolts.exCurVoltage; if ctrlVolts.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlVolts_exVoltage)); end; end; end; end; procedure tCtrl.exVoltageSelectChannel; begin CheckExInitDone; If NoError then begin if not InactiveCtrl(Panel) then begin ctrlVolts.ChannelChanged; ctrlVolts.exCurVoltageFast; if ctrlVolts.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlVolts_exVoltage)); end; end; end; end; procedure tCtrl.VoltageChannelSet; begin ctrlVolts.Channel(x); end; function tCtrl.VoltageChannel; begin VoltageChannel:=ctrlVolts.CurChannel; end; function tCtrl.exSignal:tGeneralSignalData; begin if SignalChannel=IonCounter then begin exIonCounterGet; end else begin exPNCDataGet; end; exSignal:=Signal; end; function tCtrl.Signal:tGeneralSignalData; begin Signal:=SignalEx(SignalChannel); end; function tCtrl.SignalEx(cl:tChannel):tGeneralSignalData; var s:tGeneralSignalData; {t:longint;} begin if cl=IonCounter then begin if not (fAtLeastOneGetICountDone in prData.Flags) then exSignal; s:=ctrlCount.CurCount; { if (fDoNormalization in prData.SignalTransformationFlags) then begin t:=IonCounterIntegrationTime; s:=(s + (t shr 1)) div t; end;} end else begin if not (fAtLeastOneGetPNCDone in prData.Flags) then exSignal; if (fUseMkVolts in prData.SignalTransformationFlags) then begin s:=PNC_U(Channel2CVFChannel(cl)); end else begin s:=PNC(Channel2CVFChannel(cl)); { if (fDoNormalization in prData.SignalTransformationFlags) then begin t:=PNCIntegrationTime; s:=(s + (t shr 1)) div t; end;} end; end; SignalEx:=s; end; function tCtrl.SignalNorm:tNormalizedSignalData; begin SignalNorm:=SignalNormEx(SignalChannel); end; function tCtrl.SignalNormEx(cl:tChannel):tNormalizedSignalData; var t:longint; s:tGeneralSignalData; begin if cl=IonCounter then begin if not (fAtLeastOneGetICountDone in prData.Flags) then exSignal; s:=ctrlCount.CurCount; t:=IonCounterIntegrationTime; end else begin if not (fAtLeastOneGetPNCDone in prData.Flags) then exSignal; s:=PNC(Channel2CVFChannel(cl)); t:=PNCIntegrationTime; end; SignalNormEx:=s/t; end; function tCtrl.SignalV:double; begin SignalV:=SignalVEx(SignalChannel); end; function tCtrl.SignalVEx(cl:tChannel):double; begin if cl=IonCounter then begin if not (fAtLeastOneGetICountDone in prData.Flags) then exSignal; SignalVEx:=ctrlCount.CurCount/IonCounterIntegrationTime; end else begin if not (fAtLeastOneGetPNCDone in prData.Flags) then exSignal; SignalVEx:=PNC_V(Channel2CVFChannel(cl))-prData.PNCZeroLevels[cl]; end; end; function tCtrl.exIonCounterGet:tGeneralSignalData; begin CheckExInitDone; exIonCounterGet:=0; If (NoError) then begin if not InactiveCtrl(Count) then exIonCounterGet:=ctrlCount.exGetData; if ctrlCount.NoError then begin Include(prData.Flags, fAtLeastOneGetICountDone); end else begin SetErrorCode(tErrorCode(ecFail_ctrlCount_exStartOrRead)); end; end; end; procedure tCtrl.exSignalsStart; begin // t0:=GetTickCount; if Error then Exit; if not InactiveCtrl(Count) then begin ctrlCount.exStart; if ctrlCount.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlCount_exStart)); Exit; end; end; if not InactiveCtrl(CVF) then begin // if not CalibrateValid then exCalibrate; ctrlCVF.exStart; if ctrlCVF.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlCVF_exStart)); end; end; MarkTime; prTmpData.LastSignals.Time:=IntegrationTime; prTmpData.LastSignals.Mass:=Mass; // t1:=GetTickCount; end; function tCtrl.exSignalsReady:boolean; begin exSignalsReady:=(InactiveCtrl(CVF) or ctrlCVF.exReady) and (InactiveCtrl(Count) or ctrlCount.exReady); end; procedure tCtrl.SignalsWait; var t,tc:word; begin if Error then Exit; if exSignalsReady then Exit; if not InactiveCtrl(Count) then t:=ctrlCount.CurIntegrationTime else t:=0; if not InactiveCtrl(CVF) then tc:=ctrlCVF.CurIntegrationTime else tc:=0; if tc>t then t:=tc; Delay(IntelliTimeOut(t,0)); end; procedure tCtrl.exSignalsWait; begin if Error then Exit; if exSignalsReady then Exit; if not InactiveCtrl(CVF) then begin ctrlCVF.exWaitReady; end; if not InactiveCtrl(Count) then begin ctrlCount.exWaitReady; end; end; procedure tCtrl.exSignalsRead; var i:tChannel; begin if NoError then begin if not InactiveCtrl(Count) then begin ctrlCount.exRead; if ctrlCount.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlCount_exRead)); end; end; end else begin Exit; end; if NoError then begin if not InactiveCtrl(CVF) then ctrlCVF.exRead; if ctrlCount.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlCVF_exRead)); end; end; if Error then Exit; for i:=Low(i) to High(i) do begin prTmpData.LastSignals.Signals[i]:=SignalEx(i); end; SignalsGet(Signals); end; procedure tCtrl.exSignalsVRead; var i:tChannel; begin // t2:=GetTickCount; // t3:=GetTickCount; if NoError then begin if not InactiveCtrl(CVF) then ctrlCVF.exRead; if ctrlCount.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlCVF_exRead)); end; end else begin Exit; end; if NoError then begin if not InactiveCtrl(Count) then begin ctrlCount.exRead; if ctrlCount.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlCount_exRead)); end; end; end; if Error then Exit; prTmpData.LastSignalsV.Time:=prTmpData.LastSignals.Time; prTmpData.LastSignalsV.Mass:=prTmpData.LastSignals.Mass; ctrlCVF.ChannelsV(cWorkingChannels,prTmpData.LastSignalsV.Signals[PNC1],6); for i:=PNC1 to PNC_SEM do begin prTmpData.LastSignalsV.Signals[i]:=prTmpData.LastSignalsV.Signals[i]-prData.PNCZeroLevels[i]; end; prTmpData.LastSignalsV.Signals[IonCounter]:=ctrlCount.CurCount/ctrlCount.CurIntegrationTime; // t4:=GetTickCount; SignalsVGet(Signals); end; procedure tCtrl.exSignalsNormRead; var i:tChannel; begin if Error then Exit; if not InactiveCtrl(Count) then begin ctrlCount.exRead; if ctrlCount.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlCount_exRead)); end; end; if NoError then begin if not InactiveCtrl(CVF) then ctrlCVF.exRead; if ctrlCount.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlCVF_exRead)); end; end; if Error then Exit; prTmpData.LastSignalsNorm.Time:=prTmpData.LastSignals.Time; prTmpData.LastSignalsNorm.Mass:=prTmpData.LastSignals.Mass; for i:=Low(i) to High(i) do begin prTmpData.LastSignalsNorm.Signals[i]:=SignalNormEx(i); end; SignalsNormGet(Signals); end; procedure tCtrl.exSignalsGet; begin exSignalsStart; exSignalsRead(Signals); end; procedure tCtrl.exSignalsVGet; begin exSignalsStart; exSignalsVRead(Signals); end; procedure tCtrl.exSignalsNormGet; begin exSignalsStart; exSignalsNormRead(Signals); end; procedure tCtrl.SignalsGet; begin Signals:=prTmpData.LastSignals; end; procedure tCtrl.SignalsVGet; begin Signals:=prTmpData.LastSignalsV; end; procedure tCtrl.SignalsNormGet; begin Signals:=prTmpData.LastSignalsNorm; end; procedure tCtrl.IonCounterIntegrationTimeSet(x:word); begin ctrlCount.IntegrationTime(x); end; function tCtrl.IonCounterIntegrationTime:word; begin IonCounterIntegrationTime:=ctrlCount.CurIntegrationTime; end; procedure tCtrl.PNCIntegrationTimeSet(x:word); begin ctrlCVF.IntegrationTime(x); end; function tCtrl.PNCIntegrationTime:word; begin PNCIntegrationTime:=ctrlCVF.CurIntegrationTime; end; procedure tCtrl.exPNCDataGet; begin CheckExInitDone; If (NoError) then begin if not InactiveCtrl(CVF) then begin // ctrlCVF.Regime(c_CVF.cWorkRegime); ctrlCVF.exGetData; end; if ctrlCVF.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlCVF_exGetData)); end else begin Include(prData.Flags, fAtLeastOneGetPNCDone); end; end; end; function tCtrl.PNC(Channel:c_CVF.tChannel):tGeneralSignalData; begin PNC:=0; if not (fAtLeastOneGetPNCDone in prData.Flags) then exPNCDataGet; If (NoError) then begin PNC:=ctrlCVF.Channel(Channel); end; end; function tCtrl.PNC_U(Channel:c_CVF.tChannel):tGeneralSignalData; begin if not CalibrateValid then exCalibrate; PNC_U:=ctrlCVF.ChannelU(Channel); end; function tCtrl.PNC_V(Channel:c_CVF.tChannel):double; begin if not CalibrateValid then exCalibrate; PNC_V:=ctrlCVF.ChannelV(Channel); end; procedure tCtrl.CalibrateSetDelayTime(x:word); begin if prData.CalibratePNCDelayTime<>x then begin prData.CalibratePNCDelayTime:=x; ctrlCVF.CalibrationSetInvalid; end; end; procedure tCtrl.CalibrateSetRetryCount(x:word); begin if prData.CalibratePNCRetryCount<>x then begin prData.CalibratePNCRetryCount:=x; ctrlCVF.CalibrationSetInvalid; end; end; function tCtrl.CalibrateDelayTime:word; begin CalibrateDelayTime:=prData.CalibratePNCDelayTime; end; function tCtrl.CalibrateRetryCount:word; begin CalibrateRetryCount:=prData.CalibratePNCRetryCount; end; procedure tCtrl.exSignalsZeroLevelsMeasure; begin exSignalsZeroLevelsMeasureEx([Low(tChannel)..High(tChannel)]); end; procedure tCtrl.exSignalsZeroLevelsMeasureEx(ChannelsSet:tChannels); var cl:tChannel; lZL:tSignalsVArray; sws:tSwitches; s:tSignalsV; begin if NoError then begin for cl:=Low(cl) to High(cl) do if cl in ChannelsSet then begin lZL[cl]:=prData.PNCZeroLevels[cl]; prData.PNCZeroLevels[cl]:=0.0; end; exSwitchesGet(sws); exSwitchTurnON(fCVF_InputEMU); exSwitchTurnOFF(fCVF_Beam); exSignalsVGet(s); if NoError then begin for cl:=Low(cl) to High(cl) do if cl in ChannelsSet then begin prData.PNCZeroLevels[cl]:=s.Signals[cl]; end; end else begin for cl:=Low(cl) to High(cl) do if cl in ChannelsSet then begin prData.PNCZeroLevels[cl]:=lZL[cl]; end; end; exSwitchesSet(sws); end; end; procedure tCtrl.SignalsZeroLevelsGet(var ZLs:tSignalsVArray); begin ZLs:=prData.PNCZeroLevels; end; procedure tCtrl.SignalsZeroLevelsSet(const ZLs:tSignalsVArray); begin prData.PNCZeroLevels:=ZLs; end; function tCtrl.SignalZeroLevelGet(cl:tChannel):double; begin SignalZeroLevelGet:=prData.PNCZeroLevels[cl]; end; procedure tCtrl.SignalZeroLevelSet(cl:tChannel; ZL:double); begin prData.PNCZeroLevels[cl]:=zl; end; procedure tCtrl.exCalibrate; begin exCalibrateEx([Low(tChannel)..High(tChannel)]); end; procedure tCtrl.exCalibrateEx(ChannelSet:tChannels); var r:c_CVF.tRegime; t, c:word; chnl:tVoltageChannel; chls:C_CVF.tChannels; sws:tSwitches; begin CheckExInitDone; If NoError and (not InactiveCtrl(CVF)) then begin exSwitchesGet(sws); // exSwitchTurnON(fCVF_InputEMU); exSwitchTurnOFF(fCVF_Beam); ctrlCVF.CurRegime(r); VoltageReadParametersGet(t, c); VoltageReadParametersSet(CalibrateDelayTime, CalibrateRetryCount); chnl:=VoltageChannel; VoltageChannelSet(BaseUPT); if (not InactiveCtrl(Volts)) then ctrlVolts.exCurVoltageFast; if (not InactiveCtrl(Volts)) then begin ctrlCVF.exCalibrationRegime0; prData.U0:=exVoltage; end else begin prData.U0:=0; end; if (not InactiveCtrl(Volts)) then begin ctrlCVF.exCalibrationRegime1; prData.U1:=exVoltage; end else begin prData.U1:=-9000000; end; if NoError then begin Include(prData.Flags, fPNCCalibrationUisMeasured); ChannelsToCVFChannel(ChannelSet,chls); ctrlCVF.exCalibrateEx(prData.U0,prData.U1,chls); if ctrlCVF.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlCVF_exCalibration)); end; end; VoltageReadParametersSet(t, c); ctrlCVF.Regime(r); if Error then ctrlCVF.CalibrationSetInvalid; VoltageChannelSet(chnl); ctrlVolts.exCurVoltageFast; exSignalsZeroLevelsMeasureEx(ChannelSet); exSwitchesSet(sws); end; end; procedure tCtrl.exCalibrateFast; begin if (fPNCCalibrationUisMeasured in prData.Flags) then begin If NoError and (not InactiveCtrl(CVF)) then begin ctrlCVF.exCalibrate(prData.U0, prData.U1); exSignalsZeroLevelsMeasure; if ctrlCVF.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlCVF_exCalibration)); end; end; end else begin exCalibrate; end; end; procedure tCtrl.exDeviceUSet(Device:tDevice; Value:longint); begin if Device=UnknownDevice then EXIT; CheckExInitDone; If NoError then begin if Device=SEM_Voltage then begin ctrlPanel.exSEM_ValueSet(Value); if ctrlPanel.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlPanel_exSetValue)); end; end else begin ctrlISSB.exSetValue(c_ISSB.tUnit(Device), Value); if ctrlISSB.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlISSB_exSetValue)); end; end; end; end; procedure tCtrl.exDeviceReset(Device:tDevice); begin if Device=UnknownDevice then EXIT; CheckExInitDone; If NoError then begin if Device=SEM_Voltage then begin end else begin ctrlISSB.exResetValue(c_ISSB.tUnit(Device)); if ctrlISSB.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlISSB_exResetValue)); end; end; end; end; procedure tCtrl.exDeviceCounterSet(Device:tDevice; Value:word); begin if Device=UnknownDevice then EXIT; CheckExInitDone; If NoError then begin if Device=SEM_Voltage then begin ctrlPanel.exSetCountSEM(Value); if ctrlPanel.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlPanel_exSetValue)); end; end else begin ctrlISSB.exSetCount(c_ISSB.tUnit(Device), Value); if ctrlISSB.Error then begin SetErrorCode(tErrorCode(ecFail_ctrlISSB_exSetValue)); end; end; end; end; function tCtrl.DeviceCounterMax(Device:tDevice):word; begin if Device=UnknownDevice then begin DeviceCounterMax:=0; end else if Device=SEM_Voltage then begin DeviceCounterMax:=ctrlPanel.SEMCountMax; end else begin DeviceCounterMax:=ctrlISSB.MaxCount(c_ISSB.tUnit(Device)); end; end; function tCtrl.DeviceCounter(Device:tDevice):word; begin if Device=UnknownDevice then begin DeviceCounter:=0; end else if Device=SEM_Voltage then begin DeviceCounter:=ctrlPanel.SEMCount; end else begin DeviceCounter:=ctrlISSB.CurCount(c_ISSB.tUnit(Device)); end; end; function tCtrl.DeviceUMax(Device:tDevice):longint; begin if Device=UnknownDevice then begin DeviceUMax:=0; end else if Device=SEM_Voltage then begin DeviceUMax:=ctrlPanel.SEMMax; end else begin DeviceUMax:=ctrlISSB.MaxValue(c_ISSB.tUnit(Device)); end; end; function tCtrl.DeviceUMin(Device:tDevice):longint; begin if Device=UnknownDevice then begin DeviceUMin:=0; end else if Device=SEM_Voltage then begin DeviceUMin:=ctrlPanel.SEMMin; end else begin DeviceUMin:=ctrlISSB.MinValue(c_ISSB.tUnit(Device)); end; end; function tCtrl.DeviceUStep(Device:tDevice):longint; begin if Device=UnknownDevice then begin DeviceUStep:=0; end else if Device=SEM_Voltage then begin DeviceUStep:=ctrlPanel.SEMStep; end else begin DeviceUStep:=ctrlISSB.Step(c_ISSB.tUnit(Device)); end; end; function tCtrl.DeviceU(Device:tDevice):longint; begin if Device=UnknownDevice then begin DeviceU:=0; end else if Device=SEM_Voltage then begin DeviceU:=ctrlPanel.exSEM_Value; end else begin DeviceU:=ctrlISSB.CurValue(c_ISSB.tUnit(Device)); end; end; function tCtrl.DeviceIndicator(Device:tDevice):integer; begin if Device=UnknownDevice then begin DeviceIndicator:=0; end else if Device=SEM_Voltage then begin DeviceIndicator:=ctrlPanel.exSEM_Value; end else begin DeviceIndicator:=ctrlISSB.Indicator(c_ISSB.tUnit(Device)); end; end; function tCtrl.exCatodOK:boolean; begin exCatodOK:=not exCatodBurnOut; end; function tCtrl.exCatodBurnOUT:boolean; var x:tEmergencyFlags; begin exEmergencyFlagsGet(x); exCatodBurnOut:=(efCatodBurnOUT in x); end; function tCtrl.exOverload:boolean; var x:tEmergencyFlags; begin exEmergencyFlagsGet(x); exOverload:=(efOverload in x); end; procedure tCtrl.exEmergencyFlagsGet(var x:tEmergencyFlags); var xx:tCtrlFlags; begin CheckExInitDone; x:=[efFlagsUnavailable]; If NoError then begin ctrlISSB.exCurFlags(xx); if ctrlISSB.NoError then begin Exclude(x,efFlagsUnavailable); if not (fCatodOK in xx) then Include(x,efCatodBurnOUT); if (fOverload in xx) then Include(x,efOverload); end else begin SetErrorCode(tErrorCode(ecFail_ctrlISSB_exCurFlags)); end; end; end; {------------------------------------------------------------------------} { * PRIVATE секция } { методы самотестирования } procedure tCtrl.exSelfTest; begin if NoError then begin ProgressMessage('Тестирование аппаратуры...'); if not (CVF in prData.DoNotTest) then exTestCVF; if not (Volts in prData.DoNotTest) then exTestVolts; if not (Roll in prData.DoNotTest) then exTestRoll; ProgressMessage(''); end; end; procedure tCtrl.exTestRoll; var v1,v2,v3:tMkVolts; c0:tMagnetCounter; t, c:word; const Shift=100000; begin if NoError then begin ProgressMessage('Тестирование работоспособности контроллера электромагнита...'); c0:=Counter; VoltageReadParametersGet(t,c); VoltageChannelSet(Magnet); VoltageReadParametersSet(300, 20); // if (c0+Shift)>CounterMax then begin // exJumpTo(CounterMin); // end; v1:=exVoltage; exScroll(Shift); v2:=exVoltage; exScroll(-Shift); Delay(1000); v3:=exVoltage; exJumpTo(c0); if (NoError) then begin if (v1>v2) or ((Abs(v1-v3)*1000 div (v1+v3))> 1000) then begin SetErrorCode(tErrorCode(ecScrolIsUnoperational)); end; end; VoltageReadParametersSet(t,c); ProgressMessage(''); end; end; procedure tCtrl.exTestCVF; var it, x00, x01, x0,x1:tGeneralSignalData; Fail:boolean; begin if NoError then begin ProgressMessage('Тестирование работоспособности контроллера ПНЧ...'); it:=ctrlCVF.CurIntegrationTime; ctrlCVF.IntegrationTime(1000); ctrlCVF.exGetData; x0:=ctrlCVF.CurAverageOverActiveChannels; ctrlCVF.exGetData; x1:=ctrlCVF.CurAverageOverActiveChannels; x00:=(x0 div 2) + (x1 div 2); Fail:=(x00=0) or (ctrlCVF.Error); if not Fail then begin Fail:=(100*Abs(x0-x1) > x00); end; if not Fail then begin ctrlCVF.IntegrationTime(5000); ctrlCVF.exGetData; x01:=ctrlCVF.CurAverageOverActiveChannels; Fail:=((x01 div x00)<4) or (ctrlCVF.Error); end; ctrlCVF.IntegrationTime(it); if Fail then begin SetErrorCode(tErrorCode(ecCVF_Is_Unoperational)); end; ProgressMessage(''); end; end; procedure tCtrl.exTestVolts; var c:tVoltageChannel; b:byte; v00,v0,v1:tMkVolts; Fail:boolean; const cChannels=[IMCh,Acceleration, Magnet, Mutiplicator, AntiDinatron, BaseUPT, UPT1, UPT2, UPT3, UPT4, UPT5, UPTU, Lens]; begin if NoError then begin ProgressMessage('Тестирование работоспособности контроллера измерения напряжений...'); b:=0; VoltageChannelSet(BaseUPT); VoltageReadParametersSet(200, 10); v0:=exVoltage; v00:=v0; VoltageReadParametersSet(100, 10); for c:=tVoltageChannel(0) to tVoltageChannel(15) do if c in cChannels then begin VoltageChannelSet(c); v1:=exVoltage; if (v1<>v0) then Inc(b); v0:=v1; end; VoltageChannelSet(BaseUPT); VoltageReadParametersSet(200, 10); v0:=exVoltage; Fail:=(b<8) and (Abs(v0-v00)>(v00 div 1000)); if Fail then begin SetErrorCode(tErrorCode(ecVoltageIsUnoperational)); end; ProgressMessage(''); end; end; procedure tCtrl.exDetectCtrl(var x:tCtrlAlive); var a:byte; begin if NoError then begin a:= Byte(ctrlISSB.Present)+ { контроллер Блока питания источника ионов АК2} Byte(ctrlPanel.Present)+ { контроллер Пульта управления АК3} Byte(ctrlVolts.Present)+ { контроллер Напряжений АК5} Byte(ctrlCount.Present)+ { контроллер Счетчика ионов АК7} Byte(ctrlRoll.Present)+ { контроллер Магнита АК8} Byte(ctrlCVF.Present); { контроллер ПНЧ АК9} x:=tCtrlAlive(a div 6); end else begin x:=aNo; end; end; function tCtrl.SignalChannelName:tChannelStrName; begin case SignalChannel of PNC1: SignalChannelName:='ПНЧ 1'; PNC2: SignalChannelName:='ПНЧ 2'; PNC3: SignalChannelName:='ПНЧ 3'; PNC4: SignalChannelName:='ПНЧ 4'; PNC5: SignalChannelName:='ПНЧ 5'; // PNC6: SignalChannelName:='ПНЧ 6'; PNC_SEM: SignalChannelName:='ПНЧ ВЭУ'; IonCounter:SignalChannelName:='Счетчик ионов'; end; end; (*procedure tCtrl.MassCalibrationGetData(var cd:tMassCalibration); begin cd:=prData.MassCalibration; end; procedure tCtrl.MassCalibrationReset(M:tMass; Cnt:longint); begin with prData.MassCalibration do begin SetCalibration(M,Cnt); end; end; procedure tCtrl.MassCalibrationRefine(M:tMass; Cnt:longint); begin with prData.MassCalibration do begin Refine(M,Cnt); end; end; procedure tCtrl.MassCalibrationGet(i:tNodeNumber; var M:tMass; var Cnt:longint); begin with prData.MassCalibration do begin M:=GetMass(i); Cnt:=GetCount(i); end; end; *) procedure tCtrl.IntegrationTimeSet(t:word); begin IonCounterIntegrationTimeSet(t); PNCIntegrationTimeSet(t); end; function tCtrl.IntegrationTimeGetAndSet(t:word):word; begin IntegrationTimeGetAndSet:=IntegrationTime; IonCounterIntegrationTimeSet(t); PNCIntegrationTimeSet(t); end; function tCtrl.IntegrationTime:word; begin IntegrationTime:=IntegrationTimeForChannelGet; end; function tCtrl.IntegrationTimeMax:word; begin IntegrationTimeMax:=High(word); end; procedure tCtrl.SwitchesSetTimeOutSet(ATimeOut:word); begin prData.SwitchesSetTimeOut:=ATimeOut; end; function tCtrl.SwitchesSetTimeOut:word; begin SwitchesSetTimeOut:=prData.SwitchesSetTimeOut; end; { Возвращает результат проверки наличия СЕТИ (220В) - включен ли прибор Функция возвращает TRUE, если 1) Модуль управления не инициализирован - не выполнен успешно exInit; 2) Если хотя бы один из субконтроллеров возврашает exIsPowerON=TRUE. } function tCtrl.exIsPowerON:boolean; var ctrls:tControllers; begin exIsPowerON:=not CompletelyInitiated or ( ctrlISSB.exIsPowerON { контроллер Блока питания источника ионов АК2} or ctrlPanel.exIsPowerON { контроллер Пульта управления АК3} or ctrlVolts.exIsPowerON { контроллер Напряжений АК5} or ctrlCount.exIsPowerON { контроллер Счетчика ионов АК7} or ctrlRoll.exIsPowerON { контроллер Магнита АК8} or ctrlCVF.exIsPowerON { контроллер ПНЧ АК9} ); ErrorGetCtrlsWith(ctrls); if ctrls<>[] then SetErrorCode(tErrorCode(ecIsPowerON_Fail)) end; END.