#include #include /* Дефайны */ #define F_CPU 1000000UL // тактовая частота #define PIND_MASK 0b00001100 // Маска для сравнения с PIND /* Переменные */ volatile uint8_t next_state, prev_state, up_state, down_state; int sw34; // Передача /* Прерывания */ ISR(TIMER1_COMPA_vect) { next_state = PIND & PIND_MASK; // Считываем текущее значение битов if (next_state != prev_state) { switch (prev_state) { case 8: { if (next_state == 12) up_state++; if (next_state == 0) down_state++; break; } case 0: { if (next_state == 8) up_state++; if (next_state == 4) down_state++; break; } case 4: { if (next_state == 0) up_state++; if (next_state == 12) down_state++; break; } case 12: { if (next_state == 4) up_state++; if (next_state == 8) down_state++; break; } default: { break; } } prev_state = next_state; // Присваиваем текущему состоянию предыдущее } TCNT1H = 0x00; TCNT1L = 0x00; // Обнуляем счетчик(на всякий случай) } void timer1_init() { TCCR1A = 0x00; TCCR1B |= (1«CS11); // устанавливаем коэффициент деления 8 TCNT1H = 0x00; // Обнуляем старший и младший байты счетного регистра TCNT1L = 0x00; OCR1AH = 0x03; // Настройка регистра сравнения для старшего и младщего байта OCR1AL = 0xE8; // Разрешаем прерывание таймера по совпадению с OCR1A TIMSK1 |= (1«OCIE1A); } int main(void) { Serial.begin(9600); int s = 0; DDRD = 0x00; PORTD = 0x0C; timer1_init(); // Инициализация таймера1 sei(); // Разрешаем глобальные прерывания while (1) { if (up_state >= 4) // 1 раз за 4 импульса изменяем состояние передачи { sw34++; // Передача + up_state = 0; Serial.println(sw34); } if (down_state >= 4) { sw34--; // Передача - down_state = 0; Serial.println(sw34); } } }