Перейти к содержанию
    

Вопросик по алгоритму на Си......

Здравствуйте!

В предыдущем топике понял как подключать полевик.... :08:

Теперь вот вопросик по самой программе: имеется устройство с кнопочкой: нажимаешь на нее -сработало прерывание- пошла выполняться основная программа - длится она может несколько часов (включение/выключение реле, светодиоды мыргают и т.п.)....Но этой же кнопочкой надо и остановить выполнение этого цикла, то есть кнопка выполняет функции старт/стоп..... :cranky:

В программировании пока не силен - по идее надо в прерывании какой нибудь флаг выставить, чтобы произошел старт/стоп, а в основной программе как то этот флаг прочитать....но цикл основной программы большой.... - может еще сделать прерывание через какой то промежуток времени и смотреть состояние этого флага?

Посоветуйте плиз - хотя бы идеей!!! Спасибо!!! :laughing:

 

Можно еще один вопросик в догонку?! Как еще правильно вставлять WDT в прогу на Си?!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здравствуйте!

В предыдущем топике понял как подключать полевик.... :08:

Теперь вот вопросик по самой программе: имеется устройство с кнопочкой: нажимаешь на нее -сработало прерывание- пошла выполняться основная программа - длится она может несколько часов (включение/выключение реле, светодиоды мыргают и т.п.)....Но этой же кнопочкой надо и остановить выполнение этого цикла, то есть кнопка выполняет функции старт/стоп..... :cranky:

В программировании пока не силен - по идее надо в прерывании какой нибудь флаг выставить, чтобы произошел старт/стоп, а в основной программе как то этот флаг прочитать....но цикл основной программы большой.... - может еще сделать прерывание через какой то промежуток времени и смотреть состояние этого флага?

Посоветуйте плиз - хотя бы идеей!!! Спасибо!!! :laughing:

 

 

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

 

Основной цикл программы (даже если она выполняется "несколько часов") короткий (чем короче, тем лучше:-) ). Так вот в этом основном цикле и надо проверять нажатие кнопки.

Предарительно описываете некоторую переменную, которая будет принимать значение 1 при одном нажатии, и значение 0 при следующем и так далее: 1,0,1,0... (Так называемая "триггерная кнопка")

В зависимости от значения этой переменной выполняется или нет рабочий цикл.

Приблизительная структура программы следующая:

void main(void){
unsigned char Mode=0;
  // Инициализация контроллера
  ...........
while(1){ // вечный цикл
  // Обработка кнопки
  if(! КНОПКА){ // нажата?
    delay_mc(20); // задержка - ликвидация дребезга
    if(! КНОПКА) { // все еще нажата - значит не ложное срабатывание
      while(! КНОПКА); // ожидание отжатия
      if(Mode) Mode=0; else Mode=1; //Изменяем режим 
    }
  }
  // основные действия 
  if(Mode) {
  .............
  }
  else{
  ...............
  }
}
}

 

Это самый простейший вариант, имеющий некоторые ограничения.

1) Использование ватчдога здесь не имеет смысла - можно "передержать" кнопку нажатой - и тем самым вызвать сброс

2) Констркуция "основные действия" должна быть линейной (не содержать замкнутых циклов)

 

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

Но для начального понимания приведенный кусок может пригодиться.

 

Можно еще один вопросик в догонку?! Как еще правильно вставлять WDT в прогу на Си?!

 

Для ответа на данный вопрос надо знать какой проц. Вы используете. У каждого свои регистры ватчдога и разные способы его запуска и обработки событий от него.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, ALexx!!!

1) Только судя по программе, получается, что произвести остановку в любой момент не получится - надо ждать N-ое число часов....

2) Проц ATMega 8...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1) Только судя по программе, получается, что произвести остановку в любой момент не получится - надо ждать N-ое число часов....

Это что же за программа такая у которой основной "суперцикл" несколько часов длится? :07:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, ALexx!!!

1) Только судя по программе, получается, что произвести остановку в любой момент не получится - надо ждать N-ое число часов....

2) Проц ATMega 8...

 

Не может цикл длиться "несколько часов"!!!

 

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

 

Опишите задачу подробнее. Тогда можно будет что-то предложить или посоветовать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ОК! Описываю задачу: :1111493779:

