; Программа управления морозильником через энкодер и индикацией на символьном дисплее WH2004
; подключены 2 датчика DS18B20 и управлется 1 канал ШИМ(для подсветки)
; Автор: Феклистов Андрей
; Кодировка Win 1251!!!!
;*****************************************************************************
 ; Конфигурация   
 ;   list     p=16f1937  
#include "p16F1937.inc"

; CONFIG1
; __config 0x9A4
 __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
; CONFIG2
; __config 0x1BFF
 __CONFIG _CONFIG2, _WRT_OFF & _VCAPEN_OFF & _PLLEN_ON & _STVREN_ON & _BORV_HI & _LVP_OFF
;*****************************************************************************
T1m		equ 20h  
T2m		equ 21h  
T3m		equ 22h 
T1		equ 23h 
T2		equ 24h  
T3		equ 20h  

povtor		equ 25h  
stroka		equ 26h  
encoder		equ 27h  
encoder_temp	equ 28h  
schet		equ 29h  
T_ust_start	equ 2Ah 
T_ust_end	equ 2Bh 
T_ust_gist	equ 2Ch  
Timer_period	equ 2Dh 
Reg		equ 2Eh  
sotni		equ 2Fh 
desyatki	equ 30h  
edenici		equ 31h 
temp_BIN	equ 32h  
selection	equ 33h  
Temp		equ 34h  
Temp_doli	equ 35h  
Temp_doli4	equ 34h  
DATA_EE_ADDR	equ 37h  
DATA_EE_DATA	equ 38h 
N          	equ 39h          ; Счетчик битов.
Count      	equ 3Ah          ; Многофункциональный регистр временного хранения.
Temp_MSB    	equ 3Bh          ; Байт знака температуры (старший байт).
Temp_LSB    	equ 3Ch          ; Байт значения температуры (младший байт).
grad	   	equ 3Dh  
grad_bin  	equ 3Eh  	
temp_grad   	equ 3Fh  
temp_des   	equ 40h  	
temp	  	equ 41h 
temp_bin	equ 42h  
temp_grad_din	equ 43h  	;Это текущая температура временные ячейки
temp_des_din	equ 44h  	;Это текущая температура
doli_din	equ 45h	;Это текущая температура
doli		equ 46h 
temp_grad_din1	equ 47h  	;Это текущая температура 1 датчика
temp_des_din1	equ 48h  	;Это текущая температура
doli_din1	equ 49h	;Это текущая температура
ADRES_TEMP	equ 4Ah  
		  
flag_min	equ 4Bh	; 0 - фременный флаг минуса для обоих датчиков
			; 1 - флаг "-" для первого датчика в САР
			; 2 - флаг "-" для второго датчика в САР
		  
Flag_ust_min	equ 4Ch	; 0 - общий временный флаг
			; 1 - флаг для T_ust_start и T_ust_var
			; 2 - флаг для T_ust_end
			; 3 - флаг для T_ust_HI(Вроде не использую)
			; 4 - флаг для T_ust_LOW
			; (5 - флаг для T_ust_var)
			
flag_step	equ 4Dh  	; 1 - флаг прохождения T_ust_start
			; 2 - флаг достижения T_ust_LOW
			; 3 - флаг достижения T_ust_HI
			; 4 - флаг включения таймера
schet_temp	equ 4Eh  
schet_print	equ 4Fh  
temp_procent	equ 50h  
CCPR3L_temp	equ 51h   
grad_1	    	equ 52h   
		
T_ust_des 	equ 53h   	; для хранения зоны гистерезиса
T_ust	    	equ 54h   	; и врем ячейки для её формирования
T_ust_doli	equ 55h   
T_ust_HI_des	equ 56h   	
T_ust_HI	equ 57h   
T_ust_HI_doli	equ 58h   
T_ust_LOW_des	equ 59h   
T_ust_LOW    	equ 5Ah  
T_ust_LOW_doli	equ 5Bh   
T_ust_gist_edinici	  equ 5Ch     
T_ust_gist_doli	   	  equ 5Dh   
T_ust_var_des	   	  equ 5Eh   ; для хранения постоянно изменяющейся уставки
T_ust_var	  	  equ 5Fh     
T_ust_var_doli		  equ 60h   
T_ust_start_des		  equ 61h	; для хранения стартовой уставки
T_ust_start_edenici	  equ 62h  
Timer_period_temp	  equ 63h   ; ячеки для работы таймера
timer_temp_HI		  equ 64h  
timer_temp_LOW		  equ 65h  
schet_enc		  equ 66h  
T_ust_end_ed		  equ 67h 
T_ust_end_des		  equ 68h
CCPR3L_temp_100		  equ 69h
PCLATH_TEMP 		  equ 6Ah
 
#define INT	PORTB,0
#define RS	PORTD,0
#define RW	PORTD,1
#define E	PORTD,2	
#define LCD_DB	PORTC   
;----------------------
DQ          equ        2           ; Бит порта B для управления DS1820.	
DQ2         equ        3           ; Бит порта B для управления DS1820 #2.
   	
;----------------------
;*****************************************************************************
;макросы
запрещено macro
		bcf 	INTCON,7
		endm
можно macro
		bsf 	INTCON,7
		endm
;*****************************************************************************
	org 000h                ; Вектор сброса
	goto Startik

        org 004h	
		movf        PCLATH,0          ;запись содержимого регистра PCLATH в
		movwf       PCLATH_TEMP       ;регистр PCLATH,TEMP
    ;    PAGESEL START_PAGE
		goto PRERIV	; Вектор прерывания
;*****************************************************************************
    org 020h
;****************************
    ; Очистка RAM
;****************************
Startik	
min	equ	H'0b'
max	equ	H'6f'

	movlw	max
	movwf	FSR0L
metka	clrf	INDF0
	decf	FSR0L,F
	movlw	min
	xorwf	FSR0L,W
	btfss	STATUS,Z
	goto	metka 
;*****************************	
;	PAGESEL INIT
		call INIT
		call INIT_LCD
		call vostanovlenie
;	PAGESEL START_PAGE
		;clrf PCLATH
		goto START
;=====================
;START_PAGE  ; тупая программа для выполнения функции PAGESEL
		nop
		return
;==============================================================================
START
;==============================================================================
	;можно
	call datchiki
;    PAGESEL SAR_1
	call SAR_1	; здесь формируем границы гистереза
	call SAR_2	; здесь сраниваем значение уставок и управляем морозилкой
	call SAR_3
;    PAGESEL START_PAGE
	
  	btfsc flag_step,1   ; прошли мы первый этап охлождения ?
	;call Timer_verefi   ; да. тогда запускаем/сверяем таймер
	goto call_T
	goto START	    ; нет - идем в начало.
call_T	
;    PAGESEL Timer_verefi
	call Timer_verefi   ; да. тогда запускаем/сверяем таймер
 ;   PAGESEL START_PAGE
	goto START
;*****************************************************************************;*****************************************************************************
; обработка прерывания
;*****************************************************************************;*****************************************************************************
PRERIV
	BANKSEL INTCON
    	bcf INTCON,7		;запрет всех прерываний
	btfsc PIR1, TMR1IF	; есть ли флаг прерывания от таймера?
	goto TIMER_restart
				; иначе обрабатываем прерывание от кнопки
    	bcf INTCON,1		;сброс флага INT
;************************************************
; сразу настраиваемся на регулировку первого параметра
    BANKSEL T_ust_start  ; копируем во временную ячеку текушую уставку
    movf    T_ust_start,0
    BANKSEL schet 
    movwf   schet
; и занимаем место на экране
    movlw   05h  
    movwf   ADRES_TEMP
    call    SET_ADRES
;**************************************** 
; Первоначальный опрос энкодера
;**************************************** 
    BANKSEL PORTD
    call pause
    btfss PORTD,6
    goto нол_0
    bsf encoder,0
    goto след
нол_0
    bcf encoder,0
след
    btfss PORTD,7
    goto нол_1
    bsf encoder,1
    goto след_2
нол_1
    bcf encoder,1
    
след_2 	
;**************************************** 
snova
    btfsc INTCON,1 ; проверяем, было ли снова нажатие на кнопку выбора
    goto vibor
    goto em
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++    
vibor
        movlw	.250
	call pause_T2
     	bcf INTCON,1		;сброс флага INT

    btfsc selection,1
    goto set_2
    btfsc selection,2
    goto set_3
    btfsc selection,3
    goto set_4
    btfsc selection,4
    goto set_5
    btfsc selection,5
    
 ;   PAGESEL  SAR_1
   	call SAR_1
 ;   PAGESEL PRINT_T_us
    	call PRINT_T_us
 ;   PAGESEL START_PAGE
    goto vihod

set_2
	bcf selection,1	    ; записываем наше местоположение
	bsf selection,2
        movf    T_ust_end,0 ; копируем во временную ячеку текушую уставку
        movwf   schet
	movlw   45h		    ; и занимаем место на экране
	movwf   ADRES_TEMP
	call    SET_ADRES
	goto	em
set_3
	bcf selection,2
	bsf selection,3
	movf    T_ust_gist,0
	movwf   schet
	movlw   19h  
	movwf   ADRES_TEMP
	call    SET_ADRES
	goto	em
set_4
	bcf selection,3
	bsf selection,4
	movf    Timer_period,0
	movwf   schet
	movlw   59h
	movwf   ADRES_TEMP
	call    SET_ADRES
	goto	em
set_5
	bcf selection,4
	bsf selection,5
	movf	CCPR3L_temp_100,0
	movwf	schet
	movlw   24h
	movwf   ADRES_TEMP
	call    SET_ADRES
	goto	em
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++    
em
    btfss PORTD,6
    goto но_0
    bsf encoder_temp,0
    goto следу
но_0
    bcf encoder_temp,0
следу
    btfss PORTD,7
    goto но_1
    bsf encoder_temp,1
    goto следу_2
но_1
    bcf encoder_temp,1
следу_2 
  ; определяем текущее сотояние(temp)
   btfsc encoder,1	; если первый бит равен 1 
   goto __10_11		; - значит проверяем на 10 или 11
			; иначе проверяем нулевой бит 
   btfss encoder,0	; если нулевой бит равен 0 
   goto __00		; - значит  это 00
   goto __01		; иначе - еденица - значит это 01
__10_11
   btfss encoder,0	; если нулевой бит равен 0 
   goto __10		; - значит  это 00
   goto __11		; иначе - еденица - значит это 01
__00   ; если было 00
   btfsc encoder_temp,1	; если первый бит равен 1 
   goto plus_enc		; - значит однозначно плюс
   btfss encoder_temp,0	; если нулевой бит равен 0 
   goto snova		; - значит ничего не изменилось
   goto minus_enc		; иначе - еденица - значит это минус
__11   ; если было 11
   btfss encoder_temp,0	; если нулевой бит равен 0 
   goto minus_enc		; - значит однозначно минус
   btfsc encoder_temp,1	; если первый бит равен 1 
   goto snova		; - значит ничего не изменилось
   goto plus_enc		; иначе - 0 - значит это плюс
__01   ; если было 01
   btfss encoder_temp,0	; если нулевой бит равен 0 
   goto plus_enc		; - значит однозначно плюс
   btfss encoder_temp,1	; если первый бит равен 0 
   goto snova		; - значит ничего не изменилось
   goto minus_enc		; иначе - еденица - значит это минус
__10   ; если было 10
   btfss encoder_temp,1	; если первый бит равен 0 
   goto minus_enc		; - значит однозначно минус
   btfss encoder_temp,0	; если нулевой бит равен 0 
   goto snova		; - значит ничего не изменилось
;   goto plus_enc		; иначе - еденица - значит это плюс
   
plus_enc
    movf encoder_temp,0	; теперь принимаем временные данные за начальное состояние.
    movwf encoder
    incf schet_enc
    movlw   .3
    subwf   schet_enc,0
    btfss STATUS,C
    goto snova
plus
    clrf schet_enc
    incf schet
    goto minus_li
   
minus_enc
    movf encoder_temp,0	; теперь принимаем временные данные за начальное состояние.
    movwf encoder
    incf schet_enc
    movlw   .3
    subwf   schet_enc,0
    btfss STATUS,C
    goto snova
minus
    clrf schet_enc
    decf schet	    ;    goto minus_li
 ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
minus_li
	btfsc selection,1   ; а может у нас сейчас не температура?
	goto min_li
	btfsc selection,2
	goto min_li
	goto temp_to_enc 
			    ; а нет! все таки уставки! 
min_li			    
	btfss schet,7	    ; проверить старший бит в ячейке schet
	goto temp_to_enc    ; если там 0 - обрабатываем как раньше
			    ; иначе у нас минус!!! (работает такая проверка только до -128)
	bsf Flag_ust_min,0  ; устанавливаем флаг отрицательной уставки
	comf schet,0	    ; инвертируем значение в регистре и сохраняем в W
	movwf	schet_temp  ; копируем полученое значение во временную ячейку
	goto temp_to_enc_min
 
 
temp_to_enc
    movf    schet,0
    movwf   schet_temp 
    bcf Flag_ust_min,0	    ; в это место мы могли перейти только в случае положительных уставок
			    ; поэтому можно смело убирать флаг "минуса"
temp_to_enc_min 
    movf encoder_temp,0	; теперь принимаем временные данные за начальное состояние.
    movwf encoder
    ;Устанавливаем заполнение ШИМ	;(только если настраивается последний параметр!!!)
    movf schet_temp,0	; копируем в аккумулятор значение нового заполнения ; иначе просто копируем уставки куда нужно)   
			; и ищем, куда его копировать
    btfsc selection,1
    goto set_10
    btfsc selection,2
    goto set_20
    btfsc selection,3
    goto set_30
    btfsc selection,4
    goto set_40
    btfsc selection,5
    goto set_50
