IQMath入门学习
1.IQMath的HelloWorld例程
#include "DSP281x_Device.h"
#include "IQmathLib.h"
#define PI 3.14159
_iq sinout_iq;
float sinout_flt;
void main(void)
{
InitSysCtrl();
InitXintf();
DINT;
IER=0X0000;
IFR=0X0000;
sinout_iq=_IQ29sin(_IQ29mpy(_IQ29(0.25),_IQ29(PI)));
sinout_flt=_IQ29toF(sinout_iq);
//上述代码的功能是计算sin(π/4)的值,然后赋给sinout_flt。
for(;;){}
}
注意:
1. 计算的时候不论你使用哪种IQ数据类型的数据,计算时数据类型
要统一,只有相同数据类型的IQ数据可以进行算数运算,此例中我是用
的都是IQ29类型的数据,最终转成Float数据用的也是IQ29toF。所有IQ
类型数据都有配套的方法,使用时这点需要注意。
2. sinout_flt=_IQ29toF(sinout_iq);
//这里将IQ类型再转成Float类型数据,供最终计算使用
案例1分析
/*
* 经调试得出:
* 1. 当结果集AdcaResults的长度为256,且测量电压在0-3V之间时,用IQ11数据类型是合理的。
* IQ数据类型要根据实际测量值进行选择,如果选择不当会导致:
* - 精度丢失【情节较轻】
* - 计算值超过该数据类型最大范围,导致数据溢出,可以理解为【计算错误】,编译器会给出警告
在可行的情况下遵循以下原则:
- IQ类型数据取值范围越小越好,因为范围越小,数据精度越高
2. 注意:
- IQ类型数据进行计算时,一定要特别注意!!!!!!!!!!!!!
!!!!!!!!!!所有进行计算的数据都要统一类型!!!!!!!!!!
折腾了一下午,就坑在这了,生气!_!....
垃圾代码&_&...
* */
adc->result.avg = _IQ11div(_IQ11(adc->result.sum),_IQ11(RESULTS_BUFFER_SIZE));
//求实际值
//adc->result.realValue = adc->result.avg*3/4095;
adc->result.realValue = _IQ11toF( _IQ11div(_IQ11mpy(adc->result.avg,_IQ11(3)),_IQ11(4095)) ) ;
看图
图中的警告是因为式中计算值超过了当前IQ类型数据的最大值范围,相当于
数据溢出了,那么计算出来的值就是完全错误的。
案例2分析:
目标:求sin(PI/2) //求sin(90°)的值
/* 代码如下 */
#define GLOBAL_Q 18 //要认真选择GLOBAL_Q的值,计算值不能超过其最大值
long GlobalQ = GLOBAL_Q; // Used for legacy GEL & Graph Debug.
#define PI 3.141592653589793f
#include "IQmathLib.h"
_iq sinT;
float FsinT;
int main(){
while(1){
sinT = _IQsin(_IQ(0.5*PI));
FsinT = _IQtoF(sinT);//仿真结果:FsinT = 0.999996185
}
}