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

 

Конечный автомат на 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




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

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

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