Управление энкодером на 400 шагов


• О проекте
• Обратная связь
• Полезные ссылки
• Полезные программы
• Друзья сайта


Последние комментарии

Васил: Загрузчик для AVR микроконтроллеров
Ошибка #ifdef ST...

Алексей: Загрузчик для AVR микроконтроллеров
Да, есть такая фи...




           

Библиотека для AVR





AXLIB Генератор





Помощь сайту


   
				

Управление энкодером на 400 шагов

	
	
	

Дата: 22 Июля 2015. Автор: Алексей

	
	
Привет всем! Помниться я уже разок писал про инкрементальный энкодер. Но суть данной статьи сводится к подключению энкодера на 400 шагов. Собственно, а какая разница. А разница вот в чем. Если взять программу которую я описывал в прошлой статье про энкодер, то она с этим работать не будет. Вся затыка уперлась в скорости опрашивания данных с энкодера. Представьте, 400 импульсов за оборот. Если крутануть со всей дури, то можно разогнать до 180 оборотов в минуту. Если посчитать 180/60 то получим 3 оборота в секунду. А теперь 3*400 то получим 1200 импульсов. А мы хотим еще вывести на ЖК, а у ЖК обязательно есть 2 мс задержки. Короче пропусков дофига. А че делать? А есть у нас в МК внешнее прерывание INT0. Данное прерывание стоит первым после сброса. А это значит что все другие прерывания имеют нисший приоритет. То есть сделаем просто, повесим вход энкодера на прерывание и по нему определим что он сдвинулся, а в обработчике узнаем куда. Для теста я решил ограничить шаги от 0 до 400 и выводить их на ЖК дисплей 16х2. Теперь немного о железе.

Энкодер

Друзья из Китая довольно таки не корректно перевели цветовую палитру проводов, что это чуть ли не привело к похоронам энкодера. Но всемогущий гугл оказался круче Китайцев. Были проведены сравнения закорючек на энкодере с гугл переводчиком что дало новые данные по подключению.

Цветовая палитра энкодера

Когда все встало на свои места, была собрана следующая схема.

Схема подключения энкодера

Посмотреть по крупнее.
Что собственно мы видим на схеме. МК Mega8A подключени по классической схеме, здесь я ничего не мудрил. ЖК дисплей подключен к порту D за небольшим моментом. Стробирование ЖК дисплея отдано третьему разряду порта С. Это сделано из-за того, что на порту D пин PD2 является входом внешнего прерывания INT0. Можно было конечно перейти на PD1, но у меня отладочная плата уже разведена и не позволяет что-то менять, ЖК прикручен намертво. Резистор R1 нужен для регулировки контрастности, так что подбирайте для своего дисплея сами по месту. Частота кварца тоже принята из расчета припаянного на глухо. На работу программы не влияет. А вот теперь про энкодер. Красный провод вешаем на 5 вольт. Да кстати я его разобрал и нашел внутри линейный стабилизатор 78M05. При подаче на него 5 вольт, на выходе 3,5 вольта. Я так и не понял почему диапазон питания разрешен от 5 вольт до 24. Я бы начал он 9 до 24. Но это не важно. 3,5 вольт оказалось достаточно для принятия МК импульсов. Черный провод и экран вешаем на общий провод. Белый оказался каналом В, но я его все таки оставил на ножке РС0. Мне было проще в программе поменять значения чем перетыкать провода. Зеленый, канал А вешаем на РС1. Как и для любого энкодера оба канала подтягиваем резисторами на 10К к плюсу. А вот дальше самое интересное. Для того чтобы внешнее прерывание могло контролировать оба канала одновременно, необходимо от каждого канала пробросить на ножку прерывание быстродействующий диод. Катодом к каналу, а анодом к INT0. Это даст нам возможность не мешая друг другу получить изменения на каналах. Логика проста, если на обоих каналах присутствует единица, то диоды не дадут выйти ей на наружу. Но как только на одном из каналов появится ноль, то его перехватит прерывание, а из-за диодов этот ноль не перескочит на другой канал. Правда есть косяк. Когда на каналах две единицы, то INT0 получается висит в воздухе и может наловит помех из вне. Чтобы этого не случилось подтягиваем его к плюсу резистором на 10К. Он на схеме обозначен как R4. Теперь переходим к программированию.
Перед обработчиком прерывания пишем.

