====== Счётчик нажатий на кнопку ======
Пример программирования микроконтроллера Atmel ATMega8.
Практической пользы не представляет более чем для обучения программированию таких контроллеров.
Но в этом качестве полезен.
Делался сверхоперативно для нужд экзаменационных и физически представлял отладочную плату для ATMega8
(в которой уже есть кнопка) и распаянный блок из двух семисегментных светодиодных индикаторов,
подключенных к портам ATMega8 в статическом режиме.
.include "m8.inc"
.def param = r23 ; Для передачи параметров
.def temp = r16 ; Для разных целей
start:
ldi temp,low(RAMEND)
out SPL,temp ; Установить указатель стека на конец внутренней ОП
ldi temp,high(RAMEND)
out SPH,temp
SER r21 ; Все единицы
; Устанавливаем порты в режимы ввода/вывода
OUT DDRB,r21
OUT DDRC,r21
LDI temp, 0b01011011
OUT DDRD,temp
clr param
rcall set_l
clr param
rcall set_h
.def des = r18 ; Десятки
.def ed = r17 ; Единицы
.def dreb = r19 ; Защита от дребезга
clr des
clr ed
loop:
ser dreb ; наполняем переменную дребезга
getkey:
in temp, PIND ; получаем PIND в temp
bst temp, 2 ; записать пин кнопки в бит T
brts loop ; переход, если бит T (кнопка отпущена)
dec dreb ; убавить переменную дребезга
breq plused ; если исчерпана - прибавить единичку к счётчику
rjmp getkey
plused:
inc ed ; прибавили счётчик
cpi ed, 10 ; не получилось ли десять в младшем разряде ?
breq plusdes
mov param, ed
rcall set_l
rcall waitrel
rjmp loop
plusdes:
clr ed ; запишем ноль в единицы
mov param, ed ; отобразим их
rcall set_l
inc des
cpi des, 10 ; не получилось ли десять в старшем разряде ?
brne dispdes
clr des
dispdes:
mov param, des ; отобразим их
rcall set_h
rcall waitrel
rjmp loop
rjmp plused
rjmp loop
waitrel: ; ожидаем отпускания кнопки
in temp, PIND ; получаем PIND в temp
bst temp, 2 ; записать пин кнопки в бит T
brtc waitrel ; переход, если не бит T (кнопка нажата)
ret
set_l: ; Показать младший разряд
;Вход: в param значение цифры младшего разряда
rcall get_img
out PortB,param
in temp, PORTD ; биты на другом порту (сегменты D,E,F,G)
bst param, 3
bld temp, 0
bst param, 4
bld temp, 1
bst param, 5
bld temp, 3
bst param, 6
bld temp, 4
out PORTD, temp
ret
set_h: ; Показать старший разряд
;Вход: в param значение цифры старшего разряда
rcall get_img
out PortC,param
in temp, PORTD ; шестой бит на другом порту (сегмент G)
bst param, 6
bld temp, 6
out PORTD, temp
ret
get_img: ; Получить изображение знака
;Вход: в param значение цифры разряда
;Выход: в param значение изображения знака
ldi ZH,HIGH(sg0*2) ;загружаем адрес начала знака
ldi ZL,LOW(sg0*2) ;
add ZL,param ;адрес знака
lpm ;знак - в регистре r0
mov param,r0
ret
sg0: ; Изображения знаков
; 0 1 2 3 4 5 6 7 8 9
.db 0b11000000,0b11111001,0b10100100,0b10110000,0b10011001,0b10010010,0b10000010,0b11111000,0b10000000,0b10010000