AFON // радиотехник affonya@mail.ru
← Проекты на AVR

Проект 48. Энкодер: чтение вращения

Ручка энкодера даёт два сигнала со сдвигом фаз: по их взаимному состоянию определяется направление вращения. Основа современных панелей управления.

Задача

Определять направление вращения ручки и вести счёт.

Микроконтроллер: ATmega8, кварц 4 МГц. Среда: Atmel Studio / avra (или avra / Atmel Studio). Как настроить среду и прошить контроллер — в статье программирование AVR.

Что понадобится

  • ATmega8
  • кварц 8 МГц + 2×22 пФ
  • механический энкодер с кнопкой
  • 8 светодиодов для индикации
  • конденсаторы 100 нФ на каналы (аппаратный антидребезг)

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

ВыводПодключение
PD2канал A энкодера
PD3канал B энкодера
Общий выводна GND
PB0…PB7индикация значения счётчика

Алгоритм

  1. Включить внутренние подтяжки на обоих каналах.
  2. Следить за изменением состояния канала A.
  3. В момент спада на A прочитать состояние канала B.
  4. Единица на B означает одно направление, ноль — противоположное.

Листинг на ассемблере

Код проверен ассемблером и собирается без ошибок. Скачать: a48.asm · a48.hex (готовая прошивка).

;=======================================================
; Проект 48. Энкодер: чтение вращения
; ATmega8, 8 МГц. Выводы энкодера A — PD2, B — PD3
; Значение счётчика (0..255) выводится на светодиоды PORTB
;=======================================================
.include "m8def.inc"

.def tmp   = r16
.def value = r17
.def prev  = r18
.def cur   = r19

.cseg
.org 0x0000
        rjmp    RESET

RESET:
        ldi     tmp, low(RAMEND)
        out     SPL, tmp
        ldi     tmp, high(RAMEND)
        out     SPH, tmp

        ldi     tmp, 0xFF
        out     DDRB, tmp
        cbi     DDRD, 2                 ; A — вход
        cbi     DDRD, 3                 ; B — вход
        sbi     PORTD, 2                ; подтяжки
        sbi     PORTD, 3
        clr     value
        in      prev, PIND
        andi    prev, 0b00000100

MAIN:
        in      cur, PIND
        andi    cur, 0b00000100         ; следим за каналом A
        cp      cur, prev
        breq    MAIN                    ; состояние не изменилось
        mov     prev, cur

        cpi     cur, 0                  ; интересует только спад на A
        brne    MAIN

        rcall   Delay2ms                ; подавление дребезга контактов
        sbic    PIND, 3                 ; смотрим канал B
        rjmp    TURN_LEFT
        inc     value                   ; B в нуле — вращение вправо
        rjmp    SHOW
TURN_LEFT:
        dec     value                   ; B в единице — вращение влево
SHOW:
        out     PORTB, value
        rjmp    MAIN

Delay2ms:
        ldi     r20, 26
V1:     ldi     r21, 255
V2:     dec     r21
        brne    V2
        dec     r20
        brne    V1
        ret

Пояснения

  • Направление определяется именно взаимным сдвигом каналов: при вращении в разные стороны один из сигналов опережает другой.
  • Механические энкодеры сильно дребезжат, поэтому кроме программной паузы полезны конденсаторы 100 нФ прямо на выводах.
  • Для быстрого вращения опрос в главном цикле начинает пропускать шаги — тогда каналы заводят на внешние прерывания.

Что дальше

Разобравшись с этим проектом, переходите к следующему в разделе проекты на PIC. Справочник по архитектуре и периферии контроллеров — на странице микроконтроллеры AVR.