цифровая электроника
вычислительная техника
встраиваемые системы

 

Конечный автомат на C

Автор: Mike(admin) от 10-02-2014, 04:55

При программировании приложений для встраиваемых систем удобно пользоваться конечными автоматами. Они дают ряд преимуществ:


  • Вы можете перевести требования системы в диаграмму состояний или в таблицу состояний переходов.

  • По диаграмме состояний или таблице состояний переходов вы можете проверить правильность проекта до написания программы.

  • Это облегчает понимание кода.

  • Вы можете быстро сопоставлять друг с другом код и требования к системе.

  • Обеспечивается детерминизм, то есть вы сможете точно знать, что делает система в определенный момент.

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



/*********************************************************************
текущее сост-е INPUT_0 INPUT_1 INPUT_2 INPUT_3 Next State OUTPUT_0
DETECT_IN0 0 X X X DETECT_IN1 0
1 X X X DETECT_IN0 0
DETECT_IN1 X 0 X X DETECT_IN2 0
X 1 X X DETECT_IN1 0
DETECT_IN2 X X 0 X DETECT_IN3 0
X X 1 X DETECT_IN2 0
DETECT_IN3 X X X 0 SET_OUTPUT 0
X X X 1 DETECT_IN3 0
SET_OUTPUT X X X X DETECT_IN0 1
X X X X DETECT_IN0 1
*
********************************************************************/

#include <stdio.h>

/*Настройка входов и выходов
Вы можете назначить свои имена для порта микроконтроллера,
это облегчит понимание кода для вас
*/
#define INPUT_0 PTA0
#define INPUT_1 PTA1
#define INPUT_2 PTA2
#define INPUT_3 PTA3
#define OUTPUT_0 PTB0

/*
Входы имеют подтягивающие резисторы, поэтому
мы можем определить условие, когда выбран определенный
вход. В данном случае на нем должен быть 0
*/
#define SELECTED 0x00

/*Определение состояний
Здесь также для лучшего понимания кода
вы можете задать состояниям свои имена
*/
typedef enum { DETECT_IN0 = 0x00,
DETECT_IN1,
DETECT_IN2,
DETECT_IN3,
SET_OUTPUT} SM_STATES;

/*Нам нужна переменная состояния для хранения значения
следующего состояния, также мы должны назначить
этой переменной начальное состояние
*/
unsigned char state = DETECT_IN0;

int ctr_ms = 500; /*Этот конечный автомат выполняется каждые 500 мс*/

/*Функция задержки*/
static unsigned char wait_ms(void);

void main(void) {
for(;;) {
if(wait_ms()) { /*Синхронизация конечного автомата с таймером*/
switch(state) {
case DETECT_IN0:
OUTPUT_0 = 0;
if(INPUT_0 == SELECTED) {
state = DETECT_IN1;
}
break;
case DETECT_IN1:
if(INPUT_1 == SELECTED) {
state = DETECT_IN2;
}
break;
case DETECT_IN2:
if(INPUT_2 == SELECTED) {
state = DETECT_IN3;
}
break;
case DETECT_IN3:
if(INPUT_3 == SELECTED) {
state = SET_OUTPUT;
}
break;
case SET_OUTPUT:
OUTPUT_0 = 1;
state = DETECT_IN0;
break;
default:
/*Ни один из вышеперечисленных*/
break;
}
}
} /* Бесконечный цикл */
}

unsigned char wait_ms(void) {
unsigned char ctr_flag;

ctr_flag = 0;

/*Проверка флага переполнения таймера*/
if(TPM_Get_OVFlag() == 1) {
if (ctr_ms == 0) {
ctr_flag = 1;
} else {
ctr_ms--;
}
TPM_Clr_OVFlag();
}
return ctr_flag;
}



Перевод © digitrode.ru


<Источник>


Теги: конечный автомат, язык C



   Благодарим Вас за интерес к информационному проекту digitrode.ru.
   Если Вы хотите, чтобы интересные и полезные материалы выходили чаще, и было меньше рекламы,
   Вы можее поддержать наш проект, пожертвовав любую сумму на его развитие.


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

Комментарии:

Оставить комментарий