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


Запуск АЦП Е502 от внешнего сигнала

Вы не вошли.

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

Роман Петров
09.09.2016 14:10:53
#1

Гость

Запуск АЦП Е502 от внешнего сигнала

Здравствуйте, у меня возникла вот такая дилемма:
необходимо оцифровать сигнал с 12и датчиков с помощью Е502 -  для этого я резервирую 12 логических каналов Е502 с режимами оцифровки, задаваемыми пользователем(диапазон измерений и в каком режиме - дифференциальный или с общей землей)

внешний сигнал, по которому надо оцифровывать, выглядит следующим образом(описываю физический уровень, 1 - +3.3В, 0 ~ GND):

в начальном состоянии держится 1, затем идет 12 стробов меандра, в каждом из которых длительность 0 = 0,25 мкс, длительность 1 = 0,25 мкс, т.е. период = 0,5мкс, частота 2МГц, затем идет пауза около 1 мкс, при которой сигнал висит в 1, а потом опять 12 стробов с теми же параметрами и так 2094 раза...

внешний сигнал формирует ПЛИС(не стоящая в Е502), времянка соответствует действительности, проверил на осциле...

я использовал синхронный режим оцифровки, старт оцифровки я задал внутреннюю частоту, а вот саму оцифровку через спад DYSIN1, к этому пину подключен внешний сигнал, описанный выше...

но каждый раз я получал количество отсчетов на 1 меньше, тогда я вставил один импульс прямоугольный(меандр) до начала основной передачи за 3 мкс, длительность 0 и 1 которого так же 0,25 мкс, тогда все пришло в норму по количеству...

но вот только смущают результаты, что я оцифровываю, такое ощущение, что Е502 не по перепаду из 1 в 0 оцифровывает, а в каком-то другом месте...

по умолчанию:
ADC_LCH_CNT = 12
adc_sinh = X502_SYNC_DI_SYN1_FALL
adc_mode = X502_LCH_MODE_COMM

