.INCLUDE     "tn2313def.inc"
;==============================================================
;Програма управляемого ШИМа для AT90S1200
; 5 уровней регулирвки скважности ШИМ
;==============================================================
.ORG 000                                      ;Вектор сброса
                    rjmp reset   
 
.ORG 006                                      ;Вектор прерывания по переполнению таймера
                  inc r27                         ;Додаем единицу к регистру r27
                  sbrc r27,0                   ;Проверяем на четность младший бит r27
                  rjmp pause                 ;Если четный то пауза
                  sbrs r27,0                   ;Проверяем на четность младший бит r27
                  rjmp impulse              ;Если не четный то импульс
pause:
                   cbi portb,3                ;Устанавливаем на выводе PB3 логический 0
                   out tcnt0,r28             ;Загружаем таймер длительностю логической 1
                   rjmp exit_timer         ;Идем на выход из прерывания
impulse:
                   sbi portb,3                ;Устанавливаем на выводе PB3 логический 1
                   out tcnt0,r29             ;Загружаем таймер длительностю логического 0
                   rjmp exit_timer         ;Идем на выход из прерывания
exit_timer:
                   reti                             ;Выход из процедуры припывания


reset:
                  ldi R31,RamEnd       ;установка указателя стека
                  out SPL,R31

				  
	ldi r31,$18           ;настраиваем порт В
                  out ddrb,r31        ;PB0,PB1,PB2--как входы,а PB3,PB4--как выходы
                  ldi r28,$99          ;Задаем начальную длительность импульса
                  ldi r29,$66          ;Задаем начальную длительность паузы
                  ldi r31,$17          ;Включаем подтягивающие резисторы
                  out portb,r31      ;к входам PB0,PB1,PB2
                  ldi r31,$01         ;Настраиваем роботу таймера
                  out tccr0,r31      ;Тактировка от частоти генратора МК без делителя
                  ldi r31,$02
                  out timsk,r31     ;Розрешение прерывания от таймера
stop:
                  cbi portb,4         ;Сбрасываем вывод PB4 в ноль чем зажыгаем светодиод
                  ldi r27,$0           
                  rjmp scan1        ;Отправляемся на сканирование клавиатуры
scan1:
                  sbis pinb,0        ;Если нажата кнопка ON/OFF(PD0)
                  rjmp start           ;то идем на старт
                  sbis pinb,1        ;Если нажата кнопка "+"(PD1)
                  rjmp start           ;то идем на старт
                  sbis pinb,2        ;Если нажата кнопка "-"(PD2)
                  rjmp start          ;то идем на старт
                  rjmp scan1        ;Если ничего не нажато то повторяем цыкл сканирования клавиатуры заново
start:
                  sbi portb,4             ;Устанавливаем лог.1 на выводе PB4 чем гасим светодиод
                  sbi portb,3             ;Устанавливаем лог. 1 на выходе ШИМ (PB3)
                  out tcnt0,r29          ;Загружаем в таймер счечик начальное значение длины импульса ШИМа
                  sei                          ;Разрешаем прерывания
                  rcall pause_scan   ;Вызываем подпрогаму задержки
                  rjmp scan2             ;Переходим на сканирование клавиатуры
scan2:
                  sbis pinb,0             ;Если нажата кнопка ON/OFF(PD0)
                  rjmp off                    ;то переходим на на часть програмы выключение
                  sbis pinb,1              ;Если нажата кнопка "+"(PD1)
                  rjmp plus                  ;то переходим на часть програмы увеличения значения ШИМ
                  sbis pinb,2              ;Если нажата кнопка "-"(PD2)
                  rjmp minus                ;то переходим на часть програмы уменьшения значения ШИМ
                  rjmp scan2               ;Если нечего не нажато то повторяем цыкл сканирования клавиатуры заново
off:            
                  cli                                ;Запрещаем все прирывания и от таймера в том числе
                  cbi portb,3                 ;Устанавливаем на выходе ШИМа (PB3)  лог. 0
                  rcall pause_scan      ;Вызываем подпрограму задержки сканирования клавиатуры
                  rjmp stop                    ;Идем в начало програми на метку stop
plus:
                  ldi r26,$ff                     ;Задаем максимальное значение ШИМ                
                  cpse r26,r28               ;Проверяем не максимальное ли значение
                  rjmp plus1                   ;если нет то идем на часть програмы увеличения значения ШИМ
                  rjmp scan2                  ;если максимальное значение то идем назад на сканирование кнопок
minus:
                  ldi r26,$33                   ;Задаем минимальное значение ШИМа
                  cpse r26,r28                ;Проверяем ни минимальное ли значение
                  rjmp minus1                 ;если нет то идем на часть програмы уменьшения значения ШИМа
                  rjmp scan2                   ;Если же значение минимальное то возвращаемся на цыкл сканирования клавиатуры
plus1:
                  ldi r26,$33                    ;Задаем дискретность ШИМа тоесть значение на которое будет увеличиватся или уменшатся значение ШИМ
                  add r28,r26                  ;Увеличиваем длительность импульса
                  sub r29,r26                   ;Уменьшаем значение паузы
                  rcall pause_scan         ;Вызываем подпрограму задержки
                  rjmp scan2                    ;Возвращаемся назад на сканирование клавиатуры
minus1:
                  ldi r26,$33                    ;Задаем дискретность ШИМа тоесть значение на которое будет увеличиватся или уменшатся значение ШИМ   
                  add r29,r26                  ;Увеличиваем длительность паузы ШИМа
                  sub r28,r26                   ;Уменьшаем длительность импульса ШИМа
                  rcall pause_scan          ;Вызываем подпрограму задержки
                  rjmp scan2                   ;Возвращаемся назад на сканирование клавиатуры
;==============================================================
;Подпрограма задержки.Основная задача етой подпрограмы защита от дребезга контактов кнопок а также задает интервал с которым будет действовать автоповтор при удержании кнопки.
;==============================================================
pause_scan:
                   ldi	r25,3
D100_3:	clr	r24          ;Обнуляем регистр
D100_2:	clr	r23          ;Обнуляем регистр
D100_1:	dec	r23          ;Отнимаем единицу от значения даного регистра
	brne	D100_1  ;Проверяем условие перехода
	dec            r24          ;Отнимаем единицу от значения даного регистра
	brne	D100_2   ;Проверяем условие перехода
	dec	R25          ;Отнимаем единицу от значения даного регистра
	brne	D100_3   ;Проверяем условие перехода
	ret                               ;выходим из подпрограмы

.EXIT

