jojofeixiang 发表于 2008-11-11 11:16

振动信号采集与分析的几个问题的请教

本帖最后由 wdhd 于 2016-8-29 10:17 编辑

  SEM/ADT-620 模块化中速模拟输入模块可将与IBM PC 兼容的PC/104 CPU 模块系统构
  成一个高性能的数据采集与控制系统。结构紧凑,适于嵌入式与便携式应用的SEM/ADT-620
  模块的特点是:
  􀁺 八/十六个单端模拟输入通道
  􀁺 12 位,20 微秒或10 微秒A/D 变换器
  􀁺 ±5V,±10V 或0 到+10V 模拟输入量程
  􀁺 可用电阻配置增益
  􀁺 24 通道基于TTL/CMOS 71055 芯片的可编程数字量I/O
  􀁺 三个独立的16 位,10MHz 定时器/计数器
  􀁺 C 源码及诊断程序
  请问:
  1.厂家提供的api函数没有采样率参数的设置,如何解决?
  2.厂家提供的dll好像是vc里用的,labview调用吗?
  3.厂家提供的vc的demo程序,我想转成labview要注意什么问题?
  4.怎样实现连续采集?
  5.存储,回放和频谱分析
  请高手指点,或跟帖讨论,或加入群31945202,谢谢
  附:
  1)
  API函数Ø
  ADT620_DevLoad:加载设备驱动函数原型:
  HANDLE
  ADT620_DevLoad( )
  函数说明:
  该函数通知系统加载设备驱动,然后才能对其它API函数进行操作。
  输入:
  无
  输出:
  无
  返回值:
  成功返回标识此设备驱动的句柄,失败返回INVALID_HANDLE_VALUE。
  Ø
  ADT620_DevClose:卸载设备驱动函数原型:
  BOOL
  ADT620_DevClose(HANDLE hDevice)
  函数说明:
  该函数通知系统卸载设备驱动.
  输入:
  hDevice:从ADT620_DevLoad( )函数中返回的句柄
  输出:
  无
  返回值:
  成功返回1,失败返回非1的错误值。
  Ø
  ADT620_InitBoard:设备初始化函数原型:
  void
  ADT620_InitBoard (HANDLE hDevice,unsigned int BaseAddr,int irq_chn)
  函数说明:
  该函数对设备进行初始化,包括设置设备基地址、中断号等。
  输入:
  hDevice:从ADT620_DevLoad( )函数中返回的句柄
  BaseAddr:设备基地址
  irq_chn:设备中断号,如果不用中断则输入0。
  输出:
  无
  返回值:
  无
  Ø
  ADT620_SetEvent:将通知事件发送到驱动程序函数原型:
  int ADT620_SetEvent(HANDLE hDevice, HANDLE hEvent)
  函数说明:
  该函数用来将通知事件发送到驱动程序。具体参照示例程序。
  输入:
  hDevice:从CDT2000_DevLoad( )函数中返回的句柄
  hEvent:
  事件句柄
  输出:
  无
  返回值:
  成功返回0,失败返回非0的错误值。
  Ø
  ADT620_ConfigIOPorts:配置数字I/O口
  函数原型:
  void  ADT620_ConfigIOPorts(HANDLE hDevice,unsigned char Port0, unsigned char Port1,unsigned char Port2)
  函数说明:
  该函数对71055芯片的3个I/O口工作于模式0进行配置
  输入:
  hDevice:从ADT620_DevLoad( )函数中返回的句柄
  Port0:71055芯片的A口,1表示输入,0表示输出
  Port1:71055芯片的B口,1表示输入,0表示输出
  Port2:71055芯片的C口,1表示输入,0表示输出
  输出:
  无
  返回值:
  无
  Ø
  ADT620_ReadDigitIO:读数字I/O口
  函数原型:
  unsigned char    ADT620_ReadDigitIO(HANDLE hDevice,unsigned char InputPort);
  函数说明:
  该函数对71055芯片的3个I/O口进行读操作。
  输入:
  hDevice:从ADT620_DevLoad( )函数中返回的句柄
  InputPort:71055芯片的3个I/O口,0表示A口,1表示B口,2表示C口
  输出:
  无
  返回值:
  返回从指定I/O口读出的值
  Ø
  ADT620_WriteDigitIO:写数字I/O口
  函数原型:
  void    ADT620_WriteDigitIO(HANDLE hDevice,unsigned char OutputPort, unsigned char v);
  函数说明:
  该函数对71055芯片的3个I/O口进行写操作。
  输入:
  hDevice:从ADT620_DevLoad( )函数中返回的句柄
  OutputPort:71055芯片的3个I/O口,0表示A口,1表示B口,2表示C口
  v: 从指定I/O口写入的值
  输出:
  无
  返回值:
  无
  Ø
  ADT620_ClearIRQ:清除中断
  函数原型:
  void  ADT620_ClearIRQ(HANDLE hDevice)
  函数说明:
  该函数用于清除中断。在中断产生后必须调用该函数。
  输入:
  hDevice:从ADT620_DevLoad( )函数中返回的句柄
  输出:
  无
  返回值:
  无
  Ø
  ADT620_ClockMode:设置计数器/定时器工作方式
  函数原型:
  void ADT620_ClockMode(HANDLE hDevice,unsigned char Clock, unsigned char Mode)
  函数说明:
  该函数对82C54芯片的3个计数器/定时器的工作方式进行设置
  输入:
  hDevice:从ADT620_DevLoad( )函数中返回的句柄
  Clock:82C54芯片的3个计数器/定时器,0表示计数器0,1表示计数器1,2表示计数器2
  Mode:82C54芯片的工作方式,0~5分别表示方式0~方式5
  输出:
  无
  返回值:
  无
  Ø
  ADT620_ClockDivisor:设置计数器/定时器计数值函数原型:
  void   ADT620_ClockDivisor(HANDLE hDevice,unsigned char Clock, unsigned int Divisor)
  函数说明:
  该函数对82C54芯片的3个计数器/定时器的计数值进行设置
  输入:
  hDevice:从ADT620_DevLoad( )函数中返回的句柄
  Clock:82C54芯片的3个计数器/定时器,0表示计数器0,1表示计数器1,2表示计数器2
  Divisor: 16位计数器/定时器的计数值
  输出:
  无
  返回值:
  无
  Ø
  ADT620_ReadPITStatus:读取计数器/定时器的状态函数原型:
  char   ADT620_ReadPITStatus(HANDLE hDevice,unsigned char Timer)
  函数说明:
  该函数对82C54芯片的3个计数器/定时器的单次计数状态进行读取。
  输入:
  hDevice:从ADT620_DevLoad( )函数中返回的句柄
  Timer:82C54芯片的3个计数器/定时器,0表示计数器0,1表示计数器1,2表示计数器2
  输出:
  无
  返回值:
  单次计数结束返回1,否则返回0。
  Ø
  ADT620_ClockReadBack:读回计数器/定时器的计数值函数原型:
  unsigned int
  ADT620_ClockReadBack(HANDLE hDevice,unsigned char Timer)
  函数说明:
  该函数对82C54芯片的3个计数器/定时器的计数值进行读取。
  输入:
  hDevice:从ADT620_DevLoad( )函数中返回的句柄
  Timer:82C54芯片的3个计数器/定时器,0表示计数器0,1表示计数器1,2表示计数器2
  输出:
  无
  返回值:
  返回读取的计数器/定时器的计数值。
  Ø
  ADT620_ADSettings:设置模拟输入电压的量程和极性函数原型:
  void ADT620_ADSettings(HANDLE hDevice,float Range, char Polarity)
  函数说明:
  该函数对模拟输入电压的量程和极性进行设置。
  输入:
  hDevice:从ADT620_DevLoad( )函数中返回的句柄
  Range:模拟输入电压的量程,可输入10和20
  Polarity:模拟输入电压的极性,0表示单极性,1表示双极性
  输出:
  无
  返回值:
  无。
  Ø
  ADT620_SetChannel:设置模拟输入通道函数原型:
  void ADT620_SetChannel(HANDLE hDevice,unsigned char ChannelNumber)
  函数说明:
  该函数对模拟输入通道进行设置。
  输入:
  hDevice:从ADT620_DevLoad( )函数中返回的句柄
  ChannelNumber:模拟输入通道, 可输入0~15,分别表示通道1~通道16
  输出:
  无
  返回值:
  无。
  Ø
  ADT620_SetIRQStatus:设置中断状态函数原型:
  void ADT620_SetIRQStatus(HANDLE hDevice,char IRQStatus)
  函数说明:
  该函数对中断状态进行设置。
  输入:
  hDevice:从ADT620_DevLoad( )函数中返回的句柄
  IRQStatus:1表示中断使能,0表示中断禁止
  输出:
  无
  返回值:
  无。
  Ø
  ADT620_StartConversion:启动A/D变换函数原型:
  void ADT620_StartConversion(HANDLE hDevice)
  函数说明:
  该函数用于启动A/D变换。
  输入:
  hDevice:从ADT620_DevLoad( )函数中返回的句柄
  输出:
  无
  返回值:
  无。
  Ø
  ADT620_ConversionDone:监测A/D变换的状态函数原型:
  char ADT620_ConversionDone(HANDLE hDevice)
  函数说明:
  该函数用于监测A/D变换的状态。
  输入:
  hDevice:从ADT620_DevLoad( )函数中返回的句柄
  输出:
  无
  返回值:
  A/D变换结束返回1, 否则返回0。
  Ø
  ADT620_ReadData:读取A/D变换的数据函数原型:
  int ADT620_ReadData(HANDLE hDevice)
  函数说明:
  该函数用于读取A/D变换的数据。
  输入:
  hDevice:从ADT620_DevLoad( )函数中返回的句柄
  输出:
  无
  返回值:
  返回读取的A/D变换的数据。
  Ø
  ADT620_DigitToAnalog:将A/D变换的数据转换为输入电压值 函数原型:
  float ADT620_DigitToAnalog(HANDLE hDevice,int DigitalValue)
  函数说明:
  该函数用于将A/D变换的数据转换为输入电压值。
  输入:
  hDevice:从ADT620_DevLoad( )函数中返回的句柄
  DigitalValue:A/D变换的数据
  输出:
  无
  返回值:
  返回转换后的输入电压值。
  Ø
  ReadIOPort:读取IO地址函数原型:
  unsigned int   ReadIOPort(HANDLE hDevice,unsigned int portAddr)
  函数说明:
  该函数对指定的IO地址进行读取。
  输入:
  hDevice:从ADT620_DevLoad( )函数中返回的句柄
  portAddr:IO地址
  输出:
  无
  返回值:
  返回从指定的IO地址读取的值。
  Ø
  WriteIOPort:写入IO地址 函数原型:
  void
  WriteIOPort(HANDLE hDevice,unsigned int portAddr,unsigned int byte)
  函数说明:
  该函数对指定的IO地址进行写入。
  输入:
  hDevice:从ADT620_DevLoad( )函数中返回的句柄
  portAddr:IO地址
  byte: 向指定的IO地址写入的值
  输出:
  无
  返回值:
  无