вот прилагаю код настройки АЦП:

    err = X502_StreamsEnable(hnd_E502,X502_STREAM_ADC);
    if(err != X502_ERR_OK)
    {
        str = "Ошибка открытия потока для АЦП :";
        str.append(QString("%1").arg(err));
        str +="\n";
        window.ui->textBrowser->moveCursor(QTextCursor::End);
        window.ui->textBrowser->textCursor().insertText(str);
        return err;
    }

    X502_Configure(hnd_E502,0);

   /* Устанавливаем кол-во логических каналов */
    err = X502_SetLChannelCount(hnd_E502, ADC_LCH_CNT);
    if (err != X502_ERR_OK) {
        str = "Ошибка при задании количества логических каналов : ";
        str.append(QString("%1").arg(err));
        str += "\n";
        window.ui->textBrowser->moveCursor(QTextCursor::End);
        window.ui->textBrowser->textCursor().insertText(str);
        return err;
    }

    //устанавливаем параметры заданного логического канала в логической таблице АЦП

    str = "Диапазон измерений АЦП : ";
    switch(adc_range){
            case X502_ADC_RANGE_05: str += "от -0,5В до +0,5В \n"; break;
            case X502_ADC_RANGE_1:  str += "от -1В до +1В \n"; break;
            case X502_ADC_RANGE_2:  str += "от -2В до +2В \n"; break;
            case X502_ADC_RANGE_5:  str += "от -5В до +5В \n"; break;
    }
    window.ui->textBrowser->moveCursor(QTextCursor::End);
    window.ui->textBrowser->textCursor().insertText(str);

    str = "Режим работы каналов АЦП : ";
    switch(adc_mode){
            case X502_LCH_MODE_DIFF: {
                        str += "дифференциальный \n";
                        str += "Подключение : OS -> X1,DOS -> Y1,замкнуть AGND c Y1\n";
                        break;
            }
            case X502_LCH_MODE_COMM: {
                        str += "c общей землей \n";
                        str += "Подключение : OS -> X1,DOS -> не подключен,замкнуть AGND c GND32\n";
                        break;
            }
    }
    window.ui->textBrowser->moveCursor(QTextCursor::End);
    window.ui->textBrowser->textCursor().insertText(str);

    for(uint32_t i = 0; i < ADC_LCH_CNT; i++)
    {   err = X502_SetLChannel(hnd_E502, i,i, adc_mode, adc_range,0);
        if (err != X502_ERR_OK) {
            str = "Ошибка при задании  параметров канала ";
            str.append(QString("%1").arg(i));
            str = " : ";
            str.append(QString("%1").arg(err));
            str += "\n";
            window.ui->textBrowser->moveCursor(QTextCursor::End);
            window.ui->textBrowser->textCursor().insertText(str);
            return err;
        }
    }


    str = "Оцифровка каналов АЦП : ";
    switch(window.ui->comboBoxListStartADC->currentIndex()){
           case 0: {adc_sinh = X502_SYNC_INTERNAL;
                    str += "от внутренней частоты\n";
                    break;
                    }
           case 1: {adc_sinh = X502_SYNC_EXTERNAL_MASTER;
                    str += "от внешней частоты\n";
                    break;
                   }
           case 2: {adc_sinh = X502_SYNC_DI_SYN1_RISE;
                    str += "по перепаду из 0 в 1 входа DI_SYN1\n";
                    break;
                   }
           case 3: {adc_sinh = X502_SYNC_DI_SYN2_RISE;
                    str += "по перепаду из 0 в 1 входа DI_SYN2\n";
                    break;
                   }
           case 4: {adc_sinh = X502_SYNC_DI_SYN1_FALL;
                    str += "по перепаду из 1 в 0 входа DI_SYN1\n";
                    break;
                   }
           case 5: {adc_sinh = X502_SYNC_DI_SYN2_FALL;
                    str += "по перепаду из 1 в 0 входа DI_SYN2\n";
                    break;
                   }
   }

    window.ui->textBrowser->moveCursor(QTextCursor::End);
    window.ui->textBrowser->textCursor().insertText(str);

    // Настраиваем источник частоты синхронизации и запуска сбора данных АЦП
    err = X502_SetSyncMode(hnd_E502, adc_sinh);
    if (err != X502_ERR_OK) {
        str = "Ошибка при настраивании источника частоты синхронизации и запуска сбора данных АЦП : ";
        str.append(QString("%1").arg(err));
        str += "\n";
        window.ui->textBrowser->moveCursor(QTextCursor::End);
        window.ui->textBrowser->textCursor().insertText(str);
        return err;
    }

    //устанавливаем условие запуска синхронного ввода/вывода данных
    err = X502_SetSyncStartMode(hnd_E502,X502_SYNC_INTERNAL);
    if (err != X502_ERR_OK) {
        str = "Ошибка при выставлении условия запуска сбора данных с АЦП : ";
        str.append(QString("%1").arg(err));
        str += "\n";
        window.ui->textBrowser->moveCursor(QTextCursor::End);
        window.ui->textBrowser->textCursor().insertText(str);
        return err;
    }

    //На входе принимает требуемое значения частоты сбора АЦП в Гер-
    //цах. На выходе возвращает реально установленное значение частоты.
    if (regim_work == 0) f_acq_adc = f_cur *2;
    else f_acq_adc = X502_REF_FREQ_2000KHZ;

    //На входе принимает требуемое значение частоты сбора кадров
    //(частоты сбора на логический канал) АЦП в Герцах. На выходе возвращает реально
    //установленное значение. Если передан нулевой указатель,
    //то устанавливает максимальную частоту сбора кадров (нулевую межкадровую задержку).
    f_frame_adc = 0;

    // настраиваем частоту сбора с АЦП
    err = X502_SetAdcFreq(hnd_E502, &f_acq_adc, NULL);
    if (err != X502_ERR_OK) {
        str = "Ошибка при задании частоты сбора данных с АЦП : ";
        str.append(QString("%1").arg(err));
        str += "\n";
        window.ui->textBrowser->moveCursor(QTextCursor::End);
        window.ui->textBrowser->textCursor().insertText(str);
        return err;
    }

    str = "Внутренняя частота Е502 равна ";
    str.append(QString("%1").arg(f_acq_adc));
    str += " Гц\n";

    window.ui->textBrowser->moveCursor(QTextCursor::End);
    window.ui->textBrowser->textCursor().insertText(str);

    pal.setColor(QPalette::WindowText, Qt::blue);
    str = "Внутренняя частота Е502 равна ";
    str.append(QString("%1").arg(f_acq_adc));
    str += " Гц";

    window.ui->labelSetF_ADC_E502->setPalette(pal);
    window.ui->labelSetF_ADC_E502->setText(str);

    err = X502_Configure(hnd_E502, 0);
    if (err != X502_ERR_OK) {
        str = "Ошибка при настройке параметров АЦП : ";
        str.append(QString("%1").arg(err));
        str += "\n";
        window.ui->textBrowser->moveCursor(QTextCursor::End);
        window.ui->textBrowser->textCursor().insertText(str);
        return err;
    }

