Российский производитель и разработчик сертифицированного измерительного оборудования с 1987 года


PCI плата!

Вы не вошли.

 Поиск | Регистрация | Вход 

Vlad PU
26.10.2011 11:21:57
#1

Гость

PCI плата!

Доброго времени суток, L-CARD!

Приобрел плату L-780M. Очень доволен ей, попробовал съем информации с помощью L-Graph I и LGraph2, все работает отлично и

АЦП и ЦАП!

Теперь к основному! Начал писать свою программу для съема данных с платы (С++ Builder). Подключил файлы: "ioctl.h",

"ifc_ldev.h", "create.h","791cmd.h", "pcicmd.h", как показало в примере l7xx.tst!

Загрузил библиотеку, создал виртуальный слот,получил указатель на интерфейс! Все прошло успешно. Все параметры платы

читаются!

Теперь к основному: Почему-то не идут данные с платы, как мне кажется! *sync по нулям, а data выдает "безумные" значение!

Листинг:
//---------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"

#include "L-780//ioctl.h"
#include "L-780//ifc_ldev.h"
#include "L-780//create.h"
#include "L-780//791cmd.h"
#include "L-780//pcicmd.h"

//-------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

IDaqLDevice* pI;                //Указатель на интерфейс
ULONG slot = 0;                 //Номер слота
PLATA_DESCR_U2 pd;              //Структура
USHORT *data;
ULONG *sync;

USHORT IrqStep = 1024;//777-777%7; // половинка буфера кратная числу каналов
USHORT FIFO = 1024;         //
USHORT pages = 128;
USHORT multi = 4; // - количество половинок кольцевого буфера, которое мы хотим собрать


ULONG status;
USHORT complete;

HANDLE hThread;
ULONG Tid;


USHORT   *fdata;
HANDLE hFile, hMap;
long fsize;
ULONG WINAPI ServiceThread(PVOID /*Context*/);

ULONG WINAPI ServiceThread(PVOID /*Context*/)
{
Form1->Memo1->Lines->Add("Thread");

   ULONG halfbuffer = IrqStep*pages/2;             // Собираем половинками кольцевого буфера
   ULONG fl2,fl1 = fl2 = (*sync<=halfbuffer)? 0:1; // Настроили флаги
   USHORT *tmp, *tmp1;
   for(int i=0;i<multi;i++)                        // Цикл по необходимомму количеству половинок
   {
      while(fl2==fl1) fl2=(*sync<=halfbuffer)? 0:1; // Ждем заполнения половинки буфера
      tmp=fdata+(halfbuffer*i);                    // Настраиваем указатель в файле
      tmp1=data+(halfbuffer*fl1);                  // Настраиваем указатель в кольцевом буфере
      memcpy(tmp,tmp1,halfbuffer*sizeof(USHORT));// Записываем данные в файл
      fl1=(*sync<=halfbuffer)? 0:1;                // Обновляем флаг
      Sleep(0);                                    // если собираем медленно то можно и спать больше
   }
   complete=1;                                     // Мы завершили сбор данных
  return 0;                                          // Вышли
}

