|
| |||||||
|
Опубликовано 2015-04-04 22:51:49 автором Ruslan Подключение энкодера к микроконтроллеруВ этом уроке мы научимся работать с инкрементальным энкодером на микроконтролле.
В наш энкодер встроена еще и кнопка. С помощью одного лишь энкодера можно легко осуществлять управление практически любым девайсом! Например, представим себе листание деревовидного меню ( прокрутка - листания меню, нажатие - переход в подкатегорию меню).Энкодер - это цифровой датчик угла поворота. У нашего инкрементального энкодера 5 контактов. Три (Общий, А и В) отвечают за вращение и 2 - это встроенная кнопка. Сначала разберемся, как подключить энкодер к микроконтроллеру и как с него считывать данные. С Энкодера выходят два сигнала А и В, сдвинутых на 90 градусов по фазе.
Выводы A и B должны быть подтянуты к плюс питанию резистором в 1 кОм для избежания ложных срабатываний, а центральный - на землю.
Я, для надежности, подключил внешнюю подтяжку.
Существуют два распространенных алгоритма опроса энкодера:
Напишем простую программу которая будет опрашивать энкодер и выводить на дисплей переменную, которая будет меняться в зависимости от направления вращения энкодера Пример кода
#include <mega8.h>
#include <stdio.h>
#include <delay.h>
#include <alcd.h>
unsigned char lcd[32],enc=0,NewEncState,PrevEncState,z=0;
void MyscanEncoder()
{
unsigned char OUTB=PINB;
NewEncState = OUTB & 0b00011000; // наш энкодер подключен к выводам 4 и 5 порта B
NewEncState = NewEncState>>3; // делаем сдвиг на 3 для удобства
if (NewEncState!=PrevEncState) //проверяем, изменилось ли состояние на выходе энкодера
{
enc=(enc<<2) | NewEncState; //записываем состояние выводов в enc, предварительно сдвинув на 2, чтобы не затереть старые состояния
if (enc == 0b11100001) { enc=0; z++; } //проверяем, совпадает ли последовательность состояний выводов энкодера с поворотом вперед
else if (enc == 0b11010010) { enc=0; z--; }; //проверяем, совпадает ли последовательность состояний выводов энкодера с поворотом назад
PrevEncState = NewEncState; //новое состояние становится предыдущим
}
}
// таймер, в котором будем опрашивать наш энкодер
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
MyscanEncoder(); // опрос энкодера
}
void main(void)
{
// Input/Output Ports initialization
// Port B initialization
PORTB=0b00011000;
DDRB=0x00;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 500,000 kHz
TCCR0=0x01;
TCNT0=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;
// Alphanumeric LCD initialization
lcd_init(16);
// Global enable interrupts
#asm("sei")
while (1)
{
// формируем строку для вывода на дисплей
sprintf(lcd,"encoder= %i",z);
lcd_clear(); //чистим дисплей перед выводом
lcd_puts(lcd); // выводим строку на дисплей
delay_ms(200); // делаем задержку
}
}
Комментарии - (1)
Добавить комментарийДля отправки комментария вы должны авторизоваться. |
|||||||