Hемедленно нажми на RESET, All!
Hаписал вот код. ~2кбайта кода для pic18. Библиотечный косинус медленный и плавающий, и к тому же уже к трём килобайтам приближается.
Почему развёрнутый цикл -- если в нормальном цикле, то не разворачиваются циклы сдвига вправо, всё сильно медленее.
Склоняюсь к мысли, что линейная интерполяция по таблице (256 байт) не такой уж и плохой вариант. Может быть можно улучшить?
/* angle 0..64 -> result 0..16383 */ void sincos_u14(uint_fast8_t angle, int_fast16_t *sin_u14, int_fast16_t
*cos_u14) { int16_t x, y, t; int16_t c, a; #define CORDIC(s, u) if (a > c) t=x-(y>>s), y+=(x>>s), x=t, c+=u; \ else t=x+(y>>s), y-=(x>>s), x=t, c-=u; a=angle<<8; x=9949, y=0; c=0; CORDIC(0, 8192); CORDIC(1, 4836); CORDIC(2, 2555); CORDIC(3, 1297); CORDIC(4, 651); CORDIC(5, 326); CORDIC(6, 163); CORDIC(7, 81); CORDIC(8, 41); CORDIC(9, 20); CORDIC(10, 10); CORDIC(11, 5); *sin_u14=y, *cos_u14=x; }/* angle 0..255 (256 is pi/2) */ int_fast16_t cos_i12(uint_fast8_t angle) { int_fast16_t sin_u14, cos_u14; if (angle<64) { sincos_u14(angle, &sin_u14, &cos_u14); } else if (angle<128) { sincos_u14(128-angle, &sin_u14, &cos_u14); cos_u14=0-cos_u14; } else if (angle<192) { sincos_u14(angle-128, &sin_u14, &cos_u14); cos_u14=0-cos_u14; } else { sincos_u14(256-angle, &sin_u14, &cos_u14); } return cos_u14>>3; }
[ZX]