//----------------------------------------------------------------------------
//Модуль поддержки энкодера
//Энкодер подключается к портам ENC_F1 (фаза 1) и ENC_F2 (фаза 2).
//Функция Enc_Scan() вызывается в основном цикле.
//Результат обработки энкодера передается в модуль
//обработки клавиатуры через функцию Keyboard_SetCode().
//----------------------------------------------------------------------------
#include <Main.h>
#include <Encoder.h>
#include <Keyboard.h>
//----------------------------- Константы: -----------------------------------
#define ENCDEB 300 //encoder debounce delay, uS
#define EF1 0x01 //encoder F1 mask
#define EF2 0x02 //encoder F2 mask
enum { ES0, ES1, ES3, ES2 }; //encoder sequential states
//----------------------------- Переменные: ----------------------------------
static char EncPre; //предыдущее состояние энкодера
static char EncPpe; //пред-предыдущее состояние энкодера
//-------------------------- Прототипы функций: ------------------------------
char Enc_Scan(void); //сканирование энкодера
//----------------------- Инициализация энкодера: ----------------------------
void Encoder_Init(void)
{
EncPre = Enc_Scan(); //сканируем энкодер и запоминаем состояние
EncPpe = EncPre; //запоминаем пред-предыдущее состояние
}
//------------------------ Сканирование энкодера: ----------------------------
char Enc_Scan(void)
{
char n = 0;
if(Pin_ENC_F1) n |= EF1; //проверка линии F1
if(Pin_ENC_F2) n |= EF2; //проверка линии F2
return(n);
}
//-------------------------- Обработка энкодера: -----------------------------
void Encoder_Exe(void)
{
char EncTmp = Enc_Scan(); //сканируем энкодер и запоминаем результат
if(EncTmp == EncPre) return; //если нет изменений, выход
Delay_us(ENCDEB); //антидребезговая задержка для энкодера
char EncNew = Enc_Scan(); //сканируем энкодер еще раз
if(EncNew != EncTmp) return; //дребезг не закончился, выход
EncTmp = EncPpe; //пред-предыдущее состояние
EncPpe = EncPre; //предыдущее состояние
EncPre = EncNew; //новое состояние
if(EncNew == ES2 && EncPpe == ES1 && EncTmp == ES0)
{ Keyboard_SetCode(ENC_DN); return; } //вращение против часовой стрелки
if(EncNew == ES2 && EncPpe == ES3 && EncTmp == ES0)
{ Keyboard_SetCode(ENC_UP); return; } //вращение по часовой стрелке
}
//----------------------------------------------------------------------------