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);

    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章