#define F_CPU 7372800UL	// Частота кварца
#include <vr/io.h>
#include <stdio.h>

#include <axlib/main_init.h>
#include <axlib/lcd.h>
#include <axlib/timers.h>

BYTE str[20]; // Буфер для вывода на ЖК

volatile BYTE input = 0;  // Текущеее значения энкодера
volatile BYTE buf = 0;	  // Прошлое значения энкодера
volatile WORD data = 0;   // Количество шагов

Здесь мы подключили необходимые библиотеки и создали необходимые переменные. Далее пишем обработчик прерывания для INT0.

ISR(INT0_vect)
{
	input = (PINC & 0x03); 

	switch(buf) 
	{
		case 0:
		{
			if(input == 2) data++;
			if(input == 3) data--; 
			break;
		}
		case 1:
		{
			if(input == 0) data++;
			if(input == 1) data--;  
			break;
		}
		case 2:
		{
			if(input == 3) data++;
			if(input == 0) data--;  
			break;
		}
		case 3:
		{
			if(input == 1) data++;
			if(input == 2) data--; 
			break;
		}
		buf = input;
}

Собственно здесь ничего нового. При входе в обработчик берем текущее значение из порта и зная предыдущее значение, выбираем куда нам считать опираясь на текущее значение. Отличие от предыдущей программы заключается в том что здесь мы не сравниваем предыдущее значение с текущем. Это связано с тем что мы попали в обработчик прерывания при изменении на ножках энкодера, а это априори говорит о том что текущее значение разнится с предыдущем. Плюс в сторону прерывания)))

int main(void)
{
	MCUCR |= (1 << ISC00); // Прерывания при любых изменениях на ножке
	GICR |= (1 << INT0); // Разрешить прерывание от INT0
	
	DDRC = 0x00; // Порт С на вход
	
	timers_init(); // Проинициализировали тамер Т2
	lcd_init(0); // Проинициализировали ЖК дисплей
	
	timer(TIMER_0, 1, ON); // Будем выводить на дисплей каждую 1мс

Этот кусок кода отвечает за инициализацию периферии. Первые две строки разрешают внешнее прерывание по любому изменению на ножке INT0. Далее настраиваем порт С на вход. Следующая строка инициализирует таймеры. Потом сам ЖК дисплей и последняя строчка создает нулевой таймер который будет обрабатываться каждую миллисекунду.

    while(1)
    {
		if(data > 400) data = 400;
		if(data < 0) data = 0;
		
		if(T0_START)
		{
			sprintf(str, "STEP %d     ", data);
			lcd_gotoxy(0,0);
			lcd_str_out(str);
		}
    }

А это бесконечный цикл основной программы. Здесь задаем граничные значения нуля и четырехсот. И пишем обработчик для таймера. В нем всего лишь форматируем строку и выводим количество шагов на ЖК дисплей. Вот и вся программа.
Если все таки у кого-то возникнут вопросы, пишите.
Проект для AtmelStudio 6.2 (Требует обязательного наличия библиотеки axlib)
И как всегда видео всего этого безобразия

JW Player goes here



Андрей    02.12.15 12:25

А зачем такой энкодер? Куда его применять?

Алексей    03.12.15 10:33

Для более точной обратной связи.

st    10.07.16 00:38

Добрый день! А можно пример использования энкодера без задействования прерывания. Заранее спасибо!

Алексей    10.07.16 19:17





Чтобы вставить ссылку используйте форму вида[url]http://www.адрес.ru[/url][text]текст ссылки[/text]
Чтобы вставить код используйте форму вида[code]код[/code]

Имя:   





  








Вверх


Рейтинг@Mail.ru Яндекс.Метрика