Необходимо собрать прогреватель для дизельного двигателя (грузовик).

С помощью 1-й кнопки выбираем режим (интервал между запусками) - 2,3,N часов....

2-я кнопка - для запуска/остановки режима автоматического прогрева, то есть выходя из

машины нажимаем кнопульку (start), а когда приходим назад (или в любой др. момент) - выключаем

(stop).... :unsure:

Получается, что в основной программе, когда нажимаем start, начинается отработка длительного цикла, который можно (нужно) в любой момент остановить..... :01:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

начинается отработка длительного цикла, который можно (нужно) в любой момент остановить..... :01:
Ну так цикла же. Т.е.

1) проверили не заглохли ли, если да - заводить заново

2) проверили, не пора ли глушить

3) пошли снова на п.1

 

Вот тут после п.2 и вставить проверку - не нажали ли кнопку "старт" снова.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Необходимо собрать прогреватель для дизельного двигателя (грузовик).

С помощью 1-й кнопки выбираем режим (интервал между запусками) - 2,3,N часов....

2-я кнопка - для запуска/остановки режима автоматического прогрева, то есть выходя из

машины нажимаем кнопульку (start), а когда приходим назад (или в любой др. момент) - выключаем (stop).... :unsure:

Дык это типовая задача управления с пользовательским интерфейсом. ;)

Получается, что в основной программе, когда нажимаем start, начинается отработка длительного цикла, который можно (нужно) в любой момент остановить..... :01:

А нафига? Общая задача управления разделяется на два независимых (почти независимых) конечных автомата (КА). Один обслуживает двухуровневое меню с кнопками, второй следит за временем и управляет включением/выключением двигателя. Оба они "крутятся" в суперцикле, но время выполнения этого суперцикла ничтожное. пара-тройка сотен команд при тактовой частоте несколько МГц даст период суперцикла в сотню-две микросекунд.

Алгоритм каждого конечного автомата разбивается на шаги/ступени. За один период обращения суперцикла выполняется один шаг конечного автомата. Обмен между этими двумя КА делается через группу общих переменных/флагов.

Пример. Для КА управления двигателем.

1 шаг. Есть задание? если есть берем параметры задания и изменяем номер шага на шаг 2. Если нет выходим без изменения номера шага.

2 шаг. Время включения настало? если да, то включаем двигатель и изменяем номер шага на шаг 3. Здесь же дополнительная проверка, а не отменено ли задание? если отменено, то выключаем двигатель и изменяем номер шага на шаг 1.

3 шаг. Время выключения настало? если да, то выключаем двигатель и изменяем номер шага на шаг 2. Доп. проверка, не отменено ли задание? если отменено, то выключаем и изменяем номер шага на шаг 1.

Все!

Для КА "меню" примерно то же самое.

1 шаг. Нажата какая-нибудь кнопка? Если нет, то выходим без изменения номера шага. если да, то изменяем номер шага на шаг 2 или на шаг 3 в зависимости от того, какая кнопка нажата.

2 шаг. Изменение параметра. Период ожидания кнопки закончен? если да, то изменяем номер шага на "шаг 1" с сохранением нового задания (если изменений не было, то без него) и выходим. Если период ожидания не закончен, то: Кнопка нажата? Да, изменение параметра на единицу или эквивалентную установленной величину. Если нет, то выходим без изменения номера шага.

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

 

Вот и весь алгоритм с практически мгновенной реакцией на нажатие любой кнопки.

 

P.S. я не описал только временнУю переменную. Для измерения интервалов нужно иметь какую-то переменную, которая, например, в прерывании от таймера инкрементируется на заранее известную величину. Я предпочитаю в мс (миллисекундах) измерять временные отрезки. Т.е. если период таймера будет скажем 10мс, то переменная должна увеличивать свое значение на 10. Тогда разница между двумя ее значениями будет давать интервал времени в целых единицах миллисекунд. Размерность/тип это переменной (unsigned char, unsigned int, unsigned long, но обязательно беззнаковый тип!) опредеяется частотой ее изменения и максимальным промежутком времени который требуется различать в программе.

 

P.P.S. забыл еще пояснить, что при входе в функцию каждого КА, происходит сразу переход на шаг в соответствии с его номером. Оператор switch можно использовать.

Изменено пользователем rezident

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...