// Определение терминальных символов. #define BUT_TIMEOUT 0x01 #define BUT_TIMER_END 0x02 #define BUT_START_ON 0x04 #define BUT_START_OFF 0x05 #define BUT_STOP_ON 0x06 #define BUT_STOP_OFF 0x07 #define BUT_SET_ON 0x08 #define BUT_SET_OFF 0x09 #define BUT_PLUS_ON 0x0A #define BUT_PLUS_OFF 0x0B #define BUT_MINUS_ON 0x0c #define BUT_MINUS_OFF 0x0D unsigned char cond = 0; unsigned short timer = 0; unsigned long longTimer = 0; signed char hours = 0, minutes = 0; unsigned char readEEPROM(unsigned short addr) // Считать задержку из ЭСППЗУ { return 0;/* Здесь нало реализовать код чтения!*/ } void writeEEPROM(unsigned short addr, unsigned char value) // Сохранить задержку в из ЭСППЗУ { /* Здесь нало реализовать код записи!*/ } void startDelay(unsigned short forTimer) // Запуск виртуального таймера с указанной задержкой. {unsigned char forSREG = SREG; cli(); timer = forTimer; SREG = forSREG; } void startLongDelay(unsigned long forTimer) // Запуск "длинного" виртуального таймера с указанной задержкой. {unsigned char forSREG = SREG; cli(); longTimer = forTimer; SREG = forSREG; } void onOffPower(unsigned char onOff) // Включение/выключение нагрузки. { if (onOff == 0) PORTD & ~(1 << PD1); else PORTD |= 1 << PD1; } void automat(unsigned char terminal) // Отработка конечного автомата системы. { switch (cond) {case 0: switch (terminal) {case BUT_START_ON: cond = 1; hours = readEEPROM(0); minutes = readEEPROM(1); startLongDelay(100 * (60 * hours + minutes)); onOffPower(1); break; case BUT_SET_ON: cond = 3; hours = readEEPROM(0); minutes = readEEPROM(1); /*вывести_задержку_на_ЖКИ*/ /*подсветить_часы*/ break; } break; case 1: switch (terminal) {case BUT_STOP_ON: cond = 0; onOffPower(0); break; case BUT_TIMER_END: cond = 2; onOffPower(0); /*включить_писк*/ startDelay(100); break; } break; case 2: switch (terminal) {case BUT_TIMEOUT: cond = 1; /*отлючить_писк*/ startDelay(100); break; case BUT_STOP_ON: cond = 0; /*отлючить_писк*/ break; } break; case 3: switch (terminal) {case BUT_SET_ON: cond = 0; writeEEPROM(hours,0); writeEEPROM(minutes,1); break; case BUT_START_ON: cond = 4; /*подсветить_минуты*/ break; case BUT_PLUS_ON: cond = 5; if (++hours >= 24) hours = 0; /*вывести_задержку_на_ЖКИ*/ startDelay(100); break; case BUT_MINUS_ON: cond = 6; if (--hours < 0) hours = 23; /*вывести_задержку_на_ЖКИ*/ startDelay(100); break; } break; case 4: switch (terminal) {case BUT_SET_ON: cond = 0; writeEEPROM(hours,0); writeEEPROM(minutes,1); break; case BUT_START_ON: cond = 3; /*подсветить_часы*/ break; case BUT_PLUS_ON: cond = 7; if (++minutes >= 60) minutes = 0; /*вывести_задержку_на_ЖКИ*/ startDelay(100); break; case BUT_MINUS_ON: cond = 8; if (--minutes < 0) minutes = 59; /*вывести_задержку_на_ЖКИ*/ startDelay(100); break; } break; case 5: switch (terminal) {case BUT_PLUS_OFF: cond = 3; break; case BUT_TIMEOUT: cond = 5; if (++hours >= 24) hours = 0; /*вывести_задержку_на_ЖКИ*/ startDelay(30); break; } break; case 6: switch (terminal) {case BUT_PLUS_OFF: cond = 3; break; case BUT_TIMEOUT: cond = 6; if (--hours < 0) hours = 23; /*вывести_задержку_на_ЖКИ*/ startDelay(30); break; } break; case 7: switch (terminal) {case BUT_PLUS_OFF: cond = 4; break; case BUT_TIMEOUT: cond = 7; if (++minutes >= 60) minutes = 0; /*вывести_задержку_на_ЖКИ*/ startDelay(30); break; } break; case 8: switch (terminal) {case BUT_PLUS_OFF: cond = 4; break; case BUT_TIMEOUT: cond = 8; if (--minutes < 0) minutes = 59; /*вывести_задержку_на_ЖКИ*/ startDelay(30); break; } break; } } unsigned char lastKeys = 0b01111100, oldKeys = 0b01111100; ISR(TIMER0_OVF_vect) // Тики по переполнению таймера. Должны происходить 100 раз в секунду! {unsigned char actualKey = PIND, iPoz; if (actualKey != lastKeys) // Началось изменение состояния кнопок - выполнить временную задержку для завершение переходных процессов. lastKeys = actualKey; else if (actualKey != oldKeys) // Переходные процессы закончились и состояние клавиш именилось. {oldKeys ^= actualKey; // Определить, какие кнопки изменили состояние. for (iPoz = 0; iPoz < 7; iPoz += 2, oldKeys >>= 1, actualKey >>= 1) if (oldKeys & 0x01) automat(iPoz * 2 + (actualKey & 0x01 ? 1 : 0)); oldKeys = lastKeys; } if (timer != 0) // Отработка виртуального таймера. if (--timer == 0) automat(BUT_TIMEOUT); if (longTimer != 0) // Отработка длинного виртуального таймера. if (--longTimer == 0) automat(BUT_TIMER_END); }