считываю данные в потоке вот таким образом:

while((rcv_size > 0) || (work == 1))
    {        rcv_size = X502_Recv(hnd_E502,rcv_buf,RECV_SIZE,RECV_TOUT);
                if (rcv_size <= 0) {
                    if(rcv_size < 0)
                     { str = "Ошибка при синхронном чтении кадра с каналов АЦП : ";

                       str.append(QString("%1").arg(err));
                       str += "\n";
                       work = 0;
                       emit SignalInsertLineToTextBrowser(0,str);
                    }
                    else
                    {
                        str = "Вычитали все данные с каналов АЦП";
                        str += "\n";
                        work = 0;
                        emit SignalInsertLineToTextBrowser(3,str);
                    }
                }
                else{
                       adcSize = rcv_size;
                       err = X502_ProcessAdcData(hnd_E502,rcv_buf,adcData,&adcSize,format_data_adc);
                       if (err != X502_ERR_OK) {
                           str = "Ошибка при распознавании считанного кадра с каналов АЦП : ";
                           str.append(QString("%1").arg(err));
                           str += "\n";
                           work = 0;
                           rcv_size = err;
                           emit SignalInsertLineToTextBrowser(0,str);
                       }
                       else{
                           //qDebug() << "adcSize :" << adcSize;
                           str  = "";
                           str1 = "";
                           for( i = 0; i < adcSize; i++)
                           {запись в файл}
                         }

                       }
                    }

        }

мне необходимо считать данные в момент времени, когда внешний сигнал падает из 1 в 0...

правильно ли я задаю режим оцифровки, особенно интересует старт(X502_SetSyncStartMode) и задание тактовой частоты(X502_SetSyncMode) для оцифровки АЦП???

почему мне я получал количество данных при оцифровке на 1 меньше при подаче внешней частоты(из-за этого пришлось добавить 1 строб до оцифровки)???

09.09.2016 14:29:58
#2

Сотрудник "Л Кард"
Здесь с 17.04.2014
Сообщений: 1,316

Re: Запуск АЦП Е502 от внешнего сигнала

