TM4C IQmath 使用教程
- 介紹
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))
- 一個實例
/**
* 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);
}
}