//-------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//-------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
        //Загрузка библиотеки
        if(CallCreateInstance("lcomp.dll")){
        Memo1->Lines->Add("Загрузка бибилотеки прошла успешно");}


        //Создание объекта для слота
        LUnknown* pIUnknown = CreateInstance(slot);

        //Создание виртуального слота
        if(pIUnknown == NULL){
        ShowMessage("Создание виртуального слота ПРОВАЛЕНО");
        }//if(pIUnknown == NULL){
        else{
        Memo1->Lines->Add("Создание виртуального слота прошла успешно");}

        //Получение указателя на интерфейс
        HRESULT hr= pIUnknown->QueryInterface(IID_ILDEV, (void**) &pI);

        if(SUCCEEDED(hr)) {
        Memo1->Lines->Add("Получение указателя прошло успешно");}
        else{ShowMessage("Получение указателя на интерфейс ПРОВАЛЕНО");}
        pIUnknown->Release();

        pI->OpenLDevice();
        pI->LoadBios("l780");
        pI->PlataTest();

        SLOT_PAR sl;
        pI->GetSlotParam(&sl);
        //START: Вывод параметров
        /*
        Memo1->Lines->Add(sl.Base);
        Memo1->Lines->Add(sl.BaseL);
        Memo1->Lines->Add(sl.Mem);
        Memo1->Lines->Add(sl.Mem1);
        Memo1->Lines->Add(sl.BoardType);
        Memo1->Lines->Add(sl.DSPType);
        Memo1->Lines->Add(sl.Irq);
        */
        //EDN: Вывод параметров

        //Параметры платы
        pI->ReadPlataDescr(&pd);
        //START: Вывод свойств платы
        /*
        Memo1->Lines->Add(pd.t1.SerNum);
        Memo1->Lines->Add(pd.t1.BrdName);
        Memo1->Lines->Add(pd.t1.Rev);
        Memo1->Lines->Add(pd.t1.DspType);
        Memo1->Lines->Add(sl.BoardType);
        Memo1->Lines->Add(pd.t1.IsDacPresent);
        Memo1->Lines->Add(pd.t1.Quartz);
        */
        //END: Вывод свойств платы

       
        DWORD tm = 10000000;
        pI->RequestBufferStream(&tm,L_STREAM_ADC);

         ADC_PAR adcPar;
         
         adcPar.t1.s_Type = L_ADC_PARAM;
         adcPar.t1.AutoInit = 1;
         adcPar.t1.dRate = 100.0;
         adcPar.t1.dKadr = 0,0067;
         adcPar.t1.dScale = 0;
         adcPar.t1.SynchroType = 3;
         adcPar.t1.SynchroSensitivity = 0;
         adcPar.t1.SynchroMode = 0;
         adcPar.t1.AdChannel = 0;
         adcPar.t1.AdPorog = 0;
         adcPar.t1.NCh = 6;
         adcPar.t1.Chn[0] = 0x0;
         adcPar.t1.Chn[1] = 0x1;
         adcPar.t1.Chn[2] = 0x2;
         adcPar.t1.Chn[3] = 0x3;
         adcPar.t1.FIFO = 1024;
         adcPar.t1.IrqStep = 1024;
         adcPar.t1.Pages = 128;
         adcPar.t1.IrqEna = 1;
         adcPar.t1.AdcEna = 1;

         pI->FillDAQparameters(&adcPar.t1);

         Memo2->Lines->Add(tm);
         Memo2->Lines->Add(adcPar.t1.Pages);
         Memo2->Lines->Add(adcPar.t1.IrqStep);
         Memo2->Lines->Add(adcPar.t1.FIFO);
         Memo2->Lines->Add(adcPar.t1.dRate);
         Memo2->Lines->Add(adcPar.t1.dKadr);

         Memo2->Lines->Add("");

         pI->SetParametersStream(&adcPar.t1, &tm, (void **)&data, (void **)&sync,L_STREAM_ADC);

         Memo2->Lines->Add("");

         Memo2->Lines->Add(tm);
         Memo2->Lines->Add(adcPar.t1.Pages);
         Memo2->Lines->Add(adcPar.t1.IrqStep);
         Memo2->Lines->Add(adcPar.t1.FIFO);
         Memo2->Lines->Add(adcPar.t1.dRate);
         Memo2->Lines->Add(adcPar.t1.dKadr);


         IrqStep = adcPar.t2.IrqStep;
         pages = adcPar.t2.Pages;

         
   fsize=multi*(pages/2)*IrqStep; // размер файла

   hFile=CreateFile("data.dat",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_WRITE,
                               NULL,CREATE_ALWAYS,FILE_FLAG_RANDOM_ACCESS,NULL);

   if(hFile==INVALID_HANDLE_VALUE){ MessageBox(0,"File open error","Error",MB_OK|MB_ICONERROR);}

   hMap=CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,fsize*2,NULL);

   if(hMap==NULL){MessageBox(0,"File open error","Error",MB_OK|MB_ICONERROR);}

   fdata=(WORD *)MapViewOfFile(hMap,FILE_MAP_WRITE,0,0,0);

   complete=0;

   pI->EnableCorrection();


        // Инициализируем внутренние переменные драйвера
        pI->InitStartLDevice();


        // Создаем и запускаем поток сбора данных
        hThread=CreateThread(0,0x2000,ServiceThread,0,0,&Tid);//

        // Запускаем сбор в драйвере
        status=pI->StartLDevice();

        /*
        // Печатаем индикатор сбора данных
        while(!complete)
        {
        Memo1->Lines->Add(*sync);
        Sleep(20);
        }
        */
}
//-------------------

Не подскажите, м.б. я где-то лоханулся и что-то не вызвал (или я идиот big_smile)? Поток запускается, а сбор данных не идет!

Поток запускается, а дальше все ... создается пустой *.dat файл! Или с параметрами нужно поиграться (частота сбора,

интервал между кадрами, буфером и т.д.)

Это по поводу АЦП

Теперь по поводу ЦАП:

Листинг:
//-------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "L-780//ioctl.h"
#include "L-780//ifc_ldev.h"
#include "L-780//create.h"
#include "L-780//791cmd.h"
#include "L-780//pcicmd.h"

#include <vcl.h>
#include <windows.h>
#include <stdio.h>
#include <stdint.h>
#include <conio.h>
#include <clocale>
#include <iostream>
#include <objbase.h>
#include <math.h>

#include <assert.h>
//-------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
IDaqLDevice* pI;

ULONG *sync, *sync1;

//-------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
ULONG slot = 0;
PLATA_DESCR_U pd;
// Загрузка библиотеки и инициализация интерфейса
Label1->Caption="Load library" ;
CallCreateInstance("lcomp.dll");
Label1->Caption="Call CreateInstance";
LUnknown* pIUnknown = CreateInstance(slot);
if(pIUnknown == NULL) { Label1->Caption="Call CreateInstance FAILED"; }
else{
Label1->Caption="Get IDaqLDevice interface";
}
HRESULT hr = pIUnknown->QueryInterface(IID_ILDEV,(void**)&pI);
if(!SUCCEEDED(hr)) { Label1->Caption="Get IDaqLDevice interface FAILED"; }
else{
pIUnknown->Release();
Label1->Caption="IDaqLDevice get success";
// Начало работы с платой
}
pI->OpenLDevice();

