Страница 1 из 1
опрос энкодера
Добавлено: Ср мар 30, 2016 20:47:32
goodspeedmen
Какие используют алгоритмы с работой энкодера?
Я хочу использовать прерывание в канале A по высокому увовню INT0 input и также второй энкодер INT1 input по высокому уровню, проверка на совпадение в канала В, 1 1 = inc / 1 0 = dec. И заход в цикл ожидания изменения в канале B ""ограниченный количеством циклов цикла" - на практике слишком маленькое время, даже с отсчетом 2 байт" и выход из него по изменению на 0 канала А Но вот проблема, если первый энкодер останавливается в 1 прерывание в 2-го канала A не срабатывает находясь в цикле опроса канала B в первом энкодере... Хотя по идее должно
Re: опрос энкодера
Добавлено: Ср мар 30, 2016 23:25:42
Аlex
Проблема, по всей видимости, в программе. А экстрасенсы все уехали на
тНт 
Re: опрос энкодера
Добавлено: Чт мар 31, 2016 19:11:00
goodspeedmen
Я спрашивал о алгоритмах опроса энкодера и для примера привел тот который я придумал...
Re: опрос энкодера
Добавлено: Чт мар 31, 2016 19:28:37
Аlex
Я спрашивал о алгоритмах опроса энкодера
https://www.yandex.ru/yandsearch?clid=9 ... 59445507.1
У меня у одного поисковики работают ?

Re: опрос энкодера
Добавлено: Чт мар 31, 2016 20:05:23
goodspeedmen

В следующий раз буду сразу спрашивать у яндекса...
Re: опрос энкодера
Добавлено: Пт апр 01, 2016 00:33:14
Мikа
Вот мой код опроса энкодера:
Действие происходит при полном щелчке энкодера. То есть 4 изменения состояния.
Код: Выделить всё
//Encoder
unsigned char Encoder_State = 0;
signed char Encoder_Summ = 0;
unsigned char Encoder_NewState = 0;
Encoder();
void Encoder(void)
{
Encoder_NewState = PIND & 0x3; // Энкодер подключать к первым двум битам порта. То есть к младшим. То есть 0b000000XX.
if(Encoder_State != Encoder_NewState)
{
switch(Encoder_State)
{
case 2:
{
if(Encoder_NewState == 3) Encoder_Summ++;
if(Encoder_NewState == 0) Encoder_Summ--;
break;
}
case 0:
{
if(Encoder_NewState == 2) Encoder_Summ++;
if(Encoder_NewState == 1) Encoder_Summ--;
break;
}
case 1:
{
if(Encoder_NewState == 0) Encoder_Summ++;
if(Encoder_NewState == 3) Encoder_Summ--;
break;
}
case 3:
{
if(Encoder_NewState == 1) Encoder_Summ++;
if(Encoder_NewState == 2) Encoder_Summ--;
break;
}
}
if (Encoder_Summ == 4) // Увеличение значения числа
{
// Действие 1
Encoder_Summ = 0;
}
if (Encoder_Summ == (-4)) // Уменьшение значения числа
{
//Действие 2
Encoder_Summ = 0;
}
Encoder_State=Encoder_NewState;
// Здесь можно написать действие, которое выполнится в любом случае.
}
}
Re: опрос энкодера
Добавлено: Сб апр 02, 2016 11:00:46
goodspeedmen
Такой алгоритм подойдет для опроса трех энкодеров? Два из которых будут работать относительно на не больших скоростях а вот третий на большой и разрешение его 1000 импульсов.
Re: опрос энкодера
Добавлено: Сб апр 02, 2016 12:25:55
L.O.D
Мikа писал(а):Вот мой код опроса энкодера:
Что если заменить длинный switch простым массивом?
Код: Выделить всё
unsigned char EncTransIncs[4][4] = {
0, +1, -1, 0,
-1, 0, 0, +1,
+1, 0, 0, -1,
0, -1, +1, 0
};
...
Encoder_Summ += EncTransIncs[Encoder_NewState][Encoder_State];
...
}
Re: опрос энкодера
Добавлено: Сб апр 02, 2016 14:33:27
Мikа
goodspeedmen, этот код написан для энкодера у которого 4 состояния и который крутится рукой. Для работы на больших частотах и разрешениях надо проводить простые расчеты, которые покажут, хватит ли частоты работы МК на обработку такой кучи данных. И про дребезг не забудь) Ну в смысле не забудь с ним разделаться

Re: опрос энкодера
Добавлено: Вт апр 05, 2016 23:39:15
CATяра
INT0 и
INT1 оставьте для других более важных целей
Опрос энкодера пусть крутится по таймеру (в прерывании таймера), например
по переполнению TIM0_OVF
Я так делаю, например:
Код: Выделить всё
......
.....
....
.def Temp=R16
.def Temp1=R17
.def Temp2=R18
.def Temp3=R19
.def Temp4=R20
....
....
....
.dseg ;DSEG – это сегмент данных. В нем выделяется оперативная память.
ENCODERVAR: .byte 1 ;
....
......
...
; далее запускаем таймер с частотой 400 - 500 Гц и даём команду в прерывании таймера
RCALL ENCODERKEY
;===============
ENCODERKEY:
IN TEMP4,PINB ;ЧТИТАЕМ ПОРТ B 5,4 (выводы МК куда подключен энкодер)
LSR TEMP4 ;-> 4, 3
LSR TEMP4 ;-> 3, 2
LSR TEMP4 ;-> 2, 1
LSR TEMP4 ;-> 1, 0
ANDI TEMP4,0B00000011 ;ВЫДЕЛЯЕМ 1 И 0 БИТ (сместить биты в 1 и 0 биты!)
LDS TEMP,ENCODERVAR
ANDI TEMP,0B00000011
CP TEMP,TEMP4
BREQ NEXT_T2 ;ЕСЛИ ИЗМЕНЕНИЙ НЕТ, ТО ВЫХОД
LDS TEMP,ENCODERVAR ;b7 b6 b5 b4 b3 b2 b1 b0 => TEMP
LSL TEMP ;b6 b5 b4 b3 b2 b1 b0 0 => TEMP LEFT
LSL TEMP ;b5 b4 b3 b2 b1 b0 0 0 => TEMP LEFT
OR TEMP,TEMP4 ;b5 b4 b3 b2 b1 b0 E1 E0 => TEMP
STS ENCODERVAR,TEMP ;
LDS TEMP,ENCODERVAR
ANDI TEMP,0B11111111
CPI TEMP,0B11010010 ;КОНСТАНТА (не менять)
BRNE NEXT_T1
RCALL ВЛЕВО ;LEFT <----- свою процедуру обработки события
RJMP NEXT_T2
NEXT_T1:
CPI TEMP,0B11100001 ;КОНСТАНТА (не менять)
BRNE NEXT_T2
RCALL ВПРАВО ;RIGHT <----- свою процедуру обработки события
;RJMP NEXT_T2
NEXT_T2:
RET
;--------------------------------------------------------------------------------------------------