㈠ AD转换后的数据怎么处理啊
电压 = AD采样值 / 采样精度 *参考电压
例如:
2v采样值为102, 则读取采样值后计算得102 / 255 * 5 = 2V
㈡ AD出来的数字信号要怎么处理后才能在LCD上显示
单片机读AD的数据,可能是并行IO口读或spi或ic线来读,读到的数据送到LCD显示就行
过程就是单片机读取AD,AD数据处理,AD数据显示LCD上
如果你的读一次数据显示一次数据的话,根本没必要加什么缓存,直接送到LCD即可
㈢ 汇编语言 ad 采样出来的数据如何精确处理
用比较指令 比较两次 比较大保留 比较小保留 循环比较~ 比较后 保留的两个值就是最大和最小了
㈣ 怎么样对AD采样后的数据进行恢复得到原始数据另外还有怎样对AD采样后的数据进行FFT忘大神指点。。。。
恢复数据:1方法一:对采样数据进行低通滤波,低通滤波器的截止频率为1/2的采样频率,滤波器阶数越高效果越好。
方法二:将采样数据和SINC函数做时域卷积,等效为在频域和门函数相乘(低通滤波)
以上两个方法默认采样的数据为冲击串,现实中,采样的数据实际上是冲击串和门函数的时域卷积,这样的话要完全恢复原始数据,要对门函数对应的频域中的SINC函数进行幅度和相位补偿(具体请参考相关文献)。
FFT算法:请参考任何一本数字信号处理的教科书。在matlab中的命令为: fft(采样数据矩阵)
㈤ 单片机AD数据处理怎么精确到小数点后几位
不要用浮点运算,计算出一个系数后直接用整型运算,这样比较省时间。在计算时先乘后除,精度不够最好乘一个系数再除。比如把1V乘以1000变成1000mV,但是注意不要溢出,也就是运算过程中数据长度和精度权衡一下。最后只需在显示时做一些处理就行了
比如说5V参考电压,10位AD,读AD转换值为m,则所测电压为X=5m/1024V,处理时可以这样:X=m*(5000/1024)=m*(625/128)(mV),如果以V为单位显示,那显示的时候再加一个小数点就行了。如果不需要显示,在以后的运算中根据精度需要做适当的变换就可以了
㈥ ad转换时的数据处理是怎么回事啊就是这句temp=getdata*1.0/255*5000; //将得到的数据进行处理 谢谢了
getdata* (5000/255) 5000mv==255
㈦ ad7799采集后数据怎么处理
想问下你:
第一你采集到的数据是来自哪里(AD?还是其他?),准备如何送入FPGA?
第二你准备将采集到的数据利用什么输出?(串口?还是其他?)
你把这几个问题想清楚就很好办了,不管你用什么,我觉得数据实时输入和FPGA处理之间需要一个缓存器,双口RAM、FIFO等等都可以实现,其他的部分具体怎么实现就要看你的选择了。
㈧ ad转换后的数据处理应如何做,比如说,在电压为2.5V,AD值为1000 0000,这时我如何把2跟5提取出来,不使用C
ad转换的数据是对基准电压的一个比例值,如果你的基准电压是5v,ad转换后就通过把你转换得出的值乘以你的最小刻度,就是分辨率了,如果你是8为ad,基准5v的话,分辨率就是5/256.在数据处理的时候,你就用你ad后的值乘以5/256。实际处理的时候,先乘以5,然后再除以256,除以256,实际上可以利用右移来实现。右移一位就是相当于除以2。256就要右移8为。右移的时候不能用循环右移,需要借助cy位。然后就可以分离出数据了。就你上面的2.5v,你就是1000,0000*101=10,1000,0000,然后右移8位,就得出整数2,把右移的通过进位转到另一个寄存器,这样就能分离出整数和小数。
㈨ VC++中使用ADO方式操作ACCESS数据库视频教程地址
ADO(ActiveX Data Object)是Microsoft数据库应用程序开发的新接口,是建立在OLE DB之上的高层数据库访问技术,即使你对OLE DB,COM不了解也能轻松对付ADO,因为它非常简单易用,甚至比你以往所接触的ODBC API、DAO、RDO都要容易使用,并不失灵活性。本文详细地介绍在Visual C++开发环境下如何使用ADO来进行数据库应用程序开发,并给出示例代码。为了使读者朋友都能测试本例提供的代码,我们采用Access数据库,您可以直接在我们提供的示例代码中找到这个test.mdb。程序编译运行后的效果如图一所示:
图一、ADO操作ACESS数据库的界面效果图
一、实现方法
万事开头难,任何一种新技术对于初学者来说最重要的还是"入门",掌握其要点。让我们来看看ADO数据库开发的基本流程吧!它的基本步骤如下:
(1)初始化COM库,引入ADO库定义文件
(2)用Connection对象连接数据库
(3)利用建立好的连接,通过Connection、Command对象执行SQL命令,或利用Recordset对象取得结果记录集进行查询、处理。
(4)使用完毕后关闭连接释放对象。
下面我们将详细介绍上述步骤并给出相关代码。
1、COM库的初始化
我们可以使用AfxOleInit()来初始化COM库,这项工作通常在CWinApp::InitInstance()的重载函数中完成,请看如下代码:
BOOL CADOTest1App::InitInstance()
{
AfxOleInit();
......
}
2、用#import指令引入ADO类型库
为了引入ADO类型库,需要在项目的stdafx.h文件中加入如下语句:
#import "c:\program files\common files\system\ado\msado15.dll"
no_namespace rename("EOF","adoEOF")
这一语句有何作用呢?其最终作用同我们已经十分熟悉的#include类似,编译的时候系统会为我们生成msado15.tlh,ado15.tli两个C++头文件来定义ADO库。
需要读者朋友注意的是:您的开发环境中msado15.dll不一定在这个目录下,请按实际情况修改;在编译的时候可能会出现如下警告,对此微软在MSDN中作了说明,并建议我们不要理会这个警告:msado15.tlh(405) : warning C4146: unary minus operator applied to unsigned type, result still unsigned。
3、创建Connection对象并连接数据库
为了首先我们需要添加一个指向Connection对象的指针_ConnectionPtr m_pConnection,下面的代码演示了如何创建Connection对象实例及如何连接数据库并进行异常捕捉:
BOOL CADOTest1Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
HRESULT hr;
try
{
hr = m_pConnection.CreateInstance("ADODB.Connection");///创建Connection对象
if(SUCCEEDED(hr))
{
hr = m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;
Data Source=test.mdb","","",adModeUnknown);///连接数据库
//上面一句中连接字串中的Provider是针对ACCESS2000环境的,对于ACCESS97,
//需要改为:Provider=Microsoft.Jet.OLEDB.3.51;
}
}
catch(_com_error e)///捕捉异常
{
CString errormessage;
errormessage.Format("连接数据库失败!\r\n错误信息:%s",e.ErrorMessage());
AfxMessageBox(errormessage);///显示错误信息
}
在这段代码中我们是通过Connection对象的Open方法来进行连接数据库的,下面是该方法的原型:
HRESULT Connection15::Open ( _bstr_t ConnectionString, _bstr_t UserID, _bstr_t Password, long Options );
上述函数中参数ConnectionString为连接字串;参数UserID是用户名;参数Password是登陆密码;参数Options是连接选项,用于指定Connection对象对数据的更新许可权,一般情况下Options可以是如下几个常量:
adModeUnknown:缺省。当前的许可权未设置
adModeRead:只读
adModeWrite:只写
adModeReadWrite:可以读写
adModeShareDenyRead:阻止其它Connection对象以读权限打开连接
adModeShareDenyWrite:阻止其它Connection对象以写权限打开连接
adModeShareExclusive:阻止其它Connection对象以读写权限打开连接
adModeShareDenyNone:阻止其它Connection对象以任何权限打开连接
我们给出一些常用的连接方式供大家参考:
(1)通过JET数据库引擎对ACCESS2000数据库的连接:
m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;
Data Source=C:\\test.mdb","","",adModeUnknown);
(2)通过DSN数据源对任何支持ODBC的数据库进行连接:
m_pConnection->Open("Data Source=adotest;UID=sa;PWD=;","","",adModeUnknown);
(3)不通过DSN对SQL SERVER数据库进行连接:
m_pConnection->Open("driver={SQL Server};Server=127.0.0.1;DATABASE=vckbase;
UID=sa;PWD=139","","",adModeUnknown);
其中Server是SQL服务器的名称,DATABASE是库的名称。
Connection对象除Open()方法外还有许多方法,我们先介绍Connection对象中两个有用的属性ConnectionTimeOut与State。ConnectionTimeOut用来设置连接的超时时间,需要在Open之前调用,例如:
m_pConnection->ConnectionTimeout = 5;///设置超时时间为5秒
m_pConnection->Open("Data Source=adotest;","","",adModeUnknown);
State属性指明当前Connection对象的状态,0表示关闭,1表示已经打开,我们可以通过读取这个属性来作相应的处理,例如:
if(m_pConnection->State)
m_pConnection->Close(); ///如果已经打开了连接则关闭它
4、执行SQL命令并取得结果记录集
为了取得结果记录集,我们定义一个指向Recordset对象的指针:_RecordsetPtr m_pRecordset;
并为其创建Recordset对象的实例: m_pRecordset.CreateInstance("ADODB.Recordset"),SQL命令的执行可以采用多种形式,下面我们一一进行阐述。
(1)利用Connection对象的Execute方法执行SQL命令
Execute()方法的原型如下所示:
_RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options )
其中CommandText是命令字串,通常是SQL命令。参数RecordsAffected是操作完成后所影响的行数, 参数Options表示CommandText中内容的类型,Options可以取如下值之一:adCmdText表明CommandText是文本命令;adCmdTable表明CommandText是一个表名;adCmdProc表明CommandText是一个存储过程;adCmdUnknown表明CommandText内容未知。Execute()函数执行完后返回一个指向记录集的指针,下面我们给出具体代码并作说明:
_variant_t RecordsAffected;
///执行SQL命令:CREATE TABLE创建表格users,users包含四个字段:整形ID,字符串username,整形old,日期型birthday
m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username
TEXT,old INTEGER,birthday DATETIME)",&RecordsAffected,adCmdText);
///往表格里面添加记录
m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday)
VALUES (1, 'Washington',25,'1970/1/1')",&RecordsAffected,adCmdText);
///将所有记录old字段的值加一
m_pConnection->Execute("UPDATE users SET old = old+1",&RecordsAffected,adCmdText);
///执行SQL统计命令得到包含记录条数的记录集
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM
users",&RecordsAffected,adCmdText);
_variant_t vIndex = (long)0;
_variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得第一个字段的值放入vCount变量
m_pRecordset->Close();///关闭记录集
CString message;
message.Format("共有%d条记录",vCount.lVal);
AfxMessageBox(message);///显示当前记录条数
(2)利用Command对象来执行SQL命令
_CommandPtr m_pCommand;
m_pCommand.CreateInstance("ADODB.Command");
_variant_t vNULL;
vNULL.vt = VT_ERROR;
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,将建立的连接赋值给它
m_pCommand->CommandText = "SELECT * FROM users";///命令字串
m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);
//执行命令取得记录集
在这段代码中我们只是用Command对象来执行了SELECT查询语句,Command对象在进行存储过程的调用中能真正体现它的作用。下次我们将详细介绍。
(3)直接用Recordset对象进行查询取得记录集,例如:
m_pRecordset->Open("SELECT * FROM users",_variant_t((IDispatch *)m_pConnection,true),
adOpenStatic,adLockOptimistic,adCmdText);
Open()方法的原型如下:
HRESULT Recordset15::Open ( const _variant_t & Source, const _variant_t & ActiveConnection, enum CursorTypeEnum CursorType, enum LockTypeEnum LockType, long Options )
上述函数中参数Source是数据查询字符串;参数ActiveConnection是已经建立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象);参数CursorType光标类型,它可以是以下值之一;请看这个枚举结构:
enum CursorTypeEnum
{
adOpenUnspecified = -1,///不作特别指定
adOpenForwardOnly = 0,///前滚静态光标。这种光标只能向前浏览记录集,比如用MoveNext向前滚动,这种方式可以提高浏览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能使用
adOpenKeyset = 1,///采用这种光标的记录集看不到其它用户的新增、删除操作,但对于更新原有记录的操作对你是可见的。
adOpenDynamic = 2,///动态光标。所有数据库的操作都会立即在各用户记录集上反应出来。
adOpenStatic = 3///静态光标。它为你的记录集产生一个静态备份,但其它用户的新增、删除、更新操作对你的记录集来说是不可见的。
};
参数LockType表示数据库的锁定类型,它可以是以下值之一,请看如下枚举结构:
enum LockTypeEnum
{
adLockUnspecified = -1,///未指定
adLockReadOnly = 1,///只读记录集
adLockPessimistic = 2,悲观锁定方式。数据在更新时锁定其它所有动作,这是最安全的锁定机制
adLockOptimistic = 3,乐观锁定方式。只有在你调用Update方法时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
adLockBatchOptimistic = 4,乐观分批更新。编辑时记录不会锁定,更改、插入及删除是在批处理模式下完成。
};
参数Options的含义请参考本文中对Connection对象的Execute()方法的介绍。
5、记录集的遍历、更新
根据我们刚才通过执行SQL命令建立好的users表,它包含四个字段:ID,username,old,birthday
以下的代码实现:打开记录集,遍历所有记录,删除第一条记录,添加三条记录,移动光标到第二条记录,更改其年龄数据,保存到数据库。
_variant_t vUsername,vBirthday,vID,vOld;
_RecordsetPtr m_pRecordset;
m_pRecordset.CreateInstance("ADODB.Recordset");
m_pRecordset->Open("SELECT * FROM users",_variant_t((IDispatch*)m_pConnection,true),
adOpenStatic,adLockOptimistic,adCmdText);
while(!m_pRecordset->adoEOF)
///这里为什么是adoEOF而不是EOF呢?还记得rename("EOF","adoEOF")这一句吗?
{
vID = m_pRecordset->GetCollect(_variant_t((long)0));///取得第1列的值,从0开始计数,你也可以直接给出列的名称;
vUsername = m_pRecordset->GetCollect("username");///取得username字段的值
vOld = m_pRecordset->GetCollect("old");
vBirthday = m_pRecordset->GetCollect("birthday");
///在DEBUG方式下的OUTPUT窗口输出记录集中的记录
if(vID.vt != VT_NULL && vUsername.vt != VT_NULL && vOld.vt != VT_NULL &&
vBirthday.vt != VT_NULL)
TRACE("id:%d,姓名:%s,年龄:%d,生日:%s\r\n",vID.lVal,(LPCTSTR)(_bstr_t)vUsername,vOld.lVal,(LPCTSTR)(_bstr_t)vBirthday);
m_pRecordset->MoveNext();///移到下一条记录
}
m_pRecordset->MoveFirst();///移到首条记录
m_pRecordset->Delete(adAffectCurrent);///删除当前记录
///添加三条新记录并赋值
for(int i=0;i<3;i++)
{
m_pRecordset->AddNew();///添加新记录
m_pRecordset->PutCollect("ID",_variant_t((long)(i+10)));
m_pRecordset->PutCollect("username",_variant_t("叶利钦"));
m_pRecordset->PutCollect("old",_variant_t((long)71));
m_pRecordset->PutCollect("birthday",_variant_t("1930-3-15"));
}
m_pRecordset->Move(1,_variant_t((long)adBookmarkFirst));///从第一条记录往下移动一条记录,即移动到第二条记录处
m_pRecordset->PutCollect(_variant_t("old"),_variant_t((long)45));///修改其年龄
m_pRecordset->Update();///保存到库中
6、关闭记录集与连接
记录集或连接都可以用Close()方法来关闭:
m_pRecordset->Close();///关闭记录集
m_pConnection->Close();///关闭连接
至此,我想读者朋友已经熟悉了ADO操作数据库的大致流程,也许您已经胸有成竹,也许您还有点胡涂,不要紧!建议你尝试写几个例子,这样会更好地熟悉ADO,最后我给大家写了一个小例子,例子实现的功能是读出所有记录并放到列表控件中,同时可以添加、删除、修改记录。
二、编程步骤
1、 启动Visual C++6.0,生成一个基于对话框的应用程序,将该程序命名为ADOTest1;
2、 在对话框界面上放置显示记录列表控件和添加、删除记录用的的编辑、按钮控件,具体设置参加代码中的对话框资源部分;
3、 使用Class Wizard为添加、修改数据库记录的按钮添加消息响应函数;
4、 添加成程序代码,编译运行程序。
㈩ 如何将AD采集到的数据,用FFT进行变换
#include<math.h>
kkfft(double pr[], double pi[], int n, int k, double fr[], double fi[], int l, int il)
{
int it,m,is,i,j,nv,l0;
double p,q,s,vr,vi,poddr,poddi;
for (it=0; it<=n-1; it++)
{
m = it;
is = 0;
for (i=0; i<=k-1; i++)
{
j = m/2;
is = 2*is+(m-2*j);
m = j;
}
fr[it] = pr[is];
fi[it] = pi[is];
}
pr[0] = 1.0;
pi[0] = 0.0;
p = 6.283185306/(1.0*n);
pr[1] = cos(p);
pi[1] = -sin(p);
if (l!=0)
pi[1]=-pi[1];
for (i=2; i<=n-1; i++)
{
p = pr[i-1]*pr[1];
q = pi[i-1]*pi[1];
s = (pr[i-1]+pi[i-1])*(pr[1]+pi[1]);
pr[i] = p-q;
pi[i] = s-p-q;
}
for (it=0; it<=n-2; it=it+2)
{
vr = fr[it];
vi = fi[it];
fr[it] = vr+fr[it+1];
fi[it] = vi+fi[it+1];
fr[it+1] = vr-fr[it+1];
fi[it+1] = vi-fi[it+1];
}
m = n/2;
nv = 2;
for (l0=k-2; l0>=0; l0--)
{
m = m/2;
nv = 2*nv;
for (it=0; it<=(m-1)*nv; it=it+nv)
for (j=0; j<=(nv/2)-1; j++)
{
p = pr[m*j]*fr[it+j+nv/2];
q = pi[m*j]*fi[it+j+nv/2];
s = pr[m*j]+pi[m*j];
s = s*(fr[it+j+nv/2]+fi[it+j+nv/2]);
poddr = p-q;
poddi = s-p-q;
fr[it+j+nv/2] = fr[it+j]-poddr;
fi[it+j+nv/2] = fi[it+j]-poddi;
fr[it+j] = fr[it+j]+poddr;
fi[it+j] = fi[it+j]+poddi;
}
}
if (l!=0)
{
for (i=0; i<=n-1; i++)
{
fr[i] = fr[i]/(1.0*n);
fi[i] = fi[i]/(1.0*n);
}
}
if (il!=0)
{
for (i=0; i<=n-1; i++)
{
pr[i] = sqrt(fr[i]*fr[i]+fi[i]*fi[i]);
if (fabs(fr[i])<0.000001*fabs(fi[i]))
{
if ((fi[i]*fr[i])>0)
pi[i] = 90.0;
else
pi[i] = -90.0;
}
else
pi[i] = atan(fi[i]/fr[i])*360.0/6.283185306;
}
}
return;
}
void main()
{
double s1[128],s2[128],s3[128],s4[128],TT,TM;
int i,f,ff;
f=128;
ff=4;
for(i=0;i<128;i++)
{
TT=i;
TM=TT/f;
s1[i]=2*sin(2*3.14*ff*TM)+10;
}
kkfft(s1, s2, 128, 7, s3, s4, 0, 1);
printf("s1=%f\n",s1[0]/128) ;
getch();
for(i=1;i<12;i++)
{
printf("s1=%f,i=%d\n",s1[i]/64,i) ;
}
getch();
}
这是一段用wintc下编译的fft,double pr[], double pi[],double fr[], double fi[]是入口数组,在主函数中定义好,点数自定,你把ad采集的数存入
pr[]对应的数组中,记住如程序中的
for(i=0;i<128;i++)
{
TT=i;
TM=TT/f;
s1[i]=2*sin(2*3.14*ff*TM)+10;
}
s1对应pr
运行后可以看到直流分量(i=0点),交流分量(i=4点)
说明: kkfft(s1, s2, 128, 7, s3, s4, 0, 1);
s1对应ad才来的值,s2是ad采样的虚部一般为0,128采样点数一定要是2的
n次方,7就是那个n了,s3,s4背管了是副角返回值,0,1是程序内定的标志
fft结果的意义:她是一个数组如S1[n],那么s1[0]/采样点数是直流分量值,
而实际信号的频率在数组中的反应是f=n*采样频率/采样点数;
kkfft(double pr[], double pi[], int n, int k, double fr[], double fi[], int l, int il)
在51(020,120,060)单片机上运行通过;