Запуск кода во время ожидания кода

Я знаю, это прозвучит до абсурда просто. Но я не могу придумать или адекватно определить для поиска, как иметь код на C, чтобы светодиод мигал с постоянной частотой, пока выполняется остальная часть программы. Поставь и забудь что-нибудь. Я видел потоки сегодня, хотя это казалось немного сложным для моего базового понимания.

Я разрабатываю для Windows и работаю на MikroC для PIC18, но у меня были те же мысли, когда я работал над другим проектом на Arduino.


person Chris    schedule 13.04.2016    source источник
comment
Попробуйте получить интегрированную среду разработки (IDE). Возможно, в Visual Studio уже есть функция, которая отвечает вашим потребностям (и у них тоже есть бесплатная версия).   -  person Tim Biegeleisen    schedule 13.04.2016
comment
Вы знаете многопоточность?   -  person Mohit Jain    schedule 13.04.2016
comment
На какой ОС вы запускаете программу?   -  person user3386109    schedule 13.04.2016
comment
Окна. Я программирую на MikroC для PIC18, но у меня были те же мысли, когда я работал над другим проектом на Arduino. Я видел потоки сегодня, хотя это казалось немного сложным для моего базового понимания. Может быть, мне нужно изучить это.   -  person Chris    schedule 13.04.2016
comment
PIC18 работает под управлением Windows? Я считаю, что трудно поверить. При работе на чистом оборудовании (без операционной системы) решением является совместная многозадачность.   -  person user3386109    schedule 13.04.2016
comment
Я думаю, вам следует опубликовать какой-нибудь код и указать архитектуру. Есть много способов сделать это. На микроконтроллерах обычно используется сервисный цикл для обновления любых таймеров в системе или для использования прерываний по времени. На более сложных процессорах/ОС, поддерживающих многопоточность, вы можете создать отдельный поток таймера, который периодически пробуждается для выполнения своей задачи. Или вы можете использовать другие подходы и/или их комбинацию.   -  person paddy    schedule 13.04.2016
comment
Только потому, что ваш кросс-компилятор работает в Windows, он не заставляет PIC работать в Windows... Вам нужен учебный материал начального уровня по программированию встроенных систем. Программирование встроенных систем сильно отличается от программирования Windows.   -  person Lundin    schedule 13.04.2016


Ответы (4)


См. ответы на многопоточность с использованием C на PIC18

Для стандартной разработки C потребуется многопоточность, но в этом ответе предлагается использовать цикл обработки событий.

person Luke Pillar    schedule 13.04.2016
comment
Многопоточность на 8-битных микроконтроллерах — это нонсенс. Ни многопоточность, ни циклы событий не нужны для чего-то столь тривиального и быстрого, как переключение вывода ввода-вывода. - person Lundin; 13.04.2016

Просто используйте аппаратное обеспечение микроконтроллера, предназначенное для этого. Таймеры сравнения вывода, оборудование ШИМ и т. д. Если у вас нет такого оборудования, в большинстве случаев переключение порта ввода-вывода с прерывания должно быть достаточно точным.

person Lundin    schedule 13.04.2016

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

int shouldblink = 0;
int ledstatus = 0;
void OnTimer(void) /* configure your microcontroller to call this on timer */
{
    if (ledstatus)
    {
        turnoffLED();
        ledstatus = 0;
    }
    else {
        if (shouldblink)
        {
            turnonLED();
            ledstatus = 1;
        }
    }
}

int main()
{
    configure_timer();
    shouldblink = 1;
    do_slow_work();
    shouldblink = 0;
}
person Stian Skjelstad    schedule 13.04.2016
comment
На PIC ваш main лучше не просто доходить до конца, а оставаться в бесконечном цикле. - person tofro; 13.04.2016

На PIC вам не обязательно сразу переходить от чего-то столь простого, как циклы ожидания, к чему-то столь сложному, как многопоточные библиотеки, как предлагается в некоторых комментариях.

Предположим, вы мигаете светодиодом каждую секунду в цикле. Это дает коду в этом цикле (или вызываемому из этого цикла) почти 1 секунду для выполнения чего-то другого. Если вы можете разделить эти задачи на такие маленькие кусочки, чтобы они соответствовали интервалу «когда вам нужно вернуться», чтобы мигать светодиодом, это начало.

Очевидно, что если вы выполняете произвольный код в цикле мерцания, на частоту вашего мигания будет влиять время, затрачиваемое этими другими частями кода, и вы больше не сможете использовать ЦП в качестве временной базы. Вам нужно что-то другое, чтобы проверить, мигает ли должен. У большинства микроконтроллеров есть таймер, который позволяет вам это сделать. Первым простым шагом будет чтение автономного таймера, чтобы проверить, «нужно ли вам моргать». См. ниже псевдокод:

while (1){
  if (((time = readTimer()) - oldTime) > INTERVAL){
     /* Timer run-around ignored for reasons of simplicity */
     oldTime = time;
     blink();
  }
  else
     doSomethingElse();
}

Обратите внимание, что somethingElse() нужно закончить за минимально возможное время, так как время его выполнения влияет на точность вашего моргания.

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

person tofro    schedule 13.04.2016
comment
Это не даст никакой производительности в реальном времени. Даже если doSomethingElse быстрее, чем рабочий цикл мигания, вы получите постоянные задержки частоты мигания в интервале 0 ‹= задержка ‹= время выполнения doSomethingElse. И он использует 8-битный MCU с древним процессорным ядром из 1980-х годов, ему определенно не следует заглядывать в многопоточные библиотеки. - person Lundin; 13.04.2016
comment
Я пытался заставить ОП экспериментировать и, используя небольшие шаги, найти приемлемые решения. Даже если он увидит изменения в частоте моргания, он кое-чему научится (кстати, он не спрашивал о производительности в реальном времени). Предполагая, что речь идет не об управлении марсианским роботом, это выглядело вполне осуществимым подходом. - person tofro; 13.04.2016
comment
В зависимости от длительности задержки петля может вызвать мерцание, достаточно сильное для человеческого глаза. При этом также очень плохая идея вводить жесткую связь в свои программы. Ваш цикл имеет тесную связь между кодом светодиода и чем-то совершенно не связанным. Однажды кто-то изменит какой-нибудь код сокета TCP/IP, и вдруг светодиод из кофе начнет быстро мигать. Это не то, как вы разрабатываете надежные программы. - person Lundin; 13.04.2016
comment
Вы совершенно правы (и это уже упоминалось в моем ответе), но опять же: это предложение не было направлено на производительность марсианского робота. ОП, осознавший именно то, что вы описали (дрожание при моргании), заставит его взглянуть на следующий уровень исследования, а именно на таймеры. Подталкивая кого-то, кто, по-видимому, только что начал что-то делать, к идеальному решению, он теряет шанс действительно чему-то научиться. - person tofro; 13.04.2016
comment
Или вы могли бы просто научить его делать это с самого начала. Таймеры очень важны при разработке любой встраиваемой системы. Лучше узнать о них раньше, чем позже. - person Lundin; 13.04.2016