Электронные технологии и метрологические системы Главная Форум Поиск Карта сайта Написать
ЗАО "Электронные технологии и метрологические системы"   
Тел./факс: +7(495)739-39-19 (многоканальный); E-mail: info@zetlab.ru   
Электронные технологии и метрологические системы ZETLab
 
 Главная 
 Продукция 
 Поддержка 
 Предприятие 
 Прайс лист 
 Контакты 
 Карта сайта 
ZETServer
Grid
Gramma
PlotterXYZ
Polar
Scale
ColScale
GreenScale
TextDisp
ExtEditBox
Kompas
Unit
ZADC
DSP
Примеры программирования


Online-консультанты
388828835 - Мария
627723417 - Никита
397652821 - Елена

Приглашаем на курсы обучения (29-31 мая 2012 года)

Форум

Скидка ВУЗам!

Доставка по всему миру!

Удалённое управление прибором.

Каталог продукции.

Запрос звонка

Наш телефон

Наш мобильный телефон

Наш факс


E:mail

Анализатор спектра a17-u8. Срок поставки 2 недели.









Главная / Продукция / Программное обеспечение / ZETLab Studio - средства разработки виртуальных приборов Версия для печати Версия для печати

Текст программы Test_DAC на Delphi 2007


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, Math, Zadc_int;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Label1: TLabel;
    Label2: TLabel;
    Edit1: TEdit;
    Edit2: TEdit;

    procedure Form1OnCreate(Sender: TObject);
    procedure Form1OnCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure OpenDevice;
    procedure CloseDevice;
    procedure ProcessDevice;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
MAX_TYPE_DSP =  30;    // Максимальное поддерживаемое кол-во типов устройств

var
// Глобальные переменные
typeDevice: Longint;                    // Тип устройства
numberDSP: Longint;                     // Порядковый номер устройства
deviceOpened: Boolean = False;          // Устройство открыто
deviceError: Boolean = False;           // Ошибка устройства
deviceStarted: Boolean = False;         // Устройство проинициализировано и запущено

numChannelsDAC: Longint;       // Кол-во включенных каналов ЦАП
numWordsDAC: Longint;         // Кол-во слов (по два байта) в одном отсчете ЦАП
pBufferDAC: Pointer;              // Указатель на начало буфера драйвера
pBuffer16DAC: ^Smallint;          // Указатель на начало буфера драйвера для ЦАП с разрядностью не более 16 бит
pBuffer32DAC: ^Longint;          // Указатель на начало буфера драйвера для ЦАП с разрядностью более 16 бит
sizeBufferDAC: Longint;        // Размер буфера драйвера в словах
sizeInterruptBufferDAC: Longint;  // Размер буфера прерывания в словах
sizePacketDAC: Longint;        // Кол-во отсчетов обрабатываемых за один раз
sleepTime: Longint;           // Время ожидания в цикле (мс)
responseTime: Longint;        // Время реакции в цикле (мс). Должно быть больше времени ожидания

pointerDriverDAC: Longint;     // Указатель драйвера на текущий элемент заполнения буфера драйвера
pointerDriverDAC_old: Longint;  // Предыдущее значение указателя драйвера на буфер драйвера
pointerCycleDAC: Longint;       // Указатель цикла обработки на текущий элемент заполнения буфера драйвера

freqDAC: Double;       // Частота дискретизации ЦАП
attenDAC0: Double;     // Коэф. затухания по первому каналу ЦАП
resolutionDAC: Double;   // Вес младшего разряда ЦАП

currentSinusTime: Double;  // Аргумент функции синус
deltaSinusTime: Double;   // Значение инкремента аргумента функции синус
amplitudeSin: Double;    // Коэф. преобразования амплитуды синуса
freqSin: Double;       // Частота синуса (Гц)
volt0: Double;        // Мгновенное текущее значение, записываемое в ЦАП
volt0_int: Longint;         // Мгновенное текущее значение, записываемое в ЦАП (код)

procedure TForm1.Form1OnCreate(Sender: TObject);
begin
  //MessageDlg('OnCreate!', mtInformation, [mbOK], 0);
  OpenDevice();
end;

procedure TForm1.Form1OnCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
//  MessageDlg('OnCloseQuery!', mtInformation, [mbOK], 0);
  CloseDevice();
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if deviceError <> FALSE then
  begin
      Form1.Close();
  end
  else
  begin
      ProcessDevice();
  end;
end;

procedure TForm1.OpenDevice();
var
  Err: Longint;     // Код ошибки
  enable: Longint;  // Поддерживается / не поддерживается
  i, size: Longint; // Счетчик цикла

