【问题标题】:How to generate a square wave using C#?如何使用 C# 生成方波?
【发布时间】:2011-08-17 10:10:41
【问题描述】:

我想生成一个数字信号,然后将其用于实现 ASK(幅移键控)信号。

假设消息位是 10110,数据速率:3.9 Khz 和幅度 A。

生成方形信号(数字)的最佳方法是什么。

我尝试了以下代码,但结果并不理想。

double[] x = new double[1000];
double[] y = new double[1000];
double freq = 3900.0;

for (int k = 0; k < y.Length; k++)
{
    x[k] = k;
    y[k] = (4 / Math.PI) * (((Math.Sin(((2 * k) - 1) * (2 * Math.PI * freq))) /   ((2 * k) - 1)));
}

// Plot Square Wave
plotSquare(x, y, Msg);

【问题讨论】:

  • 你已经尝试过什么? Stack Overflow 是一个讨论与编程相关的具体问题的网站。
  • 我尝试使用以下代码,但无法获得所需的输出。
  • y[k] = (4 / Math.PI) * (((Math.Sin(((2 * k) - 1) * (2 * Math.PI * freq))) / ((2 * k) - 1)));

标签: c# signal-processing


【解决方案1】:

我能想到的最简单的方法是将 y 设置为正弦波的符号,在它等于 0 时留出余量。我不知道 C# 是否有三重运算符,但这样的东西可能会起作用:

y[k] = Math.Sin(freq * k)>=0?A:-1*A;

【讨论】:

  • 谢谢你的回复,我也试过用你的代码,现在好多了,但是间隔的输出周期不一样,而且不一样,我想生成消息特定的代码.
  • 不同的输出周期几乎可以肯定是aliasing 效果,因为您使用的 k 是整数值。
  • 有什么办法可以消除这种锯齿效果..?
  • 一般来说,如果采样频率低于信号的Nyquist frequency,则在对模拟信号进行数字化时总是会出现混叠效应。因此,在您的频率为 3900Hz 的示例中,您需要至少采样两倍的速率:因此 k 需要在每次迭代中增加 1/7800(假设 k 以秒为单位)。
  • 别名指的是样本值,而不是时间。在这方面,因为样本值是A-A,所以这里不会发生别名。采样周期是整数,这不是问题。同样,别名不是这里的问题。
【解决方案2】:

Math.Sin 对正弦波很有用,但方波应该非常简单(即信号在一段时间内为“高”,然后在一段时间内为“低”)。如果您在任何地方都有Math.Sin,您将生成正弦波,而不是方波。请记住,可以在条件(x>y)下生成方波,而正弦波需要完整的数学运算,它的效率也要高得多。

【讨论】:

    【解决方案3】:

    想到了 C# 的 Iterator Block 支持:

    IEnumerable<Tuple<double, double>> SquareWave(double freq, double lowAmp, double highAmp)
    {
        for (var x = 0.0; true; x += 1.0)
        {
            var y = ((int)(x / freq) % 2) == 0 ? lowAmp : highAmp;
            yield return Tuple.Create(x, y);
        }
    }
    

    这样使用:

    foreach(var t in SquareWave(10, -5, 5).Take(30))
        Console.WriteLine("X: {0:0.0}/Y: {1:0.0}", t.Item1, t.Item2);
    

    【讨论】:

    • 非常感谢 CKoenig,因为我是 C# 的新手,你的代码看起来很复杂,我很难理解,你能告诉我有什么简单的方法来生成信号吗。
    • 好的 - 我猜最难的部分是 (x/freq)%2 -part。我想要一个表达式,它从 0-1-0 for at freq, 2*freq, ... - 首先将 x 除以 freq 并应用 (int) 我得到 0 表示 [0..freq),1 表示[freq..2*freq)、2 来回 [2*freq..3*freq) 等等。然后我取这个整数模 2 并得到所需的 0,1,0,1,... 效果。通过将此与 amp 相乘,我得到一个来自 [0..freq) 的 0 信号,来自 [freq..2*freq) 的 amp 等等。剩下的是 C# 中的语法糖,用于生成元组序列(第一个元素是 x,第二个是 y)
    • 如果你想要 -amp / +amp 你可以相乘,只需在“y = 2*y-amp”之间添加另一行,如果你想在其中编码一些消息,你可以采取“( int)(x/freq)" 成为您消息的 index 并说“y = messageBits[(int)(x/freq)]*amp” - 等等希望这会有所帮助
    • 感谢一百万给我一个清晰的解释,是的,我会尝试将此代码实现到我的项目中。到目前为止,我还没有遇到过 Inumerable & Tuples,所以我认为它会有点复杂。我需要花一些时间学习,休息很清楚,再次感谢....!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-11
    • 2018-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多