我正在研究C中的微控制器DDS项目,并且在确定如何计算线性插值以平滑输出值方面遇到了一些麻烦 . 现在的计划
使用24位累加器的前8位作为8位输出值数组的索引 . 我需要提出一个函数,它将占用累加器的中间和低位字节,并在数组中的"previous"和"next"值之间生成一个值 . 这对于快速硬件来说足够简单,但由于我使用的是微控制器,我真的需要避免做任何浮点运算或划分!
有了这些限制,我不确定如何从我的两个8位输入数字和累加器的低2个字节获得8位插值,这表示两个输入值之间的“距离” . 提前感谢任何建议!
CLARIFICATION
DDS =直接数字合成
在DDS中,使用相位累加器从查找表生成波形 . 相位累加器通常包含整数分量和分数分量 . 整数组件用作查找表的索引 . 在简单的DDS实现中,忽略小数部分,但是对于更高质量的输出,小数分量用于在相邻查找表值之间进行内插(通常只是线性内插) . 对于上述问题,我们正在研究如何在给定分数f的两个查找表值之间有效地执行此线性插值,其中 0 <= f < 1
.
5 回答
假设您有一个波形值表(一个象限或四个象限,无关紧要),那么一个可能的优化是存储连续表值之间的增量值 . 即如果你有例如
N = 256
和波形表LUT[N]
然后您还有一个delta值表,LUT_delta[N]
. 两个预先计算的表之间的关系是LUT_delta[i] = LUT[i+1] - LUT[i]
. 因此,不是查找两个连续的表值LUT[i]
和LUT[i+1]
,减去这些值以获得增量,然后进行插值,只需查找第一个表值LUT[i]
和delta,LUT_delta[i]
然后计算插值 . 这需要相同数量的表查找,但数学运算较少 . 如果're using a DSP, otherwise it'是通用CPU上的乘法比例加,则应该能够使用单个乘法累加指令进行插值 . 此外,如果您交错LUT
和LUT_delta
值,您可以通过一次读取查找LUT[i]
和LUT_delta[i]
,然后解压缩这两个值 .伪代码:
要进行线性插值而不进行除法,应确保分母的幂为2 .
value(x)= previous,
value(x 1)=下一个值(x dx)= previous(next - previous)* dx
你的问题是,我该如何计算dx?诀窍是计算插值索引(累加器的16位低位),使最大值(dx = 1)为2的幂:
在这里,您已经计算了步长值,因此最大步长为1024,并且相应于dx = 1 . 索引= 512用于dx = 0.5等...
如果你想要更好的精度,我建议先检查累加器的低位 . 例如,如果我们想要4个输出值而不是1:
如果你真的需要速度,请查看AVR assembler .
两个值之间的线性插值a和b是(a b)/ 2 .
这在简单的硬件中很容易,并且不涉及除法或浮点 .
除以2 = =右移一位 .