diff --git a/Encoder.c b/Encoder.c new file mode 100644 index 0000000..f0b6c10 --- /dev/null +++ b/Encoder.c @@ -0,0 +1,74 @@ +#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); + } + } +} \ No newline at end of file