Перед тем как проанализировать возможность такого режима, хотелось бы уточнить, последние ли у Вас версии прошивок ARM (версия 1.0.13) и ПЛИС (версия 0.11)? Посмотреть можно в LQMeasStudio (обновить ARM можно оттуда же файлом http://www.lcard.ru/download/e502-m4.bin, а прошивку ПЛИС через утилиту lxfw-update, которая входит в SDK - в последней версии SDK должна быть последняя прошивка).

Роман Петров
12.09.2016 13:01:06
#3

Гость

Re: Запуск АЦП Е502 от внешнего сигнала

прошивки на модуле Е502 стояли ARM версия 1.0.9 и  ПЛИС версия 0.1, сейчас обновлю и прогоню тесты заново...

отпишусь о результатах, как все сделаю

спасибо за оперативный ответ smile

12.09.2016 13:33:19
#4

Инженер-электронщик
Откуда: "Л Кард"
Здесь с 21.04.2014
Сообщений: 4,597

Re: Запуск АЦП Е502 от внешнего сигнала

Роман, если внешний сигнал для преобразования АЦП будете подавать на входы  DI_SYN1, DI_SYN2, CONV_IN, то для этих режимов внешней синхронизации максимальная частота синхросигнала составляет 1,5 МГц.

Отредактировано Гарманов Александр (12.09.2016 16:16:39)

Роман Петров
13.09.2016 16:16:18
#5

Гость

Re: Запуск АЦП Е502 от внешнего сигнала

т.к. я задаю внешний сигнал через ПЛИС, не могли бы указать, максимальные длительности 0 и 1 при  частоте в 1,5 МГц с точностью до 10нс, просто выходит период в виде дробного числа 0,66666 мкс

если я задам длительность 0 и 1 внешней частоты для Е502 равными 340 нс, т.е. период будет равен 0,68 мкс, частота примерно будет равна 1,47 МГц - корректно ли будет отрабатывать оцифровка???

и правильно ли я понимаю, что необходимо так же при настройке АЦП вызвать в самом начале
(перед строчкой err = X502_StreamsEnable(hnd_E502,X502_STREAM_ADC);):
X502_SetExtRefFreqValue(hdl,X502_REF_FREQ_1500KHZ);

так же надо ли мне вызывать функцию X502_SetAdcFreq???
если да, то с параметрами X502_SetAdcFreq(hnd,X502_REF_FREQ_1500KHZ,NULL)???

13.09.2016 17:09:50
#6

Сотрудник "Л Кард"
Здесь с 17.04.2014
Сообщений: 1,316

Re: Запуск АЦП Е502 от внешнего сигнала

Роман Петров пишет:

частота примерно будет равна 1,47 МГц - корректно ли будет отрабатывать оцифровка???

Да, может использоваться произвольная частота меньше или равная  1,5 МГц.

Да, вызов X502_SetExtRefFreqValue() и после X502_SetAdcFreq() будет правильным, при этом, если хотите, чтобы каждому спаду частоты соответствовало измерение, то частота АЦП в X502_SetAdcFreq должна быть равна значению частоты, указанному при вызове X502_SetExtRefFreqValue() (как у Вас и указано), тогда соответственно делитель частоты АЦП будет выставлен в 1 как вам и требуется.

В принципе X502_SetExtRefFreqValue() может принимать просто значения в Гц, не обязательно одну из 2-х констант (т.к. внешняя частота может быть любой в пределах 1.5 МГц). Это значение не влияет напрямую на оцифровку в модуле и может строго не соответствовать реальной внешней частоте, но указание близкого значения позволяет более оптимально выделать внутренние ресурсы при передаче данных.

В общем при таких условиях и настройках модуль должен работать как Вам требуется, если после обновления и снижения частоты останутся проблемы, то пишите.

Роман Петров
14.09.2016 13:44:27
#7

Гость

Re: Запуск АЦП Е502 от внешнего сигнала

Сейчас прогнал оцифровку, примерно получается то, что я ожидал при оцифровке...

у меня вот только вопрос - я хочу оцифровать 12 отсчетов по спаду DY_SYN1

если я посылаю внешний сигнал с частотой 1,47 МГц(такая же ситуация была и на 2МГц), где в 0 сигнал переходит 12 раз, т.е. меандр с перепадом в 0 12 раз, то оцифровывается только 11 отсчетов(я имею ввиду, что получаю при считывании при вызове функции X502_Recv, а потом X502_ProcessAdcData), пробовал увеличивать время ожидания данных и т.д., но все равно получаю только 11 отсчетов...

если до начала основной оцифровки сделать 1 раз перепад DY_SYN1 из 1 в 0 с той же частотой, а потом только через некоторое время(у меня около 3 мкс) начать цифровать(12 меандров с частотой 1,47 МГц), то появляется 12 отсчетов, а реально сигнал на DY_SYN1 изменяется с 1 на 0 13 раз, а не 12....

почему так происходит???? и корректно ли это???

14.09.2016 16:39:20
#8

Инженер-электронщик
Откуда: "Л Кард"
Здесь с 21.04.2014
Сообщений: 4,597

Re: Запуск АЦП Е502 от внешнего сигнала

Роман, мы воспроизвели Ваш эксперимент у себя. По факту всё происходит так, как Вы описываете. Причину конвейерной задержки на 1 такт синхронизации посмотрим. Сообщим позже, можно ли этот вопрос решить и каким способом.

Роман Петров
14.09.2016 16:48:57
#9

Гость

Re: Запуск АЦП Е502 от внешнего сигнала

меня еще интересует, в какой именно момент фиксируется аналоговое значение на аналоговых входах и начинается их оцифровка - прямо в момент спада DY_SYN1, либо значение относительно спада DY_SYN1 + какая-то задержка???

14.09.2016 17:53:31
#10

Инженер-электронщик
Откуда: "Л Кард"
Здесь с 21.04.2014
Сообщений: 4,597

Re: Запуск АЦП Е502 от внешнего сигнала

Роман,
Да, начинается их оцифровка - прямо в момент спада DI_SYN1.
DI_SYN1 в режиме внешней синхронизации управляет непосредственно УВХ (устройством выборки-хранения) АЦП. Задержка от активного перепада DY_SYN1 до срабатывания УВХ АЦП фиксирована и довольно  мала (порядка 20 нс). Но Вас интересует, как я понял, задержка синхронизации относительно входов АЦП,  которая зависит ещё от задержки аналогового тракта (она тоже может быть порядка 20 нс). Тонкая метрология задержек синхронизации относительно входов АЦП у нас не снималась. А конвейерная задержка на 1 такт синхронизации, которую Вы видите, это задержка в системе буферизации получения данных. Можно ли её преодолеть? - сообщим позже.

Роман Петров
15.09.2016 10:30:57
#11

Гость

Re: Запуск АЦП Е502 от внешнего сигнала

я уже реализовал запуск 13 спадов,т.е. как я писал, 1 спад в самом начале, а через 3 мкс 12 спадов- вот меня интересует, на этих 12 спадах самая первая оцифровка Е502-это 1й из 12 перепадов(2й из 13 перепадов), т.е. полученные 12 оцифровок в программе будут соответствовать 2му по 13й спад внешнего для Е502 сигнала?

15.09.2016 12:25:32
#12

Инженер-электронщик
Откуда: "Л Кард"
Здесь с 21.04.2014
Сообщений: 4,597

Re: Запуск АЦП Е502 от внешнего сигнала

Роман, чтобы получить 12 отсчётов данных, лишний 13-ый импульс на  DI_SYN1 нужно добавлять не в начале, а в конце. По факту так работают текущие прошивки L-502 и E-502. Но уже сейчас понятно, что проблема решится обновлением прошивки FPGA (лишний импульс не потребуется). Советую подождать обновления, которое постараемся выпустить оперативно.

15.09.2016 19:26:54
#13

Инженер-электронщик
Откуда: "Л Кард"
Здесь с 21.04.2014
Сообщений: 4,597

Re: Запуск АЦП Е502 от внешнего сигнала

Роман, в любом случае, прошу либо подтвердить, что Вы ждёте обновление ПО, о котором я говорил выше, либо сообщить, что оно для Вас не актуально.

17.09.2016 22:44:18
#14

Инженер-электронщик
Откуда: "Л Кард"
Здесь с 21.04.2014
Сообщений: 4,597

Re: Запуск АЦП Е502 от внешнего сигнала

Роман, при детальном рассмотрении выяснилось, что трудозатраты на внесение изменений в эту часть проекта FPGA оказались слишком велики, чтобы данную работу можно было проделать оперативно и между делом. Данную работу целесообразно проводить только в рамках постановки более общей задачи по добавлению новых режимов синхронизации в изделия L-502/E-502. Требуется включение этой работы в план, привязанный к конкретному заказу. Решения по заказам принимает наш отдел продаж. Таким образом, сроки выхода обновления прошивки FPGA пока не определены. К сожалению.