/*
* Лабораторна робота №3, варіант 11
* Керування світлофорами на перехресті (кінцевий автомат / FSM)
*
* Схема перехрестя (Т-подібне):
* - Світлофор 1 (вертикальна дорога): TL1_RED=PA0, TL1_YEL=PA1, TL1_GRN=PA2
* - Світлофор 2 (горизонтальна дорога): TL2_RED=PA3, TL2_YEL=PA4, TL2_GRN=PA5
*
* Граф переходів / таблиця переходів-виходів:
* ┌──────┬─────────────────┬──────────────────┬──────────┬──────────┐
* │ Стан │ TL1 (верт.) │ TL2 (гориз.) │ Трив., с │ Наступний│
* ├──────┼─────────────────┼──────────────────┼──────────┼──────────┤
* │ S0 │ RED │ GREEN │ 15 │ S1 │
* │ S1 │ RED + YELLOW │ YELLOW │ 3 │ S2 │
* │ S2 │ RED │ RED + YELLOW │ 3 │ S3 │
* │ S3 │ GREEN │ RED │ 25 │ S4 │
* │ S4 │ YELLOW │ RED │ 2 │ S0 │
* └──────┴─────────────────┴──────────────────┴──────────┴──────────┘
*
* Загальний цикл: 15+3+3+25+2 = 48 секунд
*/
#include <Arduino.h>
// ── Піни світлофора 1 (вертикальна дорога) ──────────────────────────────────
#define TL1_RED_PIN PA0
#define TL1_YEL_PIN PA1
#define TL1_GRN_PIN PA2
// ── Піни світлофора 2 (горизонтальна дорога) ────────────────────────────────
#define TL2_RED_PIN PA3
#define TL2_YEL_PIN PA4
#define TL2_GRN_PIN PA5
// ── Визначення станів кінцевого автомата ────────────────────────────────────
typedef enum {
S0 = 0, // TL1=RED, TL2=GREEN — 15 с
S1, // TL1=RED+YELLOW, TL2=YELLOW — 3 с
S2, // TL1=RED, TL2=RED+YELLOW — 3 с
S3, // TL1=GREEN, TL2=RED — 25 с
S4, // TL1=YELLOW, TL2=RED — 2 с
STATE_COUNT
} FsmState_t;
// ── Тривалість кожного стану (мілісекунди) ──────────────────────────────────
static const uint32_t STATE_DURATION_MS[STATE_COUNT] = {
15000, // S0
3000, // S1
3000, // S2
25000, // S3
2000 // S4
};
// ── Таблиця виходів: {TL1_R, TL1_Y, TL1_G, TL2_R, TL2_Y, TL2_G} ────────────
static const uint8_t OUTPUT_TABLE[STATE_COUNT][6] = {
/* S0 */ { HIGH, LOW, LOW, LOW, LOW, HIGH },
/* S1 */ { HIGH, HIGH, LOW, LOW, HIGH, LOW },
/* S2 */ { HIGH, LOW, LOW, HIGH, HIGH, LOW },
/* S3 */ { LOW, LOW, HIGH, HIGH, LOW, LOW },
/* S4 */ { LOW, HIGH, LOW, HIGH, LOW, LOW }
};
// ── Поточний стан автомата ───────────────────────────────────────────────────
static FsmState_t currentState = S0;
static uint32_t stateStartMs = 0;
// ── Допоміжна функція: встановити виходи згідно таблиці ─────────────────────
static void applyOutputs(FsmState_t state)
{
digitalWrite(TL1_RED_PIN, OUTPUT_TABLE[state][0]);
digitalWrite(TL1_YEL_PIN, OUTPUT_TABLE[state][1]);
digitalWrite(TL1_GRN_PIN, OUTPUT_TABLE[state][2]);
digitalWrite(TL2_RED_PIN, OUTPUT_TABLE[state][3]);
digitalWrite(TL2_YEL_PIN, OUTPUT_TABLE[state][4]);
digitalWrite(TL2_GRN_PIN, OUTPUT_TABLE[state][5]);
}
// ── Друк поточного стану в Serial ────────────────────────────────────────────
static void printState(FsmState_t state)
{
const char *names[STATE_COUNT] = { "S0", "S1", "S2", "S3", "S4" };
const char *desc[STATE_COUNT] = {
"TL1=RED | TL2=GREEN | 15 s",
"TL1=RED+YELLOW | TL2=YELLOW | 3 s",
"TL1=RED | TL2=RED+YELLOW | 3 s",
"TL1=GREEN | TL2=RED | 25 s",
"TL1=YELLOW | TL2=RED | 2 s"
};
Serial.print("[FSM] Стан: ");
Serial.print(names[state]);
Serial.print(" -> ");
Serial.println(desc[state]);
}
// ────────────────────────────────────────────────────────────────────────────
void setup()
{
Serial.begin(115200);
delay(50);
Serial.println("====================================");
Serial.println(" Варіант 11 — Керування світлофором");
Serial.println(" Кінцевий автомат (FSM) — STM32");
Serial.println("====================================");
Serial.println("Граф переходів: S0->S1->S2->S3->S4->S0");
Serial.println();
// Налаштування пінів як виходи
pinMode(TL1_RED_PIN, OUTPUT);
pinMode(TL1_YEL_PIN, OUTPUT);
pinMode(TL1_GRN_PIN, OUTPUT);
pinMode(TL2_RED_PIN, OUTPUT);
pinMode(TL2_YEL_PIN, OUTPUT);
pinMode(TL2_GRN_PIN, OUTPUT);
// Початковий стан — S0
currentState = S0;
stateStartMs = millis();
applyOutputs(currentState);
printState(currentState);
}
// ────────────────────────────────────────────────────────────────────────────
void loop()
{
uint32_t now = millis();
// Перевірка умови переходу: якщо час в поточному стані вичерпано
if ((now - stateStartMs) >= STATE_DURATION_MS[currentState])
{
// Функція переходу: лінійний цикл S0->S1->S2->S3->S4->S0
currentState = (FsmState_t)((currentState + 1) % STATE_COUNT);
stateStartMs = now;
// Функція виходу: оновити піни згідно нового стану
applyOutputs(currentState);
printState(currentState);
}
}Loading
st-nucleo-c031c6
st-nucleo-c031c6