;Для PIC16F84 ;бит конфигурации 3FF1 ;XT - КВАРЦ 4MHG ;WDT-СТОРОЖЕВОЙ ТАЙМЕР OFF ;PWRTE - ТАЙМЕР ВКЛЮЧЕНИЯ ПИТАНИЯ ON ;CP code protection - защита памяти программ OFF W EQU 0 ;Буфер (аккумулятор) F EQU 1 ;в регистр PC EQU 02h STATUS EQU 03h PORTA EQU 05h PORTB EQU 06h TRISA EQU 05h TRISB EQU 06h C EQU 0 ;Флаги Z EQU 2 ;Флаги IntCon EQU 0Bh ;регистр IntCon OptionR EQU 01h ;регистр Option_REG Tmr0 EQU 01h ;таймер Reg_1 EQU 0Ch ;используется в задержках Reg_2 EQU 0Dh ;используется в задержках Reg_3 EQU 0Eh ;время таймера включения теристора (регистр яркости) Reg_4 EQU 0Fh ;нулевой битиспользуем как Метка, включен ли свет? бит1-запрешено ли прерывание? Reg_5 EQU 10h ;используется в задержках Reg_6 EQU 11h ;Для сохранения буфера в прерывании ;=================================== Reg_7 EQU 12h ;не используем Reg_8 EQU 13h ;не используем Reg_9 EQU 14h ;не используем ;=========================================================== org 00 ; самое начало программы goto start org 04 ;Вектор прерывания ;====================================================== ;сюда попадаем если произошло прерывание по таймеру или при переходе через ноль ;========================================================== movwf Reg_6 ;Сохраняем Буфер btfsc IntCon,1 ;смотрим если 1 то было прерывание по RB0/INT тогда в zaderj goto zaderj ;Если прерывание по переполнению таймера то дальше ;---------------------------------------------------------------------------- ; формеруем импульс для тиристора ;пауза = 100 машинных цыклов отвечает за длительность импульса на тиристор ;-------------------------------------------------------------------- bsf PORTA,2 ;тиристор ON movlw .33 ;пауза = 100 машинных цыклов movwf Reg_1 erq decfsz Reg_1, F goto erq bcf PORTA,2 ;тиристор OFF ;--------------------------------------------------------------------- bsf STATUS,5 ; переход в Банк 1 btfsc OptionR,6 ;смотрим полярность прерывания если 1 то ах goto ax goto xa ;---------------------------------------------------------------------- ax bcf OptionR,6 ;теперь прерывание по задниму фронту плюса bcf STATUS,5 ;переход в Банк 0 goto nt ;------------------------------------------------------------------------ xa bsf OptionR,6 ;теперь прерывание по переднему фронту плюса bcf STATUS,5 ;переход в Банк 0 ;------------------------------------------------------------------------ nt movlw b'10010000';разрешение прерыванеи RB0/INT movwf IntCon ;Запрещение прерывания по переполнению TMR0 ;сбрасываем флаг прерываний TMR0 movf Reg_6,W ;Востанавливаем буфер retfie ;уходим ;------------------------------------------------------------ ;сюда попадаем если прерывание произошло по ножке RB0 6-ой вывод ;-------------------------------------------------------------------------- zaderj movf Reg_3,W ;извлекаем значение задержки (регистр яркости) movwf Tmr0 ;В таймер кладем значение задержки из W (Буфер) movlw b'10100000';запрещение прерыванеи RB0/INT movwf IntCon ;Разрешение прерывания по переполнению TMR0 ;збрасываем флаг прерывания RB0/INT movf Reg_6,W ;Востанавливаем буфер retfie ;уходим ;====================================================== ;начало программы подготовительные моменты start bsf STATUS,5 ; переход в Банк 1 movlw b'00000000' ; определяем входы выходы movwf TRISA movlw b'00001111' movwf TRISB ;делитель перед таймером коф 1/32 movlw b'11000100' ;подтягивающие резисоры OFF movwf OptionR ;прерывание по переднему фронту плюса bcf STATUS,5 ;переход назад в Банк 0 clrf IntCon ;Заперт всех прерываний bcf PORTA,2 ;тиристор OFF bcf Reg_4,0 ;метка что свет OFF bcf Reg_4,1 ;метка что число яркости не 255 ;========================================================================== ; Опрос кнонпок ;========================================================================= monitor btfss PORTB,1 ; Смотрим кнопку on/off goto on btfss PORTB,2 ; Смотрим кнопку +яркость goto plus btfss PORTB,3 ; Смотрим кнопку -яркость goto minus goto monitor ;==================================================================== ; начинаем включать свет ;=================================================================== on movlw .238 ;delay = 50'000 machine цыклов movwf Reg_1 ;Давим помехи и дребезг movlw .65 movwf Reg_2 wr decfsz Reg_1, F goto wr decfsz Reg_2, F goto wr btfsc PORTB,1 ; Смотрим кнопку on/off ещё раз goto monitor ; Если помеха то в монитор btfsc Reg_4,0 ;смотрим метку включен ли свет goto off ; если если 1 (включен), то off ;------------------------------------------------------------------ bsf Reg_4,0 ;метка что свет включен movlw .30 ;начальное Число яркости 30 movwf Reg_3 ;с которого происходит увелечение movlw b'10010000' movwf IntCon ;Разрешение прерывания по входу RB0/INT ;---------------------------------------------------------------- ;та самая пауза 300 000 чуть меньше пол секунды, если держать выключатель дольше ; то лампа включиться на треть яркости ;----------------------------------------------------------------- ;Пауза = 300'000 machine cycles vkil movlw .153 movwf Reg_1 movlw .134 movwf Reg_2 movlw .2 movwf Reg_5 wi decfsz Reg_1, F goto wi decfsz Reg_2, F goto wi decfsz Reg_5, F goto wi btfsc PORTB,1 ;Смотрим кнопку on/off ещё раз goto iarko ;Если уже не нажата то в iarko goto tusklo ;Если ещё нажато то в tusklo ;================================================================ ; если мы сдесь то выключатель отпустили быстрее чем прошло пол секунды ; тут включаем плавно на всю яркость ;=============================================================== iarko movlw .151 ;пауза = 2'000 машинных цыклов movwf Reg_1 ;отвечает за скорость увелечения яркости movlw .3 ;при включении кнопкой ON/OFF movwf Reg_2 ;быстренько увеличиваем свет wqq decfsz Reg_1, F goto wqq decfsz Reg_2, F goto wqq movf Reg_3,W ; проверим вдруг больше некуда Reg_3 в W bcf STATUS,Z ;опустим флаг Z в ноль xorlw .230 ;проводим сравнение с числом 230 btfsc STATUS,Z ; делаем бит-проверку Z-флага goto nnn ;если Z=1, то число совпало прыг в nnn incf Reg_3,F ;Регистр яркости увеличиваем на 1 goto iarko ;----------------------------------------------------------------------- ; так как с 230 до 255 яркость почти не меняеться мы перескакиваем ;сразу с 230 на 255 чтобы не терять даром время ;-------------------------------------------------------------------- nnn movlw .255 ;Число яркости movwf Reg_3 ;Регистр яркости bsf Reg_4,1 ;метка что число яркости 255 ;----------------------------------------------------------------------- ; Сдесь нарезаем круги если досих пор держут кнопку ON/OFF пока не отпустят ;----------------------------------------------------------------------- smnn movlw .238 ;пауза = 50'000 машинных цыклов movwf Reg_1 ;Давим помехи и дребезг movlw .65 movwf Reg_2 enn decfsz Reg_1, F goto enn decfsz Reg_2, F goto enn btfsc PORTB,1 ;Смотрим кнопку on/off ещё раз goto monitor ;Если уже не нажата то в monitor goto smnn ;Если ещё нажато то в smnn ;=============================================================== ; Сюда попадаем если кнопку ON/OFF держали дольше пол секунды ; лампу включаем на треть яркости ;============================================================== tusklo movlw .90 ;Число яркости 90 примерно треть яркости movwf Reg_3 ;Регистр яркости bcf Reg_4,1 ;метка что число яркости не 255 goto smnn ;==================================================================== ; Сдесь мягко прибавляем яркость пока держат кнопку плюс ;=================================================================== plus btfss Reg_4,1 ;смотрим может яркость 255 goto plusss ;если не 255 то в plusss goto pokrug ;---------------------------------------------------------------------- plusss movlw .21 ;пауза = 7'000 машинных цыклов movwf Reg_1 ;отвечает за скорость прибавления яркости movlw .10 ;пока держут кнопку плюс movwf Reg_2 wq decfsz Reg_1, F goto wq decfsz Reg_2, F goto wq btfsc PORTB,2 ; Смотрим кнопку +яркость ещё раз goto monitor ; Если помеха то в монитор movf Reg_3,W ; содержимое яркости в W (буфер) bcf STATUS,Z ; опустим флаг Z в ноль xorlw .230 ; проводим сравнение с числом 230 btfsc STATUS,Z ; делаем бит-проверку Z-флага goto krug ; если Z=1, то число совпало прыг в krug incf Reg_3,F ;Регистр яркости увеличиваем на 1 goto plusss ;========================================================================= ; Это для того чтобы меньше держать кнопку плюс для выведения полной яркости ;так как с 230 до 255 яркость почти не меняеться ;========================================================================= krug movlw .255 ;Число яркости сразу на 255 movwf Reg_3 ;Регистр яркости bsf Reg_4,1 ;метка что число яркости 255 ;----------------------------------------------------------------------- ; Сдесь нарезаем круги если яркость уже 255 а кнопку всё держат ;---------------------------------------------------------------------- pokrug movlw .238 ;пауза = 50'000 машинных цыклов movwf Reg_1 ;Давим помехи и дребезг movlw .65 movwf Reg_2 vvv decfsz Reg_1, F goto vvv decfsz Reg_2, F goto vvv btfsc PORTB,2 ;Смотрим кнопку +яркость ещё раз goto monitor ;Если уже не нажата то в monitor goto pokrug ;Если ещё нажато то в pokrug ;=============================================================== ; В этом блоке мягко уменьшаем яркость пока держат кнопку минус ;============================================================== minus btfss Reg_4,1 ;смотрим может яркость 255 goto norma ;если не 255 то в norma movlw .230 ;Число яркости резко на 230 если была 255 movwf Reg_3 ;Регистр яркости bcf Reg_4,1 ;метка что яркость не 255 ;---------------------------------------------------------------- norma movlw .21 ;пауза = 7'000 машинных цыклов movwf Reg_1 ;отвечает за скорость убывания яркости movlw .10 ; пока держишь кнопку мнус movwf Reg_2 wp decfsz Reg_1, F goto wp decfsz Reg_2, F goto wp btfsc PORTB,3 ; Смотрим кнопку -яркость ещё разок goto monitor ; Если помеха то в монитор movf Reg_3,W ; проверим содержимое яркости чтобы не переуменьшить bcf STATUS,Z ; опустим флаг Z в ноль xorlw .30 ; проводим сравнение с числом 30(очень тускло) btfsc STATUS,Z ; делаем бит-проверку Z-флага goto san ; если Z=1, то число совпало прыг в san decf Reg_3,F ; Регистр яркости уменьшаем на 1 goto norma ;================================================================= ; В этом блоке нарезаем круги если уже яркость 30 а кнопку минус всё держат ;================================================================ san movlw .238 ;пауза = 50'000 машинных цыклов movwf Reg_1 ;Давим помехи и дребезг movlw .65 movwf Reg_2 nnd decfsz Reg_1, F goto nnd decfsz Reg_2, F goto nnd btfsc PORTB,3 ;Смотрим кнопку минус ещё раз goto monitor ;Если уже не нажата то в monitor goto san ;Если ещё нажато то в san ;======================================================================== ; Сюда попадаем если свет уже горел и нажали кнопку ON/OFF ; и определим сколько времени жали кнопку ON/OFF ;======================================================================= off movlw .153 ;пауза = 300'000 машинных цыклов movwf Reg_1 ;отвечает за отсчет времени movlw .134 ;после которого свет ,будет медленно гаснуть movwf Reg_2 ; если держать дольше 300 000 movlw .2 movwf Reg_5 wii decfsz Reg_1, F goto wii decfsz Reg_2, F goto wii decfsz Reg_5, F goto wii btfsc PORTB,1 ; Смотрим кнопку on/off ещё раз goto bistro ;Если уже не нажата то в bistro goto medlen ; Если ещё нажато то в medlen ;---------------------------------------------------------------------- ; если выключатель держали меньше пол секунды то быстро выключаем свет ;-------------------------------------------------------------------- bistro btfss Reg_4,1 ;смотрим может яркость 255 goto bistroо ;если не 255 то в bistroо movlw .230 ;Число яркости сразу с 255 на 230 movwf Reg_3 ;Регистр яркости bcf Reg_4,1 ;метка что яркость не 255 bistroо movlw .151 ;пауза = 2'000 машинных циклов movwf Reg_1 ;отвечает за быстрое погашение света movlw .3 ;Быстренько гасим свет movwf Reg_2 wrte decfsz Reg_1, F goto wrte decfsz Reg_2, F goto wrte ;------------------------------------------------------------------ movf Reg_3,W ; проверим содержимое яркости чтобы не переуменьшить bcf STATUS,Z ; опустим флаг Z в ноль xorlw .30 ; проводим сравнение с числом 30 (очень тускло) btfsc STATUS,Z ; делаем бит-проверку Z-флага goto rry ; если Z=1, то число совпало прыг в rry decf Reg_3,F ; Регистр яркости уменьшаем на 1 goto bistroо ;----------------------------------------------------------------- rry bcf PORTA,2 ;тиристор OFF clrf IntCon ;Заперт всех прерываний bcf Reg_4,0 ;метка что свет OFF bcf Reg_4,1 ;метка что яркость не 255 goto monitor ; в опрос кнопок ;=============================================================== ; Сдесь медленно гасим свет так как кнопку ON/OFF держали дольше пол секунды ;============================================================== medlen movlw .238 ;пауза = 50'000 машинных цыклов movwf Reg_1 ;Давим помехи и дребезг movlw .65 movwf Reg_2 ncc decfsz Reg_1, F goto ncc decfsz Reg_2, F goto ncc ;--------------------------------------------------------------------- btfsc PORTB,1 ; Смотрим кнопку on/off ещё раз goto med ;Если уже не нажата то в med goto medlen ; Если ещё нажато то medlen med btfss Reg_4,1 ;смотрим может яркость 255 goto medlennn ;если не 255 то в medlennn movlw .230 ;Число яркости сразу с 255 на 230 movwf Reg_3 ;в Регистр яркости число 230 bcf Reg_4,1 ;метка что яркость не 255 ;-------------------------------------------------------------------------- medlennn movlw .205 ;пауза = 150'000 машинных циклов movwf Reg_1 ;отвечает за медленную скорость погашения света movlw .195 ;очень медленно гасим свет movwf Reg_2 wrt decfsz Reg_1, F goto wrt decfsz Reg_2, F ; А вдруг пока свет медленно гаснет goto wrt ; возникла необходимость его опять включить btfss PORTB,1 ; Смотрим кнопку on/off ещё раз goto vkil ; Если нажата то vkil ;---------------------------------------------------------- movf Reg_3,W ; проверим содержимое чтобы не переуменьшить bcf STATUS,Z ; опустим флаг Z в ноль xorlw .30 ; проводим сравнение с числом 30 (очень тускло) btfsc STATUS,Z ; делаем бит-проверку Z-флага goto rry ; если Z=1, то число совпало прыг в rry decf Reg_3,F ; Регистр яркости уменьшаем на 1 goto medlennn ;будем уменьшать пока чило не = 30 ;============================================================ end