资源简介
采用优化的单片机查表法计算atan角度的方法,重点解决了几个问题:
(1)且用asin曲线计算代替难以描述的atan曲线,快速开方函数
(2)全部采用整形运算,加快了运算速度,返回的角度范围是0~360.00,包含4个象限,输出角度值
(3)asin曲线使用了一半的曲线,解决了asin邻近90度时十分陡峭的难题。本代码稍微加以修改也可以作为asin和acos的计算。
(1)且用asin曲线计算代替难以描述的atan曲线,快速开方函数
(2)全部采用整形运算,加快了运算速度,返回的角度范围是0~360.00,包含4个象限,输出角度值
(3)asin曲线使用了一半的曲线,解决了asin邻近90度时十分陡峭的难题。本代码稍微加以修改也可以作为asin和acos的计算。
代码片段和文件信息
#include
#include
#define PI 3.1415926
typedef unsigned char uint8_t;
typedef char int8_t;
typedef unsigned short int uint16_t;
typedef short int int16_t;
typedef unsigned int uint32_t;
typedef int int32_t;
//计算求得183个点
static const uint16_t tb_asin[183] = {
023456890112135157
180202224247269292314336
359381404426449471493516
538561583606628651673696
719741764786809832854877
899922945967990101310361058
10811104112711501172119512181241
12641287131013331356137914021425
14481471149515181541156415871611
16341657168117041728175117741798
18211845186918921916194019631987
20112035205920832107213121552179
22032227225122762300232423492373
23972422244724712496252125452570
25952620264526702695272027452771
27962821284728722898292329492975
30003026305230783104313131573183
32093236326232893316334333693396
34233451347835053532356035873615
36433671369937273755378338123840
38693897392639553984401440434072
41024132416241924222425242824313
4344437544064437446845004532
};
uint16_t sqrt_16(uint32_t a)
{
uint8_t i;
uint16_t b = 0;
uint32_t c;
for(i=0; i<16; i++)
{
c = ((unsigned long)1 << ((15-i) << 1)) + ((unsigned long)b << (16 - i));
if(c <= a )
{
a -= c;
b += (1 << (15-i));
}
}
return b;
}
static uint16_t calc_atan_phase(int16_t real int16_t imag)
{
uint16_t sum;
uint32_t real_abs;
uint16_t sin_valsin_duansin_yu;
uint16_t s_je_jx_j;//初角,结束角,斜率角
uint8_t sin_flag=1;
if (real==0 && imag==0)
{
x_j = 0;
}
else if(real==0 && imag>0)
{
x_j = 0;
}
else if(real>0 && imag==0)
{
x_j = 9000;
}
else if(real==0 && imag<0)
{
x_j = 18000;
}
else if(real<0 && imag==0)
{
x_j = 27000;
}
else
{
sum=sqrt_16((int32_t)real*real+(int32_t)imag*imag);
real_abs=real<0?(-real):real;
sin_val=(real_abs<<14)/sum;
sin_duan=sin_val>>6;
//arcsin曲线的后半段,斜率越来越陡,为了解决这个问题,用虚部代替实部的方法解决,求出角以后,用90-角,即是sin角
if(sin_duan>=183)
{
real_abs=imag<0?-imag:imag;
sin_val=(real_abs<<14)/sum;
sin_duan=sin_val>>6;
sin_flag=0;
}
sin_yu=sin_val-(sin_duan<<6);
s_j = tb_asin[sin_duan];
e_j = tb_asin[sin_duan+1];
//printf(“%d %d %d %d %d \n“sin_valsin_duansin_yue_js_j);
x_j=(((e_j-s_j)*sin_yu)>>6)+s_j;
}
if(!sin_flag)
{
x_j=9000-x_j;
}
//判断象限
//printf(“%d %d \n“realimag);
if(real>0 && imag>0)
{
x_j = x_j;
}
if(real>0 && imag<0)
{
x_j = 18000-x_j;
}
if(real<0 && imag>0)
{
x_j = 36000-x_j;
}
if(real<0 && imag<0)
{
x_j = 18000+x_j;
}
return x_j/10;
}
int main(int argc char *argv[])
{
float i;
uint16_t j1;
for
属性 大小 日期 时间 名称
----------- --------- ---------- ----- ----
文件 3355 2020-03-20 00:48 C语言利用半曲线法查表实现arctan arcsin 反正切 反正弦计算.c
评论
共有 条评论