Подключение энкодера к микроконтроллеру.

Подключение энкодера к микроконтроллеру

Энкодеры… Эти крутилки в современном мире вставляют куда угодно. Конечно удобно не нажимать на кнопки выставляя нужное значение, а немного покрутить ручку и смотреть как циферки сами бегут в нужную сторону. Удобная, элегантная и практичная вещь. Вот я и хочу рассказать о том, как прикрутить это чудо к микроконтроллеру. Собственно без микроконтроллера энкодер это простой кусок высокотехнологичного пластика. Итак…


О том, как работает энкодер, можно поискать в интернете много информации с картинками. Но если говорить коротко о его работе, то у энкодера есть два стабильных положения. В первом оба контакта замкнуты (см. рис. 1) и тогда на обоих входных ножках контроллера будет единица (напряжение питания) и во втором положении оба контакта разомкнуты (см. рис. 2) и на ножках контроллера будет ноль. При повороте ручки, энкодер выходит из стабильного положения, при котором необходимо определить, какой контакт вышел первым, и какое стабильное положение до этого было.

Например. Энкодер находится в замкнутом стабильном положении, и мы начинаем поворачивать ручку влево. «Левый» контакт первым размыкается, и мы это фиксируем. Если энкодер был в разомкнутом стабильном положении, то при повороте ручки влево, первым замкнется «правый» контакт. Теперь нам остается только посмотреть из какого положения какой контакт срабатывает первым.

Вот листинг подпрограммы обработки работы энкодера.

unsigned char encoder (void){
	//Константы
		//Настраевыемые константы
			#define PIN_LIFT 	PINB.7		//пин энкодера лево
			#define PIN_RIGHR 	PINB.6 		//пин энкодера право		
			#define STOP		0 		//Возвращаемое число при простое		   		
			#define RIGHT     	1      		//Возвращаемое число при повороте вправо		   	
			#define LEFT    	2      		//Возвращаемое число при повороте влево
		//внутренние константы
			#define POSITION_1	1		//Флаг позиции 1	
			#define POSITION_2	2		//Флаг позиции 2
			#define POSITION_OVER	0		//Флаг позиции неопределен
	//Переменные
		unsigned char numer_out = STOP;                    	//возвращаемое значение
		static unsigned char flag_position = POSITION_OVER;	//Флаг позиции энкодера 
			
	//Тело программы
		switch (flag_position) {			//Определение позиции смещения	
			case POSITION_1 :{
				if ((PIN_LIFT) && !(PIN_RIGHR))numer_out = LEFT; 
				if (!(PIN_LIFT) && (PIN_RIGHR))numer_out = RIGHT;
			}
				break;
			case POSITION_2 :{
				if (!(PIN_LIFT) && (PIN_RIGHR))numer_out = LEFT;
				if ((PIN_LIFT) && !(PIN_RIGHR))numer_out = RIGHT;
			}
				break;
		};
		if (numer_out != STOP) flag_position = POSITION_OVER;	//Установка флага неопределенной позиции
		else {
			if ((PIN_LIFT) && (PIN_RIGHR)) flag_position = POSITION_1;	//Установка флага позиции 1
			if (!(PIN_LIFT) && !(PIN_RIGHR))flag_position = POSITION_2;	//Установка флага позиции 2
			}
		return(numer_out);
} 

Вначале необходимо настроить работу подпрограммы, указав ей, какие два пина микроконтроллера были отведены под энкодер. Само собой эти пины должны быть инициализированы как входные. Также необходимо определить числа, которые будет возвращать подпрограмма в случае:
- Простоя (по умолчанию – 0);
- Поворота вправо (по умолчанию – 1).
- Поворота влево (по умолчанию – 2);
На этом настройка закончена.
Далее программа инициализирует две переменные. Одна из них это возвращаемое значение, а вот вторая переменная запоминает позицию энкодера. При первом проходе флаг позиции установлен как «неопределен». Затем происходит выполнение программы. Переключатель (switch) смотрит, какая позиция была установлена и в зависимости от этого происходит проверка данных с энкодера. Затем строка
if (numer_out != STOP) flag_position = POSITION_OVER;
осуществляет проверку был ли поворот энкодера или нет и в случае если был (возвращаемое число не STOP), то происходит установка флага позиции в POSITION_OVER (неопределенно). Эта строка очень важна для работы подпрограммы т.к. выставив флаг неопределенной позиции, программа пропускает все проверки данных с энкодера, пока тот опять не вернется в одну из стабильных позиций. Далее если позиция не определена подпрограмма ожидает, когда энкодер войдет в одну из стабильных позиций и как только на обоих пинах появятся единицы
if ((PIN_LIFT) && (PIN_RIGHR)) flag_position = POSITION_1;
флаг установится в позицию 1. Или в позицию 2 если на пинах будут нули
if (!(PIN_LIFT) && !(PIN_RIGHR))flag_position = POSITION_2;

Вернемся опять к переключателю (switch) который в случае позиции 1 смотрит положение данных на пинах и если на «левом» пине появляется (1), а на «правом» (0), то поворот идентифицируется как поворот влево. Если на оборот, то вправо. Противоположный выбор происходит если стабильная позиция была позиция 2.
Вот так и происходит работа энкодера.

Конечно я не утверждаю, что мой код единственно верный. Запустить энкодер можно многими путями. Например, сделать обработчик прерывания или написать более сложную программу, полностью исключающую дребезг контактов энкодера. Но, на мой взгляд, все это только будет усложнять программу. Так, что осваивайте новый вид органов управления вашими устройствами.

Еще немного о подключении энкодера можно почитать здесь и здесь.

А на сегодня всё. Удачи.

25.11.15


Если вдруг найдете в статье неточности или заблуждения. Напишите мне об этом. Я подправлю.

Приложение:
Скачать подпрограмму работы энкодера