| |
CORDIC算法的来历与用途大家网上随处可以见到,这里写 一下自己的理解。
将P(x,y)旋转角度a得到新的坐标P’(x’,y’)。这里的坐标变换为:
x’= x cos(a) – y sin(a) = cos(a)(x-y *tan(a))
y’= y cos(a) + xsin(a) = cos(a)(y+x*tan(a))
旋转角度a为常数时,如果tan(a)=2-i ,即可用移位代替乘法便于快速高效在FPGA中实现。每次都旋转固定角度delta, 则cos(delta)=cos(arctan(2-i)).
而
从而得到简便计算如下:atan(2^-i)的结果是预先计算好存储下来了
K-i=cos(arctan(2-i))
X-i+1--- =k-i -[x-i -– y-i x di x 2-i]
Y-i+1 -=K-i -[y-I + X-I x d-ix 2-i]
CORDIC有两种模式
1 rotation模式 每次旋转Z一个角度 直到等于要求的角度 即从极坐标变换到直角坐标
2 vectoring 模式 。旋转使与x轴对齐 y=0时得到的z值即所要旋转的角度,由直角坐标到极坐标的变换
1: function [horizonal,vertical]=polar2car(mag, pha);
2: x =mag; %令变量x等于极坐标的幅度,在直角坐标中y分量等于零,使其旋转角度pha,得到的分量即是得到在
3: y =0; %直角坐标系里的坐标
4: z=pha;
5: d=0;
6: i=0;
7: k = 0.6073; %K 增益
8: x = k*x;
9: while i<50
10: if z<0 d =-1;
11: else d = 1;
12: end
13: xNew=x-y*d*(2^(-i));
14: y=y+x*d*(2^(-i));
15: z=z-d*atan(1/2^(i));
16: i=i+1;
17:
18:
19: x=xNew;
20: end
21: horizonal = x;
22: vertical = y;
function [mag, pha]= car2polar(x,y); %y =0; %将直角坐标系中的点(x,y)旋转到x轴,旋转的角度即为其极坐标的相位,在x轴的长度等于极坐标的幅度 d=0; %可用于求相位,幅度 i=0; z=0; k = 0.6073; %K 增益 while i<50 if y<0 d = 1; else d = -1; end xNew=x-y*d*(2^(-i)); y=y+x*d*(2^(-i)); z=z-d*atan(1/2^(i)); i=i+1; x=xNew; end x = x*k; mag=x; pha=z;
验证:
[a,b]= polar2car( 1,pi/3)
a =
0.5000
b =
0.8661
[a,b]= car2polar( 0.5000, 0.8661)
a =
1.0001
b =
1.0472
function [ pha]= cordic_arcsin(c); %y =0; %将点(1,0)旋转至其纵坐标=c,旋转的角度为角度 求反余弦也是同样道理 d=0; i=0; z=0; x=1; y=0; k = 0.6073; %K 增益 xNew = x* k; while i<100 if y<=c d = 1; else d = -1; end x =xNew-y*d*(2^(-i)); y=y+xNew*d*(2^(-i)); z=z+d*atan(1/2^(i)); i=i+1; xNew=x; end %mag=x; pha=z;
function [pha]= cordic_arccos(c); %y =0; d=0; i=0; z=0; x=1; y=0; k = 0.6073; %K 增益 xNew = x* k; while i<100 if x>=c d = 1; else d = -1; end x =xNew-y*d*(2^(-i)); y=y+xNew*d*(2^(-i)); z=z+d*atan(1/2^(i)); i=i+1; xNew=x; end %mag=x; pha=z;
function [ pha]= cordic_arctan(x,y); %y =0; %将点(x,y)旋转到x轴所需要的角度 d=0; i=0; z=0; k = 0.6073; %K 增益 x = x*k; while i<50 if y<0 d = 1; else d = -1; end xNew=x-y*d*(2^(-i)); y=y+x*d*(2^(-i)); z=z-d*atan(1/2^(i)); i=i+1; x=xNew; end %mag=x; pha=z;
function [sine,cosine] = cordic_sine(angle); % Initialitation %%angle=30 ; x = 1; y = 0; z = angle; d = 1; i = 0; % Iterative factor k = 0.6073; %K Factor xNew = k*x; while i < 50 if z <=0 d =-1; else d = 1; end x= xNew -d*y*2^(-i); y=y+d*xNew*2^(-i); z=z-d*atan(2^(-i)); i=i+1; xNew=x; end cosine = x sine = y