begin
 sleepTime := 50;     // Время ожидания в цикле генерации синуса (мс)
 responseTime := 250;  // Время опережения (время реакции) (мс)
 amplitudeSin := 0.1;  // Амплитуда синуса 100 мВ (СКЗ = 70.71 мВ)
 freqSin := 10;      // Частота синуса 10 Гц
 attenDAC0 := 0.1;     // Значение аттенюатора зададим 0.1 (для лучшего соотношения сигнал/шум)

  numberDSP := 0;    // Здесь задан первый порядковый номер устройства
  deviceOpened := FALSE;
  deviceError := FALSE;
  deviceStarted := FALSE;
  pBufferDAC := nil;
  pBuffer16DAC := nil;
  pBuffer32DAC := nil;
  pointerDriverDAC := 0;
  pointerDriverDAC_old := 0;
  pointerCycleDAC := 0;

  // Цикл подключения к первому поддерживаемому устройству
  for i := 0 to MAX_TYPE_DSP - 1 do
  begin
    // подключиться к драйверу (обязательно)
    Err := ZOpen(i, numberDSP);
    if Err = 0 then
    begin
      // Проверить поддерживается ли АЦП
      Err := ZGetEnableADC(i, numberDSP, enable);
        if (Err = 0) and (enable <> 0) then
          break
        else
          ZClose(i, numberDSP);
    end;
  end;
  typeDevice := i;

  if typeDevice >= MAX_TYPE_DSP then
  begin
    MessageDlg('Поддерживаемое устройство не найдено!',
               mtInformation, [mbOK], 0);
    deviceError := TRUE;
    Exit;
  end;
  deviceOpened := TRUE;

  // включить первый канал ЦАП
  Err := ZSetOutputDAC(typeDevice, numberDSP, 0, 1);
  if Err <> 0 then
  begin
    MessageDlg('Ошибка в ZSetOutputDAC(), Error = ' + IntToHex(Err, 2),
               mtError, [mbOK], 0);
    deviceError := TRUE;
    Exit;
  end;

  // опросить  кол-во включенных каналов ЦАП
  // Если включено каналов больше одного, то пример правильно работать не будет
  // (синус будет выдаваться на все каналы, причем его реальная частота разделится
  // на кол-во включенных каналов)
  Err := ZGetNumberOutputDAC(typeDevice, numberDSP, &numChannelsDAC);
  if Err <> 0 then
  begin
    MessageDlg('Ошибка в ZGetNumberOutputDAC(), Error = ' + IntToHex(Err, 2),
               mtError, [mbOK], 0);
    deviceError := TRUE;
    Exit;
  end;

  // опросить вес младшего разряда ЦАП
  Err := ZGetDigitalResolChanDAC(typeDevice, numberDSP, 0, resolutionDAC);
  if Err <> 0 then
  begin
    MessageDlg('Ошибка в ZGetDigitalResolChanDAC(), Error = ' + IntToHex(Err, 2),
               mtError, [mbOK], 0);
    deviceError := TRUE;
    Exit;
  end;

  // опросить кол-во слов в одном отсчете ЦАП
  Err := ZGetWordsDAC(typeDevice, numberDSP, numWordsDAC);
  if Err <> 0 then
  begin
    MessageDlg('Ошибка в ZGetWordsDAC(), Error = ' + IntToHex(Err, 2),
               mtError, [mbOK], 0);
    deviceError := TRUE;
    Exit;
  end;

  // опросить частоту дискретизации ЦАП
  Err := ZGetFreqDAC(typeDevice, numberDSP, freqDAC);
  if Err <> 0 then
  begin
    MessageDlg('Ошибка в ZGetFreqDAC(), Error = ' + IntToHex(Err, 2),
               mtError, [mbOK], 0);
    deviceError := TRUE;
    Exit;
  end;

  // опросить размер буфера прерывания ЦАП
  Err := ZGetInterruptDAC(typeDevice, numberDSP, sizeInterruptBufferDAC);
  if Err <> 0 then
  begin
    MessageDlg('Ошибка в ZGetInterruptDAC(), Error = ' + IntToHex(Err, 2),
               mtError, [mbOK], 0);
    deviceError := TRUE;
    Exit;
  end;

  // Установить (опросить) коэф. затухания аттенюатора по первому каналу ЦАП
  Err := ZSetAttenDAC(typeDevice, numberDSP, 0, attenDAC0, attenDAC0);
  if Err <> 0 then
  begin
    MessageDlg('Ошибка в ZSetAttenDAC(), Error = ' + IntToHex(Err, 2),
               mtError, [mbOK], 0);
    deviceError := TRUE;
    Exit;
  end;

 // Проверка переменных, чтобы избежать деления на 0
 if (numWordsDAC < 1) or (numWordsDAC > 2) or (freqDAC < 1) or
     (attenDAC0 = 0) or (resolutionDAC = 0) then
  begin
    MessageDlg('Ошибочные значения параметров ЦАП!',
               mtError, [mbOK], 0);
    deviceError := TRUE;
    Exit;
  end;

 // Запросить буфер ЦАП
 Err := ZGetBufferDAC(typeDevice, numberDSP, pBufferDAC, sizeBufferDAC);
  if Err <> 0 then
  begin
    MessageDlg('Ошибка в ZSetOutputDAC(), Error = ' + IntToHex(Err, 2),
               mtError, [mbOK], 0);
    deviceError := TRUE;
    Exit;
  end;
 pBuffer16DAC := pBufferDAC;
 pBuffer32DAC := pBufferDAC;

 // Вычислим размер пакета согласно заданному времени реакции (опережения)
 sizePacketDAC := Round(freqDAC * responseTime / 1000.0);
 sizePacketDAC := numWordsDAC*sizePacketDAC;

 // Размер пакета должен быть не меньше двух размеров буфера прерывания и не больше половины буфера драйвера
 if sizePacketDAC < 2*sizeInterruptBufferDAC then
  sizePacketDAC := 2*sizeInterruptBufferDAC;
 if sizePacketDAC > sizeBufferDAC div 2 then
  sizePacketDAC := sizeBufferDAC div 2;

 // Рассчитаем параметры для генерации синуса
 amplitudeSin := amplitudeSin / (resolutionDAC * attenDAC0);
 deltaSinusTime := 2.0 * (4.0 * ArcTan2(1.0, 1.0)) * freqSin / freqDAC; // Число Пи = 4.*atan(1.)
 currentSinusTime := 0.0;

 // Запись в буфер драйвера первых двух пакетов
 size := 2*(sizePacketDAC div numWordsDAC);
 if numWordsDAC = 1 then
  begin
    pBuffer16DAC := pBufferDAC;
  for i := 0 to size - 1 do
    begin
   volt0 := amplitudeSin * sin(currentSinusTime);
      volt0_int := Round(volt0);
      CopyMemory(pBuffer16DAC, @volt0_int, 2);
      Inc(pBuffer16DAC);
   currentSinusTime := currentSinusTime + deltaSinusTime;
    end;
  end
 else
  begin
    pBuffer32DAC := pBufferDAC;
  for i := 0 to size - 1 do
    begin
   volt0 := amplitudeSin * sin(currentSinusTime);
      volt0_int := Round(volt0);
      CopyMemory(pBuffer32DAC, @volt0_int, 4);
      Inc(pBuffer32DAC);
   currentSinusTime := currentSinusTime + deltaSinusTime;
    end;
  end;
  pointerCycleDAC := 2*sizePacketDAC;

 ZStopDAC(typeDevice, numberDSP);  // Останов ЦАП
 ZStopADC(typeDevice, numberDSP);  // Останов АЦП
 ZStartDAC(typeDevice, numberDSP); // Запуск ЦАП
  ZStartADC(typeDevice, numberDSP); // Запуск АЦП

  // Задать время ожидания таймера
  Form1.Timer1.Interval := sleepTime;
  deviceStarted := TRUE;
