使用NI DAQMx设置模拟输出的频率

时间:2014-10-01 18:36:57

标签: nidaqmx digital-analog-converter

我试图使用NI DAQMx ANSI C库来输出wav文件中包含的波形。我使用libsnd库来读取wav文件,并且我能够成功提取数据,但输出波形的频率远高于实际的wav文件本身。有谁知道如何设置输出波形的频率。我使用的是PCIe 6351数据采集卡。

以下是我为完成此任务而编写的一些代码:

#include<stdio.h>
#include<conio.h>
#include <math.h>
#include <stdlib.h>
#include <windows.h>
#include "NIDAQmx.h"
#include "Sync_AIAO.h"
#include "sndfile.h"
#include "RIB2.h"


int32 fnCreateTask(TaskHandle *AOTaskHandle)
{
    int32 error=0;
    DAQmxErrChk(DAQmxCreateTask("", AOTaskHandle));
    Error:
    return error;
}






int main(int argc, char** argv)
{
    int i=0;
    int32 error=0;
    TaskHandle  AOtaskHandle = 0;
    float64* AIOSample;
    float *fWavSample;
    SNDFILE *SoundFile;
    SF_INFO SoundFileInfo;  
    int iNoOfSamples=0;
    FILE* fp;
    //Error code
    //Handle to the tasks created
    char        errBuff[2048]={'\0'};


    //DAQmxErrChk(DAQmxCreateTask("",AOtaskHandle));
    fnCreateTask(&AOtaskHandle);

    //Create an analog out channel
    DAQmxErrChk (DAQmxCreateAOVoltageChan(*   (&AOtaskHandle),"Dev1/ao1","",-10.0000000,+10.00000,DAQmx_Val_Volts,NULL));

    //Set for 
  //DAQmxErrChk     (DAQmxCfgDigEdgeStartTrig(&AOtaskHandle,"ai/StartTrigger",DAQmx_Val_Rising));


SoundFile=sf_open("sine.wav", SFM_READ, &SoundFileInfo);

  //Check if file is opened sucessfully
  if (SoundFile == NULL)
  {
    printf("Failed to open the file.\n");
    exit(-1);
  }

  //allocate memory for the buffer that is to hold the wav data:
  fWavSample = new float[SoundFileInfo.channels * SoundFileInfo.frames]; 
  iNoOfSamples = SoundFileInfo.channels * SoundFileInfo.frames;

  //Read data into the float structure
  sf_readf_float(SoundFile, fWavSample, SoundFileInfo.frames);

  printf("Float:%d, Float64:%d\n",sizeof(float),sizeof(float64));

  //printf("%f\n",fWavSample[0]);
  //printf("%f\n",fWavSample[200000]);

  AIOSample = new float64[iNoOfSamples];


 // fopen_s(&fp,"output.dat","w");

  for(i=0;i<SoundFileInfo.channels * SoundFileInfo.frames;i++)
  {
     // fprintf(fp,"Data[%d]:%f\n",i,fWavSample[i]);
      AIOSample[i] = (float64)fWavSample[i];

  }

 // fclose(fp);
  int32 written;


  /*calling function that will output the trigger on PFI6*/

  //fnSrPlayElectric(); //play electric stimulus 
  while(1)
  {
      /*
      DAQmxErrChk(DAQmxWriteAnalogF64(AOtaskHandle,(SoundFileInfo.channels * SoundFileInfo.frames), 
      true, 10.0, DAQmx_Val_GroupByChannel,AIOSample,&written,NULL));
      */

      DAQmxErrChk(DAQmxWriteAnalogF64(AOtaskHandle,1000, 
      true, 10.0, DAQmx_Val_GroupByChannel,AIOSample,&written,NULL));

  //Sleep(3000);
  }





//Display the error to the user here.
Error:
    if( DAQmxFailed(error) )
    {
        DAQmxGetExtendedErrorInfo(errBuff,2048);
        puts(errBuff);
    }




getch();
}

我很感激我能得到的任何帮助。谢谢!

阿图尔

1 个答案:

答案 0 :(得分:2)

现在,您的程序正在一次一个地将样本写入DAQ卡,并且您可以以1000个为一组发送样本。在DAQmx术语中,这是一个“软件定时”任务,因为操作系统,调度程序,CPU和其他系统动态会影响样本写入卡的频率。

由于音频文件以恒定速率进行采样,您还需要对DAQ卡进行编程,以便以相同的速率生成样本。在DAQmx术语中,使用采样时钟称为“硬件定时”任务。 DAQmx还附带ANSI C示例,用于配置采样时钟[1]。看看“连续生成电压 - 内部时钟”,它可能在磁盘上有一个缩写名称,以及它如何使用函数DAQmxCfgSampClkTiming [2]。还有更多有关DAQmx在线时序如何工作的信息[3]。

例如,如果您的音频文件以44.1 kHz采样,则需要将采样时钟频率设置为相同。 谨防但是,6351具有100 MHz时基[4]并将其除以整数以获得更低的采样时钟速率。因此,对于此44.1 kHz示例,您可以获得的最接近频率为44.111 kHz(100 MHz / 2267)或44.091 kHz(100 MHz / 2268)。您可以在配置后使用DAQmxGetSampClkRate [5]检查实际采样率 - DAQmx会将其强制转换为有效值。

  

[1]基于文本的NI-DAQmx数据采集示例:: ANSI C   
http://www.ni.com/white-paper/6999/en/#ANSIC

     

[2] NI-DAQmx C参考帮助:: DAQmxCfgSampClkTiming   
http://zone.ni.com/reference/en-XX/help/370471W-01/daqmxcfunc/daqmxcfgsampclktiming

     

[3]时间安排,硬件与软件   
http://zone.ni.com/reference/en-XX/help/370466V-01/TOC11.htm

     

[4] X系列用户手册::时钟路由(第183页)   
http://digital.ni.com/manuals.nsf/websearch/82BB2FBF407E178586257D15006F596C

     

[5] NI-DAQmx C参考帮助:: DAQmxGetSampClkRate   
http://zone.ni.com/reference/en-XX/help/370471W-01/mxcprop/func1344