在C中生成具有时间相关频率的正弦信号

时间:2017-12-28 17:01:36

标签: c arm embedded microcontroller

我想生成一个具有时间相关频率的正弦信号,该信号在fminfmax之间定期变化,在C中频率为f0。在数学上,这可以用

y(t)=1/2*(1+sin(2*Pi*(fmin*t + (fmax-fmin)*1/2*(t - 1/2/Pi/f0*cos(2*Pi*f0*t) + 1/2/Pi/f0))))

因为我想在微控制器上使用它,我想减少浮点数的使用,以节省内存并提高性能。

这也是我无法使用标准正弦函数的原因。为了计算正弦函数,我用抛物线近似它。因此,我使用以下代码:

输入范围[0R2πR]映射到[0到1024]。

输出范围[-1.0 1.0]映射到[-512 512]。

int_fast16_t sin_bam(int angle_bam) {
  angle_bam %= 1024;
  if (angle_bam < 0)
    angle_bam += 1024;
  uint_fast16_t sub_angle = angle_bam % (1024u / 2);
  int_fast16_t sn = (uint32_t) (sub_angle*(1024/2 - sub_angle) / 128);
  if (angle_bam & 512) {
    sn = -sn;
  }
  return sn;
}

我实现上述信号的第一种方法是

y(i) = sin_bam(fmin*i+(fmax-fmin)*(i-2/f0*sin_bam((int) (f0*i+1024/4))+1024/f0))+512.

对于大约f0 >= 1的值,这很有效,但是对于较小的值,我的代码似乎会破坏,例如对于f0 = 0.1,每次达到最小频率时,生成的信号变得非常“不平滑”。

这里有一个示例输出:

enter image description here

我认为问题可能是正弦函数的整数实现,因为它读取的是f0 = 0.1

sin_bam((int) (0.1*i+1024/4)).

这意味着,例如,对于0到9之间的i值,sin_bam((int)(0.1 * i + 1024/4))提供相同的输出。

我解决这个问题的第一个想法是增加正弦函数的角分辨率,但不幸的是,这没有帮助。

我的算法中是否存在任何逻辑错误,或者是否有人有更好的想法来实现它?

0 个答案:

没有答案