Страница 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
Проблема, по всей видимости, в программе. А экстрасенсы все уехали на тНт :dont_know:

Re: опрос энкодера

Добавлено: Чт мар 31, 2016 19:11:00
goodspeedmen
Я спрашивал о алгоритмах опроса энкодера и для примера привел тот который я придумал...

Re: опрос энкодера

Добавлено: Чт мар 31, 2016 19:28:37
Аlex
Я спрашивал о алгоритмах опроса энкодера
https://www.yandex.ru/yandsearch?clid=9 ... 59445507.1
У меня у одного поисковики работают ? :facepalm:

Re: опрос энкодера

Добавлено: Чт мар 31, 2016 20:05:23
goodspeedmen
:roll: В следующий раз буду сразу спрашивать у яндекса...

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
;--------------------------------------------------------------------------------------------------