;_______________________________________________________________________________
set_10  
	movwf   T_ust_start ; копируем новые значения в уставку текущего параметра
       	movlw	.50	;Сотен быть не может, максимум 50(даже это много).
	subwf	T_ust_start,0
	btfss STATUS,C
	goto	BG1
	goto	МНОГО
BG1	
	movf	schet_temp,0
	movwf	schet_print
	goto	BG2
МНОГО	
	movlw	.50
	movwf	schet_print ; выводим максимально возможные показания
	movwf   T_ust_start ; и не забываем скопировать их в уставку
	movwf	schet
BG2	
	call	BINtoDEG	    ; перенес сюда, по тому что эта операция общая для "+" и "-"
	movfw	edenici		    ; для САР
	movwf	T_ust_start_edenici
	movwf	T_ust_var
	movfw	desyatki
	movwf	T_ust_start_des 
	movwf	T_ust_var_des
	clrf	T_ust_var_doli
	btfss Flag_ust_min,0  ; сотен быть у на сне может. там должен стоять знак + или -
	goto PR_plus	    ; поэтому проверяем на наличие флага
	bsf Flag_ust_min,1  ; и не забываем сразу поставить флаг минуса для дальнейшего сравнения
	bsf Flag_ust_min,5
	movlw	.3	    ; если "-" то нужно отнять 3 знака от ноля 
	subwf	sotni,1
	call PRINT
	goto  snova2
PR_plus	
	bcf Flag_ust_min,1  ; и не забываем сразу убрать флаг минуса для дальнейшего сравнения
    	bcf Flag_ust_min,5
	movlw	.5	    ; если "+" то нужно отнять 5 знаков от ноля 
	subwf	sotni,1
	call PRINT
	goto  snova2
;_______________________________________________________________________________
set_20
	movwf   T_ust_end
    	movlw	.50	    ;Сотен быть не может, максимум 50(даже это много).
	subwf	T_ust_end,0
	btfss STATUS,C
	goto	BG1_2
	goto МНОГО_2
BG1_2	
	movf	schet_temp,0
	movwf	schet_print
	goto	BG2_2
МНОГО_2	
	movlw	.50
	movwf	schet_print ; выводим максимально возможные показания
	movwf   T_ust_end   ; и не забываем скопировать их в уставку
BG2_2	
	call BINtoDEG	    ; перенес сюда, по тому что эта операция общая для "+" и "-"
	movfw	edenici		    ; для САР
	movwf	T_ust_end_ed
	movfw	desyatki
	movwf	T_ust_end_des 
	btfss Flag_ust_min,0  ; сотен быть у на сне может. там должен стоять знак + или -
	goto PR_plus_2	    ; поэтому проверяем на наличие флага
	bsf Flag_ust_min,2  ; и не забываем сразу поставить флаг минуса для дальнейшего сравнения
	movlw	.3	    ; если "-" то нужно отнять 3 знака от ноля 
	subwf	sotni,1
	call PRINT
	goto  snova2
PR_plus_2
	bcf Flag_ust_min,2  ; и не забываем сразу убрать флаг минуса для дальнейшего сравнения
    	movlw	.5	    ; если "+" то нужно отнять 5 знаков от ноля 
	subwf	sotni,1
	call PRINT
	movfw   T_ust_end  ; после плясок с бубном копируем значение регистра в shet
	movwf	schet
	goto  snova2
;_______________________________________________________________________________
set_30
        movwf   T_ust_gist
	movlw	.5	    ;ноля быть не может, минимум 05
	subwf	T_ust_gist,0
	btfss STATUS,C
	goto	МАЛО_3
	movlw	.99	    ;Сотен быть не может, максимум 99
	subwf	T_ust_gist,0
	btfss STATUS,C
	goto	BG1_3
	goto МНОГО_3
BG1_3	
	movf	T_ust_gist,0
	movwf	schet_print
	goto	BG2_3
МАЛО_3	
	movlw	.05
	movwf	schet_print ; выводим минимально возможные показания
	movwf   T_ust_gist  ; и не забываем скопировать их в уставку
	goto	BG2_3
МНОГО_3	
	movlw	.99
	movwf	schet_print ; выводим максимально возможные показания
	movwf   T_ust_gist  ; и не забываем скопировать их в уставку
BG2_3	
	call BINtoDEG	    
	movfw	desyatki    ; сдвигаем десятки на место сотен
	movwf	sotni
	movwf	T_ust_gist_edinici  ; для САР
	clrf	desyatki
	movlw	.4	    ; для постановки запятой, нужно отнять 4 знака от ноля 
	subwf	desyatki,1
	movfw	edenici
	movwf	T_ust_gist_doli  ; для САР
	call PRINT
	movfw   T_ust_gist  ; после плясок с бубном копируем значение регистра в shet
	movwf	schet
	goto  snova2
;_______________________________________________________________________________
set_40
        movwf   Timer_period
	movlw	.1		;ноля быть не может, минимум 1
	subwf	Timer_period,0
	btfss STATUS,C
	goto	МАЛО_4
	movlw	.72		;Сотен быть не может, максимум 72
	subwf	Timer_period,0
	btfss STATUS,C
	goto	BG1_4
	goto МНОГО_4
BG1_4	
	movf	Timer_period,0
	movwf	schet_print
	goto	BG2_4
МАЛО_4	
	movlw	.01
	movwf	schet_print ; выводим минимально возможные показания
	movwf   Timer_period  ; и не забываем скопировать их в уставку
	goto	BG2_4
МНОГО_4	
	movlw	.72
	movwf	schet_print ; выводим максимально возможные показания
	movwf   Timer_period  ; и не забываем скопировать их в уставку
BG2_4	
	call BINtoDEG	    
	movfw	desyatki    ; сдвигаем десятки на место сотен
	movwf	sotni
	movfw	edenici	    ; сдвигаем еденицы на место десяток
	movwf	desyatki
	clrf	edenici
	call PRINT
	movfw   Timer_period  ; после плясок с бубном копируем значение регистра в shet
	movwf	schet
	movwf	Timer_period_temp   ; и во временный регистр для обратного отсчета
	goto  snova2
;_______________________________________________________________________________
set_50
	movwf   CCPR3L_temp_100
	btfsc CCPR3L_temp_100,7	;минуса быть не может, минимум 0
	goto	МАЛО_5
	movlw	.100		;Сотен быть не может, максимум 100%
	subwf	CCPR3L_temp_100,0
	btfss STATUS,C
	goto	BG1_5
	goto МНОГО_5
МАЛО_5	
	movlw	.00
	movwf	schet_print ; выводим минимально возможные показания
	goto	BG2_5
МНОГО_5	
	movlw	.100
	movwf	schet_print ; выводим максимально возможные показания
	goto	BG2_5
BG1_5	
	movf	CCPR3L_temp_100,0
	movwf	schet_print
BG2_5	
	movfw schet_print; теперь нужно умножить на 2,5
	movwf temp_procent
	movfw schet_print
	addwf temp_procent,1
	RRF schet_print,0
	addwf temp_procent,1
	call BINtoDEG	    
	call PRINT
	movfw	temp_procent	; копируем полученое значение в ШИМ
    BANKSEL CCPR3L
	movwf CCPR3L
    BANKSEL schet_print
    	movfw   schet_print  ; после плясок с бубном копируем значение регистра в shet
   	movwf	schet
	movwf	CCPR3L_temp_100 ;goto  snova2
;_______________________________________________________________________________  
snova2
    BANKSEL PORTA
    goto snova
;************************************************
TIMER_restart	;обработка прерывания от таймера
;************************************************
      ; заново частично заполняем таймер
  	movlw    03Dh		; частично заполняем таймер
	movwf	TMR1H
	movlw    0A0h
	movwf	TMR1L		; для задания периода в 50мс
	bcf	PIR1, TMR1IF	; сбрасываем флаг этого прерывания
	
	decfsz	timer_temp_LOW,1; декрементируем младший регистр 
	goto vihod_timer	; если не 0, то выходим
	movlw	0FFh		; если 0 - то заново заполняем этот регистр
	movwf	timer_temp_LOW
	decfsz	timer_temp_HI,1	; декрементируем старший регистр 
	goto vihod_timer	; если не 0, то выходим
	movlw	068h		; если 0 - то заново заполняем оба регистра(hi=30, low=68)
	movwf	timer_temp_LOW
	movlw	030h
	movwf	timer_temp_HI
				; декрементируем значение таймера на экране
	decfsz	Timer_period_temp,1
	goto PRINT_I_vihod     	; если не 0, то выходим
				; если 0 - то меняем текущую уставку
	movf Timer_period,0	; не забыв заново загрузить таймер
	movwf Timer_period_temp
	
	btfss	Flag_ust_min,1
	goto	polozit_ust_var   ;флага нет, значит уставка положительная
	goto	otricat_ust_var   ;есть флаг, значит арифметика будет другая
polozit_ust_var
	bcf  Flag_ust_min,1	; изначально сбрасываем флаги
	movlw	.5		; загружаем в W дольную часть дельты температуры
	subWF	T_ust_var_doli,1 ; и вычитаем из дольной часть уставки 
	btfsc STATUS,C		; результат меньше 0?
	goto PRINT_I_vihod	; нет(в данном случае такого быть может)
				; иначе результат отрицательный
	movlw	.10		; значит нужно к полученному значению
	ADDWF	T_ust_var_doli	; прибавить 10 едениц,
				; которые позаимствуем в еденицах
	movlw	.1		;
	subWF	T_ust_var,1	    		
	btfsc STATUS,C		; результат меньше 0?
	goto PRINT_I_vihod	; нет
				; да меньше
	movlw	.10		; значит нужно к полученному значению
	ADDWF	T_ust_var	; прибавить 10 едениц,
				; которые позаимствуем в десятках
	movlw	.1		; 
	subWF	T_ust_var_des,1	;
	btfsc STATUS,C		; результат меньше 0?
	goto PRINT_I_vihod	; нет
				; да меньше
	bsf  Flag_ust_min,1	; установливаем флаг отрицательной уставки			    
	incf T_ust_var_des	; прибавить обратно еденичку к десяткам		    
	movlw	.10		; обатно отнимаем 10 к еденицам
	subWF	T_ust_var,1			    
	comf T_ust_var		; инвертируем полученное значение
	goto PRINT_I_vihod			    
otricat_ust_var
	bsf  Flag_ust_min,1	; изначально ставим флаги
	movlw	.5		; загружаем в W дольную часть дельты температуры
	ADDWF	T_ust_var_doli	; и прибавляем к дольной часть уставки
				; проверяем, а не больше 10 едениц в регистре
	movlw	.10		; 
	subWF	T_ust_var_doli,0; отнимаем 10 едениц, с сохранением в W
	btfss	STATUS,C	; результат меньше 0?
	goto	PRINT_I_vihod	; да, значит идем дальше к целым числам
				; нет, т.е. результат больше 10 едениц
	movlw	.10		; значит от полученного значения
	subWF	T_ust_var_doli	; отнимаем 10 едениц,
				; которые приплюсуем к еденицам
	movlw	.1		;
	addWF	T_ust_var    	;
	movlw	.10		; и проверим, а не больше 10 едениц в регистре
	subWF	T_ust_var,0    	; отнимаем 10 едениц, с сохранением в W
	btfss	STATUS,C	; результат меньше 0?
	goto	PRINT_I_vihod	; да,значит идем дальше	
				; нет, т.е. результат больше 10 едениц
	movlw	.10		; значит от полученного значения
	subWF	T_ust_var	; отнимаем 10 едениц,
				; которые приплюсуем к десяткам
	movlw	.1		;
	addWF	T_ust_var_des  	;goto PRINT_I_vihod

PRINT_I_vihod
        movlw   59h
	movwf   ADRES_TEMP
	call    SET_ADRES
    	movf	Timer_period_temp,0 
	movwf	schet_print
	call BINtoDEG	    
	movfw	desyatki	; сдвигаем десятки на место сотен
	movwf	sotni
	movfw	edenici		; сдвигаем еденицы на место десяток
	movwf	desyatki
	clrf	edenici
	call PRINT
	call PRINT_T_us
 ;   PAGESEL Write_to_EEPROM_mini
	call Write_to_EEPROM_mini
 ;   PAGESEL START_PAGE
	
	goto vihod_timer
;************************************************
; Выход из прерывания
;************************************************
vihod
    BANKSEL selection
	bsf selection,1		; по умолчанию стоит первый параметр
	clrf flag_step		; т.к. изменяли уставки убираем флаг достижения стартовой уставки
	bcf T1CON, TMR1ON	; и останавливаем таймер
 ;   PAGESEL Write_to_EEPROM
	call Write_to_EEPROM    ; сохранение данных
 ;   PAGESEL START_PAGE
vihod_timer
    BANKSEL PCLATH_TEMP
	movf        PCLATH_TEMP,0   
        movwf       PCLATH	    ;восстановление содержимого регистра PCLATH
	bcf INTCON,0	    ; сброс флага прерывания еще какого то
	bcf INTCON,1	    ; сброс флага прерывания по INT	
	bsf INTCON,7	    ;разрешение всех прерываний
    return
;******************************************************************************	
PRINT_T_us  ; отрисовка текущей уставки(та которая меняется после истечения таймера)
;******************************************************************************	
	movf    T_ust_var_des,W 
	MOVWF	desyatki
	movf    T_ust_var,W 
	MOVWF	edenici
	movf    T_ust_var_doli,W 
	MOVWF	doli
	movlw	62h  
	call	SET_ADRES2
	btfss Flag_ust_min,1	; проверяем на отриц температуру
	goto znak_pl99		; 
	movlw	2Dh		; символ  минуса
	goto PR99
znak_pl99 
	movlw	2Bh		; символ  плюса
PR99	
	call	Print_temper
	return	
