4_Ust-vo_poluchenia_velichi.../Encoder.c

83 lines
3.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Включаем библиотеку для работы с портами ввода-вывода микроконтроллера AVR.
#include <avr/io.h>
// Определяем частоту процессора микроконтроллера в 1 МГц.
#define F_CPU 1000000UL
// Определяем бит в регистре PIND для сигнала с клока энкодера.
#define PIND_CLK 0b00010000
// Определяем бит в регистре PIND для сигнала с DT энкодера.
#define PIND_DT 0b01000000
// Определяем сдвиг для получения значения сигнала с клока энкодера.
#define PIND_SHIFT_1 (4)
// Определяем сдвиг для получения значения сигнала с DT энкодера.
#define PIND_SHIFT_2 (5)
volatile uint8_t next_state, prev_state, state, state_1;
int sw34, PIND_MASK, PIN_CLK_2, PIN_DT_2;
void read_encoder_state()
{
// Устанавливаем начальные значения переменных равное 0
PIN_CLK_2 = 0;
PIN_DT_2 = 0;
PIND_MASK = 0;
// Значение переменной PIN_CLK_2 равно результату побитовой операции "И" между PIND и PIND_CLK с последующим сдвигом на PIND_SHIFT_1 бит вправо
PIN_CLK_2 = (PIND & PIND_CLK) >> PIND_SHIFT_1;
// Значение переменной PIN_DT_2 равно результату побитовой операции "И" между PIND и PIND_DT с последующим сдвигом на PIND_SHIFT_2 бит вправо
PIN_DT_2 = (PIND & PIND_DT) >> PIND_SHIFT_2;
// Значение переменной PIND_MASK равно сумме значений переменных PIN_CLK_2 и PIN_DT_2
PIND_MASK = (PIN_CLK_2 + PIN_DT_2);
// Определяем и сохраняем следующее состояние энкодера, применяя побитовое "И" между PIND и PIND_MASK
next_state = (PIND & PIND_MASK);
// Проверяем, изменилось ли состояние энкодера
if (next_state != prev_state)
{
switch (next_state)
{
case 0: // CW
if (prev_state == 3) state++;
else if (prev_state == 0) state--;
break;
case 1: // CCW
if (prev_state == 1) state++;
else if (prev_state == 2) state--;
break;
case 2: // CW
if (prev_state == 1) state++;
else if (prev_state == 3) state--;
break;
case 3: // CCW
if (prev_state == 2) state++;
else if (prev_state == 0) state--;
break;
}
// Устанавливаем значение prev_state равным текущему состоянию энкодера
prev_state = next_state;
}
}
void setup()
{
// Инициализация последовательного порта
Serial.begin(9600);
// Настройка портов ввода-вывода
DDRD = 0x00;
PORTD = (PIND_CLK + PIND_DT);
}
void loop()
{
// Читаем состояние энкодера
read_encoder_state();
// Если состояние энкодера изменилось, выводим его в последовательный порт
if (state != sw34)
{
Serial.println(state);
sw34 = state;
}
}