В этом примере мы рассмотрим как с помощью двух кнопок можно увеличивать или уменьшать значение какого либо регистра. Факт изменения содержимого регистра мы будем отображать на индикаторе.
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 ; конец программы
Прокомментируем новые элементы программы.
В шапке программы добавились описания селектора (см. глава 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.
Элементы всех этих задач рассмотрены в предыдущих примерах.