首页 > 解决方案 > 在 C# 中创建方波(高低交替)

问题描述

我正在尝试找到一种方法来为 LED 创建 2 Hz 方波(基本上在 2Hz 的高低之间切换) C# 新手,任何帮助将不胜感激!

这是我的一般思考过程:

While(Programruns){
      read input 
(I feel like there should be a for loop here to keep the square wave going forever until I stop it)
      if(button is pressed){
     output square wave
}
    else {
     off}
}

标签: c#datetimewaveform

解决方案


您想要一个带有睡眠操作的循环。

你没有告诉我们你是如何打开和关闭那个 LED 的,所以我假设你有一个名为SetLED(val). 0 的Aval关闭 LED,1 将其打开。并且,让我们调用一个在按下按钮时ButtonPressed()返回的方法。true

要获得 2Hz 方波,您需要val每 250 毫秒翻转一次。这段代码将为您做到这一点。

var ledState = 1;
while (ButtonPressed()) {
    SetLED(ledState);
    Thread.Sleep(250);         //milliseconds
    ledState = 1 - ledState;   //flip the value
}
SetLED(0);   // turn the LED off when done.

这基本上会奏效。但有一个复杂之处:C# 及其各种底层操作系统都不是硬实时系统。因此Thread.Sleep(),有时醒来有点晚。这些迟到的唤醒会累积起来,使您的方波有点紧张,累积起来会小于 2Hz。对于抖动,您无能为力。

但是您可以通过查看时间时钟并计算每个循环中的睡眠时间来避免频率下降。

该表达式DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond以毫秒为单位为您提供当前时间(从很久以前的某个时代开始)。

因此,您可以计算代码中下一次睡眠的毫秒数。这纠正了.Sleep()睡过头。

var ledState = 1;
long nextTickTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; 
while (ButtonPressed()) {
    SetLED(ledState);
    nextTickTime += 250;
    long nowTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
    int sleepInterval = nextTickTime - nowTime;
    if (sleepInterval > 0) 
      Thread.Sleep(sleepInterval); 
    ledState = 1 - ledState;   //flip the value
}
SetLED(0);   // turn the LED off when done.

这是一个相当强大的闪光灯。您还可以在循环运行时提高线程的优先级,但这是另一天的问题和答案。


推荐阅读