sin
并且cos
功能很慢,需要大量资源才能在嵌入式系统上运行。如何以更节省资源和更快的方式计算sin
和运行?cos
11 回答
Dobb 博士的这篇文章:Optimizing Math-Intensive Applications with Fixed-Point Arithmetic很好地解释了 CORDIC 算法,并为文章中讨论的库提供了完整的源代码。
请参阅堆栈溢出问题三角函数如何工作? 那里接受的答案解释了如何减少范围,然后使用 CORDIC,然后进行一些进一步优化的一些细节。
- 查找表
- 泰勒级数,就像你说的
请注意,使用查找表,您通常可以通过限制域来优化事物,例如将角度表示为无符号字符,这样您只能绕圆 256 步,但也是一个非常紧凑的表。可以对值做类似的事情,比如使用定点。
这可能有一些帮助/灵感: Quake III 中的神奇平方根
我参加聚会有点晚了,但无论如何我想分享一个使用查找表(包括表生成器)的现成有效解决方案:DFTrig。
DFTrig 由两部分组成:
- 查找表生成器
tablegen
(用 Java 编写,但这并不重要),它接收多个选项并生成 C 代码(带有查找表的 const 结构) - 与 .生成的查找表一起使用的小型 C 模块
tablegen
。
当然,查找表仅包含最少的信息:仅单个象限的正弦值,即[0, 90]
度数。这足以计算任何角度的正弦/余弦。
该行为是完全可定制的。您可以指定:
- 查找表中每个项目乘以的因子(基于每个表);
- 表中每个项目之间的步长(基于每个表);表中项的类型(整个 C 项目通用)。
因此,根据您的需要,您可以:
- 为整个应用程序生成具有最大因子的单个表,以便您的 C 项目的任何子系统都可以使用该单个表,提供所需的因子,如果请求的因子不是表的因子,它将重新计算;
- 生成多个表,每个表都具有特定因素,并且 C 项目的每个子系统都使用其专用表。然后,可以按原样从表中返回值,而无需重新计算;工作得更快。
我在我的嵌入式项目中使用它,它工作得很好。
在某些情况下,可以只使用 IIR 滤波器进行管理,调谐到所需频率的谐振。看这里:http ://www.ee.ic.ac.uk/pcheung/teaching/ee3_Study_Project/Sinewave%20Generation(708).pdf
您可以查看这个用于 8 位 AVR 微控制器的任意定点库: https ://community.atmel.com/projects/afp-arbitrary-fixed-point-lib
编辑:链接已更新