Так сказать еще одна тренировка мозга (и добавка учебного примера в КОТУИНКЕ)...
Так сказать еще одна тренировка мозга (и добавка учебного примера в КОТУИНКЕ)...
Код: Выделить всё
proc_device ();
proc_motor ();
kbd_drv ();
proc_sensors ();
Process_Events ();
Код: Выделить всё
set_soft_timer (timer_Braking, 5000, 0);Код: Выделить всё
_proc_device = PROC_DEVICE_IDLE;Код: Выделить всё
case PROC_DEVICE_IDLE:
if (check_sensor_1_on ())
{
direction = DIRECTION_STOP;
}
Код: Выделить всё
LCDI2C_write4bits(0x03 << 4);
DelayMC(4500); // wait min 4.1ms
LCDI2C_write4bits(0x03 << 4);
DelayMC(4500); // wait min 4.1ms

Код: Выделить всё
u08 event = Get_Event (EV_ID_KEY_PRESSED);
более интересным представляется способ, когда адрес функции и есть идентификатор состояния, т.е. нет нужды ни в массивах, ни в switch-ах:NStorm писал(а):Тут удобно использовать "магию" Си того, что указатели на функции можно сохранять в массивах.
Код: Выделить всё
void (*current)(void);
void STATE_1(void);
void STATE_2(void);
void STATE_3(void);
void STATE_1(void){
current = STATE_2;
}
void STATE_2(void){
current = STATE_3;
}
void STATE_3(void){
current = STATE_1;
}
int main(void){
current = STATE_1;
while(1){
current();
}
}не просто красиво, а удобно. основное назначение программы на ЯВУ - быть понятной человеку. макаронный код плох не тем, что плохо работает (как правило, наоборот), а тем, что нечитаем (о сопровождении кода я вообще молчу - мы ж не профессионалы, а любители, какое там сопровождение?!). КА с огромным количеством состояний плох по той же причине. Чистый КА - это программа на ассемблере, машинные инструкции: каждое следующее состояние определяется текущим состоянием, кодом текущей операции и текущим состоянием данных, причем определяется однозначно - классика! но это очень неудобно, потому от машинных кодов с диким количеством состояний мы уходим в ЯВУ, где необходимости в них нет. остается лишь найти золотую середину между удобством чтения и простотой (еще вопрос) парадигмы КА.Demiurg писал(а):Красиво, но не эффективно.
традиционное программирование (раньше я называл это функциональным, но теперь смысл этого термина поменялся) то же самое: независимые функции-кубики, разделяй и властвуй. парадигма КА не в этом.Demiurg писал(а):Автоматное программирование хорошо тем, что проект раздроблен. На состояния. Разделяй и властвуй. Кубики, из которых возводишь здание.
Наверное вы имеете в виду процедурное программирование.традиционное программирование (раньше я называл это функциональным, но теперь смысл этого термина поменялся)
Код: Выделить всё
_proc_device.h
//************************************************************************
//************************ Главный автомат *******************************
//************************************************************************
//==================
STATE (PROC_DEVICE_INIT, proc_device_init)
STATE (PROC_DEVICE_WEIGHT_MODE, proc_device_weight_mode)
STATE (PROC_DEVICE_DOSER_IDLE_MODE, proc_device_doser_idle_mode)
STATE (PROC_DEVICE_DOSER_MODE, proc_device_doser_mode)
STATE (PROC_DEVICE_IDLE, proc_device_idle)
STATE (PROC_DEVICE_EMERG_MODE, proc_device_emerg_mode)
//==================
//==================
typedef enum _proc_device
{
#define STATE(name, func) name,
#include "_proc_device.h"
#undef STATE
PROC_DEVICE_STATES,
} proc_device_t;
//----------
void proc_device (void);
//----------
void proc_device_init (void);
//----------
void proc_device_weight_mode_init (void);
void proc_device_weight_mode (void);
//----------
void proc_device_doser_idle_mode_init (void);
void proc_device_doser_idle_mode (void);
//----------
void proc_device_doser_mode_init (void);
void rst_proc_device_doser_mode (void);
void proc_device_doser_mode (void);
//----------
void proc_device_idle_init (void);
void proc_device_idle (void);
//----------
void set_proc_device_emerg_mode (u08 err_id);
void proc_device_emerg_mode (void);
//==================
//==================
__flash FUNC proc_device_func [PROC_DEVICE_STATES] =
{
#define STATE(name, func) func,
#include "_proc_device.h"
#undef STATE
};
//----------
static proc_device_t _proc_device;
static u08 _proc_device_slave;
//----------
void proc_device (void)
{
// proc_meter (); // Важно!!! Инициализация!
proc_fsm_func (proc_device_func, _proc_device);
}
//==================
Код: Выделить всё
#ifndef FUNC_H
#define FUNC_H
//==================
STATE (PROC_DEVICE_INIT, proc_device_init)
STATE (PROC_DEVICE_WAIT_SWITCH_MODE, proc_device_wait_switch_mode)
//STATE (PROC_DEVICE_MANUAL, proc_device_manual_mode)
//STATE (PROC_DEVICE_AUTOMAT, proc_device_automat_mode)
//STATE (PROC_DEVICE_EMERG_MODE, proc_device_emerg_mode)
//==================
#endif
Код: Выделить всё
#ifndef PROC_DEVICE_H
#define PROC_DEVICE_H
#define __flash const
//==================
typedef void (*FUNC)(void);
//==================
typedef enum _proc_device
{
#define STATE(name, func) name,
#include "func.h"
#undef STATE
PROC_DEVICE_STATES,
}proc_device_t;
void proc_device (void);
void proc_device_init (void);
void proc_device_wait_switch_mode (void) ;
void proc_fsm_func (FUNC __flash *ptr_func, unsigned char s);
__flash FUNC proc_device_func [PROC_DEVICE_STATES] ;
#endifКод: Выделить всё
#include "_proc_device.h"
static proc_device_t _proc_device;
void proc_device (void)
{
_proc_device = PROC_DEVICE_INIT;
proc_fsm_func (proc_device_func, _proc_device);
}
void proc_device_init (void) {
PORTC = (1 << 0);
}
void proc_device_wait_switch_mode (void) {
PORTC = (1 << 1);
}
void proc_fsm_func (FUNC __flash *ptr_func, unsigned char s)
{
ptr_func [s] ();
}
__flash FUNC proc_device_func [PROC_DEVICE_STATES] =
{
#define STATE(name, func) func,
#include "func.h"
#undef STATE
};Код: Выделить всё
typedef enum _proc_device
{
#define STATE(name, func) name,
#include "func.h"
#undef STATE
PROC_DEVICE_STATES,
}proc_device_t;Код: Выделить всё
typedef enum _proc_device
{
PROC_DEVICE_INIT,
PROC_DEVICE_WAIT_SWITCH_MODE,
PROC_DEVICE_STATES,
}proc_device_t;лично меня настораживает: запятая в конце дефайна явно свидетельствует, что макрос STATE - очень контекстно-зависимый макрос, что, имхо, очень нехорошо. если подобных вещей по исходнику много - совсем беда для тех, кто захочет разобраться.Dimon456 писал(а):#define STATE(name, func) name,
Код: Выделить всё
__flash FUNC proc_device_func [PROC_DEVICE_STATES] =
{
#define STATE(name, func) func,
#include "func.h"
#undef STATE
};Код: Выделить всё
__flash FUNC proc_device_func [PROC_DEVICE_STATES] =
{
//#define STATE(name, func) func,
//#include "func.h"
//#undef STATE
proc_device_init,
proc_device_wait_switch_mode,
};