Общий подход к использованию интерфейсных функций{#sect_gen_descr}
==============================================================

  Общий алгоритм работы с модулем{#sect_gen_alg}
  ==============================================================

Данный раздел описывает типичную последовательность действий при работе с модулем LTR25. Более подробно каждый шаг будет описан в последующих разделах.

Типичная последовательность действий имеет следующий вид:
1. Создать экземпляр структуры TLTR25, представляющей собой описатель модуля. Описатель модуля содержит всю информацию о модуле и используется при вызове всех остальных функций.
2. Проинициализировать поля описателя с помощью LTR25_Init()
3. Установить соединение с интересующим модулем с помощью функции LTR25_Open().
4. При наличии датчиков с TEDS выполнить чтение информации из памяти датчиков как описано в главе @ref sect_gen_teds (порядок по отношению к следующему шагу не важен, т.е. может выполняться как до, так и после записи настроек).
5. Заполнить необходимые поля с настройками модуля подструктуры [Cfg](@ref TLTR25::Cfg) [описателя модуля](@ref TLTR25) и вызвать LTR25_SetADC() для записи настроек в модуль.
6. Запустить сбор данных с помощью LTR25_Start().
7. Прием и обработка данных, как описано ниже
9. По завершению работы выполнить останов сбора данных с помощью LTR25_Stop().
10. Закрыть соединение с модулем, вызвав функцию LTR25_Close().
 

Типичный цикл приема и обработки данных аналогичен большинству модулей АЦП системы LTR и выглядит следующим образом:
1. Прием заданного количества отсчетов с помощью LTR25_Recv().
2. Обработка принятых отсчетов с помощью LTR25_ProcessData().




Настройка модуля{#sect_gen_cfg}
=============================================================
Настройка модуля выполняется аналогично большинству других модулей LTR: вначале значения всех параметров модуля записываются в соответствующие поля [структуры описателя модуля](@ref TLTR25), затем вызывается функция LTR25_SetADC(), которая значения этих полей передает модулю. Модуль должен быть настроен перед первым запуском сбора данных. Во время запущенного сбора данных изменение настроек не допускается.

Следует отметить, что все поля, относящиеся к настройке модуля, объединены в структуру типа #TLTR25_CONFIG (поле  [Cfg](@ref TLTR25::Cfg) [описателя модуля](@ref TLTR25)). Только эти поля пользователь должен изменять вручную в [описателе модуля](@ref TLTR25) при штатной работе и только эти поля влияют на параметры, записываемые LTR25_SetADC().

При настройке модуля задаются следующие параметры:
- Частота сбора АЦП. Может быть выбрана одна из 8 предопределенных частот сбора с помощью установки соответствующего кода в поле [FreqCode](@ref TLTR25_CONFIG::FreqCode).
- Настройки каналов АЦП (раздел @ref sect_gen_cfg_adc_ch)
- Формат передаваемых данных задается полем [DataFmt](@ref TLTR25_CONFIG::DataFmt). От формата зависит разрядность передаваемых отсчетов и количество передаваемых слов на один отсчет АЦП.
- Значение источника тока (10 или 2.86 мА) задается на все каналы сразу с помощью поля [ISrcValue](@ref TLTR25_CONFIG::ISrcValue).

После выполнения LTR25_SetADC() рассчитываются некоторые параметры, которые являются производными от настроек из #TLTR25_CONFIG. Эти параметры записываются в соответствующие поля структуры состояния модуля типа #TLTR25_STATE (поле [ State](@ref TLTR25::State) [описателя модуля](@ref TLTR25)). Например, на основе установленного кода частоты  в поле [AdcFreq](@ref TLTR25_STATE::AdcFreq) записывается соответствующая частота сбора АЦП в Гц.

Настройка каналов АЦП{#sect_gen_cfg_adc_ch}
--------------------------------------------------
Каждый модуль LTR25 имеет восемь каналов, которые выполняют преобразования параллельно. Можно разрешить прием данных по любому набору из этих восьми каналов. Однако следует учитывать, что максимальное количество одновременно разрешенных каналов зависит от настроенной частоты сбора и формата отсчетов (подробнее см. в документе [\"Крейтовая система LTR. Руководство пользователя\"](http://www.lcard.ru/download/ltr.pdf) ).


Настройки каждого канала объединены в структуре #TLTR25_CHANNEL_CONFIG. Массив структур из #LTR25_CHANNEL_CNT элементов, каждый элемент которого соответствует нужному каналу, является полем [Ch](@ref TLTR25_CONFIG::Ch) структуры с [настройками модуля](@ref TLTR25::Cfg).

Для каждого канала можно независимо задать:
 - Разрешен ли сбор данных по этому каналу. Задается полем [Enabled](@ref TLTR25_CHANNEL_CONFIG::Enabled).
 - Сопротивление подключенного к каналу датчика, если необходима дополнительная коррекция данных, как описано в разделе @ref sec_sensor_rout. Задается полем [SensorROut](@ref TLTR25_CHANNEL_CONFIG::SensorROut).
 


 Прием и обработка данных{#sec_proc}
 ==========================================================
 Прием и обработка данных осуществляется таким же образом, как и во многих других модулях LTR. Сперва осуществляется прием сырых данных в виде 32-битных слов специального формата с помощью LTR25_Recv(), после чего эти данные передаются в LTR25_ProcessData() для проверки их корректности и перевода в Вольты. При этом следует учесть, что в зависимости от выбранного [формата](@ref e_LTR25_FORMATS) одному отсчету соответствует либо одно, либо два принятых слова.
 
Ниже описаны некоторые особенности обработки данных с помощью LTR25_ProcessData(), которые специфичны для данного модуля.


 Проверка на обрыв или короткое замыкание{#sec_ch_status}
----------------------------------------------------------------------
 Модуль LTR25 позволяет при запущенном сборе определять ситуации обрыва или короткого замыкания для каждого разрешенного канала. При определении одной из этих ситуаций в передаваемом слове вместо самого отсчета АЦП вставляется специальный код, сигнализирующий о возникновении события. Функция LTR25_ProcessData() анализирует эти коды и формирует для каждого разрешенного канала статус канала. Статус рассчитывается по всему блоку (но отдельно для каждого канала), то есть если хотя бы для одного отсчета из обрабатываемого блока был установлен признак обрыва, то будет возвращен статус этого канала #LTR25_CH_STATUS_OPEN. Порядок статусов соответствует порядку разрешенных каналов.
 
 Следует иметь ввиду, что определение состояний обрыва и КЗ --- процесс инерционный, и установка статусов выполняется с задержкой относительно реального события. Подробнее см.  в документе [\"Крейтовая система LTR. Руководство пользователя\"](http://www.lcard.ru/download/ltr.pdf).

Особенности калибровки данных модулем{#sect_gen_cbr}
---------------------------------------------------------------------------
В отличие от большинства остальных модулей LTR (например от LTR24), калибровка данных происходит аппаратно внутри модуля, а не программно. В связи с этим в LTR25_ProcessData() нет никаких указаний о выполнении калибровки. Самой библиотекой выполняется чтение калибровочных коэффициентов из Flash-памяти модуля, сохранение их в полях массива [CbrCoef](@ref TLTR25_MODULE_INFO::CbrCoef) в [структуре с информацией о модуле](@ref TLTR25_MODULE_INFO) и запись этих коэффициентов в ПЛИС.

Следует отметить, что калибровочные коэффициенты определяются и сохраняются отдельно только для первых #LTR25_CBR_FREQ_CNT частот сбора, так как остальные частоты получаются из частоты #LTR25_FREQ_39K фильтрацией и прореживанием в ПЛИС и для них используются те же коэффициенты, что и для исходной частоты. Для каждого из восьми каналов используются свои калибровочные коэффициенты.

ПЛИС налету выполняет калибровку по формуле \f$ Y = (X + Offset)*Gain \f$, где X --- отсчет с АЦП расширенный до 32-бит, Y --- калиброванные данные, Offset --- смещение шкалы (32-битный код), а Gain --- коэффициент шкалы. При этом перед выполнением калибровки, входное значение АЦП, расширяется до 32-бит. На выходе получаются уже откалиброванные 32-битные отсчеты. В случае 32-битного формата эти отсчеты и передаются в крейт, а в случае 20-битного передаются только старшие 20-бит.

При этом код #LTR25_ADC_SCALE_CODE_MAX соответствует напряжению, равному максимальному напряжению для заданного диапазона.

Если пользователю необходимо установить свои калибровочные коэффициенты, то он должен изменить значение полей [CbrCoef](@ref TLTR25_MODULE_INFO::CbrCoef) в [структуре с информацией о модуле](@ref TLTR25_MODULE_INFO) перед вызовом LTR25_SetADC(), в которой и происходит загрузка коэффициентов в ПЛИС на основе установленной частоты АЦП.

Инверсия входного сигнала{#sec_sig_inv}
-----------------------------------------------------------
Модуль LTR25 передает инвертированный (с обратным знаком) сигнал и изначально в этом виде он возвращался после вызова LTR25_ProcessData(). Для многих задач, где знак сигнала не имеет значения, это не является проблемой, однако в случаях, где это важно, следует учитывать данную особенность. Библиотека не корректирует полярность по умолчанию для сохранения совместимости с возможным клиентским ПО, которое могло бы учитывать эту особенность модуля. В новых версиях библиотеки  для автоматической коррекции полярности сигнала был введен отдельный флаг #LTR25_PROC_FLAG_SIGN_COR, при передаче которого в  LTR25_ProcessData() будет автоматически скорректирована полярность сигнала.


Учет выходного сопротивления датчика{#sec_sensor_rout}
------------------------------------------------------------------------------

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

Коэффициент передачи этого делителя составляет \f$ K = \frac{R_{in}}{R_{in} + R_{out}} \f$, где \f$ R_{in} \f$ --- входное сопротивление ICP канала модуля LTR25, а \f$ R_{out} \f$ --- выходное сопротивление подключенного ко входу датчика, которое также может учитывать при необходимости сопротивление проводов подключения датчика. Для модулей с расширенной полосой пропускания в области нижних частот (установлен флаг #LTR25_FEATURE_EXT_BANDWIDTH_LF в информации о модуле) входное сопротивление составляет 110 кОм, в то время как для старых модулей это сопротивление составляет 31,6 кОм.

В большинстве случаев это падение значительно меньше точности используемого датчика и им можно пренебречь, но если используется датчик, точность которого и значение выходного сопротивления таковы, что указанное падение напряжения может видимым образом влиять на результат и если для подключаемого датчика явно указано выходное сопротивление, то его можно явно учесть средствами библиотеки. Для этого необходимо во время конфигурации модуля (до вызова LTR25_SetADC())  в  структуре конфигурации соответствующего канала установить в поле [SensorROut](@ref TLTR25_CHANNEL_CONFIG::SensorROut)  значение выходного сопротивления датчика. Если значение этого поля больше нуля, то функция LTR25_ProcessData() корректирует результат для компенсации указанного падения.

В случае подключения к ICP-входу преобразователь [LPW25](http://www.lcard.ru/products/accesories/lpw25) способ учета его выходного сопротивления описан в его [Руководстве программиста](http://www.lcard.ru/download/lpw25api.pdf).


Коррекция фазы{#sec_sensor_pha_cor}
------------------------------------------------------------------------------
RC цепь ICP-входа модуля LTR25 приводит к сдвигу фаз на малых частотах входного сигнала. Для задач, где важны фазы сигнала, этот сдвиг может быть неприемлем. В библиотеке реализован  фазовый фильтр для коррекции этого сдвига, описанный в статье ["Фазовый корректор дифференцирующей RC-цепи"](http://www.lcard.ru/download/articles/iir_phase_corrector.pdf).

По умолчанию данный фильтр не применяется для обеспечения совместимости со старыми программами, которые могли учитывать сдвиг фаз модуля самостоятельно.  Для применения этого фильтра к выходным данным необходимо передать флаг #LTR25_PROC_FLAG_PHASE_COR.

Для расчета фильтра по умолчанию используются коэффициенты, рассчитанные исходя из фазового сдвига при номинальных значениях RC-цепи. В случае, если была проведена калибровка фазового сдвига, то коэффициенты фильтра рассчитываются на основании записанного во Flash-память модуля смещения фазы, что позволяет дополнительно учесть разброс элементов (в первую очередь емкости) цепи соответствующего канала.

Важно отметить, что для задач, где важны фазовые соотношения между каналами, необходимо, чтобы версия прошивки ПЛИС была не ниже 9 (может быть обновлена клиентом) и версия библиотек не ниже 1.32.3.

Работа с  TEDS{#sect_gen_teds}
===================================

Начиная с ревизии 2, модуль LTR25 поддерживает цифровой режим работы канала при подключении  [TEDS-датчиков](http://www.lcard.ru/lexicon/1451_4_cl1_2wire_sensor) класса 1, который в частности может быть в использован для чтения информации о датчике (электронный паспорт датчика --- TEDS).

Данные датчики помимо основного аналогового режима, совместимого с ICP-датчиками, имеют специальный цифровой режим, в котором по тем же линиям может выполняться взаимодействия со специальными устройствами на датчике, называемыми узлами (node). Как правило в качестве данного устройства используется энергонезавимая память, хранящая в себе информацию о датчике. Однако в более общем случае узел TEDS может реализовать и другие функциональные возможности (например настройка режимов датчика). Более того, стандартом допускается наличие более одного TEDS узла в датчике, подключенного к одному каналу.

Каждое узел TEDS имеет свой 64-битный  уникальный регистрационный номер (URN), включающий в себя код семейства, которому принадлежит микросхема, серийный номер микросхемы (не датчика), а также CRC  для проверки целостности предыдущих двух полей. Код семейства определяет, какую функциональность поддерживает узел, а также набор команд для работы с ним.  Также в случае наличия нескольких узлов URN используется для адресации узла.

В памяти узла, помимо идентификатора производителя датчика, его модели и серийного номера, также может хранится информация и о характеристиках датчика, необходимых для обработки измерений, полученных с его выхода. В частности там может хранится информация для преобразования измеренного напряжения в физические величины, калибровочные коэффициенты датчика и т.д. 

Так как формат данных TEDS  в памяти  определяется стандартом [IEEE 1451.4](https://www.iso.org/standard/54368.html), то даже программа, не знающая точной модели подключенного датчика, может определить, каким образом следует преобразовать полученные данные и какие выходные физические величины будут получены, а также учесть калибровочные коэффициенты датчиков. Это справедливо, если эта информация закодирована с помощью стандартных шаблонов или шаблонов производителя, известных программе разбора данных TEDS  (подробнее о формате данных TEDS описано в [Руководстве программиста библиотеки ltedsapi](http://www.lcard.ru/download/ltedsapi.pdf)).


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

Чтение информации выполняется следующим образом (при этом связь с модулем должна быть уже установлена, но сбор данных не запущен):
1. Перевести все подключенные  к каналам модуля датчики в цифровой режим TEDS, вызвав функцию LTR25_SetSensorsPowerMode(), указав режим #LTR25_SENSORS_POWER_MODE_TEDS
2. Для каждого интересующего канала:
    - проверить наличие узла, вызвав функцию LTR25_TEDSNodeDetect()
    - прочитать информацию о датчике из памяти узла с помощью функции LTR25_TEDSReadData()
    - разобрать прочитанную информацию
3. По завершении чтения нужной информации перевести датчики модуля в штатный рабочий режим, вызвав функцию LTR25_SetSensorsPowerMode(), указав режим #LTR25_SENSORS_POWER_MODE_ICP.

Следует отменить, что в памяти узла данные хранятся вместе с байтами контрольной суммы и при чтении данных из памяти происходит проверка контрольной суммы и байты с контрольной суммой отбрасываются из прочитанных данных. Таким образом, возвращаемый массив содержит только данные TEDS.

Для разбора прочитанной информации можно воспользоваться библиотекой [ltedsapi](http://www.lcard.ru/download/ltedsapi.pdf), входящей в состав библиотек LTR, либо воспользоваться любым сторонним ПО разбора данных TEDS в соответствии со стандартом.

Если ко входу подключен преобразователь LPW25, то все функции разбора информации для данного преобразователя реализованы в библиотеке [lpw25api](http://www.lcard.ru/download/lpw25api.pdf).

Текущая реализация поддержки TEDS имеет некоторые ограничения, которые необходимо отметить:
1. Модуль поддерживает чтение данных по цифровому интерфейсу только для датчиков с одним узлом TEDS, что как правило справедливо. Тем не менее стандарт предусматривает подключение нескольких узлов к одной линии в цифровом режиме, как для хранения данных одного преобразователя на нескольких микросхемах памяти, так и для хранения данных по нескольким датчикам. В случае наличия нескольких микросхем на одной линии, функция LTR25_TEDSNodeDetect() вернет ошибку #LTR25_ERR_TEDS_NODE_URN_CRC в связи с нарушением данных из-за конфликта при одновременной передачи URN разными узлами. Поддержка данного режима требует доработку обновляемой прошивки ПЛИС модуля LTR25 и функций данной библиотеки, что может быть рассмотрено при обращении клиентов.
2. Библиотека поддерживает чтение данных из наиболее часто используемых микросхем памяти для TEDS-датчиков, таких как DS2430A, DS2431, DS2433, DS28EC20. Тем не менее стандарт позволяет использовать в качестве узлов  любые микросхемы памяти с поддержкой интерфейса "1-wire", которые кроме того могут иметь дополнительные функции помимо памяти. В случае обнаружения не поддерживаемого устройства LTR25_TEDSNodeDetect() вернет ошибку #LTR25_ERR_TEDS_UNSUP_NODE_FAMILY, но вернет действительный код семейства, которому принадлежит устройство. Поддержка других типов устройств или API для работы с иными функциями узлов TEDS помимо памяти может быть добавлена в данную библиотеку по запросу клиентов.