pI->LoadBios("l780");
pI->ReadPlataDescr(&pd);

Label2->Caption =  pd.t2.BrdName ;
Label1->Caption =  AnsiString(pd.t2.IsDacPresent);

DAC_PAR dacPar;
dacPar.t2.s_Type = L_DAC_PARAM;
dacPar.t2.AutoInit = 0;
dacPar.t2.dRate = 0.0;
dacPar.t2.FIFO =  1024;
dacPar.t2.IrqStep = 1024;
dacPar.t2.Pages = 128;
dacPar.t2.IrqEna = 0;
dacPar.t2.DacEna = 1;

pI->FillDAQparameters(&dacPar.t2);

ULONG *data, *data1;


      ULONG db=512000;
      pI->RequestBufferStream(&db, L_STREAM_DAC);
      pI->SetParametersStream(&dacPar.t2,&db, (void **)&data1, (void **)&sync1,L_STREAM_DAC);

}
//-------------


void __fastcall TForm1::Button1Click(TObject *Sender)
{
      // Инициализируем внутренние переменные драйвера
      pI->InitStartLDevice();

      // Запускаем сбор в драйвере
      pI->StartLDevice();

USHORT u1 = 2 / 5.0 * 0x7ff;
USHORT u2 = 2 / 5.0 * 0x7ff;

ASYNC_PAR pp;

pp.s_Type = L_ASYNC_DAC_OUT;
pp.Chn[0] = 0x00;
pp.Chn[1] = 0x01;
pp.Data[0] = u1;
pp.Data[1] = u2;

pI->IoAsync(&pp);


}

//-------------

Здесь то где я мог ошибиться?

26.10.2011 13:02:31
#2

Сотрудник "Л Кард"
Откуда: Москва
Здесь с 23.04.2014
Сообщений: 3,727

Re: PCI плата!

я думаю loadbios не прошел...файла биоса наверное нет рядом с exe...

Vlad PU
26.10.2011 13:40:11
#3

Гость

Re: PCI плата!

Блин, вот я <е****>!
Действительно, счетчик пошел теперь!
Спасибо, Poul!
Вопросик, куда нужно засунуть файлы *.bio, что бы читались автоматически, как с *.dll в system32 их запихнуть или обязательно рядом *.exe обязательно?

Vlad PU
26.10.2011 14:10:58
#4

Гость

Re: PCI плата!

По поводу ЦАП
Посмотрел форум, оказывается еще надо pp.Mode = 0; сделать. (Заработало)!
Т.е. получается, что бы подавать на 2 сразу, нужно 2 раза IoAsync(&pp) вызывать или  ....??

26.10.2011 14:58:03
#5

Сотрудник "Л Кард"
Откуда: Москва
Здесь с 23.04.2014
Сообщений: 3,727

Re: PCI плата!

для биоса путь нужноуказывать в LoadBios. класть куда угодно. Да, два раза вызывать...

Vlad PU
27.10.2011 17:03:12
#6

Гость

Re: PCI плата!

Ув. Poul!

Хотел бы уточнить некоторые нюансы с АЦП кодом и его переводом в Вольты

В документации к плате написано, что пределы АЦП кодов от -8000 до +8000, а на плате L-780M пределы АЦП, как я понял от -5 В до +5 В.

Значит, что бы перевести коды АЦП в Вольты нужно всего навсего КОД АЦП разделить на 1600? Насколько корректен данных подход при переводе кодов АЦП в Вольты?

Практика показывает незначительные расхождения (подавалось переменное напряжение) или это связано с задержками ОС (имеется ввиду, задержка приема данных из кольцевого буфера)?

Vlad PU
27.10.2011 17:08:49
#7

Гость

Re: PCI плата!

В дополнение хотелось прояснить еще один момент!

В программе LGraph2 при подаче напряжения на ЦАП +5В  сигнал инвертируется, становится равным отрицательным (в районе -1,2 : -1,7 В), а при подаче +4,99 Становится равным +4,99! Как это можно устранить или подавать просто максимальный код АЦП 4192 (по моему), что бы получить +5В


Так же заметил, что при "пустых" (ничего на них не подается и не заземляются) АЦП входах в кольцевом буфере собираются какие-то странные значения, порядка 60000, хотя предел 8000! С чем это связано и можно ли это пройти?

28.10.2011 09:58:24
#8

Сотрудник "Л Кард"
Откуда: Москва
Здесь с 23.04.2014
Сообщений: 3,727

Re: PCI плата!

корректен. там есть еще коррекция через функцию EbableCorrection. C практикой непонятно. Если данные собраны и просчитаны то совпадать должно.

Большие числа это отрицательные значения. кольцевой буфер надо считать типом данных SHORT.