;*****************************************************************************
;Подпрограммы
;*****************************************************************************
BINtoDEG
	clrf sotni
	clrf desyatki
	clrf edenici
	movf schet_print,0  ; сохраняем значение заполнения во временную ячейку
	movwf temp_BIN
LOOP1	incf sotni,f	
	addlw -.100
	BTFSC	STATUS,C
	GOTO	LOOP1	    ; не было перехода через ноль? значит снова отнимаем
	DECF	sotni,f	    ;иначе возвращаем сотню на место
	ADDLW	.100
	MOVWF	temp_BIN
LOOP2	incf desyatki,f	
	addlw -.10
	BTFSC	STATUS,C
	GOTO	LOOP2	    ; не было перехода через ноль? значит снова отнимаем
	DECF	desyatki,f  ;иначе возвращаем деяток на место
	ADDLW	.10
	MOVWF	edenici	    ; остатки записываем в еденицы	
		
    return

;################################################################################
; Вывод результата "подсчета" количества попугаев на индикацию 
;################################################################################
PRINT	 
	    movf ADRES_TEMP,W 	    
	    call SET_ADRES
	    
    	    movf	sotni,W
	    addlw	30h	    ; на столько отличается значение в таблице от настоящих цифр
	    movwf       LCD_DB      ; Установка на линиях DB7...DB0 числового 
                                    ; значения текущего байта данных.
            movlw       high WRITE_D; Установка в PCH числового значения старшего 
            movwf       PCLATH      ; байта адреса (в PC) первой команды 
                                    ; ПП WRITE_D (через W). 
            call        WRITE_D     ; Переход в ПП WRITE_D (с предустановленным
                                    ; значением PCH). 
	    movf	desyatki,W
	    addlw	30h	    ; на столько отличается значение в таблице от настоящих цифр
	    movwf       LCD_DB      ; Установка на линиях DB7...DB0 числового 
                                    ; значения текущего байта данных.
            movlw       high WRITE_D; Установка в PCH числового значения старшего 
            movwf       PCLATH      ; байта адреса (в PC) первой команды 
                                    ; ПП WRITE_D (через W). 
            call        WRITE_D     ; Переход в ПП WRITE_D (с предустановленным
                                    ; значением PCH).  
	    movf	edenici,W
	    addlw	30h
	    movwf       LCD_DB      
            movlw       high WRITE_D
            movwf       PCLATH     
            call        WRITE_D 
  
	    return
;================================================================================
;******************************************************************************	
pause	; 500ms	;vremya=125ns*3*N(133*100*100 = 1 333 333)  (1 333 333 * 3 = 4 000 000) (125ns* 4 000 000 = 0.5s)
	movlw	.133
	movwf	T3
MT12	movlw	.100
	movwf	T2
MT11	movlw	.99
	movwf	T1
MT10	decfsz	T1,f
	goto	MT10
	decfsz	T2,f
	goto	MT11
	decfsz	T3,f
	goto	MT12
	return
;******************************************************************************	
;org 400h	
datchiki ; Обработка датчиков температуры (DS18B20)
	call DS18B20
	;запрещено
	    movf        temp_des_din,W  
	    MOVWF	temp_des_din1
	    MOVWF	desyatki
	    movf        temp_grad_din,W
	    MOVWF	temp_grad_din1 
	    MOVWF	edenici
	    movf        doli_din,W 
	    MOVWF	doli
	    MOVWF	doli_din1
	    
	movlw	0Eh  
	call	SET_ADRES2
	
	btfss flag_min,0	; проверяем на отриц температуру
	goto znak_pl		; 
	movlw	2Dh		; символ  минуса
	bsf flag_min,1		; символ  минуса для САР
	goto PR
znak_pl	
	movlw	2Bh		; символ  плюса
	bcf flag_min,1		; символ  плюса для САР
PR	
	call	Print_temper
	;можно 
	call DS18B20_2
	;запрещено
	    movf        temp_des_din,W 
	    MOVWF	desyatki
	    movf        temp_grad_din,W 
	    MOVWF	edenici
	    movf        doli_din,W 
	    MOVWF	doli
	    
	movlw	4Eh  
	call	SET_ADRES2
	
	btfss flag_min,0	; проверяем на отриц температуру
	goto znak_pl2		; 
	movlw	2Dh		; символ  минуса
	bsf flag_min,2		; символ  минуса для САР
	goto PRi2
znak_pl2 
	movlw	2Bh		; символ  плюса
	bcf flag_min,2		; символ  плюса для САР
PRi2	
	call	Print_temper
	;можно
	return
;-------------------------------------------------------------------------------	
Print_temper
	    movwf       LCD_DB      ; Установка на линиях DB7...DB0 числового 
                                    ; значения текущего байта данных.
            call        WRITE_D2    ; Переход в ПП WRITE_D (с предустановленным
                                    ; значением PCH). 
	    movf	desyatki,W
	    addlw	30h	    ; на столько отличается значение в таблице от настоящих цифр
	    movwf       LCD_DB      ; Установка на линиях DB7...DB0 числового 
                                    ; значения текущего байта данных.
            call        WRITE_D2    ; Переход в ПП WRITE_D (с предустановленным
                                    ; значением PCH).  
	    movf	edenici,W
	    addlw	30h
	    movwf       LCD_DB      
            call        WRITE_D2 
	    movlw	b'00101100' ; символ запятой
	    movwf       LCD_DB      
            call        WRITE_D2     
	    movf	doli,W
	    addlw	30h
	    movwf       LCD_DB      
            call        WRITE_D2 
    return
;-------------------------------------------------------------------------------	    
WRITE_D2     
	bsf RS
	bsf E
	call strobe2
	bcf E
	movlw	.5
	call pause_T2		; задержка не менее 4,1 мс
    return               
;-------------------------------------------------------------------------------
pause_T2
	movwf	T3
P12	movlw	.40
	movwf	T2
P22	movlw	.66
	movwf	T1
P32	decfsz	T1,f
	goto	P32
	decfsz	T2,f
	goto	P22
	decfsz	T3,f
	goto	P12  
    return
;-------------------------------------------------------------------------------	
SET_ADRES2
	bcf RS
	call strobe2
	bsf E
	addlw	.128
	movwf	LCD_DB
	call strobe2
	bcf E
	movlw	.1
	call pause_T2		; задержка не менее 39 мкс
    return
;-------------------------------------------------------------------------------
strobe2	    
	    nop
	    nop
	    nop
	    nop   
    return
;-------------------------------------------------------------------------------
pause_BIG ; 1секунда 
	можно
    BANKSEL T3m
	movlw	.133 ;vremya=125ns*3*N(133*200*99)  (2 633 400 * 3 * 125ns = 0.1s)
	movwf	T3m
MT120	movlw	.200
	movwf	T2m
MT110	movlw	.99
	movwf	T1m
MT100	decfsz	T1m,f
	goto	MT100
	decfsz	T2m,f
	goto	MT110
	decfsz	T3m,f
	goto	MT120
	запрещено
    return	 
;#############################################################################################
DS18B20	; Инициализация DS1820.
;#############################################################################################
   ; запрещено
;---------------------------------------------------------------------------------------------
; Команды для перевода в 9-битный режим ().
;---------------------------------------------------------------------------------------------
	    call       DQ_INIT     ; Инициализация DS1820.   
            movlw      0CCh        ; Запись команды CCh
            movwf      Temp        ; в регистр Temp.
            call       OUT_BYTE    ; Переход в ПП передачи байта OUT_BYTE.

	    movlw      04eh        ; Запись команды о начале передачи функциональных комманд
            movwf      Temp        ; в регистр Temp.
            call       OUT_BYTE    ; Переход в ПП передачи байта OUT_BYTE.

            movlw      032h        ; Запись команды о верхнем пределе температуры
            movwf      Temp        ; в регистр Temp.
            call       OUT_BYTE    ; Переход в ПП передачи байта OUT_BYTE.

            movlw      000h        ; Запись команды о нижнем пределе температуры
            movwf      Temp        ; в регистр Temp.
            call       OUT_BYTE    ; Переход в ПП передачи байта OUT_BYTE.

            movlw      07fh        ; Запись команды  о переводе в 12-битный режим
            movwf      Temp        ; в регистр Temp. (для 9 битного нужно 01fh)
            call       OUT_BYTE    ; Переход в ПП передачи байта OUT_BYTE.

;----> теперь вроде должно быть 9 бит
	    call       DQ_INIT     ; Инициализация DS18B20.
;----> Возврат по стеку из ПП DQ_INIT.
;---------------------------------------------------------------------------------------------
; Команда Skip_ROM (CCh).
; Команда пропуска процедуры сравнения серийного номера. Применяется в случае
; использования одного датчика (как в данном случае).
;---------------------------------------------------------------------------------------------
            movlw      0CCh        ; Запись команды CCh
            movwf      Temp        ; в регистр Temp.
            call       OUT_BYTE    ; Переход в ПП передачи байта OUT_BYTE.
;----> Возврат по стеку из ПП OUT_BYTE.
;---------------------------------------------------------------------------------------------
; Команда Start_Conv (44h). 
; Эта команда запускает процесс преобразования температуры. В течение времени ее 
; исполнения, DS1820 не реагирует на команды "мастера". Это время нужно просто переждать.
;---------------------------------------------------------------------------------------------
            movlw      44h         ; Запись команды 44h
            movwf      Temp        ; в регистр Temp.
            call       OUT_BYTE    ; Переход в ПП передачи байта OUT_BYTE.
;----> Возврат по стеку из ПП OUT_BYTE.
;---------------------------------------------------------------------------------------------
; Ожидание завершения процесса преобразования температуры. 
; То что Вы видите ниже, есть один из способов реализации "плавающей" (следящей)
; задержки (можно применить фиксированную задержку).
;---------------------------------------------------------------------------------------------
WAIT    	;можно
	    call pause_BIG
		;запрещено  
	    call       IN_BYTE     ; Переход в ПП приема байта IN_BYTE.
;----> Возврат по стеку из ПП IN_BYTE.
		;можно
            movlw      b'11111111' ; Запись в W числа FFh.
            subwf      Temp,W      ; Temp - FFh = ...
            btfss      STATUS,Z    ; Z=0 или Z=1 (нулевой результат)?
          ;  goto       WAIT       ; Если Z=0, то ждем дальше.
	    nop			   ; Если Z=1 (Temp заполнен единицами, то есть,
            nop                    ; на линии появился и надежно зафиксировался уровень 1),
		;запрещено         ; то программа исполняется далее.
;---------------------------------------------------------------------------------------------
; Инициализация DS18B20.
;---------------------------------------------------------------------------------------------
            call       DQ_INIT     ; Инициализация DS18B20.
;----> Возврат по стеку из ПП DQ_INIT.
;---------------------------------------------------------------------------------------------
; Еще одна команда Skip_ROM (CCh). 
;---------------------------------------------------------------------------------------------
            movlw      0CCh        ; Запись команды CCh
            movwf      Temp        ; в регистр Temp.
            call       OUT_BYTE    ; Переход в ПП передачи байта OUT_BYTE.
;----> Возврат по стеку из ПП OUT_BYTE.
;---------------------------------------------------------------------------------------------
; Команда Read Scratchpad (BEh).
; Чтение содержимого блокнотной памяти в части касающейся байтов температуры.
;---------------------------------------------------------------------------------------------
            movlw      0BEh        ; Запись команды BEh 
            movwf      Temp        ; в регистр Temp. 
            call       OUT_BYTE    ; Переход в ПП передачи байта OUT_BYTE.
;----> Возврат по стеку из ПП OUT_BYTE.
            call       IN_BYTE     ; Чтение младшего байта температуры.
;----> Возврат по стеку из ПП IN_BYTE.
            movwf      Temp_LSB    ; Запись принятого байта в регистр Temp_LSB.
            call       IN_BYTE     ; Чтение старшего байта температуры.
;----> Возврат по стеку из ПП IN_BYTE.
            movwf      Temp_MSB    ; Запись принятого байта в регистр Temp_MSB.
;---------------------------------------------------
; Итог; в Temp_MSB записан старший байт температуры,
; а в Temp_LSB записан младший байт температуры.
;---------------------------------------------------
	   ; можно
	    call       Преобразование     ; Переход в ПП вывода результата измерения на индикацию.
	    return
;------------------------------- "РАБОЧАЯ" ЧАСТЬ ПРОГРАММЫ ---------------------------------
;============================================================================================
; Подпрограмма обработки содержимого младшего байта температуры.
;============================================================================================
Преобразование
	btfss Temp_MSB,7	; Проверяем на отрицательную температуру
	goto дальше		; переходим сюда, если "+"

; сюда добавляю обработку отрицательных показаний
	bsf flag_min,0	    ; устанавливаю флаг, для дальнейшего вывода на экран "-"
	comf Temp_LSB, 1    ; инвертируем показания, и сохраняем их там-же
	comf Temp_MSB, 1    ; инвертируем показания, и сохраняем их там-же
	incf Temp_LSB	    ; прибавляем 1, что бы значения были зеркальны положительным
	goto дальше_min   	
дальше	
	bcf flag_min,0	; - убираю флаг миниса
;добавляю обработку дробной части значения температру
дальше_min	
	movfw Temp_LSB
	movwf Temp_doli
	movwf Temp_doli4
	bcf   Temp_doli,7    ; очищаем старшие биты, с целыми градусами
	bcf   Temp_doli,6
	bcf   Temp_doli,5
	bcf   Temp_doli,4
	bcf   Temp_doli,3
	clrf	doli_din	; удаляем старые значения
; теперь в зависимости от числа, нужно дать соотв. значение десятых долей
	movlw .1
	subwf Temp_doli,0   ; вычитаем и значение сохраняется в W
	btfss STATUS,Z	    ; если результат равен 0(Z=1), то НЕ исполняется след. инструкция
	goto	des1_1_1	    ; если нет - пропускаем этот шаг
	movlw .1
	movwf doli_din
	goto	des1_5
