Чт июл 26, 2012 19:29:08
#define DECODER_BUTTON_PLUS_IN PINB.2
#define DECODER_BUTTON_MINUS_IN PINB.1
#define DEC_0 0
#define DEC_STEP 1
#define DEC_FIN 2
PrintLineText, PrintLineNumber - вивод текста на екраy типа wh1602
char ShowDialogInt(const char* sCaption, int* iRes, int iMin, int iMax)
{
int i = 0, iStep = 0;
char iCurDec = DEC_0;
PrintLineText(0, sCaption);
PrintLineNumber(1, *iRes);
while(1)
{
if(0 == DECODER_BUTTON_PLUS_IN && 0 == DECODER_BUTTON_MINUS_IN)
{
if(DEC_FIN == iCurDec)
{
(*iRes) = (*iRes) + (int)iStep;
if((*iRes) < iMin) (*iRes) = iMin;
if((*iRes) > iMax) (*iRes) = iMax;
PrintLineNumber(1, *iRes);
iCurDec = DEC_0;
}
}
else if(1 == DECODER_BUTTON_PLUS_IN && 0 == DECODER_BUTTON_MINUS_IN)
{
if(DEC_0 == iCurDec)
{
iCurDec = DEC_STEP;
iStep = -1;
}
}
else if(0 == DECODER_BUTTON_PLUS_IN && 1 == DECODER_BUTTON_MINUS_IN)
{
if(DEC_0 == iCurDec)
{
iCurDec = DEC_STEP;
iStep = 1;
}
}
else
{
if(DEC_STEP == iCurDec)
{
iCurDec = DEC_FIN;
}
}
}
}
Чт июл 26, 2012 19:44:40
Чт июл 26, 2012 19:54:38
hybroid писал(а):Картинка маленькая
Чт июл 26, 2012 22:00:17
Пт июл 27, 2012 07:05:58
Пт июл 27, 2012 09:04:38
Действительно работает? Я бегло просмотрел, показалось, что тут не все гладко:oleg110592 писал(а):Использовал года 2 назад код ув. Леонида Ивановича с обсуждения на сахаре, вроде этот: http://caxapa.ru/207402.html
все работало
//---------- Обработка энкодера: ----------
void Encoder_Exe(void)
{
char EncCur = 0;
if(!Pin_ENC_F1) EncCur = StateA; //опрос фазы 1 энкодера
if(!Pin_ENC_F2) EncCur |= StateB; //опрос фазы 2 энкодера
if(EncCur != EncPrev) //если состояние изменилось,
{
if(EncPrev == StateAB && //если предыдущее состояние StateAB
EncCur != EncPrevPrev ) //и текущее и пред-предыдущее не равны,
{
if(EncCur == StateB) //если текущее состояние StateB,
Msg = ENC_UP; //шаг вверх
else //иначе
Msg = ENC_DN; //шаг вниз
}
EncPrevPrev = EncPrev; //сохранение пред-предыдущего состояния
EncPrev = EncCur; //сохранение предыдущего состояния
}
}
Пт июл 27, 2012 09:12:26
Пт июл 27, 2012 09:33:16
pierro писал(а):hybroid писал(а):Картинка маленькая
за картинку - извините - исправил
Программным - это ставит задержки? (а-ля delay_ms(5))
Пт июл 27, 2012 09:38:43
Пт июл 27, 2012 09:45:22
Спасибо, посмотрел. Этот вариант понравился гораздо больше - аккуратная автоматная реализация, явно не боящаяся дребезга и дрожания диска.s_black писал(а):Здесь посмотрите
Пт июл 27, 2012 10:27:53
Goldsmith писал(а):Насколько могу судить, при смене состояний AB -> B -> AB -> B ... диск фактически стоит на месте, а программа неуклонно шагает вверх. Поправьте меня, пожалуйста, если я ошибаюсь.
//----------
//Модуль поддержки энкодера
//Энкодер подключается к портам ENC_F1 (фаза 1) и ENC_F2 (фаза 2).
//Для подавления дребезга используется анализ двух последовательных
//состояний. Это позволяет обойтись без временных задержек.
//Функция Encoder_Init() должна вызываться один раз в начале программы.
//Функция Encoder_Exe() должна вызываться в основном цикле.
//При повороте энкодера на шаг вправо или влево вызываются функции
//To_Do_Step_Up() и To_Do_Step_Dn() соответственно.
//----------
#include "Main.h"
#include "Encoder.h"
//---------- Константы: ----------
#define ENC_F1 (1 << PC0) //фаза энкодера F2
#define ENC_F2 (1 << PC1) //фаза энкодера F1
#define Pin_ENC_F1 (PINC & ENC_F1)
#define Pin_ENC_F2 (PINC & ENC_F2)
enum { State0, StateA, StateB, StateAB }; //состояния энкодера
//---------- Переменные: ----------
static char EncPrev; //предыдущее состояние энкодера
static char EncPrevPrev; //пред-предыдущее состояние энкодера
//---------- Инициализация энкодера: ----------
void Encoder_Init(void)
{
DDRC &= ~(ENC_F1 | ENC_F2); //настройка портов на ввод
PORTC |= ENC_F1 | ENC_F2; //включение подтягивающих резисторов
EncPrev = State0; //инициализация предыдущего состояния
EncPrevPrev = State0; //инициализация пред-предыдущего состояния
}
//---------- Обработка энкодера: ----------
void Encoder_Exe(void)
{
char EncCur = 0;
if(!Pin_ENC_F1) EncCur = StateA; //опрос фазы 1 энкодера
if(!Pin_ENC_F2) EncCur |= StateB; //опрос фазы 2 энкодера
if(EncCur != EncPrev) //если состояние изменилось,
{
if(EncPrev == StateAB && //если предыдущее состояние StateAB
EncCur != EncPrevPrev ) //и текущее и пред-предыдущее не равны,
{
if(EncCur == StateB) //если текущее состояние StateB,
To_Do_Step_Up(); //шаг вверх
else //иначе
To_Do_Step_Dn(); //шаг вниз
}
EncPrevPrev = EncPrev; //сохранение пред-предыдущего состояния
EncPrev = EncCur; //сохранение предыдущего состояния
}
}
//----------
Пт июл 27, 2012 11:19:38
Точно, прошу прощения. Слишком быстро просматривал текст.Леонид Иванович писал(а):Ничего подобного происходить не будет. Для этой ситуации есть проверка EncCur != EncPrevPrev.
Вс июл 29, 2012 13:03:29
Вс июл 29, 2012 17:53:27
Ср янв 15, 2014 02:03:42
Ср янв 15, 2014 07:38:45
// каждые 20..30 мсек
old_key= key;
key= PINX.Y;
if(old_key && !key) push= 1; // момент нажатия
if(!old_key && key) pop= 1; // момент отпускания
if(old_key && key) NotPressed= 1; // не нажата
if(!old_key && !key) Pressed= 1; // удерживается нажатой
Ср янв 15, 2014 08:05:44
Ср янв 15, 2014 08:11:57
pyzhman писал(а):Я делаю так:
blackx писал(а):Суть в том, чтобы после первого сигнала о нажатии заблокировать кнопку на короткое время
Ср янв 15, 2014 08:35:41
Ср янв 15, 2014 08:41:06
SmarTrunk писал(а):...не считая тем по дребезгу энкодеров (а это отдельная история)