Пример 6. Работа нескольких кнопок. МногозадачностьВ этом примере мы рассмотрим организованную работу трех кнопок. Каждая кнопка будет отвечать за включение одного из символов фразы "УРА". Факт нажатия будем сопровождать звуковым сигналом. Между нажатиями на индикатор будем выводить мигающий символ нижнего подчеркивания.
LIST P=PIC16F84A
__CONFIG H3FF1
PC EQU H0002
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 ; очистка порта
; отслеживание нажатия кнопок
m4 movlw .169
movwf Reg_1
movlw .69
movwf Reg_2
movlw .2
movwf Reg_3
wr2 btfss PORTA,2 ; бит-проверка ножки RA2
goto m1
btfss PORTA,3 ; бит-проверка ножки RA3
goto m2
btfss PORTA,4 ; бит-проверка ножки RA4
goto m3
decfsz Reg_1, F
goto wr2
decfsz Reg_2, F
goto wr2
decfsz Reg_3, F
goto wr2
btfsc PORTB,1
goto m5
goto m6
m5 bcf PORTB,1
goto m4
m6 bsf PORTB,1
goto m4
;===== сегмент отрисовки символов
m1 movlw .0
call TABLE ; переход на метку TABLE
movwf PORTB
call beep
goto m4
m2 movlw .1
call TABLE ; переход на метку TABLE
movwf PORTB
call beep
goto m4
m3 movlw .2
call TABLE ; переход на метку TABLE
movwf PORTB
call beep
goto m4
;===== сегмент работы звукового излучателя
beep bsf PORTB,7
call Pause
clrf PORTB
return
;====================================
;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
;====================================
TABLE addwf PC,F ; Содержимое счетчика команд PC = PC + W
retlw b00111110 ; У
retlw b01111001 ; Р
retlw b01111101 ; А
retlw b00000010 ; _
;====================================
end ; конец программы
Далее текст прошивки:
:020000040000FA
:1000000083161F308500860183128601A9308C007B
:1000100045308D0002308E00051D1F28851D2428C7
:10002000051E29288C0B0C288D0B0C288E0B0C28F8
:1000300086181B281D2886100628861406280030DE
:100040003F2086002E20062801303F2086002E20EB
:10005000062802303F2086002E20062886173220F0
:1000600086010800A9308C0045308D0002308E00DA
:100070008C0B38288D0B38288E0B38280800820707
:080080003E3479347D34023472
:02400E00F13F80
:00000001FF
Прокомментируем сегмент отслеживания нажатия кнопок.
Жирным шрифтом выделены строчки формирующие паузу. Эта пауза нам нужна для организации мигания символа нижнего подчеркивания.
Курсивом (после паузы) выделены строчки, которые организуют поочередное включение/выключение нижнего подчеркивания. Этот символ в данном примере отрисовывается "вручную", т.е. мы не обращаемся к таблице символов.
Жирным курсивом выделены строчки связанные с отслеживанием нажатия кнопок.
Важным моментом в данной программе является организация многозадачности в цикле. Мы отслеживаем нажатие трех кнопок и мигаем индикатором. Закономерен вопрос – как эти задачи нам распределить во времени? Кнопки нам надо опрашивать как можно быстрее, т.к. нажатие на них может произойти в любой момент. А индикатором надо мигать гораздо реже. Опишем методику, которая была использована для создания сегмента с реализацией многозадачности.
За основу берется код паузы, создаваемый с помощью Pause ver1.2. В центре кода паузы ставятся наиболее приоритетные задачи, а в конце – те задачи, периодичность выполнения которых определяется временем созданного кода паузы. Следует обратить внимание на имена и места расположения меток (в нашем примере wr2 и m4), а также на расположение команд (goto) от которых осуществляется переход к этим меткам.
|