Цитата:
При попытке реализовать конечный автомат в ДРАКОНЕ на переключателе получается полная ерунда,
Цитата:
Речь идет о блоке "Переключатель"? В чем проблема? Что не устраивает, почему ерунда?
При попытке изобразить автомат с использованием переключателя, на получившемся листе хорошо виден (первым бросается в глаза) имено переключатель. А алгоритм работы, который реализован на этом переключателе, уходит на задний план. В то же время, "силуэт" показывает наглядно именно алгоритм работы, пряча внутри себя способ реализации этого алгоритма. Не знаю, сумел ли я понятно выразить свою мысль...
Цитата:
Нужна конструкция, которая бы могла отдавать управление каждый раз при переходе "снизу вверх" в силуэте.
Такое вообще возможно?
Цитата:
Кому передавать управление? Вызывайте процедуры.
Проблема в том, что управление надо отдавать другим таким же автоматам. Так что надо не
вызывать процедуры, а именно
возвращать управление вызвавшей нас процедуре.
Я тут прикрепил файлик на языке Си, иллюстрирующий мой способ написания программ. Заранее прошу снисхождения - я программист "ненастоящий", а, скорее, "программирующий схемотехник". В файле приведен пример некой абстрактной программы, состоящей из трёх автоматов по три состояния каждый (приведена реализация только одного из них, остальные подразумеваются подобными ему). Так вот, суть моих вопросов сводится к следующему: "как алгоритм, реализованный в этой программе, описать на языке ДРАКОН"?
Цитата:
Сергей, ответил на ваши вопросы так, как их понял.
Огромное Вам спасибо за ответы!
Не хотелось бы злоупотреблять Вашим терпением, так что Вы намекните, когда мне следут отстать со своими глупыми вопросами.
С уважением, Ефанов Сергей.
Код:
// В системе есть прерывание по таймеру,
// в нём инкрементируется счётчик "тиков"
#define SEKUNDA 1000L // за секунду происходит 1000 "тиков"
unsigned long int GetTime(void); // эта функция возвращает копию счётчика "тиков"
void init(void);// эта функция настраивает таймерное прерывание
extern volatile bool FlagA; // некое внешнее условие
extern volatile bool FlagB; // некое внешнее условие
// типичный автомат
void Step1(void)
{
static unsigned long int Time; // "местное время", переменная 32 бита
static char ss;// переменная состояния автомата
switch(ss)
{
case 0:
if(FlagA)// что то произошло, на это надо реагировать
{
FlagA = false;
Time = GetTime();// запомнить текущее время
ss = 1;
}
break;
case 1:
if((GetTime() - Time) >= SEKUNDA*45)// условие выполнится через 45 секунд.
{
ss = 2;
}
break;
case 2:
if(FlagB)// опять что то произошло...
{
FlagB = false;
ss = 0;
}
break;
}
}
// вся программа реализована на таких автоматах:
void Step2(void); // построен по тому же принципу, что и Step1
void Step3(void); // построен по тому же принципу, что и Step1
// в главном цикле все автоматы вызываются "по кругу":
void main(void)
{
init(); // настроить прерывание и всё, что нужно.
for(;;)
{
Step1();
Step2();
Step3();
}
}
// функция, реализующая автомат, при каждом вызове возвращает управление очень быстро.
// в состоянии "1" автомата приведён пример отработки задержки. Вычисляется разница
// между текущим моментом времени, и моментом, когда произошёл переход.
// Это вычисление занимает несколько микросекунд. Переход произойдёт (в данном примере) через 45 секунд.
// В течении этого времени автомат много-много раз ненадолго получает управление, производит вычисление,
// и тут же возвращает управление.
// В итоге, в системе одновременно работают 3 автомата, каждый отрабатывает свои временные
// интервалы, не задерживая работу остальных.
// В реальных программах у меня типично 20-30 автоматов с числом состояний
// от 10 до 100, отрабатывающих выдержки от миллисекунд до суток. Всё это хорошо работает,
// но "пасти" такое "стадо кошек" нелегко.
// Вся надежда на помощь ДРАКОНа.