Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- LIST P=PIC16F84A
- __CONFIG H'3FF1'
- #include <P16F84A.inc>
- PC EQU H'0002'
- Reg_1 EQU H'000C'
- Reg_2 EQU H'000D'
- Reg_3 EQU H'000E'
- Time1L EQU H'0010'
- Time1R EQU H'0011'
- Time2L EQU H'0012'
- Time2R EQU H'0013'
- TimerS EQU H'0014'
- Timer1_L EQU H'0015'
- Timer1_R EQU H'0016'
- Timer1_S EQU H'0017'
- Timer2_L EQU H'0018'
- Timer2_R EQU H'0019'
- Timer2_S EQU H'001A'
- BlinkS1 EQU H'001B'
- BlinkS2 EQU H'001C'
- BlinkS3 EQU H'001D'
- BlinkS4 EQU H'001E'
- Count EQU H'000F'
- EEData EQU 08h
- EECon1 EQU 08h
- EEAdr EQU 09h
- EECon2 EQU 09h
- OPTIONR EQU 81H ; Option (RP0=1)
- INTCON EQU 0BH ; регистр флагов прерываний
- ; Старт выполнения программы
- org 0
- goto Start
- ; Сработало прерывание
- org 4
- call Pause20ms ; Дребезг контактов
- btfsc PORTB,0 ;
- goto TestPlayer ; Проверка кто нажал кнопку
- EndInterrupt
- bcf INTCON,INTF
- bsf INTCON,INTE
- bsf OPTION_REG,6
- RETFIE ; возврат из прерывания
- TestPlayer
- btfsc PORTA,0 ; Если левая кнопка нажата, то
- goto LeftPlayer ; выполняем счет левого игрока
- btfsc PORTA,4 ; Если правая кнопка нажата, то
- goto RightPlayer ; выполняем счет правого игрока
- btfsc PORTB,0 ; Если центральная кнопка нажата, то
- goto SetUp ; Переходим к установкам
- goto EndInterrupt
- ;RETFIE
- LeftPlayer
- movf TimerS, W ; Считываем значения основных таймеров
- movwf Timer1_S ; и копируем их в таймеры
- movf Time1L, W ; игрока
- movwf Timer1_L ;
- movf Time1R, W ;
- movf Timer1_R ;
- bcf PORTA,2 ; Гасим индикатор левого игрока
- bsf PORTA,1 ; и включаем индикатор правого
- movf Timer2_S, W ; Копируем значения времени
- movwf TimerS ; правого игрока в основной таймер
- movf Timer2_R, W ;
- movwf Time2R ;
- movf Timer2_L, W ;
- movf Time2L ;
- goto EndInterrupt
- ; RETFIE
- RightPlayer
- movf TimerS, W ; Считываем значения основных таймеров
- movwf Timer2_S ; и копируем их в таймеры
- movf Time1L, W ; игрока
- movwf Timer2_L ;
- movf Time1R, W ;
- movf Timer2_R ;
- bsf PORTA,2 ; Включаем индикатор левого игрока
- bcf PORTA,1 ; и гасим индикатор правого
- movf Timer1_S, W ; Копируем значения времени
- movwf TimerS ; правого игрока в основной таймер
- movf Timer1_R, W ;
- movwf Time1R ;
- movf Timer1_L, W ;
- movf Time1L ;
- goto EndInterrupt
- SetUp
- call Pause20ms
- btfsc PORTB,0
- goto CheckSetUp
- call ScoreL_0 ; Показываем нули
- call ScoreR_0 ;
- SetUpScore
- bsf PORTA,2
- bsf PORTA,1
- btfsc PORTA,4 ; Увеличиваем на 1 минуту
- goto TestMinUp ;
- btfsc PORTA,0 ; Уменьшаем на 1 минуту
- goto TestMinDown ;
- decfsz BlinkS1
- goto SetUpScore
- decfsz BlinkS2
- goto SetUpScore
- bcf PORTA,2
- bcf PORTA,1
- decfsz BlinkS3
- goto SetUpScore2
- decfsz BlinkS4
- goto SetUpScore2
- goto SetUpScore
- SetUpScore2
- btfsc PORTA,4 ; Увеличиваем на 1 минуту
- goto TestMinUp ;
- btfsc PORTA,0 ; Уменьшаем на 1 минуту
- goto TestMinDown ;
- decfsz BlinkS3
- goto SetUpScore2
- decfsz BlinkS4
- goto SetUpScore2
- goto SetUpScore
- TestExitInterrupt
- btfsc PORTA,4
- goto TestExit2
- goto SetUpScore
- TestExit2
- btfsc PORTA,0
- goto EndSetupInterrupt
- goto SetUpScore
- EndSetupInterrupt
- bsf PORTA,2
- bsf PORTA,1
- btfsc PORTB,0
- goto $-1
- call Pause1s
- movf Time1R, W
- movwf Timer1_R
- movf Time1R, W
- movwf Timer2_R
- movf Time1L, W
- movwf Timer1_L
- movf Time1L, W
- movwf Timer2_L
- movlw .240
- movwf TimerS
- movlw .240
- movwf Timer1_S
- movlw .240
- movwf Timer2_S
- movlw .1
- movwf Reg_1
- movlw .1
- movwf Reg_2
- movlw .1
- movwf Reg_3
- bcf PORTA,2
- bcf PORTA,1
- btfss PORTB,0
- goto $-1
- btfsc PORTA,0
- bsf PORTA,1
- btfsc PORTA,4
- bsf PORTA,2
- bcf INTCON,INTF
- bsf INTCON,INTE
- bsf OPTION_REG,6
- RETFIE
- CheckSetUp
- call Pause05
- btfsc PORTB,0
- goto $-1
- bcf INTCON,7 ; Запрещаем прерывания
- bcf INTCON,4 ;
- bcf OPTION_REG,6
- movlw .255
- movwf BlinkS1
- movlw .255
- movwf BlinkS2
- movlw .255
- movwf BlinkS3
- movlw .255
- movwf BlinkS4
- goto SetUp
- TestMinUp
- call Pause20ms
- btfsc PORTA,4 ; Ждем пока отпустят кнопку
- call Pause200ms
- btfsc PORTB,0
- goto TestExitInterrupt
- movf Time1R, W ; Копируем текущее значение правой цифры
- incf Time1R, F ; Увеличиваем его на 1
- call ShowScore ; Выводим число
- goto SetUpScore
- TestMinDown
- call Pause20ms
- btfsc PORTA,0 ; Ждем пока отпустят кнопку
- call Pause200ms
- btfsc PORTB,0
- goto TestExitInterrupt
- movf Time1R, W ; Копируем текущее значение правой цифры
- decf Time1R, F ; Уменьшаем его на 1
- call ShowScore ; Выводим правое число
- goto SetUpScore
- ; Проверяем какое число у нас в регистре и выводим на индикатор
- ShowScore
- movf Time1R, W
- bcf STATUS, Z
- xorlw .0
- btfsc STATUS, Z
- call ScoreR_0
- movf Time1R, W
- bcf STATUS, Z
- xorlw .1
- btfsc STATUS, Z
- call ScoreR_1
- movf Time1R, W
- bcf STATUS, Z
- xorlw .2
- btfsc STATUS, Z
- call ScoreR_2
- movf Time1R, W
- bcf STATUS, Z
- xorlw .3
- btfsc STATUS, Z
- call ScoreR_3
- movf Time1R, W
- bcf STATUS, Z
- xorlw .4
- btfsc STATUS, Z
- call ScoreR_4
- movf Time1R, W
- bcf STATUS, Z
- xorlw .5
- btfsc STATUS, Z
- call ScoreR_5
- movf Time1R, W
- bcf STATUS, Z
- xorlw .6
- btfsc STATUS, Z
- call ScoreR_6
- movf Time1R, W
- bcf STATUS, Z
- xorlw .7
- btfsc STATUS, Z
- call ScoreR_7
- movf Time1R, W
- bcf STATUS, Z
- xorlw .8
- btfsc STATUS, Z
- call ScoreR_8
- movf Time1R, W
- bcf STATUS, Z
- xorlw .9
- btfsc STATUS, Z
- call ScoreR_9
- movf Time1R, W
- bcf STATUS, Z
- xorlw .10
- btfsc STATUS, Z
- call LeftUp1
- movf Time1R, W
- bcf STATUS, Z
- xorlw .255
- btfsc STATUS, Z
- call LeftDown1
- call ShowLeftScore
- return
- LeftUp1
- call ScoreR_0 ; Показываем на правом индикаторе ноль
- movlw .0 ; Обнуляем регистр с правым индикатором
- movwf Time1R ;
- movf Time1L, W ; Добавляем 1 в левый регистр
- incf Time1L, F ;
- return
- LeftDown1
- call ScoreR_9 ; Показываем на правом индикаторе 9
- movlw .9 ; Загружаем 9 в регистр с правым индикатором
- movwf Time1R ;
- movf Time1L, W ; Отнимаем 1 в левом регистре
- decf Time1L, F ;
- return
- ShowLeftScore
- movf Time1L, W
- bcf STATUS, Z
- xorlw .0
- btfsc STATUS, Z
- call ScoreL_0
- movf Time1L, W
- bcf STATUS, Z
- xorlw .1
- btfsc STATUS, Z
- call ScoreL_1
- movf Time1L, W
- bcf STATUS, Z
- xorlw .2
- btfsc STATUS, Z
- call ScoreL_2
- movf Time1L, W
- bcf STATUS, Z
- xorlw .3
- btfsc STATUS, Z
- call ScoreL_3
- movf Time1L, W
- bcf STATUS, Z
- xorlw .4
- btfsc STATUS, Z
- call ScoreL_4
- movf Time1L, W
- bcf STATUS, Z
- xorlw .5
- btfsc STATUS, Z
- call ScoreL_5
- movf Time1L, W
- bcf STATUS, Z
- xorlw .6
- btfsc STATUS, Z
- call ScoreL_6
- movf Time1L, W
- bcf STATUS, Z
- xorlw .7
- btfsc STATUS, Z
- call ScoreL_7
- movf Time1L, W
- bcf STATUS, Z
- xorlw .8
- btfsc STATUS, Z
- call ScoreL_8
- movf Time1L, W
- bcf STATUS, Z
- xorlw .9
- btfsc STATUS, Z
- call ScoreL_9
- movf Time1L, W
- bcf STATUS, Z
- xorlw .10
- btfsc STATUS, Z
- call ResetLeft
- movf Time1L, W
- bcf STATUS, Z
- xorlw .255
- btfsc STATUS, Z
- call ResetLeft
- return
- ResetLeft
- call ScoreL_0
- movlw .0
- movwf Time1L
- return
- Start
- ; Подготовительные моменты
- bsf STATUS,5 ; Переход в Банк 1
- movlw b'00010001' ; Включаем ноги PORTA
- movwf TRISA
- movlw b'00000001' ; Включаем ноги PORTB
- movwf TRISB
- bcf STATUS,5 ; Переход назад в Банк 0
- clrf PORTB
- clrf PORTA
- bsf INTCON,7 ; Разрешаем прерывания
- BSF INTCON,4 ; разрешаем прерывания по INT
- BSF OPTION_REG,6 ; Прерывание на RB0 по переднему фронту
- ;PORTB,0 = Прерывание
- ;PORTA,0 = Левая кнопка
- ;PORTA,4 = Правая кнопка
- ;PORTB,0 = Центральная кнопка (установка)
- ;PORTA,2 = Левый светодиод
- ;PORTA,1 = Правый светодиод
- ; Левый сегмент
- ; PORTA,3 = 1
- ; PORTB,1 = 8
- ; PORTB,2 = 2
- ; PORTB,3 = 4
- ; Правый сегмент
- ; PORTB,7 = 4
- ; PORTB,6 = 2
- ; PORTB,5 = 8
- ; PORTB,4 = 1
- ; Тест цифр
- bsf PORTA,2
- call ScoreL_0
- call ScoreR_9
- call Pause05
- bcf PORTA,2
- call ScoreL_1
- call ScoreR_8
- call Pause05
- bsf PORTA,1
- call ScoreL_2
- call ScoreR_7
- call Pause05
- bcf PORTA,1
- call ScoreL_3
- call ScoreR_6
- call Pause05
- bsf PORTA,2
- call ScoreL_4
- call ScoreR_5
- call Pause05
- bcf PORTA,2
- call ScoreL_5
- call ScoreR_4
- call Pause05
- bsf PORTA,1
- call ScoreL_6
- call ScoreR_3
- call Pause05
- bcf PORTA,1
- call ScoreL_7
- call ScoreR_2
- call Pause05
- bsf PORTA,2
- bsf PORTA,1
- call ScoreL_8
- call ScoreR_1
- call Pause05
- bcf PORTA,2
- call ScoreL_9
- call ScoreR_0
- call Pause05
- bcf PORTA,1
- call ScoreL_0
- ; Начало цикла выполнения часов
- Main
- WaitButton
- btfsc PORTA,0
- goto BeginFactory
- btfsc PORTA,4
- goto BeginFactory
- goto WaitButton
- BeginFactory
- movlw .1 ; Установка часов на 15 минут
- movwf Time1L ;
- movlw .5 ;
- movwf Time1R ;
- Begin
- movf Time1R, W ; Синхронизируем показания
- movwf Timer1_R ; таймеров для обоих
- clrw
- movf Time1R, W ; игроков
- movwf Timer2_R;
- movlw .240 ;
- movwf Timer1_S ;
- movlw .240 ;
- movwf Timer2_S ;
- movf Time1L, W ;
- movwf Timer1_L ;
- movf Time1L, W ;
- movwf Timer2_L ;
- movlw .240
- movwf TimerS
- clrw
- RunGame
- call ShowScore
- call Pause250ms
- decfsz TimerS
- goto RunGame
- btfsc PORTA,2 ; Если горит индиктор левого игрока
- call LeftGamer ; то снимаем с него минуты
- btfsc PORTA,1 ; Если горит индикатор правого игрока
- call RightGamer ; то снимаем с него минуты
- movlw .240
- movwf TimerS
- goto RunGame ; зацикливаем
- LeftGamer
- movf Timer1_R, W ; Считываем значение правого индикатора
- decf Timer1_R ; Уменьшаем на 1
- movf Timer1_R, W ; Считываем значение правого индикатора
- movwf Time1R ; помещаем его в основной таймер
- movf Time1R, W ; Считываем значение правого индикатора
- movf Timer1_L, W ; Считтываем значение левого индикатора
- movwf Time1L ; помещаем его в основной таймер
- call ShowScore ; Выводим число
- movf Time1L, W ; Считываем значение левого индикатора
- movwf Timer1_L ; помещаем его в таймер игрока
- movf Timer1_L, W ; Считываем показания левого индикатора
- bcf STATUS,Z ; сравниваем с нулем
- xorlw .0 ;
- btfsc STATUS,Z ; Если обнулен, то проверяем
- call LeftGamerMin ; правый индикатор
- return
- LeftGamerMin
- movf Timer1_R, W ; Считываем показания правого индикатора
- bcf STATUS,Z ; Сравниваем с нулем
- xorlw .0 ;
- btfsc STATUS,Z ; Если обнулен, то
- goto WinGamer ; выиграл правый игрок
- return
- WinGamer
- btfsc PORTA,1 ; Проверка на сброс таймера
- call Check2LeftMin ;
- btfsc PORTA,2 ;
- call Check1LeftMin ;
- btfsc PORTA,2 ; Проверка кто выиграл
- goto LeftBlink ;
- btfsc PORTA,1 ;
- goto RightBlink ;
- goto WinGamer ;
- Check2LeftMin
- movf Timer2_L, W ; Считываем показания левого индикатора
- bcf STATUS,Z ; сравниваем с нулем
- xorlw .0 ;
- btfsc STATUS,Z ; Если обнулен, то мигаем проигравшим
- goto Check2RightMin
- goto RunGame
- Check2RightMin
- movf Timer2_R, W ; Считываем показания правого индикатора
- bcf STATUS,Z ; сравниваем с нулем
- xorlw .0 ;
- btfsc STATUS,Z ; Если обнулен, то проверяем левый
- return
- goto RunGame
- Check1LeftMin
- movf Timer1_L, W ; Считываем показания левого индикатора
- bcf STATUS,Z ; сравниваем с нулем
- xorlw .0 ;
- btfsc STATUS,Z ; Если обнулен, то мигаем проигравшим
- goto Check1RightMin
- goto RunGame
- Check1RightMin
- movf Timer1_R, W ; Считываем показания правого индикатора
- bcf STATUS,Z ; сравниваем с нулем
- xorlw .0 ;
- btfsc STATUS,Z ; Если обнулен, то проверяем левый
- return
- goto RunGame
- LeftBlink
- bcf PORTA,2 ; Мигаем проигравшим
- call ScoreR_1
- call ScoreL_0
- call Pause05 ;
- bsf PORTA,2 ;
- call Pause05 ;
- goto WinGamer ;
- RightBlink
- bcf PORTA,1 ; Мигаем проигравшим
- call ScoreL_1
- call ScoreR_0
- call Pause05 ;
- bsf PORTA,1 ;
- call Pause05 ;
- goto WinGamer ;
- RightGamer
- movf Timer2_R, W ; Считываем значение правого индикатора
- decf Timer2_R ; Уменьшаем на 1
- movf Timer2_R, W ; Считываем значение правого индикатора
- movwf Time1R ; помещаем его в основной таймер
- movf Timer2_L, W ; Считтываем значение левого индикатора
- movwf Time1L ; помещаем его в основной таймер
- call ShowScore ; Выводим число
- movf Time1L, W ; Считываем значение левого индикатора
- movwf Timer2_L ; помещаем его в таймер игрока
- movf Timer2_L, W ; Считываем показания левого индикатора
- bcf STATUS,Z ; сравниваем с нулем
- xorlw .0 ;
- btfsc STATUS,Z ; Если обнулен, то проверяем
- call RightGamerMin ; правый индикатор
- return
- RightGamerMin
- movf Timer2_R, W ; Считываем показания правого индикатора
- bcf STATUS,Z ; Сравниваем с нулем
- xorlw .0 ;
- btfsc STATUS,Z ; Если обнулен, то
- goto WinGamer ; выиграл левый игрок
- return
- ScoreL_0
- bcf PORTA,3
- bcf PORTB,1
- bcf PORTB,2
- bcf PORTB,3
- return
- ScoreL_1
- bsf PORTA,3
- bcf PORTB,1
- bcf PORTB,2
- bcf PORTB,3
- return
- ScoreL_2
- bcf PORTA,3
- bcf PORTB,1
- bsf PORTB,2
- bcf PORTB,3
- return
- ScoreL_3
- bsf PORTA,3
- bcf PORTB,1
- bsf PORTB,2
- bcf PORTB,3
- return
- ScoreL_4
- bcf PORTA,3
- bcf PORTB,1
- bcf PORTB,2
- bsf PORTB,3
- return
- ScoreL_5
- bsf PORTA,3
- bcf PORTB,1
- bcf PORTB,2
- bsf PORTB,3
- return
- ScoreL_6
- bcf PORTA,3
- bcf PORTB,1
- bsf PORTB,2
- bsf PORTB,3
- return
- ScoreL_7
- bsf PORTA,3
- bcf PORTB,1
- bsf PORTB,2
- bsf PORTB,3
- return
- ScoreL_8
- bcf PORTA,3
- bsf PORTB,1
- bcf PORTB,2
- bcf PORTB,3
- return
- ScoreL_9
- bsf PORTA,3
- bsf PORTB,1
- bcf PORTB,2
- bcf PORTB,3
- return
- ScoreR_0
- bcf PORTB,7
- bcf PORTB,6
- bcf PORTB,5
- bcf PORTB,4
- return
- ScoreR_1
- bcf PORTB,7
- bcf PORTB,6
- bcf PORTB,5
- bsf PORTB,4
- return
- ScoreR_2
- bcf PORTB,7
- bsf PORTB,6
- bcf PORTB,5
- bcf PORTB,4
- return
- ScoreR_3
- bcf PORTB,7
- bsf PORTB,6
- bcf PORTB,5
- bsf PORTB,4
- return
- ScoreR_4
- bsf PORTB,7
- bcf PORTB,6
- bcf PORTB,5
- bcf PORTB,4
- return
- ScoreR_5
- bsf PORTB,7
- bcf PORTB,6
- bcf PORTB,5
- bsf PORTB,4
- return
- ScoreR_6
- bsf PORTB,7
- bsf PORTB,6
- bcf PORTB,5
- bcf PORTB,4
- return
- ScoreR_7
- bsf PORTB,7
- bsf PORTB,6
- bcf PORTB,5
- bsf PORTB,4
- return
- ScoreR_8
- bcf PORTB,7
- bcf PORTB,6
- bsf PORTB,5
- bcf PORTB,4
- return
- ScoreR_9
- bcf PORTB,7
- bcf PORTB,6
- bsf PORTB,5
- bsf PORTB,4
- return
- ;delay = 1'000'000 machine cycles
- Pause1s movlw .173
- movwf Reg_1
- movlw .19
- movwf Reg_2
- movlw .6
- movwf Reg_3
- wr decfsz Reg_1, F
- goto wr
- decfsz Reg_2, F
- goto wr
- decfsz Reg_3, F
- goto wr
- nop
- nop
- return
- ;delay = 500'000 machine cycles
- Pause05 movlw .85
- movwf Reg_1
- movlw .138
- movwf Reg_2
- movlw .3
- movwf Reg_3
- wr05 decfsz Reg_1, F
- goto wr05
- decfsz Reg_2, F
- goto wr05
- decfsz Reg_3, F
- goto wr05
- nop
- nop
- return
- ;delay = 20'000 machine cycles
- Pause20ms movlw .248
- movwf Reg_1
- movlw .26
- movwf Reg_2
- wr20ms decfsz Reg_1, F
- goto wr20ms
- decfsz Reg_2, F
- goto wr20ms
- nop
- return
- ;delay = 200'000 machine cycles
- Pause200ms movlw .186
- movwf Reg_1
- movlw .4
- movwf Reg_2
- movlw .2
- movwf Reg_3
- wr200ms decfsz Reg_1, F
- goto wr200ms
- decfsz Reg_2, F
- goto wr200ms
- decfsz Reg_3, F
- goto wr200ms
- nop
- return
- ;delay = 250'000 machine cycles
- Pause250ms
- movlw .169
- movwf Reg_1
- movlw .69
- movwf Reg_2
- movlw .2
- movwf Reg_3
- wr250ms decfsz Reg_1, F
- goto wr250ms
- decfsz Reg_2, F
- goto wr250ms
- decfsz Reg_3, F
- goto wr250ms
- nop
- nop
- return
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement