|
// Программа, включающая канал ЦАП устройства и отображающая значения указателя драйвера на текущий элемент заполнения буфера драйвера
// и указатель цикла обработки на текущий элемент заполнения буфера драйвера
// © ЗАО "ЭТМС" 1992-2011. Все права защищены
#include "stdafx.h"
#include <windows.h>
#include <conio.h>
#include <stdio.h>
#include <math.h>
#include "zadc_int.h" // Интерфейс библиотеки Zadc.dll
#define MAX_TYPE_DSP 20 // Максимальное поддерживаемое количество типов устройств
#define MAX_DEVICE_NAME 16 // Максимальное значение длины возвращаемого имени устройства
int main(int argc, char* argv[])
{
long typeDevice; // Тип устройства
long numberDSP = 0; // Порядковый номер сигнального процессора
long Err; // Код ошибки
long enable; // Флаг поддерживается / не поддерживается
long numChannelsDAC; // Количество включенных каналов ЦАП
long numWordsDAC; // Количество слов (по два байта) в одном отсчете ЦАП
short *pBuffer16DAC = NULL; // Указатель на начало буфера драйвера для ЦАП с разрядностью не более 16 бит
long *pBuffer32DAC = NULL; // Указатель на начало буфера драйвера для ЦАП с разрядностью более 16 бит
long sizeBufferDAC; // Размер буфера драйвера в словах
long sizeInterruptBufferDAC; // Размер буфера прерывания в словах
long sizePacketDAC; // Количество отсчетов, обрабатываемых за один раз
long sleepTime = 50; // Время ожидания в цикле (мс)
long responseTime = 250; // Время реакции в цикле (мс). Должно быть больше времени ожидания
long serial; // Серийный номер устройства
char deviceName[MAX_DEVICE_NAME]; // Имя устройства
long size; // Счетчик цикла
long pointerDriverDAC = 0; // Указатель драйвера на текущий элемент заполнения буфера драйвера
long pointerDriverDAC_old = 0; // Предыдущее значение указателя драйвера на буфер драйвера
long pointerCycleDAC = 0; // Указатель цикла обработки на текущий элемент заполнения буфера драйвера
double freqDAC; // Частота дискретизации ЦАП
double attenDAC0 = 0.1; // Коэффициент затухания по первому каналу ЦАП
double resolutionDAC; // Вес младшего разряда ЦАП
double currentSinusTime = 0.; // Аргумент функции синус
double deltaSinusTime; // Значение инкремента аргумента функции синус
double volt0; // Мгновенное текущее значение, записываемое в ЦАП (код)
double amplitudeSin = 0.1; // Амплитуда синусоидального сигнала (В)
double freqSin = 10; // Частота синусоидального сигнала (Гц)
// Цикл подключения к первому поддерживаемому устройству
for(typeDevice = 0; typeDevice < MAX_TYPE_DSP; typeDevice++)
{
// Подключение к драйверу устройства
Err = ZOpen(typeDevice, numberDSP);
// Если подключение прошло без ошибок
if(Err == 0)
{
// Проверка поддержки устройством ЦАП
Err = ZGetEnableDAC(typeDevice, numberDSP, &enable);
// Если устройство поддерживает ЦАП
if(Err == 0 && enable != 0)
{
// Выход из цикла подключения
break;
}
// Если устройство не поддерживает ЦАП
else
{
// Вывод информации об ошибке
printf("ZGetEnableDAC() return Error = 0x%X\n\r", Err);
// Отключение от драйвера устройства
Err = ZClose(typeDevice, numberDSP);
}
}
}
// Если не удалось подключиться к драйверу устройства
if(typeDevice >= MAX_TYPE_DSP)
{
// Вывод информации об ошибке
printf("Device not found! Error = 0x%X\n\r", Err);
getch();
return 0;
}
// Если удалось подключиться к драйверу устройства
else
{
// Вывод информации о том, что произошло подключение к драйверу устройства
printf("Device found...\n\r");
}
// Опрос имени устройства
Err = ZGetNameDevice(typeDevice, numberDSP, deviceName, MAX_DEVICE_NAME);
// Если опрос выполнился с ошибкой
if(Err != 0)
{
// Вывод информации об ошибке
printf("ZGetNameDevice() return Error = 0x%X\n\r", Err);
// Отключение от драйвера устройства
Err = ZClose(typeDevice, numberDSP);
getch();
return 0;
}
// Если опрос выполнился без ошибок
else
{
// Вывод имени устройства
printf("Device name: %s\n\r", deviceName);
}
// Опрос серийного номера устройства
Err = ZGetSerialNumberDSP(typeDevice, numberDSP, &serial);
// Если опрос выполнился с ошибкой
if(Err != 0)
{
// Вывод информации об ошибке
printf("ZGetNameDevice() return Error = 0x%X\n\r", Err);
// Отключение от драйвера устройства
Err = ZClose(typeDevice, numberDSP);
getch();
return 0;
}
// Если опрос выполнился без ошибок
else
{
// Вывод серийного номера устройства
printf("Serial number: %ld\n\r", serial);
}
// Запрос на включение первого канала ЦАП устройства
Err = ZSetOutputDAC(typeDevice, numberDSP, 0, 1);
// Если запрос выполнился с ошибкой
if(Err != 0)
{
// Вывод информации об ошибке
printf("ZSetOutputDAC() return Error = 0x%X\n\r", Err);
// Отключение от драйвера устройства
Err = ZClose(typeDevice, numberDSP);
getch();
return 0;
}
// Если запрос выполнился без ошибок
else
{
// Вывод информации об успешном включении первого канала ЦАП устройства
printf("First channel activation is successful...\n\r");
}
// Опрос количества включенных каналов ЦАП
// Если включено каналов больше одного, то пример правильно работать не будет
// (синус будет выдаваться на все каналы, причем его реальная частота разделится на количество включенных каналов)
Err = ZGetNumberOutputDAC(typeDevice, numberDSP, &numChannelsDAC);
// Если опрос выполнился с ошибкой
if(Err != 0)
{
// Вывод информации об ошибке
printf("Function ZGetNumberOutputDAC() return Error = 0x%X\n\r", Err);
// Отключение от драйвера устройства
Err = ZClose(typeDevice, numberDSP);
getch();
return 0;
}
// Если опрос выполнился без ошибок
else
{
// Вывод количества включенных каналов ЦАП устройства
printf("Quantity of activated DAC channel: %ld\n\r", numChannelsDAC);
}
// Опрос веса младшего разряда ЦАП первого канала устройства
Err = ZGetDigitalResolChanDAC(typeDevice, numberDSP, 0, &resolutionDAC);
// Если опрос выполнился с ошибкой
if(Err != 0)
{
// Вывод информации об ошибке
printf("ZGetDigitalResolutionDAC() return Error = 0x%X\n\r", Err);
// Отключение от драйвера устройства
Err = ZClose(typeDevice, numberDSP);
getch();
return 0;
}
// Если опрос выполнился без ошибок
else
{
// Вывод веса младшего разряда ЦАП первого канала устройства
printf("First channel digital resolution: %f\n\r", resolutionDAC);
}
// Опрос количества слов в одном отсчете ЦАП
Err = ZGetWordsDAC(typeDevice, numberDSP, &numWordsDAC);
// Если опрос выполнился с ошибкой
if(Err != 0)
{
// Вывод информации об ошибке
printf("ZGetWordsDAC() return Error = 0x%X\n\r", Err);
// Отключение от драйвера устройства
Err = ZClose(typeDevice, numberDSP);
getch();
return 0;
}
// Если опрос выполнился без ошибок
else
{
// Вывод количества слов в одном отсчете ЦАП устройства
printf("Quantity of words: %ld\n\r", numWordsDAC);
}
// Опрос частотs дискретизации ЦАП
Err = ZGetFreqDAC(typeDevice, numberDSP, &freqDAC);
// Если опрос выполнился с ошибкой
if(Err != 0)
{
// Вывод информации об ошибке
printf("ZGetFreqDAC() return Error = 0x%X\n\r", Err);
// Отключение от драйвера устройства
Err = ZClose(typeDevice, numberDSP);
getch();
return 0;
}
// Если опрос выполнился без ошибок
else
{
// Вывод частоты дискретизации ЦАП устройства
printf("Frequency: %f\n\r", freqDAC);
}
// Опрос размера буфера прерывания ЦАП
Err = ZGetInterruptDAC(typeDevice, numberDSP, &sizeInterruptBufferDAC);
// Если опрос выполнился с ошибкой
if(Err != 0)
{
// Вывод информации об ошибке
printf("ZGetInterruptDAC() return Error = 0x%X\n\r", Err);
// Отключение от драйвера устройства
Err = ZClose(typeDevice, numberDSP);
getch();
return 0;
}
// Если опрос выполнился без ошибок
else
{
// Вывод размера буфера прерывания ЦАП
printf("Interrupt buffer size: %ld\n\r", sizeInterruptBufferDAC);
}
// Запрос на установку коэффициента затухания аттенюатора ЦАП по первому каналу
Err = ZSetAttenDAC(typeDevice, numberDSP, 0, attenDAC0, &attenDAC0);
// Если запрос выполнился с ошибкой
if(Err != 0)
{
// Вывод информации об ошибке
printf("ZSetAttenDAC() return Error = 0x%X\n\r", Err);
// Отключение от драйвера устройства
Err = ZClose(typeDevice, numberDSP);
getch();
return 0;
}
// Проверка переменных, чтобы избежать деления на ноль
if(numWordsDAC < 1 || numWordsDAC > 2 || freqDAC < 1. || attenDAC0 == 0. || resolutionDAC == 0.)
{
// Вывод информации об ошибке
printf("Error DAC parameters\n\r");
// Отключение от драйвера устройства
Err = ZClose(typeDevice, numberDSP);
getch();
return 0;
}
// Запрос буфера ЦАП
Err = ZGetBufferDAC(typeDevice, numberDSP, (void**) &pBuffer16DAC, &sizeBufferDAC);
// Если запрос выполнился с ошибкой
if(Err != 0)
{
// Вывод информации об ошибке
printf("Function ZGetBufferDAC() return Error = 0x%X\n\r", Err);
// Отключение от драйвера устройства
Err = ZClose(typeDevice, numberDSP);
getch();
return 0;
}
pBuffer32DAC = (long*) pBuffer16DAC;
// Вычисление размера пакета согласно заданному времени реакции (опережения)
sizePacketDAC = (long) freqDAC * responseTime / 1000;
sizePacketDAC = numWordsDAC * sizePacketDAC;
// Размер пакета должен быть не меньше двух размеров буфера прерывания и не больше половины буфера драйвера
if(sizePacketDAC < 2 * sizeInterruptBufferDAC)
sizePacketDAC = 2 * sizeInterruptBufferDAC;
if(sizePacketDAC > sizeBufferDAC / 2)
sizePacketDAC = sizeBufferDAC / 2;
// Расчет параметров для генерации синусоидального сигнала (число "Пи" = 4. * atan(1.))
amplitudeSin = amplitudeSin / (resolutionDAC * attenDAC0);
deltaSinusTime = 2. * (4. * atan(1.)) * freqSin / freqDAC;
// Запись в буфер драйвера первых двух пакетов
size = 2 * sizePacketDAC / numWordsDAC;
// Для ЦАП с размерностью не более 16 бит
if(numWordsDAC == 1)
{
for(long i = 0; i < size; i++)
{
volt0 = amplitudeSin * sin(currentSinusTime);
pBuffer16DAC[i] = (short) volt0;
currentSinusTime += deltaSinusTime;
}
}
// Для ЦАП с разрядностью более 16 бит
else
{
for(long i = 0; i < size; i++)
{
volt0 = amplitudeSin * sin(currentSinusTime);
pBuffer32DAC[i] = (long) volt0;
currentSinusTime += deltaSinusTime;
}
}
pointerCycleDAC = 2 * sizePacketDAC;
// Запрос на останов ЦАП
Err = ZStopDAC(typeDevice, numberDSP);
// Запрос на останов АЦП
Err = ZStopADC(typeDevice, numberDSP);
// Запрос на запуск ЦАП
Err = ZStartDAC(typeDevice, numberDSP);
// Запрос на запуск АЦП
Err = ZStartADC(typeDevice, numberDSP);
// Цикл генерации синусоидального сигнала и записи данных ЦАП
while(!kbhit())
{
// Задержка обновления данных ЦАП для отображения
Sleep(sleepTime);
// Запрос указателя на текущий элемент буфера
Err = ZGetPointerDAC(typeDevice, numberDSP, &pointerDriverDAC);
// Если запрос выполнился с ошибкой
if(Err != 0)
{
// Вывод информации об ошибке
printf("Function ZGetPointerDAC() return Error = 0x%X\n\r", Err);
// Выход из цикла
break;
}
// Вывод информации об указателях
printf("pointerCycleDAC = %ld, pointerDriverDAC = %ld\n", pointerCycleDAC, pointerDriverDAC);
// Если опережение записи данных больше чем на один пакет, то перейти в начало цикла и подождать
if(pointerCycleDAC - pointerDriverDAC > sizePacketDAC)
continue;
if((pointerDriverDAC > pointerCycleDAC) && (sizeBufferDAC - pointerDriverDAC + pointerCycleDAC > sizePacketDAC))
continue;
// Обновление предыдущего значения указателя драйвера
pointerDriverDAC_old = pointerDriverDAC;
// Запись в буфер драйвера очередного пакета данных
size = sizePacketDAC;
// Если пакет выходит за границы буфера драйвера, то его нужно разделить на две части
if(pointerCycleDAC + sizePacketDAC > sizeBufferDAC)
size = sizeBufferDAC - pointerCycleDAC;
size = size / numWordsDAC;
// Для ЦАП с размерностью не более 16 бит
if(numWordsDAC == 1)
{
for(long i = 0; i < size; i++)
{
volt0 = amplitudeSin * sin(currentSinusTime);
pBuffer16DAC[pointerCycleDAC + i] = (short) volt0;
currentSinusTime += deltaSinusTime;
}
}
// Для ЦАП с разрядностью более 16 бит
else
{
for(long i = 0; i < size; i++)
{
volt0 = amplitudeSin * sin(currentSinusTime);
pBuffer32DAC[pointerCycleDAC / numWordsDAC + i] = (long) volt0;
currentSinusTime += deltaSinusTime;
}
}
// Передвижение указателя на отсчет для следующей записи
pointerCycleDAC += numWordsDAC * size;
// Если подошли к концу буфера, то перейти в начало
if(pointerCycleDAC >= sizeBufferDAC)
pointerCycleDAC = 0;
if(size < (sizePacketDAC / numWordsDAC))
{
// Запись в буфер драйвера второй части пакета данных, если пакет пришлось разорвать
size = (sizePacketDAC / numWordsDAC) - size;
// Для ЦАП с размерностью не более 16 бит
if(numWordsDAC == 1)
{
for(long i = 0; i < size; i++)
{
volt0 = amplitudeSin * sin(currentSinusTime);
pBuffer16DAC[pointerCycleDAC + i] = (short) volt0;
currentSinusTime += deltaSinusTime;
}
}
// Для ЦАП с разрядностью более 16 бит
else
{
for(long i = 0; i < size; i++)
{
volt0 = amplitudeSin * sin(currentSinusTime);
pBuffer32DAC[pointerCycleDAC / numWordsDAC + i] = (long) volt0;
currentSinusTime += deltaSinusTime;
}
}
// Передвижение указателя на отсчет для следующей записи
pointerCycleDAC += numWordsDAC * size;
}
}
// Запрос на останов ЦАП
Err = ZStopDAC(typeDevice, numberDSP);
// Запрос на останов АЦП
Err = ZStopADC(typeDevice, numberDSP);
// Запрос на освобождение буфера ЦАП
if(pBuffer16DAC != NULL)
{
Err = ZRemBufferDAC(typeDevice, numberDSP, (void**) &pBuffer16DAC);
// Если запрос выполнился с ошибкой
if(Err != 0)
{
// Вывод информации об ошибке
printf("Function ZRemBufferDAC() return Error = 0x%X\n\r", Err);
}
}
// Отключение от драйвера устройства
Err = ZClose(typeDevice, numberDSP);
// Если запрос выполнился с ошибкой
if(Err != 0)
{
// Вывод информации об ошибке
printf("Function ZClose() return Error = 0x%X\n\r", Err);
}
if(!kbhit())
getch();
printf("Press any key for exit...");
getch();
return 0;
}
|