Управляем светодиодами с помощью кнопок

В прошлой части мы разобрали примеры инициализации МК и создали простую программу. Сейчас немного доработаем программу, задействуем порты ввода, разберем несколько примеров обработки цикла опроса кнопки и применим простую антидребезговую защиту.
Прежде чем начать обращаться с портом и считывать с него данные, необходимо настроить данный вывод МК на вход. При этом стоить помнить, что на выходе выбранного порта установиться логическая единица.
Посмотрев на прошлую программу, можно найти строку настройки порта В на выход:
ser temp ; настраиваем все выводы порта В на выход
out DDRB, temp ;
Для простоты мы оставим PORTB в таком состоянии и проведем настройки порта D.
ldi temp,0b00000011
out PORTD,temp
В данном примере мы настроили выводы PD0 и PD1 на вход.
С настройкой определились, теперь необходимо разобрать простой пример обработчика кнопки. Подключим к выводу PD0 обычную кнопку, которая будет замыкаться на массу.

1

Вспомним наш цикл main:
main:
sbi portb,5; устанавливаем логическую “1” в PORTB5
rcall delay ;вызываем подпрограмму задержки
cbi portb,5; устанавливаем логический “0” в PORTB5
rcall delay
rjmp main
Здесь обычное переключение порта с логического состояния«0» в «1». Доработаем цикл, чтобы мигание включилось после нажатия на кнопку, подключенную к PD0.
main:
sbic PIND,0
rjmp main
sbi portb,5; устанавливаем логическую “1” в PORTB5
rcall delay ;вызываем подпрограмму задержки
cbi portb,5; устанавливаем логический “0” в PORTB5
rcall delay
rjmp main
Как видно, добавилась строка «sbic PIND,0» и дополнительная метка перехода «rjmp main». Командой «sbic» мы проверяем логическое состояние порта ввода. Если кнопка нажата и на порте установился логический «0», то пропускается следующая строка «rjmp main» и программа переходит к «sbi portb,5». После того, как программа дойдет до «cbi portb,5» и «rcall delay», произойдет возврат на начальную метку «main:». Снова попадаем на цикл опроса порта ввода. Если на сей раз кнопка не будет нажата, на выводе PD0 установиться логическая «1» и цикл замкнется на опросе порта.
Стоить отметить, что такая программа очень простая и годится только для компьютерного моделирования. В реальности из-за переходного процесса в коммутации контактов возникнет дребезг сигнала, который необходимо подавлять.
Простейшим способом для фильтрации сигнала от дребезга является применение задержки опроса порта ввода. Таким образом, мы минимизируем влияние переходных процессов на выполнение нашей программы. Для этого достаточно будет перед строкой «sbic PIND,0» вставить подпрограмму задержки «rcall delay». На рисунке ниже, можно посмотреть выполнение нашей программы.

2

К каналу А подключен вход PD0, а к каналу В подключен выход PB5. Как видно, цикл мигания сработал несколько раз из-за долгого удержания кнопки.
Так как временной цикл переключения порта, в данном примере, достаточно маленький, около 100мс, то для исключения лишний срабатываний можно доработать программу, отследив задний фронт сигнала.
Для этого нужно будет добавить всего несколько строк в цикл «main».
main:
rcall delay
sbic PIND,0 ;Отслеживаем нажатие кнопки
rjmp main
otpuskaem:
rcall delay ;задержка
sbis PIND,0 ;Отслеживаем отпускание кнопки
rjmp otpuskaem ;

sbi portb,5; устанавливаем логическую “1” в PORTB5
rcall delay ;вызываем подпрограмму задержки
cbi portb,5; устанавливаем логический “0” в PORTB5
rcall delay
rjmp main
Как видно появился дополнительный небольшой цикл отслеживания отпускания кнопки «otpuskaem».
Посмотрим на осциллограмму.

3

По каналу А видно, что кнопка удерживалась около 1400 мс, при этом не было ни одного срабатывания на выводе PB5. Как только фронт сигнала на выводе PD0 спал, сразу же произошло срабатывание порта PB5.
С помощью такого простого примера обработки входных сигналов, можно с легкостью избавиться от самых больших дребезгов при коммутации. Необходимо лишь будет подстроить временные задержки в подпрограмме «delay», либо же организовать отдельную подпрограмму по подобному принципу.
Допишем несколько строк и сделаем простейшую бегущую строку.
Код полной программы бегущей строки:
.device Attiny2313 ; указываем тип устройства
.include “tn2313def.inc” ; подключаем файл директив МК ATtiny2313
.def temp = r16 ; задаем имя нашему регистру общего назначения
.org 0x0000 ; начало программы с 0 адреса
ldi temp,ramend ; грузим значение ramend в регистр temp
out $3d, temp ;
ser temp ; настраиваем все выводы порта В на выход
out DDRB, temp ; порт на выход
ldi temp,0b00000011
out PORTD,temp

ldi r22,1 ; загружаем в регістр r22 константу 1
out PORTB,r22 ; значение выводим в PORTB

main:
rcall delay
sbic PIND,0 ;Отслеживаем нажатие кнопки
rjmp main
otpuskaem:
rcall delay ;задержка
sbis PIND,0 ;Отслеживаем отпускание кнопки
rjmp otpuskaem ;
rol r22 ;сдвиг влево
out PORTB,r22 ; значение выводим в PORTB
rjmp main
delay:
clr r20
clr r21
d_1:
inc r20
cpi r20,200
brne d_1
d_2:
inc r21
cpi r21,50
brne d_1
ret
Программу можно компилировать и проверять ее в Proteus.
На рисунках ниже видны переключения светодиодов после каждого нажатия на кнопку.

4

5

6

Итак мы разобрали примеры простейшего цикла обработки кнопок, применили защиту от дребезга контактов, написали простую программу бегущей строки.
В следующей статье разберем примеры использования внешних прерываний INT0, INT1. Доработаем существующую программу, избавимся от цикла «main».

Предыдущие статьи:

 Микроконтроллер и как его победить
 Микроконтроллер и системы счисления
 Микроконтроллер и логические операции
 Общее устройство микроконтроллера
 Арифметико-логическое устройство и организация памяти – память программ, память данных, энергонезависимая память
 Регистры общего назначения, регистры ввода/вывода, стек, счетчик команд
 Регистр состояния SREG




Оставить комментарий

Ваш email не будет опубликован. Обязательные поля отмечены *


Вы можете использовать это HTMLтеги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>