Переключение бит с высокой скоростью в C # - PullRequest
1 голос
/ 14 июля 2011

Я бы хотел переключить бит со временем менее 1 мс. Я бы предпочел сделать это в C # Windows Forms, но это может быть, например, консольное приложение на C ++, C #. Что я хочу сделать, это переключить бит и отправить его через порт LPT.

Переключение бита в этом коде должно замедлить ..

PortAccess.Output(888,1);
Thread.Sleep(1);
PortAccess.Output(888,0);
Thread.Sleep(1);

Я читал этот пост: Как использовать QueryPerformanceCounter? , но это только таймер ..

Пожалуйста, помогите:)

Ответы [ 3 ]

3 голосов
/ 14 июля 2011

Нет простого или очевидного способа сделать этот вид детального контроля времени в среде C # / .NET.Вы можете использовать класс Stopwatch, чтобы приблизиться, но разрешение не подходит для работы в реальном времени.Чтобы использовать таймер, чтобы сделать что-то вроде этого - бессмысленный код, но вы зацикливаетесь, пока истекшее время не станет вашим желаемым интервалом:

Stopwatch swatch = new Stopwatch();

while(true)
{
    swatch.Reset();
    swatch.Start();
    PortAccess.Output(888, 1);
    while (swatch.ElapsedMilliseconds < 1) { }

    swatch.Stop();
    swatch.Reset();
    swatch.Start();
    PortAccess.Output(888, 0);
    while (swatch.ElapsedMilliseconds < 1) { }
    swatch.Stop();
}

Sleep не должен использоваться нигде для синхронизации.Sleep только в основном говорит: «спи хотя бы X миллисекунд».Так что Sleep(1) может находиться в спящем режиме 25 мс.

И кстати: рядом нет компьютеров, у которых больше нет параллельных портов.Это древний - нет, самый древний способ записи битов или переворачивания выводов на внешний компьютер.Делать это, напрямую выводя на порт ввода-вывода ПК, тоже очень глупо.Вы могли бы искать внешнее цифровое устройство ввода / вывода / плату / интерфейс с приличным драйвером - гораздо лучшая идея.

1 голос
/ 14 июля 2011

Имея в виду, что, что Lucero и Kieren, я все равно отвечу на ваш вопрос.

Вы можете использовать секундомер, чтобы получить точность до миллисекунды, используя Ticks, где 1 Tick == 1/10000 миллисекунд.Например, здесь подождите 1/10 миллисекунды:

    Stopwatch sw = Stopwatch.StartNew();
    while (sw.ElapsedTicks <1000);
    Debug.Print(sw.ElapsedTicks.ToString());

Вы должны убедиться, что у секундомера достаточно высокая частота для ваших потребностей в системе, которую вы будете использовать.Также, пожалуйста, помните, что вы не находитесь на уровне водителя, так что нет ничего, что могло бы гарантировать гарантии в реальном времени.

1 голос
/ 14 июля 2011

Во-первых, вы должны знать, что Sleep() не имеет такого высокого разрешения. Обычно разрешение составляет около 20 мс, поэтому ваши звонки будут ждать намного дольше, чем вы хотите.

Во-вторых, в такой системе, как Windows, которая не предоставляет гарантии в реальном времени, вы не можете рассчитывать на то, что сможете выполнять что-то каждую миллисекунду, даже если вы поддерживаете поток живым (например, с помощью Spinwait()) , Поток может и будет по-прежнему прерываться ОС в обычном процессе переключения задач, и поэтому у вас будут периоды бездействия в течение нескольких миллисекунд.

Короче, не пытайся. Это не сработает.

...