//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "Zadc_int.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
#define MAX_TYPE_DSP 30 // Максимальное поддерживаемое кол-во типов устройств
// Глобальные переменные
long typeDevice; // Тип устройства
long numberDSP; // Порядковый номер устройства
bool deviceOpened; // Устройство открыто
bool deviceError; // Ошибка устройства
bool deviceStarted; // Устройство проинициализировано и запущено
long numChannelsADC; // Кол-во включенных каналов АЦП
long numWordsADC; // Кол-во слов (по два байта) в одном отсчете АЦП
long sizeBufferADC; // Размер буфера драйвера в словах
double amplifyADC[2]; // Коэф. усиления по первым двум каналам
double resolutionADC[2]; // Вес младшего разряда АЦП
short *pBuffer16ADC; // Указатель на начало буфера драйвера для АЦП с разрядностью не более 16 бит
long *pBuffer32ADC; // Указатель на начало буфера драйвера для АЦП с разрядностью более 16 бит
long pointerADC; // Указатель на текущий элемент заполнения буфера драйвера
long pointerADC_old; // Предыдущее значение указателя заполнения буфера драйвера
double volt[2]; // Мгновенное текущее значение напряжение на входах АЦП (в вольтах)
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
OpenDevice();
}
//---------------------------------------------------------------------------
__fastcall TForm1::~TForm1(void)
{
CloseDevice();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
if(deviceError)
this->Close();
else
ProcessDevice();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::OpenDevice(void)
{
long Err; // Код ошибки
long enable; // Поддерживается / не поддерживается
long Serial; // Серийный номер
numberDSP = 0; // Здесь задан первый порядковый номер устройства
deviceOpened = FALSE;
deviceError = FALSE;
deviceStarted = FALSE;
pBuffer16ADC = NULL;
pBuffer32ADC = NULL;
pointerADC = 0;
pointerADC_old = 0;
// Цикл подключения к первому поддерживаемому устройству
for(typeDevice=0; typeDevice < MAX_TYPE_DSP; typeDevice++)
{
// подключиться к драйверу (обязательно)
Err = ZOpen(typeDevice, numberDSP);
if(Err == 0)
{
// Проверить поддерживается ли АЦП
Err = ZGetEnableADC(typeDevice, numberDSP, &enable);
if(Err == 0 && enable != 0)
break;
else
Err = ZClose(typeDevice, numberDSP);
}
}
if(typeDevice >= MAX_TYPE_DSP)
{
MessageDlg("Поддерживаемое устройство не найдено!",
mtInformation, TMsgDlgButtons() << mbOK, 0);
deviceError = TRUE;
return;
}
deviceOpened = TRUE;
Err = ZGetSerialNumberDSP(typeDevice, numberDSP, &Serial);
if(Err == 0)
this->Caption = "Test_Zadc для устройства № " + IntToStr(Serial);
// опросить кол-во каналов АЦП
Err = ZGetQuantityChannelADC(typeDevice, numberDSP, &numChannelsADC);
if(Err != 0)
{
MessageDlg("Ошибка в ZGetQuantityChannelADC(), Error = " + IntToHex((int) Err,2),
mtError, TMsgDlgButtons() << mbOK, 0);
deviceError = TRUE;
return;
}
// включить первый канал АЦП
Err = ZSetInputADC(typeDevice, numberDSP, 0, 1);
if(Err != 0)
{
MessageDlg("Ошибка в ZSetInputADC(), Error = " + IntToHex((int) Err,2),
mtError, TMsgDlgButtons() << mbOK, 0);
deviceError = TRUE;
return;
}
if(numChannelsADC > 1)
{
// включить второй канал АЦП
Err = ZSetInputADC(typeDevice, numberDSP, 1, 1);
if(Err != 0)
{
MessageDlg("Ошибка в ZSetInputADC(), Error = " + IntToHex((int) Err,2),
mtError, TMsgDlgButtons() << mbOK, 0);
deviceError = TRUE;
return;
}
}
// опросить коэф. усиления по первому каналу АЦП
Err = ZGetAmplifyADC(typeDevice, numberDSP, 0, &lifyADC[0]);
if(Err != 0)
{
MessageDlg("Ошибка в ZGetAmplifyADC(), Error = " + IntToHex((int) Err,2),
mtError, TMsgDlgButtons() << mbOK, 0);
deviceError = TRUE;
return;
}
if(numChannelsADC > 1)
{
// опросить коэф. усиления по второму каналу АЦП
Err = ZGetAmplifyADC(typeDevice, numberDSP, 1, &lifyADC[1]);
if(Err != 0)
{
MessageDlg("Ошибка в ZGetAmplifyADC(), Error = " + IntToHex((int) Err,2),
mtError, TMsgDlgButtons() << mbOK, 0);
deviceError = TRUE;
return;
}
}
// опросить вес младшего разряда АЦП первого канала
Err = ZGetDigitalResolChanADC(typeDevice, numberDSP, 0, &resolutionADC[0]);
if(Err != 0)
{
MessageDlg("Ошибка в ZGetDigitalResolChanADC(), Error = " + IntToHex((int) Err,2),
mtError, TMsgDlgButtons() << mbOK, 0);
deviceError = TRUE;
return;
}
if(numChannelsADC > 1)
{
// опросить вес младшего разряда АЦП второго канала
Err = ZGetDigitalResolChanADC(typeDevice, numberDSP, 1, &resolutionADC[1]);
if(Err != 0)
{
MessageDlg("Ошибка в ZGetDigitalResolChanADC(), Error = " + IntToHex((int) err,2),
mtError, TMsgDlgButtons() << mbOK, 0);
deviceError = TRUE;
return;
}
}
// опросить кол-во включенных каналов АЦП
Err = ZGetNumberInputADC(typeDevice, numberDSP, &numChannelsADC);
if(Err != 0)
{
MessageDlg("Ошибка в ZGetNumberInputADC(), Error = " + IntToHex((int) Err,2),
mtError, TMsgDlgButtons() << mbOK, 0);
deviceError = TRUE;
return;
}
// опросить кол-во слов в одном отсчете АЦП
Err = ZGetWordsADC(typeDevice, numberDSP, &numWordsADC);
if(Err != 0)
{
MessageDlg("Ошибка в ZGetWordsADC, Error = " + IntToHex((int) Err,2),
mtError, TMsgDlgButtons() << mbOK, 0);
deviceError = TRUE;
return;
}
// Проверка переменных, чтобы избежать деления на 0
if(numWordsADC == 0 || amplifyADC[0] == 0 ||
(numChannelsADC > 1 && amplifyADC[1] == 0))
{
MessageDlg("Ошибочные значения параметров АЦП!",
mtError, TMsgDlgButtons() << mbOK, 0);
deviceError = TRUE;
return;
}
// Запросить буфер АЦП
Err = ZGetBufferADC(typeDevice, numberDSP, (void**) &pBuffer16ADC, &sizeBufferADC);
if(Err != 0)
{
MessageDlg("Ошибка в ZGetBufferADC(), Error = " + IntToHex((int) Err,2),
mtError, TMsgDlgButtons() << mbOK, 0);
deviceError = TRUE;
return;
}
pBuffer32ADC = (long*) pBuffer16ADC;
// останов АЦП
Err = ZStopADC(typeDevice, numberDSP);
// запуск АЦП
Err = ZStartADC(typeDevice, numberDSP);
deviceStarted = TRUE;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::CloseDevice(void)
{
deviceStarted = FALSE;
if(!deviceOpened)
return;
// Останов АЦП
ZStopADC(typeDevice, numberDSP);
// Освободить буфер АЦП
if(pBuffer16ADC != NULL)
ZRemBufferADC(typeDevice, numberDSP, (void**) &pBuffer16ADC);
// Отключиться от драйвера (обязательно)
ZClose(typeDevice, numberDSP);
pBuffer16ADC = NULL;
pBuffer32ADC = NULL;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ProcessDevice(void)
{
long Err; // Код ошибки
// Если устройство еще не стартовали и переменные не проинициализированны, то выйти
if(!deviceStarted)
return;
// Запросить текущее значение указателя
Err = ZGetPointerADC(typeDevice, numberDSP, &pointerADC);
if(Err != 0)
{
deviceError = TRUE;
return;
}
// Если новые данные в буфер не поступили, то выйти из процедуры
if(pointerADC == pointerADC_old)
return;
// Обновить предыдущее значение указателя
pointerADC_old = pointerADC;
// перейти на отсчет первого включенного канала последнего кадра АЦП
if(pointerADC - numWordsADC * numChannelsADC < 0)
pointerADC = sizeBufferADC + pointerADC - numWordsADC * numChannelsADC;
else
pointerADC = pointerADC - numWordsADC * numChannelsADC;
// вычислить из целого значения отсчета АЦП вещественное значение отсчета (в Вольтах)
if(numWordsADC == 1)
volt[0] = resolutionADC[0] * (pBuffer16ADC[pointerADC]) / amplifyADC[0];
else
volt[0] = resolutionADC[0] * (pBuffer32ADC[pointerADC/numWordsADC]) / amplifyADC[0];
// отобразить мгновенное значение напряжения для первого канала
this->Edit1->Text = FloatToStrF(volt[0], ffFixed, 8, 6);
// если включено более одного канала АЦП, то сделать то же самое для второго канала
if(numChannelsADC > 1)
{
// перейти на следующий отсчет АЦП
pointerADC += numWordsADC;
// если вышли за границу буфера, то перейти в начало
if(pointerADC >= sizeBufferADC)
pointerADC = pointerADC - sizeBufferADC;
if(numWordsADC == 1)
volt[1] = resolutionADC[1] * (pBuffer16ADC[pointerADC]) / amplifyADC[1];
else
volt[1] = resolutionADC[1] * (pBuffer32ADC[pointerADC/numWordsADC]) / amplifyADC[1];
// отобразить мгновенное значение напряжения для второго канала
this->Edit2->Text = FloatToStrF(volt[1], ffFixed, 8, 6);
}
}
//---------------------------------------------------------------------------