des1_1_1
	movlw .2
	subwf Temp_doli,0   ; вычитаем и значение сохраняется в W
	btfss STATUS,Z	    ; если результат равен 0(Z=1), то НЕ исполняется след. инструкция
	goto	des1_2	    ; если нет - пропускаем этот шаг
	movlw .1
	movwf doli_din
	goto	des1_5
des1_2
	movlw .3
	subwf Temp_doli,0   ; вычитаем и значение сохраняется в W
	btfss STATUS,Z	    ; если результат равен 0(Z=1), то НЕ исполняется след. инструкция
	goto	des1_2_2	    ; если нет - пропускаем этот шаг
	movlw .2
	movwf doli_din
	goto	des1_5
des1_2_2
	movlw .4
	subwf Temp_doli,0   ; вычитаем и значение сохраняется в W
	btfss STATUS,Z	    ; если результат равен 0(Z=1), то НЕ исполняется след. инструкция
	goto	des1_3	    ; если нет - пропускаем этот шаг
	movlw .2
	movwf doli_din
	goto	des1_5
des1_3
	movlw .5
	subwf Temp_doli,0   ; вычитаем и значение сохраняется в W
	btfss STATUS,Z	    ; если результат равен 0(Z=1), то НЕ исполняется след. инструкция
	goto	des1_4	    ; если нет - пропускаем этот шаг
	movlw .3
	movwf doli_din
	goto	des1_5
des1_4
	movlw .6
	subwf Temp_doli,0   ; вычитаем и значение сохраняется в W
	btfss STATUS,Z	    ; если результат равен 0(Z=1), то НЕ исполняется след. инструкция
	goto	des1_4_2	    ; если нет - пропускаем этот шаг
	movlw .4
	movwf doli_din
	goto	des1_5
des1_4_2
	movlw .7
	subwf Temp_doli,0   ; вычитаем и значение сохраняется в W
	btfss STATUS,Z	    ; если результат равен 0(Z=1), то НЕ исполняется след. инструкция
	goto	des1_5	    ; если нет - пропускаем этот шаг
	movlw .4
	movwf doli_din
des1_5
	btfss Temp_doli4,3   ; если в 3 бите есть 1, то прибавляем 5 десятых 
	goto des1_6	    ; если нет - пропускаем этот шаг
	movlw .5
	addwf doli_din,1 ; к ранее полученному результату
; А далее идет старая программа обработки целых значений
des1_6	
	SWAPF Temp_MSB,1    ; Меняем места полубайты в регистрах темепературы
	SWAPF Temp_LSB,1
	bcf   Temp_LSB,7    ; очищаем старшие биты, которые могли остаться после дробной температуры
	bcf   Temp_LSB,6
	bcf   Temp_LSB,5
	bcf   Temp_LSB,4
	movfw Temp_MSB	    ; и складываем их вместе
	addWF Temp_LSB,1    ; с сохранением их в LSB
		clrf	temp_des
		movfw	Temp_LSB
		movwf	temp_grad
		movwf	grad_1
META	
		movfw	temp_grad
; Выделяем количество десятков
	clrf temp_des
naz2	
	movlw .10
	subwf temp_grad,1
	btfss STATUS,C
	goto META2
	incf temp_des,1
	goto naz2
META2
	movlw .10
	addwf temp_grad,1
;сохраняем значения для динамики
	movfw	temp_grad
	movwf	temp_grad_din
	movfw	temp_des
	movwf	temp_des_din
	 return
;********************************************************************************************
;=============================================================================================
; Подпрограмма нициализации 1-Wire устройства (DS1820).
;=============================================================================================
DQ_INIT     
	    call       PIN_HI      ; Установка вывода в высокоимпедансное состояние: за счет
                                   ; подтягивающего резистора, на линии устанавливается 1.
;----> Возврат по стеку из ПП PIN_HI.
            call       PIN_LO      ; Установка на линии нуля.
;----> Возврат по стеку из ПП PIN_LO.
            movlw      .60         ; Установка количества проходов по 10мкс.
            call       PAUSE_X     ; Переход в ПП задержки (задержка=60х10=600мкс.).
;----> Возврат по стеку из ПП PAUSE_X.
            call       PIN_HI      ; Установка вывода в высокоимпедансное состояние: за счет
                                   ; подтягивающего резистора, на линии устанавливается 1.
;----> Возврат по стеку из ПП PIN_HI.
	;можно
            movlw      .60         ; Установка количества проходов по 10мкс.
            call       PAUSE_X     ; Переход в ПП задержки (задержка=60х10=600мкс.).
	;запрещено
;----> Возврат по стеку из ПП PAUSE_X.
            return                 ; Возврат по стеку.
;*********************************************************************************************
; Подпрограмма задержки.
;=============================================================================================
; Задание количества проходов по 10 мкс.
;----------------------------------------
PAUSE_X     
	    movwf      Count          ; Копирование количества проходов из W в Count.
;----------------------------------------
; Пауза в 10 мкс.
;----------------------------------------
PAUSE_10    
	    nop
	    nop
            goto       $+1            ; Одноразрядный,
            goto       $+1            ; вычитающий
            goto       $+1            ; счетчик
	    goto       $+1            ; Одноразрядный,
            goto       $+1            ; вычитающий
            goto       $+1            ; счетчик
	    goto       $+1            ; Одноразрядный,
            goto       $+1            ; вычитающий
            goto       $+1            ; счетчик
	    goto       $+1            ; Одноразрядный,
            goto       $+1            ; вычитающий
            goto       $+1            ; счетчик
	    goto       $+1            ; Одноразрядный,
            goto       $+1            ; вычитающий
            goto       $+1            ; счетчик
	    goto       $+1            ; Одноразрядный,
            goto       $+1            ; вычитающий
            goto       $+1            ; счетчик
	    goto       $+1            ; Одноразрядный,
            goto       $+1            ; вычитающий
            goto       $+1            ; счетчик
	    goto       $+1            ; Одноразрядный,
            goto       $+1            ; вычитающий
            goto       $+1            ; счетчик
	    goto       $+1            ; Одноразрядный,
            goto       $+1            ; вычитающий
            goto       $+1            ; счетчик
	    goto       $+1            ; Одноразрядный,
            goto       $+1            ; вычитающий
            goto       $+1            ; счетчик
	    goto       $+1            ; Одноразрядный,
            goto       $+1            ; вычитающий
            goto       $+1            ; счетчик
	    goto       $+1            ; Одноразрядный,
            goto       $+1            ; вычитающий
            goto       $+1            ; счетчик
	    goto       $+1            ; Одноразрядный,
            goto       $+1            ; вычитающий
            decfsz     Count,F        ; с "врезкой".
            goto       PAUSE_10       ; 

    return                    ; Возврат по стеку.
;=============================================================================================
OUT_BYTE    
	    movlw      .8           ; Запись количества бит передаваемого
            movwf      N            ; байта в регистр N.
METKA_1     
	    rrf        Temp,F       ; Сдвиг вправо содержимого передаваемого байта.
            btfss      STATUS,C     ; В бите С "лежит" 0 или 1 ?
            goto       OUT_0        ; Если С=0, то переход в ПП передачи нуля.
            goto       OUT_1        ; Если С=1, то переход в ПП передачи единицы.
METKA_2     
	    decfsz     N,F          ; Уменьшение на 1 содержимого счетчика битов.
            goto       METKA_1      ; Если результат не =0, то переход на метку METKA_1.
    return			     ; Если результат =0, то возврат по стеку.
;=============================================================================================
IN_BYTE     
	    movlw      .8           ; Запись количества бит принимаемого
            movwf      N            ; байта в регистр N.
            clrf       Temp         ; Очистка регистра принимаемого байта.
IN_BYTE_1   
	    call       PIN_LO       ; Формирование на линии уровня 0.
            call       PIN_HI       ; Формирование на линии уровня 1.
