Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: организация шагов в программе
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
RicLab
Добрый день.
Решил спросить совета у знающих.
Устройство должно управлять нагрузкой(светодиод) регулируя мощность на нём в зависимости от состояния двери. Т.е. при открытиии двери в течении 1 сек плавно повысить мощность до max, при закрытии с задержкой 10 сек в течении 3 сек плавно понизить мощность до min.
В программе ввел переменную step по которой отслеживается какой сейчас шаг. В зависимости от шага меняется коэффициент счетчика изменения мощности. Также отслеживается состояния двери между шагами для возврата на предыдущий шаг при изменении её состояния.
При моделировании в Proteus выполняется только первый шаг, дальше программа не переходит.
Во вложении проект в CVAVR.
Возможно кто то увидет ошибку или предложит другой способ организации шагов.
Сильно не ругать, я только учусь.

smile3046.gif
mempfis_
Цитата(RicLab @ May 24 2010, 07:12) *
Устройство должно управлять нагрузкой(светодиод) регулируя мощность на нём в зависимости от состояния двери.


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

Делал довольно много программ на основе переменной состояния программы.
Например нужно сделать программу которая в зависимости от состояния многих датчиков должна выполнять различные действия.
Предположим у вас есть датчик открытия двери door. Вводите переменную state которая определяет текущее состояние программы.

Организовываете основной цикл программы:

Код
state = 0; //исходное состояние
for(;;)
{
    switch(state)
    {
        case 0: State0();
        break;

        case 1: State1();
        break;
        
        case 2: State2();
        break;
        
        case 3: State3();
        break;
    
     }
}


Описываете подпрограммы конкретных состояний.

Код
//в State0 опрашиваете датчик состояния двери
void State0(void)
{
  if(door != 0)
{
    //дверь открылась
    state = 1; //переход в состояние повышения мощности в теч 1 сек
    
}
}

//в State1 реализовывается алгоритм зажигания в течение 1 сек
void State1(void)
{
  if(не вышло время 1 сек)
{
    наращиваете мощность
  }
else
{
   //переход на ожидание закрытия
   state = 2;
}
}

//в State2 опрашиваете датчик состояния двери
void State2(void)
{
  if(door == 0)
{
    //дверь закрылась
    state = 3; //переход в состояние гашения светодиода
    
}
}


//в State3 гасим светодиод
void State3(void)
{
  if(не вышло время гашения светодиода)
{
    реализуем алгоритм гашения светодиода
    
}
else
{
   state = 0; //переход в исходное состояние
}
}


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

Да и поробуйте для начала сделать простой алгоритм включения/выключения в зависимости от стостояния датчика двери. А уже потом думать как плавно зажигать или гасить их. По-поводу сложных алгоритмов пауза+плавное гашение - ничто не мешает разделить этот процесс на 2 состояния программы (состояние паузы в 10 сек с переходом в состояние гашения за 3 сек).
kratmel
Сам боролся с подобной задачей. Очень помогла статья проф.Шалыто . Построив граф переходов системы программируется все за 5 минут. Обратите внимание на часть 3 -там пример.
Результат похож на предложеный mempfis_.
RicLab
Да действительно на конструкции switch всё выглядит лаконичней.
За статью спасибо. Почитаю в свободное от работы время.
Juray
Автоматный подход - хороший. Граф переходов (диаграмма состояний) очень наглядная вещь.

Кроме уже приведенной статьи Шалыто, рекомендую ознакомиться с прочими материалами по этой теме - того же Шалыто, Туккеля и пр.
Куча статей лежит по адресам http://softcraft.ru/auto.shtml, http://is.ifmo.ru/ и http://is.ifmo.ru/progeny/

Напомню также довольно известную рекомендацию, что состояниям (как и переменным, функциям и т.п.) лучше давать осмысленные имена - легче потом в ней разбираться. В неосмысленных именах можно запутаться уже на следующий день.
RicLab
Автоматный подход это действительно хорошо.
Программа реализованная на данном подходе заработала сразу.
Первый вариант программы кстати тоже заработал. Ошибка была в схеме, вход датчика состояния двери был без подтягивающего резистора.
Ловил на входе всё что можно и нельзя когда датчик разомкнут, от того и не работало ничего.

Спасибо всем за знания! smile.gif

Позже планирую выложить отшлифованный проект перенесённый на tiny13.
mempfis_
Цитата(RicLab @ Jun 2 2010, 12:25) *
вход датчика состояния двери был без подтягивающего резистора.


В tiny/atmega есть внутренние подтягивающие резисторы.
Включаются:
Код
DDRx = (1<<5); //пин 5 порта - вход
PORTx = (1<<5); //для пина 5 сконфигурированного на вход включить pull-up


Обычно всегда для входов включаю pull-up (даже если есть внешний). Просто так на всякий случай
mempfis_
Упс обшибся!!!!
Надо так:

Код
DDRx &= ~(1<<5); //пин 5 порта - вход
PORTx |= (1<<5); //для пина 5 сконфигурированного на вход включить pull-up
RicLab
про подтягивающие резисторы я в курсе. но они подключены к VCC, а у меня активный уровень датчика двери высокий.
так что мне нужен был подтягивающий резистор на землю, что бы помехи не ловил.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.