end;


procedure TForm1.CloseDevice();
begin
  deviceStarted := FALSE;
  if deviceOpened = FALSE then
    Exit;

  // Останов ЦАП
  ZStopDAC(typeDevice, numberDSP);
  // Останов АЦП
  ZStopADC(typeDevice, numberDSP);
  // Освободить буфер ЦАП
  if pBufferDAC <> nil then
    ZRemBufferDAC(typeDevice, numberDSP, pBufferDAC);
  // Отключиться от драйвера (обязательно)
  ZClose(typeDevice, numberDSP);
  pBufferDAC := nil;
end;


procedure TForm1.ProcessDevice();
var
  Err: Longint;     // Код ошибки
  i, size: Longint; // Счетчик цикла
begin
  // Если устройство еще не стартовали и переменные не проинициализированны, то выйти
  if deviceStarted = FALSE then
    Exit;

 Err := ZGetPointerDAC(typeDevice, numberDSP, pointerDriverDAC);
  if Err <> 0 then
  begin
    deviceError := TRUE;
    Exit;
  end;

  // Отобразить указатель цикла обработки на текущий элемент заполнения буфера драйвера
  Form1.Edit1.Text := IntToStr(pointerCycleDAC);
   // Отобразить указатель драйвера на текущий элемент заполнения буфера драйвера
  Form1.Edit2.Text := IntToStr(pointerDriverDAC);

 // Если опережение записи данных больше чем на один пакет, то перейти в начало цикла и подождать
 if (pointerCycleDAC - pointerDriverDAC) > sizePacketDAC then
  Exit;
 if (pointerDriverDAC > pointerCycleDAC) and
    (sizeBufferDAC - pointerDriverDAC + pointerCycleDAC > sizePacketDAC) then
  Exit;

 // Обновить предыдущее значение указателя драйвера
 pointerDriverDAC_old := pointerDriverDAC;

 // Запись в буфер драйвера очередного пакета данных
 size := sizePacketDAC;
   // Если пакет выходит за границы буфера драйвера, то его нужно разделить на две части
 if (pointerCycleDAC + sizePacketDAC) > sizeBufferDAC then
    size := sizeBufferDAC - pointerCycleDAC;

 size := size div numWordsDAC;
  if numWordsDAC = 1 then
  begin
    pBuffer16DAC := pBufferDAC;
    Inc(pBuffer16DAC, pointerCycleDAC);
   for i := 0 to size - 1 do
    begin
   volt0 := amplitudeSin * sin(currentSinusTime);
      volt0_int := Round(volt0);
      CopyMemory(pBuffer16DAC, @volt0_int, 2);
      Inc(pBuffer16DAC);
   currentSinusTime := currentSinusTime + deltaSinusTime;
    end;
  end
 else
  begin
    pBuffer32DAC := pBufferDAC;
    Inc(pBuffer32DAC, (pointerCycleDAC div numWordsDAC));
   for i := 0 to size - 1 do
    begin
   volt0 := amplitudeSin * sin(currentSinusTime);
      volt0_int := Round(volt0);
      CopyMemory(pBuffer32DAC, @volt0_int, 4);
      Inc(pBuffer32DAC);
   currentSinusTime := currentSinusTime + deltaSinusTime;
    end;
  end;

 // Передвинуть указатель на отсчет для следующей записи
 pointerCycleDAC := pointerCycleDAC + numWordsDAC * size;
 // Если подошли к концу буфера, то перейти в начало
 if pointerCycleDAC >= sizeBufferDAC then
  pointerCycleDAC := 0;

 if size < (sizePacketDAC div numWordsDAC) then
  begin
  // Запись в буфер драйвера второй части пакета данных, если пакет пришлось разорвать
  size := (sizePacketDAC div numWordsDAC) - size;
  if numWordsDAC = 1 then
    begin
      pBuffer16DAC := pBufferDAC;
      Inc(pBuffer16DAC, pointerCycleDAC);
   for i := 0 to size - 1 do
      begin
     volt0 := amplitudeSin * sin(currentSinusTime);
        volt0_int := Round(volt0);
        CopyMemory(pBuffer16DAC, @volt0_int, 2);
        Inc(pBuffer16DAC);
     currentSinusTime := currentSinusTime + deltaSinusTime;
      end;
    end
  else
    begin
      pBuffer32DAC := pBufferDAC;
      Inc(pBuffer32DAC, (pointerCycleDAC div numWordsDAC));
   for i := 0 to size -1 do
      begin
     volt0 := Round(amplitudeSin * sin(currentSinusTime));
        volt0_int := Round(volt0);
        CopyMemory(pBuffer32DAC, @volt0_int, 4);
        Inc(pBuffer32DAC);
     currentSinusTime := currentSinusTime + deltaSinusTime;
      end;
    end;
    // Передвинуть указатель на отсчет для следующей записи
  pointerCycleDAC := pointerCycleDAC + numWordsDAC * size;
 end;
end;


end.


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

Россия, Москва, Зеленоград, проезд 4922 (Озерная аллея), дом 4 стр. 5. Схема проезда.
Тел./Факс: +7(495)739-39-19 (многоканальный); E-mail: info@zetlab.ru, sale@zetlab.ru.
GPS координаты: долгота 37°13′14.57″E (37.220713) широта 55°59′1.3″N (55.983695)






     
Главная | Продукция | Поддержка | Предприятие | Контакты | Карта сайта | Прайс-лист | Старый сайт | www.zetlab.ru | www.sigmausb.ru