jojofeixiang 发表于 2008-11-11 11:17

2.vc的demo程序



//

#include "stdafx.h"
#include "resource.h"
#include "adt620.h"
#include "stdlib.h"

#define ID_TIMER    1//设定一个定时器的ID值


HANDLE hDevice=0;//加载设备驱动程序的句柄
unsigned int count=0;//计数值
unsigned intBaseAddr=0x300;//基地址
unsigned char irq=7;            //中断号
unsigned char IOport0=1,IOport1=1,IOport2=1;// 三个数字I/O口都为输入状态
unsigned char IOport; // 数字I/O口
unsigned char outbyte,inbyte;      //数字I/O输入输出数值
float result;//模拟输入电压值
int ADValue;   //A/D变换的数据
int channel=0;//模拟输入通道

HANDLE hEvent=0; // AD采样事件句柄
HWND hAdDlg;//窗口句柄
char buffer;

//应用程序窗口的消息处理函数
BOOL CALLBACK DlgProc(HWND, WPARAM, WPARAM,LPARAM);
void ftoa(float source,char destination,char precision);

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR   lpCmdLine,
                     int       nCmdShow)
{
// TODO: Place code here.
    DialogBox(hInstance, (LPCTSTR)IDD_DIALOG1,0, DlgProc);
return 0;
}