;-------------------------------------------------------------------
; Запись, в бит С, уровня текущего бита, выдаваемого DS1820 в линию.
;-------------------------------------------------------------------
	    btfss     PORTB,DQ      ; На линии 0 или 1 ? 
            bcf       STATUS,C      ; Если на линии 0, то в бите С выставляется 0.
            btfsc     PORTB,DQ      ; Если на линии 1 (а также после исполнения предыдущей
            bsf       STATUS,C      ; Если на линии 1, то в бите С выставляется 1.
;-------------------------------------------------------------------
; Последовательное заполнение битами регистра Temp.
;-------------------------------------------------------------------
            rrf       Temp,F        ; Сдвиг содержимого регистра Temp вправо (через C).
            movlw     .4            ; Установка количества проходов по 10мкс.
            call      PAUSE_X       ; Переход в ПП задержки (задержка=4х10=40мкс.).
            decfsz    N,F           ; Уменьшение на 1 содержимого счетчика битов.
            goto      IN_BYTE_1     ; Если результат не=0, то переход на прием следующего бита.
            movf      Temp,W        ; Если =0, то копирование принятого байта в регистр W.
    return			    ; Возврат по стеку.
;=============================================================================
; Подпрограмма передачи бита с уровнем "0".
;=============================================================================
OUT_0      
	    call       PIN_LO       ; Переход в ПП установки уровня 0. Начало передачи.
            movlw      .6           ; Установка количества проходов по 10мкс.                   
            call       PAUSE_X      ; Переход в ПП задержки (задержка=6х10=60мкс.).
            call       PIN_HI       ; Переход в ПП установки уровня 1. Конец передачи.
            goto       METKA_2      ; Переход на исполнение процедуры декремента и анализа содержимого счетчика битов.
;============================================================================
; Подпрограмма передачи бита с уровнем "1".
;============================================================================
OUT_1      
	    call       PIN_LO       ; Переход в ПП установки уровня 0. Начало передачи.
	nop
	nop
	nop
	    call       PIN_HI       ; Переход в ПП установки уровня 1. (передача 1).
            movlw      .6           ; Установка количества проходов по 10мкс.                  
            call       PAUSE_X      ; Переход в ПП задержки (задержка=6х10=60мкс.).
            goto       METKA_2      ; Переход на новый цикл передачи бита.
;----------------------------------------------------------------------------
; Формирование на линии уровня "1" за счет подтягивающего резистора
;----------------------------------------------------------------------------
PIN_HI	    
	    BANKSEL    TRISB	    ; Переход в банк 1.
            bsf        TRISB,DQ     ; Настройка вывода RA4 на работу "на вход".
            BANKSEL    PORTB	    ; Переход в банк 0.
	    movlw      .2           ; Установка количества проходов по 10мкс.                   
            call       PAUSE_X      ; Переход в ПП задержки (задержка=2х10=20мкс.).
            return                  ; Возврат по стеку.
;-----------------------------------------------------------------------------
; Формирование на линии уровня "0" средствами микроконтроллера
;-----------------------------------------------------------------------------
PIN_LO      
	    BANKSEL    TRISB	    ; Переход в банк 1.
            bcf        TRISB,DQ     ; Настройка вывода RA4 на работу "на выход".
            BANKSEL    PORTB	     ; Переход в банк 0.
	    bcf        PORTB,DQ     ; Установка 0 на выходе защелки вывода RA4.
	    nop
	    nop
	    nop
	    nop   
	    nop
	    nop
	    nop
	    nop 
	    nop
	    nop
	    nop
	    nop
	    nop
	    nop
	    nop
	    nop 
            return                  ; Возврат по стеку.
;****************************************************************************
DS18B20_2 ; опрос второго датчика DS18B20
;****************************************************************************	    
	   ; запрещено
;----------------------------------------------------------------------------
; Команды для перевода в 12-битный режим ().
;----------------------------------------------------------------------------
	    call       DQ_INIT2     ; Инициализация DS1820.   
            movlw      0CCh        
            movwf      Temp       
            call       OUT_BYTE2    
	    movlw      04eh        
            movwf      Temp        
            call       OUT_BYTE2   
            movlw      032h        
            movwf      Temp        
            call       OUT_BYTE2    
            movlw      000h        
            movwf      Temp        
            call       OUT_BYTE2    
            movlw      07fh        ; Запись команды  о переводе в 12-битный режим
            movwf      Temp        
            call       OUT_BYTE2    
	    call       DQ_INIT2     ; Инициализация DS18B20.
;----------------------------------------------------------------------------
; Команда Skip_ROM (CCh).
;----------------------------------------------------------------------------
            movlw      0CCh    
            movwf      Temp  
            call       OUT_BYTE2 
;----------------------------------------------------------------------------
; Команда Start_Conv (44h). 
;----------------------------------------------------------------------------
            movlw      44h       
            movwf      Temp      
            call       OUT_BYTE2  
WAIT2   ;можно
	    call pause_BIG
	;запрещено 
	    call       IN_BYTE2 
	;можно
            movlw      b'11111111' 
            subwf      Temp,W     
            btfss      STATUS,Z    
         ;   goto       WAIT2       
	;запрещено
	nop
	nop
;----------------------------------------------------------------------------
; Инициализация DS18B20.
;----------------------------------------------------------------------------
            call       DQ_INIT2     ; Инициализация DS18B20.
;----------------------------------------------------------------------------
; Еще одна команда Skip_ROM (CCh). 
;----------------------------------------------------------------------------
            movlw      0CCh       
            movwf      Temp      
            call       OUT_BYTE2    
            movlw      0BEh      
            movwf      Temp        
            call       OUT_BYTE2
            call       IN_BYTE2 
            movwf      Temp_LSB
            call       IN_BYTE2 
            movwf      Temp_MSB   
	;можно
	    call       Преобразование     
	    return
;============================================================================
; Подпрограмма нициализации 1-Wire устройства (DS1820). №2
;============================================================================
DQ_INIT2    
	    call       PIN_HI2   
            call       PIN_LO2      
            movlw      .60         
            call       PAUSE_X  
            call       PIN_HI2     
	;можно
            movlw      .60         
            call       PAUSE_X     
	;запрещено
            return                 ; Возврат по стеку.

OUT_BYTE2   
	    movlw     .8           
            movwf      N            
METKA_12    
	    rrf        Temp,F      
            btfss      STATUS,C     
            goto       OUT_02       
            goto       OUT_12      
METKA_22    
	    decfsz     N,F         
            goto       METKA_12     
            return                  
;=============================================================================
; Подпрограмма приема "мастером" байта
;=============================================================================
IN_BYTE2    
	    movlw      .8         
            movwf      N          
            clrf       Temp  
IN_BYTE_12  
	    call       PIN_LO2    
            call       PIN_HI2   
;-------------------------------------------------------------------
; Запись, в бит С, уровня текущего бита, выдаваемого DS1820 в линию.
;-------------------------------------------------------------------
	    btfss     PORTB,DQ2  
            bcf       STATUS,C 
            btfsc     PORTB,DQ2
            bsf       STATUS,C  
;-------------------------------------------------------------------
; Последовательное заполнение битами регистра Temp.
;-------------------------------------------------------------------
            rrf       Temp,F  
            movlw     .4   
            call      PAUSE_X 
            decfsz    N,F          
            goto      IN_BYTE_12   
            movf      Temp,W
    return 
;============================================================================
; Подпрограмма передачи бита с уровнем "0".
;============================================================================
OUT_02      
	    call       PIN_LO2 
            movlw      .6                          
            call       PAUSE_X 
            call       PIN_HI2 
            goto       METKA_22
;============================================================================
; Подпрограмма передачи бита с уровнем "1".
;============================================================================
OUT_12      
	    call       PIN_LO2
	nop
	nop
	nop
	    call       PIN_HI2
            movlw      .6                          
            call       PAUSE_X 
            goto       METKA_22      
;----------------------------------------------------------------------------
; Формирование на линии уровня "1" за счет подтягивающего резистора
;----------------------------------------------------------------------------
PIN_HI2	    
	BANKSEL    TRISB	   
            bsf    TRISB,DQ2    
        BANKSEL    PORTB	   
	    movlw  .2                            
            call   PAUSE_X      
    return                  
;----------------------------------------------------------------------------
; Формирование на линии уровня "0" средствами микроконтроллера
;----------------------------------------------------------------------------
PIN_LO2     
	BANKSEL    TRISB	
            bcf    TRISB,DQ2  
        BANKSEL    PORTB     
	    bcf    PORTB,DQ2  
	    nop
	    nop
	    nop
	    nop   
	    nop
	    nop
	    nop
	    nop 
	    nop
	    nop
	    nop
	    nop
	    nop
	    nop
	    nop
	    nop 
    return                  ; Возврат по стеку.
;********************************************************************************************* 
    org 400h
;******************************************************************************
INIT    ;Инициализация			
;******************************************************************************  
    BANKSEL OSCCON
	 MOVLW B'11110000'	;Настройка на 32 МГц
	 MOVWF OSCCON
    BANKSEL PORTA 		;
	CLRF PORTA 		;Инициализация PORTA
    BANKSEL LATA 		;
	CLRF LATA 		;
    BANKSEL ANSELA 		;
	CLRF ANSELA 		;
    BANKSEL TRISA 		;
	MOVLW B'00000000' 	;все выходы
	MOVWF TRISA
    BANKSEL PORTB 		;
	CLRF PORTB		;Инициализация PORTB
    BANKSEL LATB 		;
	CLRF LATB 		;
    BANKSEL ANSELB 		;
	CLRF ANSELB 		;
    BANKSEL TRISB 		;
	MOVLW B'00000001' 	;все выходы(кроме 0 - он INT)
	MOVWF TRISB
    BANKSEL WPUB 		;
	MOVLW B'11111111' 	;подтяжка к +
	MOVWF WPUB
    BANKSEL PORTC 		;
	CLRF PORTC 		;Инициализация PORTC
    BANKSEL LATC 		;
	CLRF LATC 		;
    BANKSEL TRISC 		;
	MOVLW B'00000000' 	;все выходы
	MOVWF TRISC
    BANKSEL PORTE 		;
	CLRF PORTE 		;Инициализация PORTE
    BANKSEL LATE 		;
	CLRF LATE 		;
    BANKSEL TRISE 		;
	MOVLW B'00000000' 	;все выходы
	MOVWF TRISE
	MOVLW B'11111111' 	;подтяжка к '+' PORTE,3
	MOVWF WPUE
    BANKSEL PORTD 		;
	CLRF PORTD 		;Инициализация PORTD
    BANKSEL LATD 		;
	CLRF LATD 		;
    BANKSEL ANSELD 		;
	CLRF ANSELD 		;
    BANKSEL TRISD 		;
	MOVLW B'11000000' 	; 6 и 7 - входы
	MOVWF TRISD

    BANKSEL INTCON
	movlw	b'01010000'	;разрешаем INT, и переферийные прерывания
	movwf	INTCON
    BANKSEL PIE1
	bsf PIE1, TMR1IE	; разрешаем прерывания от TMR1
    BANKSEL OPTION_REG
	bcf  OPTION_REG,7	; включение индивидуальных подтяжек
        bcf  OPTION_REG,5	; внутренний тактовый сигнал для таймера
        bcf  OPTION_REG,3	; Предделитель перед таймером
        bsf  OPTION_REG,2	; Коэф. предделителя перед ТМR0 = 256
        bsf  OPTION_REG,1
        bsf  OPTION_REG,0
    BANKSEL PORTD   
	clrf encoder
	clrf encoder_temp
	clrf schet
 	bsf selection,1		; по умолчанию стоит первый параметр
	bsf PORTD,5		; для инициализации DHT11
	
	movlw	001h	    ; сразу записываем количество циклов таймера (30 68)
	movwf	timer_temp_HI
	movlw	068h	    
	movwf	timer_temp_LOW	
	
 ; 	return; ; для отладки 	, чтобы симуляция не тормозила
	    call    INIT_CCP

    BANKSEL CCPR3L
	MOVLW b'01111111';8 старших битов заполнения ШИМ
	MOVWF CCPR3L ;заполнение 50%
    BANKSEL PORTA
	   
    return
;******************************************************************************
INIT_CCP
;************************************
; Настройка модуля ШИМ-3:
;************************************
; Прелюдия:
    BANKSEL CCP3AS
	MOVLW b'00000000' ; отключаем автоотключение ШИМ
	MOVWF CCP3AS
    BANKSEL PWM3CON
	MOVLW b'10111111' ; авторестарт ШИМ задержка на включение 1/2 максимальной
	MOVWF PWM3CON
    BANKSEL PSTR3CON
	MOVLW b'00010001' ; выход ШИМ только на ножке Р3А(PORTE,0)
	MOVWF PSTR3CON
    BANKSEL APFCON
	bcf APFCON,0	;CCP3, точнее говоря выход P3A будет на PORTE,0(альтернатива PORTB5)
; 1 - Отключение используемых для ШИМа пинов (потом включим их в работу)
	BANKSEL TRISE	;
	bsf TRISE,0 	;все выходы (RE0 - вход)
; 2 - настройка периода ШИМ
   BANKSEL PR2		;
	MOVLW B'11111111' ; на 31.25кГц (0хFF), если выше - придется работать с младшими битами((
	MOVWF PR2
; 3 - Конфигурируем режим работы ШИМ
    BANKSEL CCP3CON
	CLRF CCP3CON ;Выключаем CCP modulе 2 младших байта заполнения -00(5-4 биты)
	MOVLW b'00001100'
	MOVWF CCP3CON ;включаем нужную конфигурацию
; 4 - Устанавливаем заполнение ШИМ
     BANKSEL CCPR3L
	MOVLW b'00000000';8 старших битов заполнения ШИМ
	MOVWF CCPR3L ;заполнение 0
; 5 - Конфигурирование и включение таймера-2
    BANKSEL CCPTMRS0
	MOVLW b'00000000' ; Все ШИМ-модули(1-4) базируются на Таймере-2
	MOVWF CCPTMRS0
    BANKSEL PIR1
	BCF PIR1,TMR2IF     ; Сбрасываем флаг прерывания
    BANKSEL T2CON
	MOVLW b'01111000' ; настройка таймера для ШИМ с постделителем на 16.
	MOVWF T2CON       ; и предделителем на 1. таймер еще выключен.
	BSF T2CON,TMR2ON ; Включаем таймер-2
; (Для того чтобы ШИМ начал работать с начала цикла небходим пункт 6. Проверено)
; 6 - Разрешаем выход ШИМа на выход после переполнения Таймера - 2.
    BANKSEL PIR1
A	
	BTFSS PIR1,TMR2IF
	goto A
   BANKSEL TRISE    ;
	bcf TRISE,0     ; (RE0 - выход)
; ШИМ-3 дожен уже работать.
    return
;****************************************
; Конец инициализации ШИМ
;****************************************
;******************************************************************************	
vostanovlenie	; подпрограмма востановления данных после выключения
;******************************************************************************
; восстановление данных после выключения
;Read_to_EEPROM
		movlw	.1
	MOVWF	DATA_EE_ADDR
	call	Read_EEPROM
    BANKSEL	T_ust_start
	movwf	T_ust_start
	
		movlw	.2
	MOVWF	DATA_EE_ADDR
	call	Read_EEPROM
    BANKSEL	T_ust_end
	movwf	T_ust_end
	
		movlw	.3
	MOVWF	DATA_EE_ADDR
	call	Read_EEPROM
    BANKSEL	T_ust_gist
	movwf	T_ust_gist
	
		movlw	.4
	MOVWF	DATA_EE_ADDR
	call	Read_EEPROM
    BANKSEL	Timer_period
	movwf	Timer_period
	
		movlw	.5
	MOVWF	DATA_EE_ADDR
	call	Read_EEPROM
    BANKSEL	CCPR3L_temp_100
	movwf	CCPR3L_temp_100

		movlw	.6
	MOVWF	DATA_EE_ADDR
	call	Read_EEPROM
    BANKSEL	Flag_ust_min
	movwf	Flag_ust_min
	
		movlw	.7
	MOVWF	DATA_EE_ADDR
	call	Read_EEPROM
    BANKSEL	flag_step
	movwf	flag_step
	;clrf	flag_step	; для отладки
	
		movlw	.8
	MOVWF	DATA_EE_ADDR
	call	Read_EEPROM
    BANKSEL	T_ust_var_des
	movwf	T_ust_var_des
	
		movlw	.9
	MOVWF	DATA_EE_ADDR
	call	Read_EEPROM
    BANKSEL	T_ust_var
	movwf	T_ust_var
	
		movlw	.10
	MOVWF	DATA_EE_ADDR
	call	Read_EEPROM
    BANKSEL	T_ust_var_doli
	movwf	T_ust_var_doli

		movlw	.11
	MOVWF	DATA_EE_ADDR
	call	Read_EEPROM
    BANKSEL	flag_min
	movwf	flag_min
	
	goto	back_UP_2
	    
Read_EEPROM
    BANKSEL	EEADRL		;
	BCF	EECON1, WRERR
    BANKSEL	DATA_EE_ADDR	;
	MOVf	DATA_EE_ADDR,0	;
    BANKSEL	EEADRL
    	MOVWF	EEADRL		;Data Memory
				;Address to read
	BCF	EECON1, CFGS	;Deselect Config space
	BCF	EECON1, EEPGD	;Point to DATA memory
	BSF	EECON1, RD	;EE Read
	MOVF	EEDATL, W	;W = EEDATL
	
	return
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
	; выводим данные лежащие в соответствующих ячейках на экран
back_UP_2
;1 - вывод первого параметра
	movlw   05h  
	movwf   ADRES_TEMP
	call    SET_ADRES
	movf	T_ust_start,0	    ; 
	movwf	schet_print
	call	BINtoDEG		    
	movfw	edenici		    ; для САР
	movwf	T_ust_start_edenici ;  
	movfw	desyatki	    ;
	movwf	T_ust_start_des	    ;
	btfss Flag_ust_min,1	; сотен быть у на сне может. там должен стоять знак + или -
	goto PR_plus_recover	; поэтому проверяем на наличие флага
	;bsf Flag_ust_min,1	; и не забываем сразу поставить флаг минуса для дальнейшего сравнения
	movlw	.3		; если "-" то нужно отнять 3 знака от ноля 
	subwf	sotni,1
	call PRINT
	comf	T_ust_start,1	; если "-" то инвертируем для нормальной обработки энкодера
	goto rec2
PR_plus_recover
	;bcf Flag_ust_min,1  ; и не забываем сразу убрать флаг минуса для дальнейшего сравнения
    	movlw	.5	    ; если "+" то нужно отнять 5 знаков от ноля 
	subwf	sotni,1
	call PRINT
;2 - вывод второго параметра
rec2	
	movlw   45h  
	movwf   ADRES_TEMP
	call    SET_ADRES
	movf	T_ust_end,0	    ; 
	movwf	schet_print
	call BINtoDEG	    
	btfss Flag_ust_min,2	; сотен быть у на сне может. там должен стоять знак + или -
	goto PR_plus_2_recover	; поэтому проверяем на наличие флага
	;bsf Flag_ust_min,2	; и не забываем сразу поставить флаг минуса для дальнейшего сравнения
	movlw	.3		; если "-" то нужно отнять 3 знака от ноля 
	subwf	sotni,1
	movfw	edenici		    ; для САР
	movwf	T_ust_end_ed
	movfw	desyatki
	movwf	T_ust_end_des 
	call PRINT
	comf	T_ust_end,1	; если "-" то нужно отнять 255 для дальнейшей нормальной обработки энкодера
	goto rec3
PR_plus_2_recover	
	;bsf Flag_ust_min,2  ; и не забываем сразу убрать флаг минуса для дальнейшего сравнения
    	movlw	.5	    ; если "+" то нужно отнять 5 знаков от ноля 
	subwf	sotni,1
	call PRINT
;3 - вывод третьего параметра	
rec3	
	movlw   19h  
	movwf   ADRES_TEMP
	call    SET_ADRES
	movf	T_ust_gist,0	    ; 
	movwf	schet_print
	call BINtoDEG	    
	movfw	desyatki    ; сдвигаем десятки на место сотен
	movwf	sotni
	movwf	T_ust_gist_edinici  ; для САР
	clrf	desyatki
	movlw	.4	    ; для постановки запятой, нужно отнять 4 знака от ноля 
	subwf	desyatki,1
	movfw	edenici
	movwf	T_ust_gist_doli  ; для САР
	call PRINT
;4 - вывод четвертого параметра	
        movlw   59h
	movwf   ADRES_TEMP
	call    SET_ADRES
    	movf	Timer_period,0	    ; 
	movwf	Timer_period_temp   ; и во временный регистр для обратного отсчета
	movwf	schet_print
	call BINtoDEG	    
	movfw	desyatki    ; сдвигаем десятки на место сотен
	movwf	sotni
	movfw	edenici	    ; сдвигаем еденицы на место десяток
	movwf	desyatki
	clrf	edenici
	call PRINT
;5 - вывод пятого параметра		
	movlw   24h
	movwf   ADRES_TEMP
	call    SET_ADRES
	movf	CCPR3L_temp_100,0	 ; 
	movwf	schet_print
	; теперь нужно умножить на 2,5
	movfw schet_print
	movwf temp_procent
	movfw schet_print
	addwf temp_procent,1
	RRF schet_print,0
	addwf temp_procent,1
	call BINtoDEG	    
	call PRINT
	movfw	temp_procent	; копируем полученое значение в ШИМ
    BANKSEL	CCPR3L
	movwf	CCPR3L
    BANKSEL	schet_print
    
 ;   PAGESEL  PRINT_T_us ;6 - вывод шестого параметра	
	call PRINT_T_us
	
	return
;==============================================================================
; Инициализация дисплея
;==============================================================================
INIT_LCD
	bcf RS
	bcf RW
	bcf E
	movlw	.20
	call pause_T		; задержка не менее 15мс
	bsf E
	movlw	b'00110000'	;Команда "Function set"
	movwf	LCD_DB
	call strobe
	bcf E
	movlw	.5
	call pause_T		; задержка не менее 4,1 мс
	bsf E
	movlw	b'00110000'	;снова команда "Function set"
	movwf	LCD_DB
	call strobe
	bcf E
	movlw	.200
	call pause_T		; задержка не менее 100 мкс
	bsf E
	movlw	b'00111100'	;И снова команда "Function set"
	movwf	LCD_DB		;но уже с настройками: 8 бит, 2-line, 5x11dots
	call strobe
	bcf E
	movlw	.1
	call pause_T		; задержка не менее 39 мкс
	bsf E
	movlw	b'00001110'	;Команда "Display On/OF"
	movwf	LCD_DB		;включаем дисплей, курсор и отелючаем подсветку курсора
	call strobe
	bcf E
	movlw	.1
	call pause_T		; задержка не менее 39 мкс
	bsf E
	movlw	b'00000001'	;Команда "Display Clear"
	movwf	LCD_DB		;очистка дисплея
	call strobe
	bcf E
	movlw	.2
	call pause_T		; задержка не менее 1,53 мс	
	bsf E
	movlw	b'00000110'	;Команда "Entery Mode Set"
	movwf	LCD_DB		;автоматический сдвиг курсора(вкл) и сдвиг всего дисплея(откл)
	call strobe
	bcf E
	movlw	.1
	call pause_T		; задержка не менее 39 мкс
	call    zalivka
	movlw   40h		;занимаем 40 адрес
	call    SET_ADRES
	call    zalivka2
    return
;*****************************
; Конец инициализации дисплея
;*****************************
strobe	
	nop
	nop
    return
;--------------------------------------
pause_T
	movwf	T3
P1	movlw	.40
	movwf	T2
P2	movlw	.66
	movwf	T1
P3	decfsz	T1,f
	goto	P3
	decfsz	T2,f
	goto	P2
	decfsz	T3,f
	goto	P1  
    return
;========================================================================	
SET_ADRES
	bcf RS
	call strobe
	bsf E
	addlw	.128
	movwf	LCD_DB
	call strobe
	bcf E
	movlw	.1
	call pause_T		; задержка не менее 39 мкс
    return
; заполенее экрана текстом
zalivka	    
	    movlw       .40         ; Назначение
            movwf       Temp        ; числа проходов.
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Циклическая ПП заполнения байтами данных столбцов страницы.
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
WR_1        
	    movf        Temp,W      ; Число проходов --> в W.
            sublw       .40         ; .64 - Temp = ... (результат --> в W).
            movwf       Reg         ; В регистр Reg записывается номер текущего 
                                    ; сценария вычисляемого перехода.
;-------------------------------------
; Отработка ПП, в состав которой
; входит вычисляемый переход.
;-------------------------------------
            call        TEXT_1      ; Переход в ПП TEXT_1.
;---> Возврат по стеку из ПП TEXT_1  
;-------------------------------------
; Вывод на индикацию текущего байта
; данных ("лежит" в W).
;-------------------------------------
            movwf       LCD_DB      ; Установка на линиях DB7...DB0 числового 
                                    ; значения текущего байта данных.
            movlw       high WRITE_D; Установка в PCH числового значения старшего 
            movwf       PCLATH      ; байта адреса (в PC) первой команды 
                                    ; ПП WRITE_D (через W). 
            call        WRITE_D     ; Переход в ПП WRITE_D (с предустановленным
                                    ; значением PCH).  
;---> Возврат по стеку из ПП WRITE_D
            decfsz      Temp,F      ; Число проходов уменьшается на 1.
            goto        WR_1        ; Если результат не=0, то переход на
                                    ; обработку следующего байта данных.
                                    ; Если =0, то запись в 1-ю страницу 
                                    ; заканчивается и программа исполняется
    return			    ; далее.
;--------------------------------------------------------------------------------	
WRITE_D     
	bsf RS
	call strobe
	bsf E
	call strobe
	bcf E
	movlw	.4
	call pause_T		; задержка не менее 4,1 мс
        return                  ; Возврат по стеку в то место, откуда
                                ; произошел вызов подпрограммы. 				    
; Данные 1-й страницы 1-го кристалла. 
;--------------------------------------------------------------------------------
TEXT_1      
	movlw       high STR_1  ; Установка в PCH числового значения старшего 
        movwf       PCLATH      ; байта адреса (в PC) первой команды (retlw 
                                    ; ...) табличного перехода 
                                    ; (помечена меткой STR_1).
;--------------------------------------
; Анализ выхода или нет за пределы
; текущего блока памяти программ.
;--------------------------------------
        movf        Reg,W       ; Номер сценария вычисляемого перехода --> W.
        addlw       low STR_1   ; Суммирование номера сценария и числового 
                                    ; значения младшего байта адреса (в PC) 
                                    ; ПП STR_1 (через W). 
;---------------------------------------------
; Проверка на наличие или отсутствие переноса
; (PCH+1 или этого делать не нужно?).
;---------------------------------------------
        btfsc       STATUS,C    ; Перенос был или нет?
        incf        PCLATH,F    ; Если был, то PCLATH+1 (PCH+1=...).
        movf        Reg,W       ; Если не был, то инкремента содержимого PCH 
                                    ; не происходит и номер сценария вычисляемого 
                                    ; перехода (в любом случае) копируется в W.
;--------------------------------------
; Табличный, вычисляемый переход.
;--------------------------------------
            addwf       PCL,F       ; Приращение PCL на величину содержимого W.
STR_1       Dt            0x74,0xBD,0x61,0xC0,0x3D,0x2D,0x4F,0x31,0xEF,0xFF
            Dt            0x74,0xB3,0xBD,0x3D,0x2D,0x4F,0x4F,0x2C,0x4F,0xEF
	    Dt		  0x74,0xB4,0xB8,0x63,0x3D,0x4F,0x2C,0x31,0xEF,0xFF
            Dt            0x43,0xB3,0x65,0xBF,0x20,0x3D,0x31,0x4F,0x4F,0x25
;--------------------------------------------------------------------------------
zalivka2
	    movlw       .40         ; Назначение
            movwf       Temp        ; числа проходов.
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Циклическая ПП заполнения байтами данных столбцов страницы.
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
WR_2        
	    movf        Temp,W      ; Число проходов --> в W.
            sublw       .40         ; .64 - Temp = ... (результат --> в W).
            movwf       Reg         ; В регистр Reg записывается номер текущего 
                                    ; сценария вычисляемого перехода.
;-------------------------------------
; Отработка ПП, в состав которой
; входит вычисляемый переход.
;-------------------------------------
            call        TEXT_2      ; Переход в ПП TEXT_1.
;---> Возврат по стеку из ПП TEXT_1  
;-------------------------------------
; Вывод на индикацию текущего байта
; данных ("лежит" в W).
;-------------------------------------
            movwf       LCD_DB      ; Установка на линиях DB7...DB0 числового 
                                    ; значения текущего байта данных.
            movlw       high WRITE_D; Установка в PCH числового значения старшего 
            movwf       PCLATH      ; байта адреса (в PC) первой команды 
                                    ; ПП WRITE_D (через W). 
            call        WRITE_D     ; Переход в ПП WRITE_D (с предустановленным
                                    ; значением PCH).  
;---> Возврат по стеку из ПП WRITE_D
            decfsz      Temp,F      ; Число проходов уменьшается на 1.
            goto        WR_2        ; Если результат не=0, то переход на
                                    ; обработку следующего байта данных.
                                    ; Если =0, то запись в 1-ю страницу 
                                    ; заканчивается и программа исполняется
                                    ; далее.
; Данные 1-й страницы 1-го кристалла. 
;--------------------------------------------------------------------------------
TEXT_2      
	    movlw       high STR_2  ; Установка в PCH числового значения старшего 
            movwf       PCLATH      ; байта адреса (в PC) первой команды (retlw 
                                    ; ...) табличного перехода 
                                    ; (помечена меткой STR_1).
;--------------------------------------
; Анализ выхода или нет за пределы
; текущего блока памяти программ.
;--------------------------------------
            movf        Reg,W       ; Номер сценария вычисляемого перехода --> W.
            addlw       low STR_2   ; Суммирование номера сценария и числового 
                                    ; значения младшего байта адреса (в PC) 
                                    ; ПП STR_1 (через W). 
;---------------------------------------------
; Проверка на наличие или отсутствие переноса
; (PCH+1 или этого делать не нужно?).
;---------------------------------------------
            btfsc       STATUS,C    ; Перенос был или нет?
            incf        PCLATH,F    ; Если был, то PCLATH+1 (PCH+1=...).
            movf        Reg,W       ; Если не был, то инкремента содержимого PCH 
                                    ; не происходит и номер сценария вычисляемого 
                                    ; перехода (в любом случае) копируется в W.
;--------------------------------------
; Табличный, вычисляемый переход.
;--------------------------------------
            addwf       PCL,F       ; Приращение PCL на величину содержимого W.    
STR_2       Dt            0x74,0xBA,0x6F,0xBD,0x3D,0x2D,0x33,0x4F,0xEF,0xFF
            Dt            0x74,0xE3,0xB3,0x3D,0x2D,0x4F,0x4F,0x2C,0x4F,0xEF
	    Dt		  0x54,0x61,0xB9,0xBC,0x3D,0x33,0x36,0x4F,0xBC,0xFF
            Dt            0x74,0x79,0x63,0x3D,0x2D,0x4F,0x4F,0x2C,0x4F,0xEF
;******************************************************************************
  ;  org 800h 
;==============================================================================	
Timer_verefi	; программа работы с таймером
;==============================================================================	
;таймер уже запущен?
	btfsc flag_step,4 
	goto Timer_proverka ; да, тогда идем на проверку(пока еще не знаю чего), скорее всего достижения конечной температуры
	goto Timer_start    ; нет, значит запускаем таймер

; запускаем таймер
Timer_start	
	BANKSEL T1CON
	movlw b'00110000'  ; коэф предделителя 1:8, вкл. внутр такт ген
	movwf	T1CON	    ; внутренний источник тактового сигнала fosc/4
	
	movlw    03Dh	    ; частично заполняем таймер
	movwf	TMR1H
	movlw    0A0h	    ; для задания периода в 50мс
	movwf	TMR1L	
	bcf	PIR1, TMR1IF
	bsf T1CON, TMR1ON   ; запускаем таймер

	bsf flag_step,4	    ; делаем отметку о запущенном таймере
	
	movlw	030h	    ; сразу записываем количество циклов таймера (30 68)
	movwf	timer_temp_HI
	movlw	068h	    
	movwf	timer_temp_LOW	
Timer_proverka	
		
	return
;==============================================================================		

;==============================================================================	
SAR_3	; Система автоматического регулирования (достигли ли конечной температуры?)
;==============================================================================	
	btfsc flag_step,1   ; Прошли мы первый этам охлождения?
	goto sar3_0	    ; да
	goto timer_stop	    ; нет
	;для начал нужно сравнить знаки температур(флаги)
sar3_0	btfss Flag_ust_min,2 ; знак конечной тепмературы отрицательный?
	goto sar3_1	     ; нет
			     ; да
	btfss Flag_ust_min,1 ; текущая уставка отрицательная
	goto sar3_vihod	     ; нет(не достигли)
	goto sar3_3min	     ; да(тогда нужно их сравнивать)
sar3_1	
	btfss Flag_ust_min,1 ; текущая уставка отрицательная
	goto sar3_3plus	     ; нет (тогда нужно их сравнивать)
	goto sar3_vihod	     ; да(такого не может быть в нормальном режиме работы)
	
sar3_3min
	movfw	T_ust_var_des	; загружаем в W текущую уставку
	subWF	T_ust_end_des,0	; и вычитаем из конечной уставку
	btfss	STATUS,C	; был заем? (C=0)?
	goto	timer_stop	; да,  уставку достигли, останавливаем таймер	
				; нет, проверим на нулевой результат
	btfsc	STATUS,Z	; результат равен 0(Z=1)?
	goto	sar3_3m_1	; да,  тогда проверяем еденицы
	goto	sar3_vihod	; нет,	значит 	уставка не достигнута	
sar3_3m_1		
	movfw	T_ust_var	; загружаем в W текущую уставку
	subWF	T_ust_end_ed,0	; и вычитаем из конечной уставку
	btfss	STATUS,C	; был заем? (C=0)?
	goto	timer_stop	; да,  уставку достигли, останавливаем таймер	
				; нет, проверим на нулевой результат
	btfsc	STATUS,Z	; результат равен 0(Z=1)?
	goto	timer_stop	; да,  уставку достигли, останавливаем таймер
	goto	sar3_vihod	; нет,	значит 	нужно морозить дальше

sar3_3plus	
	movfw	T_ust_var_des	; загружаем в W текущую уставку
	subWF	T_ust_end_des,0	; и вычитаем из конечной уставки
	btfss	STATUS,C	; был заем? (C=0)?
	goto	sar3_vihod	; да,  уставку не достигли
				; нет, проверим на нулевой результат
	btfsc	STATUS,Z	; результат равен 0(Z=1)?
	goto	sar3_3p_1	; да,  тогда проверяем еденицы
	goto	timer_stop	; нет,	значит 	уставка достигнута	
sar3_3p_1		
	movfw	T_ust_var	; загружаем в W текущую уставку
	subWF	T_ust_end_ed,0	; и вычитаем из конечной уставки
	btfss	STATUS,C	; был заем? (C=0)?
	goto	sar3_vihod	; да,  уставку не достигли
				; нет, проверим на нулевой результат
	btfsc	STATUS,Z	; результат равен 0(Z=1)?
	goto	sar3_3p_2	; да,  уставку возможно достигли, но еще нужно проверить доли грудусов
	goto	sar3_vihod	; нет,	значит 	нужно морозить дальше
sar3_3p_2
	movf T_ust_var_doli,0
	btfsc	STATUS,Z	; результат равен 0(Z=1)?
	goto	timer_stop	; да,  уставку достигли, останавливаем таймер
	goto	sar3_vihod	; нет, нужно отнять еще 0,5 градуса
		
timer_stop
	bcf T1CON, TMR1ON   ; останавливаем таймер
	return
sar3_vihod
	bsf T1CON, TMR1ON   ; запускаем таймер,  если ранее остановили
	return		    ; например после изменения конечной уставки
	
;==============================================================================	
SAR_2	; Система автоматического регулирования (программа сравнения уставок)
;==============================================================================		
	BANKSEL PORTA
	;для начал нужно сравнить знаки температур
	btfss flag_min,1     ; знак текущей температуры отрицательный?
	goto sar0	     ; нет
			     ; да
	btfss Flag_ust_min,3 ; верхняя уставка отрицательная
	goto sar001	     ; нет(такое может быть только, если уставки около нуля)
	goto sar01m	     ; да(переходим на проверку в отриц диапазоне)
sar0	
	btfss Flag_ust_min,3 ; верхняя уставка отрицательная
	goto sar01	     ; нет(переходим на проверку в положит диапазоне)
	goto ON_FREEZ	     ; да(однозначно нужно охлождать)
	
sar001	
	btfss Flag_ust_min,4 ; нижняя уставка отрицательная
	goto OFF_FREEZ	     ; нет(такое не может быть нормальном режиме работы)
	goto sravn_niz_ustm  ; да(переходим на проверку c нижним уставкой в отрицательном диапазоном)
	
;****************************************	
	; Сравниваем с верхней уставкой(положительный диапазон)
;****************************************
sar01	
	movfw	T_ust_HI_des	; загружаем в W уставку
	subWF	temp_des_din1,0	; и вычитаем из текущей температуры 
	btfss	STATUS,C	; был заем? (C=0)?
	goto	sravn_niz_ust	; да,  уставку достигли, значит идем на проверку нижней уставки	
				; нет, проверим на нулевой результат
	btfsc	STATUS,Z	; результат равен 0(Z=1)?
	goto	sar1		; да,  тогда проверяем еденицы
	goto	ON_FREEZ	; нет,	значит 	нужно морозить дальше	
sar1		
	movfw	T_ust_HI	; загружаем в W уставку
	subWF	temp_grad_din1,0	; и вычитаем из текущей температуры 
	btfss	STATUS,C	; был заем? (C=0)?
	goto	sravn_niz_ust	; да,  уставку достигли, значит идем на проверку нижней уставки	
				; нет, проверим на нулевой результат
	btfsc	STATUS,Z	; результат равен 0(Z=1)?
	goto	sar2		; да,  тогда проверяем доли градусов
	goto	ON_FREEZ	; нет,	значит 	нужно морозить дальше
sar2		
	movfw	T_ust_HI_doli	; загружаем в W уставку
	subWF	doli_din1,0	; и вычитаем из текущей температуры 
	btfss	STATUS,C	; был заем? (C=0)?]
	goto	sravn_niz_ust	; да,  уставку достигли, значит идем на проверку нижней уставки	
				; или если даже нулевой результат
	goto	ON_FREEZ	; нет, значит 	нужно морозить дальше
;****************************************
sravn_niz_ust; Сравниваем с нижней уставкой(положительный диапазон)
;****************************************
	movfw	T_ust_LOW_des	; загружаем в W уставку
	subWF	temp_des_din1,0	; и вычитаем из текущей температуры 
	btfss	STATUS,C	; был заем? (C=0)?
	goto	OFF_FREEZ	; да,  уставку достигли, отключаем морозилку
				; нет, проверим на нулевой результат
	btfsc	STATUS,Z	; результат равен 0?
	goto	sar3		; да,  тогда проверяем еденицы
	goto	prov_flaga	; нет,	уставку не достигли, проверяем на достижение нижней уставки ранее	
sar3		
	movfw	T_ust_LOW	; загружаем в W уставку
	subWF	temp_grad_din1,0	; и вычитаем из текущей температуры 
	btfss	STATUS,C	; был заем? (C=0)?
	goto	OFF_FREEZ	; да,  уставку достигли, отключаем морозилку
				; нет, проверим на нулевой результат
	btfsc	STATUS,Z	; результат равен 0?
	goto	sar4		; да,  тогда проверяем доли градусов
	goto	prov_flaga	; нет,	уставку не достигли, проверяем на достижение нижней уставки ранее
sar4		
	movfw	T_ust_LOW_doli	; загружаем в W уставку
	subWF	doli_din1,0	; и вычитаем из текущей температуры 
	btfss	STATUS,C	; был заем? (C=0)?
	goto	OFF_FREEZ	; да, значит нижняя граница достигнута и пора отключть морозилку
	
	btfsc	STATUS,Z	; результат равен 0?
	goto	OFF_FREEZ	; да, значит нижняя граница достигнута и пора отключть морозилку
	;goto	prov_flaga	; нет, уставку не достигли, проверяем на достижение нижней уставки ранее	
				
prov_flaga	
	btfsc flag_step,2	; есть флаг достижения нижней уставки?
	return			; есть - ни чего не делаем, о идее сейчас не морозит.
	goto	ON_FREEZ	; нет флага - значит морозим до нижней уставки
;*******************************************************************************	
;*******************************************************************************	
	; Сравниваем с верхней уставкой (отрицательный диапазон)
;****************************************;**************************************
sar01m	
	movfw	T_ust_HI_des	; загружаем в W уставку
	subWF	temp_des_din1,0	; и вычитаем из текущей температуры 
	btfss	STATUS,C	; результат меньше 0?
	goto	ON_FREEZ	; да, не достигли, морозим дальше
				; нет, проверим на нулевой результат
	btfsc	STATUS,Z	; результат равен 0?
	goto	sar1m		; да,  тогда проверяем еденицы
	goto	sravn_niz_ustm	; нет,	достигли и идем на проверку нижней уставки
sar1m		
	movfw	T_ust_HI	; загружаем в W уставку
	subWF	temp_grad_din1,0	; и вычитаем из текущей температуры 
	btfss	STATUS,C	; результат меньше 0?
	goto	ON_FREEZ	; да, не достигли, морозим дальше
				; нет, проверим на нулевой результат
	btfsc	STATUS,Z	; результат равен 0?
	goto	sar2m		; да,  тогда проверяем доли градусов
	goto	sravn_niz_ustm	; нет,	достигли и идем на проверку нижней уставки
sar2m		
	movfw	T_ust_HI_doli	; загружаем в W уставку
	subWF	doli_din1,0	; и вычитаем из текущей температуры 
	btfss	STATUS,C	; результат меньше 0?
	goto	ON_FREEZ	; да, не достигли, морозим дальше
				
	btfsc	STATUS,Z	; результат равен 0?
	goto	ON_FREEZ	; да, морозим дальще
;	goto 	sravn_niz_ustm	; нет, достигли и идем на проверку нижней уставки
;****************************************
sravn_niz_ustm; Сравниваем с нижней уставкой (отрицательный диапазон)
;****************************************
	movfw	T_ust_LOW_des	; загружаем в W уставку
	subWF	temp_des_din1,0	; и вычитаем из текущей температуры 
	btfss	STATUS,C	; результат меньше 0?
	goto	prov_flagam	; да,  уставку не достигли, проверяем на достижение нижней уставки ранее
				; нет, проверим на нулевой результат
	btfsc	STATUS,Z	; результат равен 0?
	goto	sar3m		; да,  тогда проверяем еденицы
	goto	OFF_FREEZ	; нет,	уставку достигли, вырубаем
sar3m		
	movfw	T_ust_LOW	; загружаем в W уставку
	subWF	temp_grad_din1,0; и вычитаем из текущей температуры 
	btfss	STATUS,C	; результат меньше 0?
	goto	prov_flagam	; да,  уставку не достигли, проверяем на достижение нижней уставки ранее
				; нет, проверим на нулевой результат
	btfsc	STATUS,Z	; результат равен 0?
	goto	sar4m		; да,  тогда проверяем доли градусов
	goto	OFF_FREEZ	; нет,	уставку достигли, выключаем
sar4m		
	movfw	T_ust_LOW_doli	; загружаем в W уставку
	subWF	doli_din1,0	; и вычитаем из текущей температуры 
	btfss	STATUS,C	; результат меньше 0?
	goto	prov_flagam	; да, уставку не достигли, проверяем на достижение нижней уставки ране
	goto	OFF_FREEZ	; нет, значит нижняя граница достигнута
				; и пора отключть морозилку
prov_flagam	
	btfsc flag_step,2	; есть флаг достижения нижней уставки?
	return			; есть - ни чего не делаем, о идее сейчас не морозит.
	goto	ON_FREEZ	; нет флага - значит морозим до нижней уставки
	
		
	;return
;==============================================================================	
SAR_1	; Система автоматического регулирования (программа формирования уставок)
;==============================================================================	
	btfsc flag_step,1   ; Это первый запуск? (прошли мы первый этам охлождения)
	goto ne_perviy	    ; не первый запуск
			    ; иначе обрабатываем как первый запуск
			    ; и охлаждаем сразу до этой температуры
;****************************************
	movfw	T_ust_start_des ; копируем стартовую уставку во временный регистр
	movwf	T_ust_des	; т.к. она всегда целая, поэтому не используем дольную часть
	movfw	T_ust_start_edenici 
	movwf	T_ust	    
	clrf	T_ust_doli  ; дольную часть обнуляем от случайных данных
	goto	SAR0
;****************************************	
ne_perviy	; если запуск не первый, то берем уставку из другого регистра	
	movfw	T_ust_var_des	; копируем стартовую уставку во временный регистр
	movwf	T_ust_des	
	movfw	T_ust_var
	movwf	T_ust	    
	movfw	T_ust_var_doli	; В том числе и доли тоже.
	movwf	T_ust_doli	    
;	goto	SAR0
;****************************************
	; уставка отрицательная??
SAR0	
	btfss	Flag_ust_min,1
	goto	polozit_ust_start   ;флага нет, значит уставка положительная
	goto	otricat_ust_start   ;есть флаг, значит арифметика будет другая
;*******************************************************************
polozit_ust_start
	bcf  Flag_ust_min,3	; изначально сбрасываем флаги
	bcf  Flag_ust_min,4	; если появиться минус - то поставим флаг
; Формируем T_ust_LOW
	movfw	T_ust_gist_doli  ; загружаем в W дольную часть гистерезиса
	subWF	T_ust_doli,1	 ; и вычитаем из дольной часть уставки 
	btfsc STATUS,C		; результат меньше 0?
	goto met1		; нет(в данном случае такого быть не может)
				; иначе результат отрицательный
	movlw	.10		; значит нужно к полученному значению
	ADDWF	T_ust_doli	; прибавить 10 едениц,
				; которые позаимствуем в еденицах
	movlw	.1		;
	subWF	T_ust,1	    	;		
	btfsc STATUS,C		    ; результат меньше 0?
	goto	SAR1		    ; нет
				    ; да меньше
	movlw	.10		; значит нужно к полученному значению
	ADDWF	T_ust		; прибавить 10 едениц,
				; которые позаимствуем в десятках
	movlw	.1		; 
	subWF	T_ust_des,1	;
	btfsc STATUS,C		    ; результат меньше 0?
	goto	SAR1		    ; нет
				    ; да меньше
	comf T_ust_des		; значит нужно инвертировать полученное значение
	incf T_ust_des		; и прибавить к нему еденичку	
	bsf  Flag_ust_min,4	; и установливаем флаг отрицательной уставки
SAR1	
	movfw	T_ust_gist_edinici  ; загружаем в W целую часть гистерезиса
	subWF	T_ust,1		    ; и вычитаем из целой часть уставки 
	btfsc STATUS,C		    ; результат меньше 0?
	goto	SAR2		    ; нет
				    ; да меньше
	movlw	.10		; значит нужно к полученному значению
	ADDWF	T_ust		; прибавить 10 едениц,
				; которые позаимствуем в десятках
	movlw	.1		;
	subWF	T_ust_des,1	;		
	btfsc STATUS,C		    ; результат меньше 0?
	goto	SAR2		    ; нет
				    ; да меньше
	comf T_ust_des		; значит нужно инвертировать полученное значение
	incf T_ust_des		; и прибавить к нему еденичку	
	bsf  Flag_ust_min,4	; и установливаем флаг отрицательной уставки
SAR2	
	movfw	T_ust_des	; копируем значение в регистры гистерезиса
	movwf	T_ust_LOW_des
	movfw	T_ust		
	movwf	T_ust_LOW
	movfw	T_ust_doli	
	movwf	T_ust_LOW_doli
;*******************************************************************
	movfw	T_ust_var_des ; снова копируем стартовую уставку во временный регистр
	movwf	T_ust_des     ; 
	movfw	T_ust_var     ; 
	movwf	T_ust	      ;
	movfw	T_ust_var_doli 
	movwf	T_ust_doli    ; дольную часть тоже копируем
;*******************************************************************
; Формируем T_ust_HI	
met1	
	movfw	T_ust_gist_doli ; загружаем в W дольную часть гистерезиса
	ADDWF	T_ust_doli	; и прибавляем к дольной часть уставки
				; проверяем, а не больше 10 едениц в регистре
	movlw	.10		; 
	subWF	T_ust_doli,0	; отнимаем 10 едениц, с сохранением в W
	btfss	STATUS,C	; результат меньше 0?
	goto	SAR3		; да, значит идем дальше к целым числам
				; нет, т.е. результат больше 10 едениц
	movlw	.10		; значит от полученного значения
	subWF	T_ust_doli	; отнимаем 10 едениц,
				; которые приплюсуем к еденицам
	movlw	.1		;
	addWF	T_ust	    	;
	
	movlw	.10		; и проверим, а не больше 10 едениц в регистре
	subWF	T_ust,0	    	; отнимаем 10 едениц, с сохранением в W
	btfss	STATUS,C	; результат меньше 0?
	goto	SAR3		; да,значит идем дальше	
				; нет, т.е. результат больше 10 едениц
	movlw	.10		; значит от полученного значения
	subWF	T_ust		; отнимаем 10 едениц,
				; которые приплюсуем к десяткам
	movlw	.1		;
	addWF	T_ust_des    	;
	
SAR3	
	movfw	T_ust_gist_edinici  ; загружаем в W целую часть гистерезиса
	ADDWF	T_ust		; и прибавляем к целой часть уставки
				; проверяем, а не больше 10 едениц в регистре
	movlw	.10		; 
	subWF	T_ust,0		; отнимаем 10 едениц, с сохранением в W
	btfss	STATUS,C	; результат меньше 0?
	goto	SAR4		; да, значит идем дальше 
				; нет, т.е. результат больше 10 едениц
	movlw	.10		; значит от полученного значения
	subWF	T_ust	    	; отнимаем 10 едениц,
				; которые приплюсуем к десяткам
	movlw	.1		;
	addWF	T_ust_des    	;
SAR4	
	movfw	T_ust_des	; копируем значение в регистры гистерезиса
	movwf	T_ust_HI_des
	movfw	T_ust		
	movwf	T_ust_HI
	movfw	T_ust_doli	
	movwf	T_ust_HI_doli
;********************************
	return			; Возвращаемся в основное тело программы
;******************************************************************************
otricat_ust_start
	bsf  Flag_ust_min,3	; изначально ставим флаги
	bsf  Flag_ust_min,4	; если появиться плюс - то уберем флаг
; Формируем T_ust_HI
	movfw	T_ust_gist_doli  ; загружаем в W дольную часть гистерезиса
	subWF	T_ust_doli	 ; и вычитаем из дольной часть уставки 
	btfsc STATUS,C		; результат меньше 0?
	goto	SAR1m		; нет
				; иначе результат отрицательный
	movlw	.10		; значит нужно к полученному значению
	ADDWF	T_ust_doli	; прибавить 10 едениц,
				; которые позаимствуем в еденицах
	movlw	.1		;
	subWF	T_ust	    	;		
	btfsc STATUS,C		    ; результат меньше 0?
	goto	SAR1m		    ; нет
				    ; да меньше
	movlw	.10		; значит нужно к полученному значению
	ADDWF	T_ust		; прибавить 10 едениц,
				; которые позаимствуем в десятках
	movlw	.1		; 
	subWF	T_ust_des	;
	btfsc STATUS,C		    ; результат меньше 0?
	goto	SAR1m		    ; нет
				    ; да меньше
	comf T_ust_des		; значит нужно инвертировать полученное значение
	incf T_ust_des		; и прибавить к нему еденичку	
	bcf  Flag_ust_min,4	; и сбрасываем флаг отрицательной уставки
SAR1m	
	movfw	T_ust_gist_edinici  ; загружаем в W целую часть гистерезиса
	subWF	T_ust		    ; и вычитаем из целой часть уставки 
	btfsc STATUS,C		    ; результат меньше 0?
	goto	SAR2m		    ; нет
				    ; да меньше
	movlw	.10		; значит нужно к полученному значению
	ADDWF	T_ust		; прибавить 10 едениц,
				; которые позаимствуем в десятках
	movlw	.1		;
	subWF	T_ust_des	;		
	btfsc STATUS,C		    ; результат меньше 0?
	goto	SAR2m		    ; нет
				    ; да меньше
	comf T_ust_des		; значит нужно инвертировать полученное значение
	incf T_ust_des		; и прибавить к нему еденичку	
	bcf  Flag_ust_min,4	; и сбросить флаг отрицательной уставки
SAR2m	
	movfw	T_ust_des	; копируем значение в регистры гистерезиса
	movwf	T_ust_HI_des
	movfw	T_ust		
	movwf	T_ust_HI
	movfw	T_ust_doli	
	movwf	T_ust_HI_doli
;*******************************************************************
	movfw	T_ust_var_des ; снова копируем стартовую уставку во временный регистр
	movwf	T_ust_des     ; 
	movfw	T_ust_var     ; 
	movwf	T_ust	      ;
	movfw	T_ust_var_doli 
	movwf	T_ust_doli    ; дольную часть тоже копируем
;*******************************************************************
; Формируем T_ust_LOW	
	movfw	T_ust_gist_doli ; загружаем в W дольную часть гистерезиса
	ADDWF	T_ust_doli	; и прибавляем к дольной часть уставки
				; проверяем, а не больше 10 едениц в регистре
	movlw	.10		; 
	subWF	T_ust_doli,0	; отнимаем 10 едениц, с сохранением в W
	btfss	STATUS,C	; результат меньше 0?
	goto	SAR3m		; да, значит идем дальше к целым числам
				; нет, т.е. результат больше 10 едениц
	movlw	.10		; значит от полученного значения
	subWF	T_ust_doli	; отнимаем 10 едениц,
				; которые приплюсуем к еденицам
	movlw	.1		;
	addWF	T_ust	    	;
	
	movlw	.10		; и проверим, а не больше 10 едениц в регистре
	subWF	T_ust,0	    	; отнимаем 10 едениц, с сохранением в W
	btfss	STATUS,C	; результат меньше 0?
	goto	SAR3m		; да,значит идем дальше	
				; нет, т.е. результат больше 10 едениц
	movlw	.10		; значит от полученного значения
	subWF	T_ust		; отнимаем 10 едениц,
				; которые приплюсуем к десяткам
	movlw	.1		;
	addWF	T_ust_des    	;
	
SAR3m	
	movfw	T_ust_gist_edinici  ; загружаем в W целую часть гистерезиса
	ADDWF	T_ust		; и прибавляем к целой часть уставки
				; проверяем, а не больше 10 едениц в регистре
	movlw	.10		; 
	subWF	T_ust,0		; отнимаем 10 едениц, с сохранением в W
	btfss	STATUS,C	; результат меньше 0?
	goto	SAR4m		; да, значит идем дальше 
				; нет, т.е. результат больше 10 едениц
	movlw	.10		; значит от полученного значения
	subWF	T_ust	    	; отнимаем 10 едениц,
				; которые приплюсуем к десяткам
	movlw	.1		;
	addWF	T_ust_des    	;
SAR4m	
	movfw	T_ust_des	; копируем значение в регистры гистерезиса
	movwf	T_ust_LOW_des
	movfw	T_ust		
	movwf	T_ust_LOW
	movfw	T_ust_doli	
	movwf	T_ust_LOW_doli
;********************************
	return	    		; Возвращаемся в основное тело программы
;******************************************************************************
;******************************************************************************
ON_FREEZ
    BANKSEL PORTA
    bsf PORTA,1
    bsf PORTA,0
    bcf flag_step,2	; убираем флаг достижения T_ust_LOW
    return
OFF_FREEZ
    BANKSEL PORTA
    bcf PORTA,1
    bcf PORTA,0
    bsf flag_step,1	; флаг достижения T_ust_start
    bsf flag_step,2	; флаг достижения T_ust_LOW
    return	    
;==============================================================================		    
Write_to_EEPROM
    BANKSEL	T_ust_start
	movf	T_ust_start,0
    BANKSEL	DATA_EE_DATA
	movwf	DATA_EE_DATA 
	movlw	.1
	MOVWF	DATA_EE_ADDR
	call	Write_EEPROM  
	
    BANKSEL	T_ust_end
	movf	T_ust_end,0
    BANKSEL	DATA_EE_DATA
	movwf	DATA_EE_DATA 
	movlw	.2
	MOVWF	DATA_EE_ADDR
	call	Write_EEPROM 
	
    BANKSEL	T_ust_gist
	movf	T_ust_gist,0
    BANKSEL	DATA_EE_DATA
	movwf	DATA_EE_DATA 
	movlw	.3
	MOVWF	DATA_EE_ADDR
	call	Write_EEPROM
	
	BANKSEL CCPR3L_temp_100
	movf	CCPR3L_temp_100,0
	BANKSEL DATA_EE_DATA
	movwf	DATA_EE_DATA 
	movlw	.5
	MOVWF	DATA_EE_ADDR
	call	Write_EEPROM
	
	BANKSEL flag_step
	movf	flag_step,0
	BANKSEL DATA_EE_DATA
	movwf	DATA_EE_DATA 
	movlw	.7
	MOVWF	DATA_EE_ADDR
	call	Write_EEPROM

	BANKSEL flag_min
	movf	flag_min,0
	BANKSEL DATA_EE_DATA
	movwf	DATA_EE_DATA 
	movlw	.11
	MOVWF	DATA_EE_ADDR
	call	Write_EEPROM
	
Write_to_EEPROM_mini
	BANKSEL T_ust_var_des
	movf	T_ust_var_des,0
	BANKSEL DATA_EE_DATA
	movwf	DATA_EE_DATA 
	movlw	.8
	MOVWF	DATA_EE_ADDR
	call	Write_EEPROM
	
	BANKSEL T_ust_var
	movf	T_ust_var,0
	BANKSEL DATA_EE_DATA
	movwf	DATA_EE_DATA 
	movlw	.9
	MOVWF	DATA_EE_ADDR
	call	Write_EEPROM
	
	BANKSEL T_ust_var_doli
	movf	T_ust_var_doli,0
	BANKSEL DATA_EE_DATA
	movwf	DATA_EE_DATA 
	movlw	.10
	MOVWF	DATA_EE_ADDR
	call	Write_EEPROM   

	BANKSEL Timer_period
	movf	Timer_period,0
	BANKSEL DATA_EE_DATA
	movwf	DATA_EE_DATA 
	movlw	.4
	MOVWF	DATA_EE_ADDR
	call	Write_EEPROM
	
	BANKSEL Flag_ust_min
	movf	Flag_ust_min,0
	BANKSEL DATA_EE_DATA
	movwf	DATA_EE_DATA 
	movlw	.6
	MOVWF	DATA_EE_ADDR
	call	Write_EEPROM
;    PAGESEL START_PAGE
	;clrf PCLATH
	return
	
Write_EEPROM
	;запрещено
    BANKSEL	EEADRL		;
	BCF	EECON1, WRERR
    BANKSEL	DATA_EE_ADDR
	MOVf	DATA_EE_ADDR,0
    BANKSEL	EEADRL		;
	MOVWF	EEADRL		;Data Memory Address to write
    BANKSEL	DATA_EE_DATA
	MOVf	DATA_EE_DATA,0	;
    BANKSEL	EEADRL
	MOVWF	EEDATL		;Data Memory Value to write
	BCF EECON1, CFGS	;Deselect Configuration space
	BCF EECON1, EEPGD	;Point to DATA memory
	BSF EECON1, WREN	;Enable writes
	BCF INTCON, GIE		;Disable INTs.
	MOVLW 55h		;
	MOVWF EECON2		;Write 55h
	MOVLW 0AAh		;
	MOVWF EECON2		;Write AAh
	BSF EECON1, WR		;Set WR bit to begin write
	;BSF INTCON, GIE		;Enable Interrupts
	BCF EECON1, WREN	;Disable writes
	BTFSC EECON1, WR	;Wait for write to complete
	GOTO $-1		;Done
  ;  PAGESEL	Write_to_EEPROM
	;можно
	return	
;========================================================================
	
	
;========================================================================

	
;******************************************************************************
	    end                 ; Конец
;******************************************************************************





