Рассмотрим пример, по нажатии кнопки будет включатьсч индикатор, а после того как кнопка будет отпущена индикатор будет выключен. А также пример – антидребезг (триггер) – одно нажатие кнопки приводит к одному устойчивому состоянию, а следующее нажатие к другому устойчивому состоянию.
Приступим к рассмотрению следующей программы, которая по нажатии кнопки будет включать индикатор, а после того как кнопка будет отпущена индикатор будет выключен.
LIST P=PIC16F84A __CONFIG H3FF1 STATUS EQU H0003 TRISA EQU H0005 PORTA EQU H0005 TRISB EQU H0006 PORTB EQU H0006 org 0 ; начало программы ; подготовительные моменты bsf STATUS,5 ; переход в Банк 1 movlw b00011111 movwf TRISA clrf TRISB bcf STATUS,5 ; переход назад в Банк 0 clrf PORTB ; очистка порта ; отслеживание нажатия кнопки m1 btfsc PORTA,2 ; бит-проверка ножки RA2 goto m1 movlw .255 movwf PORTB clrf PORTB goto m1 end
На нашем макете имеется три кнопки. Физически они подключены к линиям RA2, RA3, RA4, которые внешними подтягивающими резисторами соединены с плюсом питания (о подтягивающих резисторах см. “Теория и практика работы портов”). В нашей программе мы решили отслеживать кнопку на линии RA3.
В шапке программы появились описании регистров касающихся работы ножек порта А, а именно TRISA и PORTA.
В разделе подготовительных моментов мы указали для порта А работу всех ножек на вход (а их у нас 5 штук), записав число b00011111. Старшие три бита для регистров TRISA и PORTA не являются значащими и, следовательно, с таким же успехом можно записать число b11111111. Строго говоря, в данном примере в регистрах TRISA и PORTA нас интересует только второй бит, касающийся работы ножки RA2 и, следовательно, для определения направления работы ножки можно было бы использовать всего лишь одну команду bsf TRISA,2 .
Перед началом отслеживания кнопки мы очистили порт B и тем самым погасили все сегменты индикатора.
Нажатие кнопки мы отслеживаем с помощью команды btfsc PORTA,2 , которую мы называем командой бит-проверки. Если кнопка не нажата, то на RA2 присутствует высокий уровень сигнала за счет подтягивающего резистора и, соответственно этот факт приводит к выполнению следующей команды – переход по метке m1. В этом месте программа зацикливается до тех пор, пока не будет сделано нажатие на кнопку. После нажатия кнопки на RA2 устанавливается низкий уровень сигнала, что приводит к изменению хода программы, а именно к пропуску команды перехода по метке m1. Далее записывается число в порт, производится включение сегментов индикатора на 1 мкс. Затем порт очищается, индикатор выключается. Затем производится зацикливание.
Таким образом, пока нажата кнопка индикатор периодически включается и выключается. За счет высокой скорости работы МК (1 млн. операций в секунду) у нас создается впечатление что индикатор светится, а не мигает. Необходимо отметить, что индикатор светится не на полную яркость и объяснение этому простое – в выключенном состоянии он находится гораздо большее время. Звуковой излучатель на моей макетной плате вообще не подает признаков жизни.
Пример рассматриваемой программы специально упрощен, для того, чтобы вам было проще понять механизм работы. Такой подход пригоден для учебных целей, но на практике следует делать иначе.
Рассмотрим модифицированный фрагмент
; отслеживание нажатия кнопки m1 clrf PORTB m2 btfsc PORTA,2 ; бит-проверка ножки RA2 goto m1 movlw .255 movwf PORTB goto m2
Сначала выполняется очистка порта B. Затем выполняется бит проверка: если кнопка не нажата – переход по метке m1 для очистки порта и дальнейшее зацикливание. Если кнопка нажата – пропускается переход по метке m1 и выполняется запись числа в порт B. Затем осуществляется переход на очередную бит-проверку и дальнейшее зацикливание.
Как видим, процедуры записи в порт и очистки порта у нас разнесены и не накладываются друг на друга, что приводит к полноценной работе ножек порта.
——————–
Кнопка в режиме переключателя. Антидребезг
——————–
Во многих устройствах требуется работа кнопки в режиме переключателя, т.е. одно нажатие приводит к одному устойчивому состоянию, а следующее нажатие к другому устойчивому состоянию. Сделаем постановку задачи: первым нажатием включить только верхний сегмент индикатора, следующим нажатием – только нижний сегмент.
LIST P=PIC16F84A __CONFIG H3FF1 STATUS EQU H0003 PORTA EQU H0005 PORTB EQU H0006 TRISA EQU H0005 TRISB EQU H0006 Reg_1 EQU H000C Reg_2 EQU H000D Reg_3 EQU H000E org 0 ; начало программы ; подготовительные моменты bsf STATUS,5 ; переход в Банк 1 movlw b00011111 movwf TRISA clrf TRISB bcf STATUS,5 ; переход назад в Банк 0 clrf PORTB ; очистка порта ; отслеживание нажатия кнопки m1 btfsc PORTA,2 ; бит-проверка ножки RA2 goto m1 m2 btfss PORTA,2 ; бит-проверка ножки RA2 goto m2 ; отслеживаем отжатие кнопки movlw b01000000 movwf PORTB call Pause m3 btfsc PORTA,2 ; бит-проверка ножки RA2 goto m3 m4 btfss PORTA,2 ; бит-проверка ножки RA2 goto m4 ; отслеживаем отжатие кнопки movlw b00000010 movwf PORTB call Pause goto m1 ;delay = 250000 machine cycles Pause movlw .169 movwf Reg_1 movlw .69 movwf Reg_2 movlw .2 movwf Reg_3 wr decfsz Reg_1, F goto wr decfsz Reg_2, F goto wr decfsz Reg_3, F goto wr return end ; конец программы
Пример 5. Кнопка в режиме переключателя. Антидребезг
Во многих устройствах требуется работа кнопки в режиме переключателя, т.е. одно нажатие приводит к одному устойчивому состоянию, а следующее нажатие к другому устойчивому состоянию. Сделаем постановку задачи: первым нажатием включить только верхний сегмент индикатора, следующим нажатием – только нижний сегмент.
Рассмотрим программу
LIST P=PIC16F84A
__CONFIG H3FF1
STATUS EQU H0003
PORTA EQU H0005
PORTB EQU H0006
TRISA EQU H0005
TRISB EQU H0006
Reg_1 EQU H000C
Reg_2 EQU H000D
Reg_3 EQU H000E
org 0 ; начало программы
; подготовительные моменты
bsf STATUS,5 ; переход в Банк 1
movlw b00011111
movwf TRISA
clrf TRISB
bcf STATUS,5 ; переход назад в Банк 0
clrf PORTB ; очистка порта
; отслеживание нажатия кнопки
m1 btfsc PORTA,2 ; бит-проверка ножки RA2
goto m1
m2 btfss PORTA,2 ; бит-проверка ножки RA2
goto m2 ; отслеживаем отжатие кнопки
movlw b01000000
movwf PORTB
call Pause
m3 btfsc PORTA,2 ; бит-проверка ножки RA2
goto m3
m4 btfss PORTA,2 ; бит-проверка ножки RA2
goto m4 ; отслеживаем отжатие кнопки
movlw b00000010
movwf PORTB
call Pause
goto m1
;delay = 250000 machine cycles
Pause movlw .169
movwf Reg_1
movlw .69
movwf Reg_2
movlw .2
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
:1000000083161F3085008601831286010519062894
:10001000051D082840308600152005190D28051DEE
:100020000F280230860015200628A9308C004530A4
:100030008D0002308E008C0B1B288D0B1B288E0B25
:040040001B28080071
:02400E00F13F80
:00000001FF
Это наиболее простой подход к реализации кнопки в режиме переключателя. Однако, программа требует некоторых комментарий.
После нажатия кнопки осуществляется процедура проверки “отжатия” кнопки. Это нужно для того, чтобы “затормозить” ход выполнения программы. Каким бы быстрым и коротким не было наше нажатие на кнопку, программа в любом случае успеет сделать несколько циклов своей работы (1 млн. операций в секунду).
Кроме этого, мы видим вставку сегмента паузы. Пауза длительностью 0,25 сек позволяет нам избежать явление дребезга контактов, которое ведет к ложным срабатываниям. Не сложно предположить, что в секунду мы не сможем сделать больше четырех нажатий на кнопку, поэтому такая длительность оправдана.
Следует отметить, что проверка “отжатия” и наличие паузы для подавления дребезга определяется каждым конкретным случаем. Например, проверка “отжатия” не нужна, если требуется непрерывное увеличение (уменьшение) значения какого либо регистра (аналогия с кнопками громкости на пульте дистанционного управления). Что касается наличия паузы для подавления явления дребезга, то здесь нужно оценивать длительность времени для выполнения дальнейшего кода программы. В большинстве случаев такая пауза не нужна.
Для самостоятельного рассмотрения предлагаю модифицированный фрагмент программы.
; отслеживание нажатия кнопки m1 btfsc PORTA,2 ; бит-проверка ножки RA2 goto m1 m2 btfss PORTA,2 ; бит-проверка ножки RA2 goto m2 btfsc PORTB,6 goto m3 goto m4 m3 movlw b00000010 movwf PORTB call Pause goto m1 m4 movlw b01000000 movwf PORTB call Pause goto m1
Принцип основан на проверке содержимого порта B, и дальнейшего выполнения программы по одному из двух сценариев. Здесь более интеллектуальный подход к работе в отличии от предыдущего примера, где задача решалась прямолинейно.