TM4C IQmath 使用教程+FPU介绍

TM4C IQmath 使用教程

  1. 介绍

Texas Instruments®Tiva™IQmath Library是一个高度优化和高精度的集合,数学函数为C/ C++程序员无缝地将浮点算法移植到Tiva设备上的定点代码。

这些例程通常用于计算密集型实时应用,其中最优的执行速度和高精度是至关重要的。通过使用IQmath库,它有可能实现比同等代码快得多的执行速度。

IQmath使用起来并没有想象中那么复杂,简单来说就是将浮点数转化为整数计算,然后再将整数转为浮点数。

使用过程中合数选和定义IQ变量,获得更好的计算性能。

IQmath使用手册在TIVAware中:

C:\ti\tivaware_c_series_2_1_4_178\docs

       FPU,编译器默认开启FPU,double型变量计算速度有所下降,1.0默认是double型变量,1.0f为float型变量,计算速度在某些情况下比double快几倍,大概5倍左右,如果对精度要求不是很高可以采用float。

2. 测试分析

代码如下。

while(1)

    {

        MAP_GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_6|GPIO_PIN_7,0);

        for(i=0;i<0xFF;i++)

        {

//           value = 0.4f+0.8f+0.8f*0.8f+79.8f/7.8f;

           c = _IQ24sin(a)+ _IQ24sin(b);

//           value = sin(3.1245)+ sin(2.14);

        }

       MAP_GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_6|GPIO_PIN_7,GPIO_PIN_6|GPIO_PIN7);

       for(i=0;i<0xFF;i++)

      {

//          value =0.4f+0.8f+0.8f*0.8f+79.8f/7.8f;

           c = _IQ24sin(a)+ _IQ24sin(b);

//           value = sin(3.1245)+sin(2.14);

      }

          value1=(float)(c*1.0/m24);

}

      当使用IQmath时候,每秒计算速度在480k左右,当不使用时在每秒计算次数在7k左右。这明显提高了计算三角函数的速度。

     当不用来计算三角函数时候,用来计算乘积运算,计算性能大大降低,不如不使用IQmath的计算速度。实测降低1536k左右。

      在求平方根时,采用,math库函数计算速度为34k/s,而采用IQ时候,计算速度为488k/s。

 

3. IQ变量定义范围

4.使用范例

#include "IQmath/IQmathLib.h"

int

main(void)

{

_iq24 X, Y, Z;

X = _IQ24(1.0);

Y = _IQ24(7.0);

Z = _IQ24div(X, Y);

}

其中iq24,定义IQ变量,X = _IQ24(1.0);则将数据1.0转为IQ数据。

    转换关系如下:

浮点数(x)转换为定点数(xq):xq=(int)x*2Q;

定点数(xq)转化为浮点数(x):x=(float)(xq*1.0/2Q);

5. 常用IQ库函数

以IQ30为例。IQ位数之间的转换这里不做说明。

转化一个数据为IQnumber

//*****************************************************************************

//

// Convert a value into an IQ number.

//

//*****************************************************************************

#define _IQ30(A)                (A)

IQ转浮点数,实验中数字可能变为0,不知道什么原因,谨慎使用。

//*****************************************************************************

//

// Convert an IQ number to a floating point value.

//

//*****************************************************************************

#define _IQ30toF(A)             (A)

//*****************************************************************************

//

// Convert an IQ number to a double-precision floating point value.

//

//*****************************************************************************

#define _IQ30toD(A)             (A)

乘积

//*****************************************************************************

//

// Multiplies two IQ numbers, with rounding.

//

//*****************************************************************************

extern _iq30 _IQ30rmpy(_iq30 A, _iq30 B);

//round() 函数作用就是,返回浮点数x的四舍五入值。

 

//*****************************************************************************

//

// Multiplies two IQ numbers, with rounding and saturation.

//

//*****************************************************************************

extern _iq30 _IQ30rsmpy(_iq30 A, _iq30 B);

//*****************************************************************************

//

// Multiplies two IQ numbers.

//

//*****************************************************************************

extern _iq30 _IQ30mpy(_iq30 A, _iq30 B);

整数相乘

//*****************************************************************************

//

// Multiplies an IQ number by an integer.