// AD采样事件的线程被驱动程序唤醒,用来通知应用程序中断到来并且显示中断记录
DWORD WINAPI ServiceThread(PVOID hEvent)
{
while (TRUE)
{
WaitForSingleObject(hEvent, INFINITE);
while (ADT620_ConversionDone(hDevice) == 0); //监测A/D变换是否结束
      ADValue = ADT620_ReadData(hDevice);         //读取A/D变换的数据
      result=ADT620_DigitToAnalog(hDevice,ADValue);    //转换为模拟输入电压值
         ftoa(result,buffer,2);
   SetDlgItemText(hAdDlg,IDC_ADVALUE,buffer);
   ADT620_ClearIRQ(hDevice);   //清除中断
      }
return 0;
}

void hevent()// AD采样事件
{
DWORD Tid;   

hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
ADT620_SetEvent(hDevice,hEvent);         // 产生一个事件并且发送到驱动程序

CreateThread(0, 0x1000, ServiceThread, (PVOID)hEvent, 0, &Tid); // 产生一个等待AD采样事件的线程
}

BOOL CALLBACK DlgProc(HWND hDlg, WPARAM uMsg, WPARAM wParam, LPARAM lParam)
{

switch (uMsg)
{
case WM_CLOSE://关闭窗口消息
   if(hDevice)
   {
   if(hEvent)CloseHandle(hEvent);
   KillTimer (hDlg, ID_TIMER);
   ADT620_DevClose(hDevice);//卸载设备驱动程序
   }
   EndDialog(hDlg,TRUE);//关闭对话框
   break;
   case WM_TIMER://定时器消息
   if(!hDevice)
    break;
   ADT620_StartConversion(hDevice);   //启动A/D变换
   break;
         case WM_COMMAND:
   switch (wParam)
   {
    case Load_Driver://加载设备驱动程序
         if(hDevice)
      break;
   
         hDevice=ADT620_DevLoad();
            
         if(hDevice==INVALID_HANDLE_VALUE)
         {
      MessageBox(hDlg,"Load driver Error","error",MB_OK);
      ExitProcess(1);
         }
      EnableWindow(GetDlgItem(hDlg,Load_Driver),FALSE);
      
      break;
    case Initial://初始化
      if(!hDevice)
      break;
       ADT620_InitBoard(hDevice,BaseAddr,irq);
       if(!hEvent)
       {
       ADT620_SetIRQStatus(hDevice,1);          //设置中断使能
       hevent();         // AD采样事件
          hAdDlg=hDlg;
       }
      EnableWindow(GetDlgItem(hDlg,Initial),FALSE);
      break;
    case Read_IO:// 读数字I/O
      if(!hDevice)
      break;
      IOport = (unsigned char)GetDlgItemInt(hDlg,IDC_RPORT,NULL,FALSE);
                  
      if(IOport == 0)IOport0=1;
      else if(IOport == 1)IOport1=1;
      else if(IOport == 2)IOport2=1;
      ADT620_ConfigIOPorts(hDevice,IOport0,IOport1,IOport2);
                  inbyte = ADT620_ReadDigitIO(hDevice,IOport);
      SetDlgItemInt(hDlg,IDC_RVALUE,inbyte,FALSE);
      break;
    case Write_IO:// 写数字I/O
      if(!hDevice)
      break;
      IOport = (unsigned char)GetDlgItemInt(hDlg,IDC_WPORT,NULL,FALSE);
      outbyte = (unsigned char)GetDlgItemInt(hDlg,IDC_WVALUE,NULL,FALSE);

      if(IOport == 0)IOport0=0;
      else if(IOport == 1)IOport1=0;
      else if(IOport == 2)IOport2=0;
      ADT620_ConfigIOPorts(hDevice,IOport0,IOport1,IOport2);
            ADT620_WriteDigitIO(hDevice,IOport,outbyte);
      break;
    case Start_AD://启动A/D变换
      ADT620_ADSettings(hDevice,10,1);   //设置模拟输入电压量程和极性
      channel= (unsigned char)GetDlgItemInt(hDlg,IDC_CHANNEL,NULL,FALSE);
                     ADT620_SetChannel(hDevice,channel);   //设置模拟输入通道               
                  if (!SetTimer (hDlg, ID_TIMER, 100, NULL))//启动定时器
      {
      MessageBox (hDlg, "定时器太多!","error", MB_OK) ;
      return FALSE ;
         }
      
                      break;
    case Start_Counter:   //启动计数器
      ADT620_ClockMode(hDevice,0, 2);
                     ADT620_ClockDivisor(hDevice,0, 800);

                     ADT620_ClockMode(hDevice,1, 2);
                     ADT620_ClockDivisor(hDevice,1, 2000);

                     ADT620_ClockMode(hDevice,2, 2);
                     ADT620_ClockDivisor(hDevice,2, 5000);
      break;
    case ReadBackCountV:   //读回计数值
      count=ADT620_ClockReadBack(hDevice,2);
      SetDlgItemInt(hDlg,IDC_RBCOUNTV,count,FALSE);
      break;
      
   }
   break;
}
   return FALSE;
}

