TM4C IQmath 使用教程
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
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左右。
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);
}
}