Имя пользователя:
Пароль:
 

Название темы: C# Программирование АЦП
Показать сообщение отдельно

Старожил


Сообщения: 251
Благодарности: 3

Профиль | Отправить PM | Цитировать


Спасибо за ответ. Я попробовал 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.

Отправлено: 14:59, 04-02-2021 | #3

Название темы: C# Программирование АЦП