我们在使用单片机编程时可能会遇到无法使用sin和cos函数的困扰,下面跟大家分享下用查表法写的sin、cos函数。sin函数原型需要进行浮点运算,因此有时候也可以采用查表法计算来提高程序的执行效率。
下面以采样点为256个为例,说明一下函数的具体实现。
#define TAB_N 256 //定义查表的点数
#define PI 3.1415926535897932384626433832795028841971 //定义圆周率值
float SIN_TAB[TAB_N/4+1]={ //初始化1/4的sin表(256点)
0.0000,0.0245,0.0491,0.0735,0.0980,0.1224,0.1467,0.1710,
0.1951,0.2191,0.2430,0.2667,0.2903,0.3137,0.3369,0.3599,
0.3827,0.4052,0.4276,0.4496,0.4714,0.4929,0.5141,0.5350,
0.5556,0.5758,0.5957,0.6152,0.6344,0.6532,0.6716,0.6895,
0.7071,0.7242,0.7410,0.7572,0.7730,0.7883,0.8032,0.8176,
0.8315,0.8449,0.8577,0.8701,0.8819,0.8932,0.9040,0.9142,
0.9239,0.9330,0.9415,0.9495,0.9569,0.9638,0.9700,0.9757,
0.9808,0.9853,0.9892,0.9925,0.9952,0.9973,0.9988,0.9997,
1.0000
};
/******************************************************************
函数原型:float sin_tab(float pi)
函数功能:采用查表的方法计算一个数的正弦值
输入参数:pi 所要计算正弦值弧度值,范围0--2*PI,不满足时需要先转换
输出参数:输入值pi的正弦值
******************************************************************/
float sin_tab(float pi)
{
int n;
float a;
n=(int)(pi*TAB_N/2/PI); // SIN_TAB[i] = sin(2*PI*i/TAB_N);
if(n>=0&&n<=TAB_N/4) // 0 ~ PI/2
{
a=SIN_TAB[n];
}
else if(n>TAB_N/4&&n=TAB_N/2&&n<3*TAB_N/4) // PI ~ 3/4*PI
{
n-=TAB_N/2;
a=-SIN_TAB[n];
}
else if(n>=3*TAB_N/4&&n2*PI)
pi2-=2*PI;
a=sin_tab(pi2);
return a;
}
=TAB_N/2&&n<3*TAB_N/4) // PI ~ 3/4*PI
{
n-=TAB_N/2;
a=-SIN_TAB[n];
}
else if(n>=3*TAB_N/4&&n2*PI)
pi2-=2*PI;
a=sin_tab(pi2);
return a;
}
创建sin表可以通过相关工具生成对应精度的文件,然后将数值复制过来,如 http://download.csdn.net/detail/gdm2010/4811087
如果能包含math.h头文件,使用查表法计算只是为了提高运算效率,则可使用下面的函数自动生成sin表。
/******************************************************************
函数原型:void create_sin_tab(float *sin_t)
函数功能:创建一个正弦采样表的1/4,采样点数等于TAB_N
输入参数:*sin_t存放正弦表的数组指针
输出参数:无
******************************************************************/
void create_sin_tab(float *sin_t)
{
int i;
for(i=0;i<=TAB_N/4;i++)
sin_t[i]=sin(2*PI*i/TAB_N);
}
要得到参数为角度值得sin和cos函数则需对其进行修改即可,弧度值 = 角度值 * PI / 180。
附:单片进行浮点运算时一件比较耗费资源的事,有些算法还有待改进。。。