//

//*****************************************************************************

#define _IQ30mpyI32(A, B)       ((A) * (B))

//*****************************************************************************

//

// Multiplies an IQ number by an integer, and returns the integer portion.

//

//*****************************************************************************

extern _iq30 _IQ30mpyI32int(_iq30 A, long B);

相除,A/B

//

// Divides two IQ numbers.

//

//*****************************************************************************

extern _iq30 _IQ30div(_iq30 A, _iq30 B);

//*****************************************************************************

//

// Computes the sin of an IQ number.

//

//*****************************************************************************

求根

//*****************************************************************************

//

// Computes the square root of an IQ number.

//

//*****************************************************************************

extern _iq30 _IQ30sqrt(_iq30 A);

1/A的算术平方根

//*****************************************************************************

//

// Computes 1 over the square root of an IQ number.

//

//*****************************************************************************

extern _iq30 _IQ30isqrt(_iq30 A);

求平方和的根

//*****************************************************************************

//

// Computes the square root of A^2 + B^2 using IQ numbers.

//

//*****************************************************************************

extern _iq30 _IQ30mag(_iq30 A, _iq30 B);

 

三角函数计算,以弧度为单位

//*****************************************************************************

//

// Computes the arcsin of an IQ number.

//

//*****************************************************************************

extern _iq29 _IQ29sin(_iq29 A);

//*****************************************************************************

//

// Computes the cos of an IQ number.

//

//*****************************************************************************

extern _iq29 _IQ29cos(_iq29 A);

//*****************************************************************************

//

// Computes the arccos of an IQ number.

//

//*****************************************************************************

#define _IQ29acos(A)            (_IQ29(1.570796327) - _IQ29asin(A))

//*****************************************************************************

//

// Computes the arctan of an IQ number.

//

//*****************************************************************************

#define _IQ29atan(A)            _IQ29atan2(A, _IQ29(1.0))

 

//*****************************************************************************

//

// Computes e^x of an IQ number.

//

//*****************************************************************************

extern _iq30 _IQ30exp(_iq30 A);

//*****************************************************************************

//

// Computes 2^x of an IQ number.

//

//*****************************************************************************

extern _iq30 _IQ30exp2(_iq30 A);

返回整数

//*****************************************************************************

//

// Returns the integer portion of an IQ number.

//

//*****************************************************************************

#define _IQ30int(A)             ((A) >> 30)

字符串转整数

#define _atoIQ30(A)             _atoIQN(A, 30)

数字转字符串

#define _IQ30toa(A, B, C)       __IQNtoa(A, B, C, 30);

取绝对值

 

//*****************************************************************************

//

// Computes the absolute value of an IQ number.

//

//*****************************************************************************

#define _IQ30abs(A)             (((A) < 0) ? - (A) : (A))

 

  1. 一个实例

 

/**

 * main.c

 */

 

#include "common.h"

_iq24 a,b,c;   //8位数

_iq d;        //global iq

volatile int value = 0.0;

volatile float value1 = 0;

volatile float value2 = 0;

unsigned int i=0;

#define m24 16777216  //2^24

int main(void)

{

    MAP_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);   //50MHz

    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    MAP_GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_6|GPIO_PIN_7);

    a=_IQ24(3.1245);

    b=_IQ24(2.15);

    while(1)

    {

        MAP_GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_6|GPIO_PIN_7,0);

        for(i=0;i<0xFF;i++)

        {

//           value = 0.4f+0.8f+0.8f*0.8f+79.8f/7.8f;

           c = _IQ24sin(a)+ _IQ24sin(b);

//           value = sin(3.1245)+ sin(2.14);

        }

 

       MAP_GPIOPinWrite(GPIO_PORTA_BASE,GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_6|GPIO_PIN_7);

       for(i=0;i<0xFF;i++)

      {

//          value =0.4f+0.8f+0.8f*0.8f+79.8f/7.8f;

           c = _IQ24sin(a)+ _IQ24sin(b);

//           value = sin(3.1245)+sin(2.14);

      }

          value1=(float)(c*1.0/m24);

          value2=_IQ24toF(c);

    }

}

猜你喜欢

转载自blog.csdn.net/qq_42263796/article/details/93651064
FPU