В "безмежній павутині" викладено однакову реалізацію на різних площадках, але без посилання на першоджерело, тому і я його не подаю
Код: Виділити все
//cordic
// https://radioman.com.ua/viewtopic.php?f=9&t=20&p=80#p80
/*
одиниця = 0x40000000 (з плаваючою точкою 1073741824.00000)
величина зворотна коефіцієнту деформації 1 / k = 0x26DD3B6A (з плаваючою точкою 0.6072529350088812561694)
у таблиці cordic_tab зберігаються розраховані значення atan (2 ^ -i) * mul
*/
#define _CORDIC_32_
//константи
#define cordic_1K 0x26DD3B6A // 1/k = 0.6072529350088812561694
#define half_pi 0x6487ED51 // pi / 2
#define MUL 1073741824.000000 // 1.0 = 1073741824.00000
#define CORDIC_NTAB 32
int cordic_tab [] = {
0x3243F6A8, 0x1DAC6705, 0x0FADBAFC, 0x07F56EA6, 0x03FEAB76, 0x01FFD55B, 0x00FFFAAA, 0x007FFF55,
0x003FFFEA, 0x001FFFFD, 0x000FFFFF, 0x0007FFFF, 0x0003FFFF, 0x0001FFFF, 0x0000FFFF, 0x00007FFF,
0x00003FFF, 0x00001FFF, 0x00000FFF, 0x000007FF, 0x000003FF, 0x000001FF, 0x000000FF, 0x0000007F,
0x0000003F, 0x0000001F, 0x0000000F, 0x00000008, 0x00000004, 0x00000002, 0x00000001, 0x00000000
};
//змінні
int intSY;
int intSX;
int intCordic;
/*------------------------------------------------------------------------------------------------------------*/
intCordic = cordic32_atan2(intSX, intSY, MUL);
// так як алгоритм видає результат в радіанах, отримане значення потрібно помножити на 57.29578 для переведення у градуси
Serial.print("CORDIC="),Serial.print(intCordic * 57.29578 / MUL)
/*------------------------------------------------------------------------------------------------------------*/
int cordic32_atan2(int s, int c, int n)
{
int k, d, intAngle = 0;
int re = c, im = s, tx;
n = (n > CORDIC_NTAB) ? CORDIC_NTAB : n;
if (n < 3) n = 3;
for (k = 0; k < n; ++k)
{
d = im >> 31;
intAngle += ((cordic_tab[k] ^ d) - d);
tx = re;
re += (((im >> k) ^ d) - d);
im -= (((tx >> k) ^ d) - d);
}
return intAngle;
}
Значення кута, котрий потрібно розрахувати, має бути в інтервалі від -90 до 90 (в моїх експериментах функція "зависала" при наближенні кута до 100 градусів.
PS. Більш детальні роз'яснення (на англійській) у прикріпленому файлі: