Пример 7. Уменьшение и увеличение значений кнопкамиВ этом примере мы рассмотрим как с помощью двух кнопок можно увеличивать или уменьшать значение какого либо регистра. Факт изменения содержимого регистра мы будем отображать на индикаторе.
LIST P=PIC16F84A
__CONFIG H3FF1
W EQU 0
F EQU 1
PC EQU H0002
STATUS EQU H0003
PORTA EQU H0005
PORTB EQU H0006
TRISA EQU H0005
TRISB EQU H0006
C EQU 0
Z EQU 2
Reg_1 EQU H000C
Reg_2 EQU H000D
Reg_3 EQU H000E
Reg_4 EQU H000F ; регистр под результат
org 0 ; начало программы
; подготовительные моменты
bsf STATUS,5 ; переход в Банк 1
movlw b00011111
movwf TRISA
clrf TRISB
bcf STATUS,5 ; переход назад в Банк 0
; отрисовка нуля и подготовка регистра (очистка перед изменением)
movlw b01101111
movwf PORTB
clrf Reg_4
; отслеживание нажатий кнопок
m3 btfss PORTA,2 ; бит-проверка ножки RA2 - уменьшение
goto m1
btfss PORTA,3 ; бит-проверка ножки RA3 - увеличение
goto m2
goto m3 ; зацикливание проверки
; проверка на ноль (на крайнее значение) и уменьшение значения регистра
m1 bcf STATUS,Z ; опустим флаг Z в ноль
movf Reg_4,F ; копировать из Reg_4 в Reg_4
btfsc STATUS,Z ; делаем бит-проверку Z-флага
; если Z=1, то выполняется следующая инструкция, иначе – пропускается
goto m4 ; переходим на отрисовку значения
decf Reg_4,F ; уменьшить значение на 1 и сохранить
goto m4
; проверка на 9 (на др. крайнее значение) и увеличение значения регистра
m2 bcf STATUS,C ; опускаем флаг С в ноль
movlw .247 ; (255-9)+1 = 247 -> W
addwf Reg_4,W ; (Reg_4)+W
btfss STATUS,C ; делаем бит-проверку C-флага
; если бит С=0, то выполняется следующая инструкция
; если бит С=1, то следующая инструкция пропускается
goto m5
goto m4
m5 incf Reg_4,F ; увеличить значение на 1 и сохранить
m4 movf Reg_4,W
call TABLE
movwf PORTB
call Pause
goto m3
;====================================
TABLE addwf PC,F ; Содержимое счетчика команд PC = PC + W
retlw b01101111 ; 0
retlw b00001100 ; 1
retlw b01011011 ; 2
retlw b01011110 ; 3
retlw b00111100 ; 4
retlw b01110110 ; 5
retlw b01110111 ; 6
retlw b01001100 ; 7
retlw b01111111 ; 8
retlw b01111110 ; 9
;====================================
;delay = 500000 machine cycles
Pause movlw .85
movwf Reg_1
movlw .138
movwf Reg_2
movlw .3
movwf Reg_3
wr decfsz Reg_1, F
goto wr
decfsz Reg_2, F
goto wr
decfsz Reg_3, F
goto wr
return
end ; конец программы
Далее текст прошивки:
:020000040000FA
:1000000083161F308500860183126F3086008F01B2
:10001000051D0D28851D1328082803118F080319B5
:100020001A288F031A280310F7300F07031C19280A
:100030001A288F0A0F081F2086002A200828820706
:100040006F340C345B345E343C34763477344C3467
:100050007F347E3455308C008A308D0003308E0022
:0E0060008C0B30288D0B30288E0B30280800BA
:02400E00F13F80
:00000001FF
Прокомментируем новые элементы программы.
В шапке программы добавились описания селектора (см. глава 2, "Сложение и вычитание регистров") и описания битов флагов C, Z (см. глава 2, "Флаги как индикаторы событий").
После включения МК содержимое большинства регистров неизвестно (за исключением некоторых умолчаний). Содержимое порта B после включения также неизвестно. В связи с этим на порту B мы выставляем комбинацию сигналов, приводящую к отображению символа нуля – "0". Действительно, мы ведь должны что-то отобразить после включения МК.
Для Reg_4 мы определили роль регистра, в котором будет результат уменьшения/увеличения на единицу по факту нажатия кнопок. После включения мы его также обнуляем.
Следующий сегмент отслеживания кнопок прокомментирован в предыдущих примерах.
Далее следуют два сегмента, которые проверяют значение Reg_4 на крайние значения. На нашей макетной плате на одном разряде индикатора мы можем отобразить десять символов цифр от "0" до "9". Соответственно, мы будем в первую очередь делать проверку на наличие этих значений в Reg_4. Почему в первую очередь? Т.к. возможна ситуация, когда значение Reg_4 в результате предыдущего увеличения/уменьшения достигло крайнего значения. Строго говоря, после включения Reg_4 мы уже обнулили. Если бы не было организовано такого контроля, то переход за крайние значения приведет к непредсказуемой работе МК.
Проверка на крайние значения организована двумя разными способами. В первом способе реализована проверка значения регистра на ноль. Во втором способе проверка реализована через отслеживание флага переноса-займа. В нашем случае отслеживался перенос из предположения, что если к крайнему значению 9 прибавить 247 произойдет переполнение регистра и произойдёт факт переноса. Что и было сделано. Можно было бы вычитать 10 и отслеживать факт займа.
Операции увеличения/уменьшения регистров осуществляются с помощью команд, которые мы называем командами счётчиками.
Пауза в нашей программе осуществляет задержку после вывода символа на индикатор, т.е. для того, чтобы мы успели отпустить кнопку. Однако, если кнопка будет оставаться нажатой, то значение на индикаторе будет динамично увеличиваться/уменьшаться до крайних значений.
Для самостоятельной модификации программы предлагаю решить следующие задачи:
– добавить контроль отжатия кнопок;
– добавить символы крайних значений "H" и "L" (High и Low);
– добавить озвучивание нажатия кнопок;
– добавить повторяющиеся короткие звуковые сигналы в случае установки крайних значений;
– сделать мигающими символы крайних значений "H" и "L";
– задействовать третью кнопку, после нажатия на которую устанавливается среднее значение, например, число 5.
Элементы всех этих задач рассмотрены в предыдущих примерах.
|