tumanovalex |
04-02-2021 14:59 2948794 |
Спасибо за ответ. Я попробовал internal и public сразу же после того, как задал вопрос - не получилось. Оказалось, что я случайно исключил файл с функциями из DLL из компилирования. Прошу прощения за свою невнимательность.
Возникла более серьезная проблема. Есть пример программы на C++ (Test_Zadc.cpp), который я поместил в архив. Код на С++ работает, я проверял на АЦП с подключенными к первому (0) и второму (1) входам АЦП батарейками на 1.5 и 3 V. Все функции из zadc.dll работают нормально в программе на C#, ошибок не выдают. Но у меня не получается правильно перевести строки с указателями. В коде на C++ (проверку на ошибки убрал):
Код:
short *pBuffer16ADC = NULL; // Указатель на начало буфера драйвера для АЦП с разрядностью не более 16 бит
long *pBuffer32ADC = NULL; // Указатель на начало буфера драйвера для АЦП с разрядностью более 16 бит
long sizeBufferADC; // Размер буфера драйвера в словах
long pointerADC = 0; // Указатель на текущий элемент заполнения буфера драйвера (кратен 2)
long pointerADC_old = 0; // Предыдущее значение указателя на буфер драйвера
// Запрос буфера АЦП
Err = ZGetBufferADC(typeDevice, numberDSP, (void**) &pBuffer16ADC, &sizeBufferADC);
pBuffer32ADC = (long*) pBuffer16ADC;
// Запрос на останов АЦП
Err = ZStopADC(typeDevice, numberDSP);
// Запрос на запуск АЦП
Err = ZStartADC(typeDevice, numberDSP);
// Цикл чтения данных АЦП
while(!kbhit())
{
// Задержка обновления данных АЦП для отображения
Sleep(500);
// Запрос указателя на текущий элемент буфера
Err = ZGetPointerADC(typeDevice, numberDSP, &pointerADC);
// Если новые данные в буфер от АЦП не поступили, то перейти в начало цикла и подождать
if(pointerADC == pointerADC_old)
continue;
// Обновление предыдущего значения указателя
pointerADC_old = pointerADC;
// Переход на отсчет первого включенного канала последнего кадра АЦП
if(pointerADC - numWordsADC * numChannelsADC < 0)
pointerADC = sizeBufferADC + pointerADC - numWordsADC * numChannelsADC;
else
pointerADC = pointerADC - numWordsADC * numChannelsADC;
// Вычисление из целого значения отсчета АЦП вещественного значение отсчета (в вольтах) для первого канала
if(numWordsADC == 1)
volt0 = resolutionADC0 * (pBuffer16ADC[pointerADC]) / amplifyADC0;
else
volt0 = resolutionADC0 * (pBuffer32ADC[pointerADC / numWordsADC]) / amplifyADC0;
// Вывод мгновенного значения напряжения для первого канала
printf("%+8.4f", volt0);
// Если количество каналов устройства больше одного
if(numChannelsADC > 1)
{
// Переход на следующий отсчет АЦП
pointerADC += numWordsADC;
// При выходе за границу буфера, осуществляется переход в начало
if(pointerADC >= sizeBufferADC)
pointerADC = pointerADC - sizeBufferADC;
// Вычисление из целого значения отсчета АЦП вещественного значение отсчета (в вольтах) для второго канала
if(numWordsADC == 1)
volt1 = resolutionADC1 * (pBuffer16ADC[pointerADC]) / amplifyADC1;
else
volt1 = resolutionADC1 * (pBuffer32ADC[pointerADC/numWordsADC]) / amplifyADC1;
// Вывод мгновенного значения напряжения для второго канала
printf("\t%+8.4f", volt1);
Я попытался переписать код на C#:
Код:
IntPtr pBuffer16;
int sizeBuffer;
if (ZetFun.ZGetBufferADC(typeDevice, numberDSP, out pBuffer16, out sizeBuffer) != 0)
ShowMes("Не удалось получить указатель на буфер АЦП!");
IntPtr pBuffer32 = pBuffer16; //НАВЕРНОЕ, НУЖНО КАКОЕ-ТО ПРЕОБРАЗОВАНИЕ
if (ZetFun.ZStartADC(typeDevice, numberDSP) != 0) // инициализация АЦП
ShowMes("Не удалось запустить АЦП!");
var watch = new Stopwatch();
double[] volt = new double[nChan];
int pointer; int pointer_old;
watch.Start();
while (true)
{
Thread.Sleep(500);
if (watch.ElapsedMilliseconds >= 6000)
break;
if (ZetFun.ZGetPointerADC(typeDevice, numberDSP, out pointer) != 0)
ShowMes("Не удалось получить указатель на текущий элемент буфера!");
if (pointer == pointer_old)
continue;
pointer_old = pointer;
for (int i = 0; i < ariNumberChannel.Length; i++)
{
if (pointer - numWords * ariNumberChannel[i] < 0)
pointer = sizeBuffer + pointer - numWords * ariNumberChannel[i];
else
pointer = pointer - numWords * ariNumberChannel[i];
volt[i] = ardResol[i] * (pBuffer32[pointer / numWords]) / ardAmplify[i]; // ТУТ ОШИБКА
// (pBuffer32[pointer / numWords]) подчеркнут красным, я не знаю, как правильно записать эту строку
Console.WriteLine(volt[i]);
pointer += numWords;
if (pointer >= sizeBuffer)
pointer = pointer - sizeBuffer;
} // for
} // while
watch.Stop();
// Запрос на останов АЦП
if(ZetFun.ZStopADC(typeDevice, numberDSP) != 0)
ShowMes("Не удалось остановить АЦП!");
// Запрос на освобождение буфера АЦП
if (pBuffer16 != null)
{
if(ZetFun.ZRemBufferADC(typeDevice, numberDSP, ref pBuffer16) != 0)
ShowMes("Не удалось освободить буфер!");
}
if (ZetFun.ZClose(typeDevice, numberDSP) != 0)
ShowMes("Ошибка ZClose!");
Помогите, пожалуйста, разобраться, как нужно переписать строки с указателями в коде на C# так, чтобы получался правильный результат измерения входного сигнала АЦП. Проект прикрепить не смог, максимальная сумма всех вложений достигнута. Подскажите, пожалуйста, как обнулить свои сложения или размещать код по URL.
|