//将浮点数source转为字符串destination,设定小数部分为precision位
void ftoa(float source,char destination,char precision)
{
char i=0,j=0,k,a;
int temp;
float sample1;

if(source<0)
{
sample1=-source;
destination='-';
j=1;
}
else
{
sample1=source;
}
while(sample1/10>=1)
{
temp=(int)(sample1/10);
a=(char)((sample1-temp*10)+48);
i=i+1;
sample1=sample1/10;
}
a=(int)(sample1+48);

for(k=j;k<=j+i;k++)
{
destination=a;
}

destination='.';

if(source<0)
{
sample1=-source;
}
else
{
sample1=source;
}
temp=(int)sample1;
for(i=1;i<=precision;i++)
{
a=(char)((sample1*10-temp*10)+48);
destination=a;
sample1=sample1*10;
temp=(int)sample1;
}
destination=0;
}

mooncity 发表于 2008-11-11 17:05

搞这么大一堆代码,谁看得懂哦。别人顶多介绍下方法,具体实现自己去慢慢研究吧

jojofeixiang 发表于 2008-11-11 17:23

哦,请高手在关键的地方点一下。
我能实现单点采集,但读数据的readData函数的参数不像其他卡给的函数直接可以设采样率,所以高速采样不知用什么方法实现了?

黑色牛仔酷 发表于 2015-3-31 20:32

悲催的用户组!什么都看不到
页: [1]
查看完整版本: 振动信号采集与分析的几个问题的请教