      #include p16f84a.inc
       __config b'11111111110010'    ; последние два бита11-RC    10-HS
                    ;переменные
     cblock 0x15               

                   ;для сохранения контекста
	rTempW
	rTempZ
	rTempSTATUS
                    ;для шим
	rShimFlag     ;флаг тек.уровня шим
	rStop         ; регистр СТОП
	rPOL          ; регистр длительность +
	rNEG          ; регистр длительность -
	rDir

	rcnt1         ; Счетчики времени
	rcnt2
	rcnt3	
     endc  
					        ; Константы скорости
							; чтобы частота не менялась надо чтобы сумма верхних двух
							; и нижних двух констант была одинакова.Тогда периоды
							; ШИМа будут равны.И конечно нельзя задавать значения
							; более 250...чтобы оставалось время на обработку прерыв
  
	cPOL_Rapido_Fechar   equ .130		; константы для быстрого ЗАКРытия 
	cNEG_Rapido_Fechar   equ .170		;
	
	cPOL_Devagar_Fechar  equ .145		; константы для медленного ЗАКРытия
	cNEG_Devagar_Fechar  equ .155		; 
	
	cPOL_Rapido_Abrir    equ .170		; константы для быстрого ОТКРытия
	cNEG_Rapido_Abrir    equ .130		;

	cPOL_Devagar_Abrir   equ .155		; константы для медленного ОТКРытия
	cNEG_Devagar_Abrir   equ .145		;

	cPOL_Stop  			 equ .150 		; константы для СТОП
	cNEG_Stop  			 equ .150	 	;
                             


	 org 0
     goto start
;------------------------------------------
        ;вектор прерывания
	 org 4
     goto interrupt
;------------------------------------------
start                    ;инициализация спец регистров
    bcf STATUS,RP1
    bcf STATUS,RP0
    bcf INTCON,GIE       ;глоб запрет прерываний
    bsf INTCON,T0IE      ;разреш прерыв от таймера
    bsf STATUS,RP0
    movlw b'10010000'    ;преддел TMR0 включен. Последние 3 разряда 
    movwf OPTION_REG
	clrf TRISB 
    bcf STATUS,RP0
;------------------------------------------
    
	clrf rStop     
	clrf rNEG
	clrf rPOL
    clrf rShimFlag
    clrf PORTB
    clrf TMR0
                          ;конец инициализации
    bsf INTCON,GIE ;разреш прерываний
;----------------------------------------------------------------------------
; Основная программа 
main

proga
	call  Stop
	call  delay
	call  Devagar_Fechar
	call  delay 
	call  Rapido_Fechar
	call  delay
	call  Devagar_Fechar
	call  delay 
	call  Stop
	call  delay
	call  Devagar_Abrir
	call  delay
	call  Rapido_Abrir
	call  delay
	call  Devagar_Abrir
	call  delay
	goto proga



Rapido_Fechar
	movlw cPOL_Rapido_Fechar
	movwf rPOL
	movlw cNEG_Rapido_Fechar
	movwf rNEG
	return

Devagar_Fechar
	movlw cPOL_Devagar_Fechar
	movwf rPOL
	movlw cNEG_Devagar_Fechar
	movwf rNEG
	return

Rapido_Abrir
	movlw cPOL_Rapido_Abrir
	movwf rPOL
	movlw cNEG_Rapido_Abrir
	movwf rNEG
	return
	return	

Devagar_Abrir
	movlw cPOL_Devagar_Abrir
	movwf rPOL
	movlw cNEG_Devagar_Abrir
	movwf rNEG
	return

Stop
	movlw cPOL_Stop
	movwf rPOL
	movlw cNEG_Stop
	movwf rNEG
	return


	             
delay
		movlw .255         ;    предуст.счетчиков
		movwf rcnt1
            movlw .255
            movwf rcnt2
                movlw .30
                movwf rcnt3      
                                                     
dloop
                decfsz rcnt1,1    ; вычитается 1. Если результат
		        goto $+2          ; равен 0 то пропускается след
                decfsz rcnt2,1    ; операция
	            goto dloop          
                decfsz rcnt3,1      
                goto dloop
                return 
  	    
;----------------------------------------------------------------------------
;Обработчик прерывания
interrupt
                                            ;сохранение контекста
    movwf rTempW                                ;сохраняем W
    movf STATUS,w                                
    movwf rTempSTATUS                           ;сохраняем STATUS 

	btfss rShimFlag,0                ; проверка текущего флага   
    goto PWM_ON
    goto PWM_OFF

PWM_ON
	bsf   rShimFlag,0           ; ВКЛючаем rShimFlag

	bcf  PORTB,1				; ВЫКЛючаем диагональ  1-2	
	bcf  PORTB,2
	nop
	nop
	nop				
	bsf  PORTB,0				; ВКЛючаем диагональ  0-3                  
	bsf  PORTB,3                         
    goto Exit_InstTMR0_OFF

	    	
PWM_OFF 
	bcf   rShimFlag,0			; ВЫКЛючаем rShimFlag	
                      
	bcf   PORTB,3				; ВЫКЛючаем диагональ  3-0
	bcf   PORTB,0
	nop
	nop
	nop
	bsf   PORTB,2				; ВКЛючаем диагональ  2-1				
	bsf   PORTB,1
	goto Exit_InstTMR0_ON
	
	
Exit_InstTMR0_ON
	movfw rNEG             ; задание длит паузы.   
    movwf TMR0             
	goto RezetTOIF         

Exit_InstTMR0_OFF
	movfw rPOL             ; задание длит импульса
    movwf TMR0		
	goto RezetTOIF

RezetTOIF
	bcf INTCON,T0IF        ;сброс флага прерывания по таймеру
                   
					        ;восстановление контекста
    movf rTempSTATUS,w
    movwf STATUS
    movf rTempW,w

    retfie                                     ;возврат с разрешением прерываний
;------------------------------------------
  end
