技术天地

ETA104数采模块实现波形信号采集作者:朱贤武    发布时间:2018-6-20 16:05:21    被阅览数:

  ETA104模拟数据采集模块(下文简称:ETA104模块)是基于英创公司SBC840工控应用底板、符合DM5028标准应用扩展模块。ETA104模块上的模数转换功能,采用ADS7871模拟信号转换芯片,占用ESMARC工控主板的SPI总线进行通讯,最高可实现48K的数据转换率,最大支持8路14bit模拟信号转换。


  ETA104模块的A/D转换芯片的数据转换启动方法有2种,一种方法是使用软件写入指令启动数据转换,第二种方法是使用引脚“ADConvert”启动数据转换:在该引脚上产生一个由低到高的上升沿,便可根据最近一次的A/D输入端口配置,启动一次数据转换,同时引脚“ADBUSY”由低电平变为高电平;当前数据转换完成后,引脚信号“ADBUSY”会产生一个由高到低的下降沿,表示当前数据已经转换好。


  根据ETA104模块的这种特点,可以很方便地实现波形数据采样,基本思路如下:1、配置A/D转换芯片,以满足需要采集的模拟信号输入端口与输入方式;2、根据数据采样率需求,配置PWM输出参数,然后启动PWM信号,经由ADConvert信号引脚触发启动A/D数据转换;3、当数据转换完成以后,由ADBUSY信号触发系统IRQ中断;4、系统中断后,启动SPI总线进行当前数据读取。


  ADConvert信号通过ETA104的J1.P25脚接入,连接到ESMARC工控主板的PWM1信号端口;ADBUSY信号通过ETA104的J1.30脚输出,连接到ESMARC工控主板的IRQ1信号端口。ETA104数据采样控制信号所占用的相关引脚,如下表所示:


无标题文档

引脚信号名称功能描述
J1.25GPIO6PWM1信号输出用于等时采样时,启动AD转换,该信号连接到ADConvert
J1.30GPIO24中断输入IRQ1数据转换完成,通过ADBUSY信号输出下降沿到IRQ1
J1.38GPIO28SPI_MISO控制ADC器件的SPI总线信号
J1.40GPIO29SPI_MOSI
J1.42GPIO30SPI_CLK
J1.44GPIO31SPI_CSn


  模拟信号采样流程参考图如下:


ETA104数采模块实现波形信号采集.png


  程序流程说明:

  1、初始化A/D,主要是配置模拟信号输入方式、模拟信号输入通道、A/D片内增益。

  2、要得到高精度的等时采集点的数据,因此使用PWM信号来启动A/D的数据转换,以达到非常高的时间要求精度。

  3、系统使用A/D芯片的BUSY信号的下降沿,触发系统中断,通知系统,当前数据已经准备好。

  4、以上资源初始化好以后,就可以开始启动A/D转换了。直接启动PWM信号输出即可。

  5、等待IRQ中断消息,即表示当前数据转换完成。

  6、利SPI总线读取A/D已转换好的数据并存贮。

  7、检查要采样的数据个数是否已达到,则关闭PWM输出,停止数据采样。然后关才IRQ、PWM相关设备。


  以下是基于ESM9287-WinCE6.0环境的例子程序。由于ESM9287的IRQ响应速度限制,该环境最大数据采样率只能到2Kbps。


  // 申请一个数据Buff空间,用于存放采样数据结果

       AD_DataBuff = new DWORD[AD_CovCount];

       if(AD_DataBuff == NULL)

              return ;

      

       // 初始化A/D,配置A/C采样通道与信号输入模式

       MyADC_Test.ADS7871_ConfigREG(ADS7818_REG_GainMux,AD_Channel);

 

       // 初始化IRQ,配置中断源IRQ1作为系统触发

       hIRQ1 = CreateFile(_T("IRQ1:"),                         

              GENERIC_READ|GENERIC_WRITE,        

              FILE_SHARE_READ|FILE_SHARE_WRITE,     

              NULL,                                                         

              OPEN_EXISTING,                                   

              FILE_FLAG_RANDOM_ACCESS,                   

              NULL);                                                       

       if(hIRQ1==INVALID_HANDLE_VALUE)

       {

              printf("Open IRQ1 false!\r\n");

              return ;

       }

 

       // 初始化PWM信号,使用PWM1作为A/D转换启动信号

       hPWM = CreateFile( _T("PWM1:"),              

              GENERIC_READ|GENERIC_WRITE,          

              FILE_SHARE_READ|FILE_SHARE_WRITE,

              NULL,                                                           

              OPEN_EXISTING,                                     

              FILE_FLAG_RANDOM_ACCESS,                     

              NULL);                                                         

       if(hPWM==INVALID_HANDLE_VALUE)

       {

              printf("Open PWM false!\r\n");

              return ;

       }

 

       PwmInfo.dwFreq = AD_CovRate; //设置PWM输出频率为数据采样率,如1000Hz

       PwmInfo.dwDuty = 10;

       PwmInfo.dwResolution = 1;

       dwNumberOfBytesWritten = 0;

       bRet = WriteFile(hPWM, &PwmInfo, sizeof(PWM_INFO), &dwNumberOfBytesWritten, NULL);

       if(!bRet)

       {

              printf("WriteFile failed\n");

              CloseHandle(hPWM);

       }

 

       i1 = 0;

       while(1) //数据采样循环控制

       {

              dwTimeout = 5; //timeout 5ms

              if (!DeviceIoControl(hIRQ1,                  //等待中断触发信号

                    IOCTL_WAIT_FOR_IRQ,                   

                     &dwTimeout,                                       

                     sizeof(DWORD),                           

                     &dwReturn,                                   

                     sizeof(DWORD),                            

                     NULL,                                              

                     NULL))                                            

              {

                     dwReturn =  WAIT_FAILED;

              }

 

              if(dwReturn == WAIT_OBJECT_0)

              {

                     i1++;

                     MyADC_Test.ADS7871_Read( &AD_DataBuff[i1] );//读取AD采样好的数据

                     if(i1>=AD_CovCount) //判断数据采样个数是否已达到设置值

                            break;

              }

       }

 

       PwmInfo.dwFreq = 0;

       PwmInfo.dwDuty = 10;

       PwmInfo.dwResolution = 1;

       dwNumberOfBytesWritten = 0;

       bRet = WriteFile(hPWM, &PwmInfo, sizeof(PWM_INFO), &dwNumberOfBytesWritten, NULL); //停止PWM输出

 

       CloseHandle(hPWM);//关闭PWM设备

       CloseHandle(hIRQ1); //关闭IRQ设备

       //数据复制/转移到用户数据BUFF

       //......

       delete[] AD_DataBuff;//清理申请的运态数据空单

Go Top