Задача
Определять направление вращения ручки и вести счёт.
Микроконтроллер: ATmega8, кварц 4 МГц. Среда: Atmel Studio / avra (или avra / Atmel Studio). Как настроить среду и прошить контроллер — в статье программирование AVR.
Что понадобится
- ATmega8
- кварц 8 МГц + 2×22 пФ
- механический энкодер с кнопкой
- 8 светодиодов для индикации
- конденсаторы 100 нФ на каналы (аппаратный антидребезг)
Схема подключения
| Вывод | Подключение |
|---|---|
| PD2 | канал A энкодера |
| PD3 | канал B энкодера |
| Общий вывод | на GND |
| PB0…PB7 | индикация значения счётчика |
Алгоритм
- Включить внутренние подтяжки на обоих каналах.
- Следить за изменением состояния канала A.
- В момент спада на A прочитать состояние канала B.
- Единица на 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.