Текст программы Test_DAC на Visual Basic 6 |
|
Option Explicit
Const MAX_TYPE_DSP = 30 ' Максимальное поддерживаемое кол-во типов устройств
' Глобальные переменные
Dim typeDevice As Long ' Тип устройства
Dim numberDSP As Long ' Порядковый номер устройства
Dim enable As Long ' Вкл. / Выкл. (поддерживается / не поддерживается)
Dim numChannelsDAC As Long ' Кол-во включенных каналов ЦАП
Dim numWordsDAC As Long ' Кол-во слов (по два байта) в одном отсчете ЦАП
Dim pBufferDAC As Long ' Указатель на начало буфера драйвера
Dim sizeBufferDAC As Long ' Размер буфера драйвера в словах
Dim sizeInterruptBufferDAC As Long ' Размер буфера прерывания в словах
Dim sizePacketDAC As Long ' Кол-во отсчетов обрабатываемых за один раз
Dim Buffer16DAC As Integer ' Локальный буфер на один отсчет (для ЦАП с разрядность не более 16 бит)
Dim Buffer32DAC As Long ' Локальный буфер на один отсчет (для ЦАП с разрядностью более 16 бит)
Dim pointerDriverDAC As Long ' Указатель драйвера на текущий элемент заполнения буфера драйвера
Dim pointerDriverDAC_old As Long ' Предыдущее значение указателя драйвера на буфер драйвера
Dim pointerCycleDAC As Long ' Указатель цикла обработки на текущий элемент заполнения буфера драйвера
Dim pointerCycleDAC_abs As Long ' Абсолютный указатель на текущий элемент заполнения буфера драйвера
Dim i As Long, size As Long ' Счетчик цикла
Dim sleepTime As Long ' Время ожидания в цикле (мс)
Dim responseTime As Long ' Время реакции в цикле (мс). Должно быть больше времени ожидания
Dim freqDAC As Double ' Частота дискретизации ЦАП
Dim attenDAC0 As Double ' Коэф. затухания по первому каналу ЦАП
Dim resolutionDAC As Double ' Вес младшего разряда ЦАП
Dim currentSinusTime As Double ' Аргумент функции синус
Dim deltaSinusTime As Double ' Значение инкремента аргумента функции синус
Dim volt0 As Double ' Мгновенное текущее значение, записываемое в ЦАП (код)
Dim amplitudeSin As Double ' Коэф. преобразования амплитуды синуса
Dim freqSin As Double ' Частота синуса (Гц)
Private Sub Form_Load()
Me.Left = GetSetting(App.Title, "Settings", "MainLeft", 1000)
Me.Top = GetSetting(App.Title, "Settings", "MainTop", 1000)
Call OpenDevice
End Sub
Private Sub Form_Unload(Cancel As Integer)
Dim i As Integer
Call CloseDevice
'close all sub forms
For i = Forms.Count - 1 To 1 Step -1
Unload Forms(i)
Next
If Me.WindowState <> vbMinimized Then
SaveSetting App.Title, "Settings", "MainLeft", Me.Left
SaveSetting App.Title, "Settings", "MainTop", Me.Top
End If
End Sub
Public Sub OpenDevice()
Dim Err As Long ' Код ошибки
sleepTime = 50 ' Время ожидания в цикле генерации синуса (мс)
responseTime = 250 ' Время опережения (время реакции) (мс)
amplitudeSin = 0.1 ' Амплитуда синуса 100 мВ (СКЗ = 70.5 мВ)
freqSin = 10 ' Частота синуса 10 Гц
attenDAC0 = 0.1 ' Значение аттенюатора зададим 0.1 (для лучшего соотношения сигнал/шум)
numberDSP = 0 ' Здесь задан первый порядковый номер устройства
pointerCycleDAC = 0
pointerDriverDAC = 0
pointerDriverDAC_old = 0
pBufferDAC = 0
' Цикл подключения к первому поддерживаемому устройству
For typeDevice = 0 To MAX_TYPE_DSP - 1
' подключиться к драйверу (обязательно)
Err = ZOpen(typeDevice, numberDSP)
If (Err = 0) Then
' Проверить поддерживается ли ЦАП
Err = ZGetEnableDAC(typeDevice, numberDSP, enable)
If (Err = 0 And enable <> 0) Then
Exit For
Else
Err = ZClose(typeDevice, numberDSP)
End If
End If
Next typeDevice
If (typeDevice >= MAX_TYPE_DSP) Then
MsgBox ("Поддерживаемое устройство не найдено!")
End
End If
' включить первый канал ЦАП
Err = ZSetOutputDAC(typeDevice, numberDSP, 0, 1)
If (Err <> 0) Then
MsgBox ("Ошибка в ZSetOutputDAC(), Error = " + CStr(Err))
GoTo EndWithZClose
End If
' опросить кол-во включенных каналов ЦАП
' Если включено каналов больше одного, то пример правильно работать не будет
' (синус будет выдаваться на все каналы, причем его реальная частота разделится
' на кол-во включенных каналов)
Err = ZGetNumberOutputDAC(typeDevice, numberDSP, numChannelsDAC)
If (Err <> 0) Then
MsgBox ("Ошибка в ZGetNumberOutputDAC(), Error = " + CStr(Err))
GoTo EndWithZClose
End If
' опросить вес младшего разряда ЦАП
Err = ZGetDigitalResolChanDAC(typeDevice, numberDSP, 0, resolutionDAC)
If (Err <> 0) Then
MsgBox ("Ошибка в ZGetDigitalResolutionDAC(), Error = " + CStr(Err))
GoTo EndWithZClose
End If
' опросить кол-во слов в одном отсчете ЦАП
Err = ZGetWordsDAC(typeDevice, numberDSP, numWordsDAC)
If (Err <> 0) Then
MsgBox ("Ошибка в ZGetWordsDAC(), Error = " + CStr(Err))
GoTo EndWithZClose
End If
' опросить частоту дискретизации ЦАП
Err = ZGetFreqDAC(typeDevice, numberDSP, freqDAC)
If (Err <> 0) Then
MsgBox ("Ошибка в ZGetFreqDAC(), Error = " + CStr(Err))
GoTo EndWithZClose
End If
' опросить размер буфера прерывания ЦАП
Err = ZGetInterruptDAC(typeDevice, numberDSP, sizeInterruptBufferDAC)
If (Err <> 0) Then
MsgBox ("Ошибка в ZGetInterruptDAC(), Error = " + CStr(Err))
GoTo EndWithZClose
End If
' Установить (опросить) коэф. затухания аттенюатора по первому каналу ЦАП
Err = ZSetAttenDAC(typeDevice, numberDSP, 0, attenDAC0, attenDAC0)
If (Err <> 0) Then
MsgBox ("Ошибка в ZSetAttenDAC(), Error = " + CStr(Err))
GoTo EndWithZClose
End If
' Проверка переменных, чтобы избежать деления на 0
If (numWordsDAC < 1 Or numWordsDAC > 2 Or freqDAC < 1# Or attenDAC0 = 0# Or resolutionDAC = 0#) Then
MsgBox ("Ошибочные значения параметров ЦАП!")
GoTo EndWithZClose
End If
' Запросить буфер ЦАП
Err = ZGetBufferDAC(typeDevice, numberDSP, pBufferDAC, sizeBufferDAC)
If (Err <> 0) Then
MsgBox ("Ошибка в ZGetBufferDAC(), Error = " + CStr(Err))
GoTo EndWithZClose
End If
' Вычислим размер пакета согласно заданному времени реакции (опережения)
sizePacketDAC = (freqDAC * responseTime / 1000)
sizePacketDAC = numWordsDAC * sizePacketDAC
' Размер пакета должен быть не меньше двух размеров буфера прерывания и не больше половины буфера драйвера
If sizePacketDAC < 2 * sizeInterruptBufferDAC Then
sizePacketDAC = 2 * sizeInterruptBufferDAC
End If
If sizePacketDAC > sizeBufferDAC / 2 Then
sizePacketDAC = sizeBufferDAC / 2
End If
' Рассчитаем параметры для генерации синуса
amplitudeSin = amplitudeSin / (resolutionDAC * attenDAC0)
deltaSinusTime = 2# * (4# * Atn(1#)) * freqSin / freqDAC ' Число Пи = 4.*atan(1.)
currentSinusTime = 0#
' Вычислить адрес памяти куда копировать данные ЦАП для CopyMemory()
pointerCycleDAC_abs = pBufferDAC
' Запись в буфер драйвера первых двух пакетов
size = 2 * sizePacketDAC / numWordsDAC
If numWordsDAC = 1 Then
For i = 1 To size
Buffer16DAC = amplitudeSin * Sin(currentSinusTime)
'Buffer16DAC = volt0
' Скопировать два байта если отсчет ЦАП состоит из одного слова
CopyMemory ByVal pointerCycleDAC_abs, Buffer16DAC, 2
' Инкремент указателя
pointerCycleDAC_abs = pointerCycleDAC_abs + 2
' Инкремент аргумента функции синус
currentSinusTime = currentSinusTime + deltaSinusTime
Next i
Else
For i = 1 To size
Buffer32DAC = amplitudeSin * Sin(currentSinusTime)
'Buffer32DAC = volt0
' Скопировать четыре байта если отсчет ЦАП состоит из двух слов
CopyMemory ByVal pointerCycleDAC_abs, Buffer32DAC, 4
' Инкремент указателя
pointerCycleDAC_abs = pointerCycleDAC_abs + 4
' Инкремент аргумента функции синус
currentSinusTime = currentSinusTime + deltaSinusTime
Next i
End If
pointerCycleDAC = 2 * sizePacketDAC
' Останов ЦАП
Err = ZStopDAC(typeDevice, numberDSP)
' Останов АЦП
Err = ZStopADC(typeDevice, numberDSP)
' Запуск ЦАП
Err = ZStartDAC(typeDevice, numberDSP)
' Запуск АЦП
Err = ZStartADC(typeDevice, numberDSP)
' Задать время ожидания таймера
frmMain.Timer1.Interval = sleepTime
' Запуск таймера
frmMain.Timer1.Enabled = True
GoTo OnExit
EndWithZClose:
Err = ZClose(typeDevice, numberDSP)
End
OnExit:
End Sub
Public Sub CloseDevice()
Dim Err As Long ' Код ошибки
' Останов ЦАП
Err = ZStopDAC(typeDevice, numberDSP)
' Останов АЦП
Err = ZStopADC(typeDevice, numberDSP)
' Освободить буфер ЦАП
If pBufferDAC <> 0 Then
Err = ZRemBufferDAC(typeDevice, numberDSP, pBufferDAC)
End If
' Отключиться от драйвера (обязательно)
Err = ZClose(typeDevice, numberDSP)
pBufferDAC = 0
End Sub
Private Sub Timer1_Timer()
Dim Err As Long ' Код ошибки
' Запросить указатель на текущий элемент буфера
Err = ZGetPointerDAC(typeDevice, numberDSP, pointerDriverDAC)
If Err <> 0 Then
MsgBox ("Ошибка в ZGetPointerDAC(), Error = " + CStr(Err))
Unload frmMain
End
End If
' Отобразить указатель цикла обработки на текущий элемент заполнения буфера драйвера
TextBox1.Text = CStr(pointerCycleDAC)
' Отобразить указатель драйвера на текущий элемент заполнения буфера драйвера
TextBox2.Text = CStr(pointerDriverDAC)
' Если опережение записи данных больше чем на один пакет, то перейти в начало цикла и подождать
If pointerCycleDAC - pointerDriverDAC > sizePacketDAC Then
GoTo EndTimer
End If
If (sizeBufferDAC - pointerDriverDAC + pointerCycleDAC > sizePacketDAC) And _
(pointerDriverDAC > pointerCycleDAC) Then
GoTo EndTimer
End If
' Обновить предыдущее значение указателя драйвера
pointerDriverDAC_old = pointerDriverDAC
' Запись в буфер драйвера очередного пакета данных
size = sizePacketDAC
' Если пакет выходит за границы буфера драйвера, то его нужно разделить на две части
If pointerCycleDAC + sizePacketDAC > sizeBufferDAC Then
size = sizeBufferDAC - pointerCycleDAC
End If
size = size / numWordsDAC
' Вычислить адрес памяти куда копировать данные ЦАП для CopyMemory()
pointerCycleDAC_abs = pBufferDAC + 2 * pointerCycleDAC
' Запись в буфер драйвера первых двух пакетов
If (numWordsDAC = 1) Then
For i = 1 To size
Buffer16DAC = amplitudeSin * Sin(currentSinusTime)
'Buffer16DAC = volt0
' Скопировать два байта если отсчет ЦАП состоит из одного слова
CopyMemory ByVal pointerCycleDAC_abs, Buffer16DAC, 2
' Инкремент указателя
pointerCycleDAC_abs = pointerCycleDAC_abs + 2
' Инкремент аргумента функции синус
currentSinusTime = currentSinusTime + deltaSinusTime
Next i
Else
For i = 1 To size
Buffer32DAC = amplitudeSin * Sin(currentSinusTime)
'Buffer32DAC = volt0
' Скопировать четыре байта если отсчет ЦАП состоит из двух слов
CopyMemory ByVal pointerCycleDAC_abs, Buffer32DAC, 4
' Инкремент указателя
pointerCycleDAC_abs = pointerCycleDAC_abs + 4
' Инкремент аргумента функции синус
currentSinusTime = currentSinusTime + deltaSinusTime
Next i
End If
' Передвинуть указатель на отсчет для следующей записи
pointerCycleDAC = pointerCycleDAC + numWordsDAC * size
' Если подошли к концу буфера, то перейти в начало
If pointerCycleDAC >= sizeBufferDAC Then
pointerCycleDAC = 0
End If
If size < sizePacketDAC / numWordsDAC Then
' Запись в буфер драйвера второй части пакета данных, если пакет пришлось разорвать
size = sizePacketDAC / numWordsDAC - size
' Вычислить адрес памяти куда копировать данные ЦАП для CopyMemory()
pointerCycleDAC_abs = pBufferDAC + 2 * pointerCycleDAC
If (numWordsDAC = 1) Then
For i = 1 To size
Buffer16DAC = amplitudeSin * Sin(currentSinusTime)
'Buffer16DAC = volt0
' Скопировать два байта если отсчет ЦАП состоит из одного слова
CopyMemory ByVal pointerCycleDAC_abs, Buffer16DAC, 2
' Инкремент указателя
pointerCycleDAC_abs = pointerCycleDAC_abs + 2
' Инкремент аргумента функции синус
currentSinusTime = currentSinusTime + deltaSinusTime
Next i
Else
For i = 1 To size
Buffer32DAC = amplitudeSin * Sin(currentSinusTime)
'Buffer32DAC = volt0
' Скопировать четыре байта если отсчет ЦАП состоит из двух слов
CopyMemory ByVal pointerCycleDAC_abs, Buffer32DAC, 4
' Инкремент указателя
pointerCycleDAC_abs = pointerCycleDAC_abs + 4
' Инкремент аргумента функции синус
currentSinusTime = currentSinusTime + deltaSinusTime
Next i
End If
' Передвинуть указатель на отсчет для следующей записи
pointerCycleDAC = pointerCycleDAC + numWordsDAC * size
End If
EndTimer:
End Sub
В любой части настоящего сайта могут иметься неточности и технические ошибки. В содержание могут периодически вноситься изменения и/или поправки.
Россия, Москва, Зеленоград, проезд 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)
|