;Программа С.Корякова для термометра с функцией термостата на PIC16F84 4МГц с датчиком температуры DS18B20
;Претерпела изменения подпрограмма вывода на индикатор (бщий анод)и подпрограмма сравнения температур
;(включение - выключение нагревателя)
;На выходе RA3 формируется сигнал лог. ед. если измеренная температура выше заданной.
;Трищенко Константин!!!!
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
LIST P=16F84
;Описание встроенных в контроллер ресурсов
#include <P16F84.INC>
__config  _XT_OSC & _WDT_OFF & _PWRTE_ON
F0		EQU	0
RTIF	equ	2
;Переменные и константы,используемые в программе
NumL	EQU	0x0C			
NumH	EQU	0x0D			
Thou	EQU	0x0E			
Hund	EQU	0x0F			
Tens	EQU	0x10			
Ones	EQU	0x11			
I		EQU	0x13
A		EQU	0x14
BACKUPW	EQU	0x15
BACKUPS	EQU	0x16
RAZR0	EQU	0x17						;Три ячейки, содержат семисегментный код для вывода на индикатор
RAZR1	EQU 0x18
RAZR2	EQU 0x19
;В переменной FLAGS каждый бит сигнализирует о:
;0 - нажата кнопка вызова таймера
;1 - нажата кнопка установки таймера
;2 - необходимости обновления в экранном буфере оставшегося времени в таймере
;3 - произошло нажатие кнопки вызова таймера, необходимо подать короткий звуковой сигнал
;4 - закончилась выдержка времени таймера, необходимо подать условный звуковой сигнал
;5 - раз в секунду сигнализирует о необходимости считывания показаний DS1820
;6 - необходимости вывода десятичной точки
FLAGS	EQU 0x1A
J		EQU	0x1B
K		EQU	0x1C
TIME0	EQU	0x1D
TIME1	EQU	0x1E
PA		EQU 0x1F
T7SEG0	EQU	0x20
T7SEG1	EQU	0x21
T7SEG2	EQU	0x22
T_IND	EQU	0x23
TEMP_READH		EQU	0x24
TEMP_READL		EQU	0x25
TL				EQU	0x26
TH				EQU	0x27
TIME2			EQU	0x28
I_BYTE			EQU	0x29
_N				EQU	0x2A
TEMP			EQU	0x2B
O_BYTE			EQU	0x2C
LOOP1			EQU	0x2D
LOOP2			EQU	0x2E
T_ALARM		EQU	0x2F
DT_ALARM		EQU	0x30

CONSTANT 		DATA_PIN=7

;******	Начальная инициализация контроллера и программы *******
		BSF     STATUS, RP0					;Устанавливаем страницу памяти 1 
    	CLRF    TRISA						;Настраиваем все линии порта А и В на вывод 
    	CLRF	TRISB
    	GOTO	BEGIN_PROG	
	
;*****  Точка входа в процедуру обработки прерываний от таймера*************
 		BCF		INTCON,	GIE					;Запрещаем прерывания
		MOVWF	BACKUPW						;Сохраняем содержимое рабочего регистра
		MOVF	STATUS, 0					;и регистра STATUS
		MOVWF	BACKUPS

		;Програмные таймеры
		INCF	TIME0, 1
		MOVF	TIME0, 0
		SUBLW	.81							;122
		BTFSC	STATUS, C	
		GOTO	L22	
		CLRF	TIME0
		INCF	TIME2, 1
L18		MOVF	TIME2, 0
		SUBLW	.2						;Устанавливаем период измерения температуры равным 1 сек.
		BTFSC	STATUS, C	
		GOTO	L26
		CLRF	TIME2
		BSF		FLAGS, 5
L26		BTFSS	FLAGS, 0					;Корректировка таймера возможна только при нажатии кнопки
		GOTO	L22							;вызова таймера
		BTFSS	FLAGS, 1					;Если нажата кнопка установки таймера
		GOTO	L22
		BCF		FLAGS, 2
		BSF		FLAGS, 7
		INCF	T_ALARM, 1
		MOVF	T_ALARM, 0
		SUBLW	0x7D						;Если достиг 125 градусов, сбрасываем до -55 градусов
		BTFSS	STATUS, Z	
		GOTO	L22
		MOVLW	0xC9
		MOVWF	T_ALARM
		
		;Опрос состояния кнопок управления
L22		BCF		PA, 0					;Флаги, показывающие 
		BCF		FLAGS, 1					;состояние кнопок.
		BCF		PA, 1					;Выключаем индикаторы
		BCF		PA, 2
		BSF		PA, 4
		MOVF	PA, 0
		MOVWF	PORTA
		BSF     STATUS, RP0					;Устанавливаем страницу памяти 1
		BSF		TRISB, 5					;Разряды порта В, подключенные к кнопкам настраиваем на ввод
		BSF		TRISB, 6		
		BCF     STATUS, RP0					;Устанавливаем страницу памяти 0
		BTFSC	PORTB, 6					;Устанавливаем флаги в зависимости от состояния кнопок
		GOTO	L23
		BSF		FLAGS, 0
		MOVLW	.255
		MOVWF	T_IND
L23		DECFSZ	T_IND
		GOTO	L24
		BCF		FLAGS, 0
		BTFSC	FLAGS, 7
		CALL	SEEPROM
		BCF		FLAGS, 7
L24		BTFSS	PORTB, 5
		BSF		FLAGS, 1
		BSF     STATUS, RP0					;Устанавливаем страницу памяти 1
		BCF		TRISB, 5					;Разряды порта В, подключенные к кнопкам настраиваем на вывод
		BCF		TRISB, 6		
		BCF     STATUS, RP0					;Устанавливаем страницу памяти 1
		
		;Динамическая индикация содержимого RAZR0, RAZR1, RAZR2
		MOVLW	.0							;Отображаем разряд 0		
		SUBWF	I, 0		
		BTFSS	STATUS, Z
		GOTO	L2	
		MOVLW	B'10000000'
		ANDWF	PORTB, 1					;Очищаем разряды порта, подключенные к индикатору
		MOVF	RAZR0, 0
		IORWF	PORTB, 1					;Выводим отображаемую цифру
		BSF		PA, 0						;Включаем соответствующий разряд индикатора
		MOVF	PA, 0
		MOVWF	PORTA	
		GOTO	L4
L2		MOVLW	.1							;Отображаем разряд 1
		SUBWF	I, 0		
		BTFSS	STATUS, Z
		GOTO	L3	
		MOVLW	B'10000000'
		ANDWF	PORTB, 1					;Очищаем разряды порта, подключенные к индикатору
		MOVF	RAZR1, 0
		IORWF	PORTB, 1					;Выводим отображаемую цифру
		BSF		PA, 1
		BTFSC	FLAGS, 6
		BCF		PA, 4
		BTFSS	FLAGS, 6
		BSF		PA, 4
		MOVF	PA, 0
		MOVWF	PORTA
		GOTO	L4
L3		MOVLW	B'10000000'
		ANDWF	PORTB, 1					;Очищаем разряды порта, подключенные к индикатору
		MOVF	RAZR2, 0
		IORWF	PORTB, 1					;Выводим отображаемую цифру
		BSF		PA, 2
		MOVF	PA, 0
		MOVWF	PORTA	
L4		INCF	I, 1
		MOVLW	.3							;Обнулить счетчик разрядов, если достиг 3
		SUBWF	I, 0
		BTFSC	STATUS, Z
		CLRF	I

		;Завершение обработки прерывания от таймера
IRET	BCF 	INTCON, RTIF 		;Сброс флага прерывания от таймера
		MOVF	BACKUPS, 0
		MOVWF	STATUS
		MOVF 	BACKUPW, 0			;Востановление рабочего регистра
		BSF 	INTCON, GIE			;Разрешение прерываний
		RETFIE						;Возврат из обработки прерывания

;****** Продолжение начальной инициализации *****************************
BEGIN_PROG	
		MOVLW	B'01000011'			;Подключаем пределитель к таймеру и устанавливаем коэффициент
		MOVWF	OPTION_REG			;деления 1:16, сигнал на таймер от внутреннего генератора
		BCF     STATUS, RP0     	;Устанавливаем страницу памяти 0 
		CLRF	PORTB
		MOVLW	B'00000111'
		MOVWF	PA
		MOVF	PA, 0
		MOVWF	PORTA	
		CLRF	I					;Инициализируем используемые в программе	
		CLRF	FLAGS				;переменные
		CALL	START_DS
		CLRF	TMR0
		CLRF	TEMP_READL
		CLRF	TEMP_READH
		CALL	LEEPROM
		MOVLW	0x02
		MOVWF	DT_ALARM
		CLRF	TIME0
		CLRF	TIME2
		CLRF	TMR0
		MOVLW	B'10100000'			;Разрешаем прерывание от переполнения таймера
		MOVWF	INTCON
		BCF		FLAGS, 5
		BCF		FLAGS, 3
		MOVLW	B'10111111'             ;(три тире при старте)
		MOVWF	RAZR0
		MOVWF	RAZR1
		MOVWF	RAZR2
		CALL	START_DS
		;Пауза до получения первого достоверного результата измерения температуры
L0		BTFSS	FLAGS, 5
		GOTO	L0
		CALL	START_DS
		BCF		FLAGS, 5
L00		BTFSS	FLAGS, 5
		GOTO	L00
		
;****** Основной цикл программы ******
L10		CLRWDT
L25		BTFSS	FLAGS, 0
		GOTO	L12					;Необходимо отображение температуры
		BTFSC	FLAGS, 2
		GOTO	L10
		BSF		FLAGS, 2
		BCF		FLAGS, 6			;Отключение запятой
		BTFSC	T_ALARM, 7			;Вычисление целой части
		GOTO	L70					;Температура ниже нуля
		MOVF	T_ALARM, 0
		MOVWF	NumL
		GOTO	L71		
L70		MOVLW	0xFF
		MOVWF	NumL
		MOVF	T_ALARM, 0
		SUBWF	NumL, 1
L71		CLRF	NumH
		CALL	Convert
		MOVF	Ones, 0
		CALL	DS7SEG
		MOVWF	RAZR0
		MOVF	Tens, 0
		CALL	DS7SEG
		MOVWF	RAZR1
		MOVF	Hund, 0
		CALL	DS7SEG
		MOVWF	RAZR2
		BTFSC	T_ALARM, 7
		BCF		RAZR2, 6			;Включение знака минус при отрицательной температуре		
		GOTO	L10
L12		BCF		FLAGS, 2			;Отображение температуры
		BTFSC	FLAGS, 3
		CALL	CONV_T
		BCF		FLAGS, 3
		BTFSS	FLAGS, 5
		GOTO	L10
		;Передается управление каждую секунду
		BCF		FLAGS, 5
		BSF		FLAGS, 3
		CALL	READ_T
		CALL	START_DS
		ANDLW	0xFF
		BTFSS	STATUS, Z
		GOTO	L10
		MOVLW	B'00000001'
		MOVWF	RAZR0
		MOVWF	RAZR1
		MOVWF	RAZR2
		BCF		FLAGS, 3
		GOTO	L10					;Возвращаемся на начало цикла
;****************************************************************************

;Процедура преобразования десятичной цифры из WREG в код 7-ми сегментного индикатора
DS7SEG	ADDWF	PCL, 1
        RETLW  	B'01000000'			;0
        RETLW  	B'01111001'			;1
        RETLW  	B'00100100'			;2
        RETLW  	B'00110000'			;3
        RETLW  	B'00011001'			;4
        RETLW  	B'00010010'			;5
        RETLW  	B'00000010'			;6
        RETLW  	B'01111000'			;7
        RETLW  	B'00000000'			;8
        RETLW  	B'00010000'			;9
        RETLW  	B'01111111'			;Пробел
        RETLW  	B'00111111'			;Минус
	
;*****************************************************************************
;Процедура перевода числа формата HEX16 (переменые NumL, NumH) в формат BSD
;(переменные Thou, Hund, Tens, Ones) 
Convert swapf   NumH,w			
        IORLW	B'11110000'		
		movwf   Thou
		addwf   Thou, 1
		addlw   0xE2
		movwf   Hund
     	addlw   0x32
     	movwf   Ones
     	movf    NumH, 0
     	andlw   0x0F
     	addwf   Hund, 1
     	addwf   Hund, 1
     	addwf   Ones, 1
     	addlw   0xE9
     	movwf   Tens
     	addwf   Tens, 1
     	addwf   Tens, 1
     	swapf   NumL, 0
     	andlw   0x0F
     	addwf   Tens, 1
     	addwf   Ones, 1
     	rlf     Tens, 1
     	rlf     Ones, 1
     	comf    Ones, 1
     	rlf     Ones, 1
     	movf    NumL, 0
     	andlw   0x0F
     	addwf   Ones, 1
     	rlf     Thou, 1
     	movlw   0x0A
Lb1: 	addwf   Ones, 1
     	decf    Tens, 1
     	btfss   3, 0
     	goto   Lb1
Lb2: 	addwf   Tens, 1
     	decf    Hund, 1
     	btfss   3, 0
     	goto   Lb2
Lb3: 	addwf   Hund, 1
     	decf    Thou, 1
     	btfss   3, 0
     	goto   Lb3
Lb4: 	addwf   Thou, 1
     	btfss   3, 0
     	goto   Lb4
		MOVLW	Thou					;Удаление незначащих нулей
		MOVWF	FSR
		MOVLW	3
		MOVWF	I
L54		MOVF	F0, 0
		ANDLW	0x0F
		BTFSS	STATUS, Z
		RETURN							;Разряд не равен 0
		MOVLW	0x0A
		MOVWF	F0
		INCF	FSR	
		DECFSZ	I
		GOTO	L54
        RETURN

;Процедура вычисления температуры с точностью до 0.1 по данным полученным от DS18В20
;Входные параметры: TEMP_READH, TEMP_READL,результат помещается в экранный буфер
CONV_T	MOVF	TEMP_READL, 0
		MOVWF	NumL
		MOVF	TEMP_READH, 0
		MOVWF	NumH
		BTFSC	TEMP_READH, 7			;Вычисление целой части
		GOTO	L30				;Температура ниже нуля
		MOVLW	.4				;Выделяем целую часть значения температуры делением на .16d 
		MOVWF	A
L61		BCF		STATUS, C
		RRF		NumH, 1
		RRF		NumL, 1
		DECFSZ	A, 1
		GOTO	L61
		MOVF	NumL, 0
		MOVWF	TH
		MOVF	TEMP_READL, 0			;Вычисляем десятичную часть
		ANDLW	B'00001111'
		GOTO	L50
L30		MOVLW	.4				;Выделяем целую часть значения температуры делением на .16d
		MOVWF	A
L62		BCF		STATUS, C
		RRF		NumH, 1
		RRF		NumL, 1
		DECFSZ	A, 1
		GOTO	L62
		MOVLW	0xFF
		MOVWF	TH
		MOVF	NumL, 0
		SUBWF	TH, 1
		movlw	0xFF
		movwf	NumH
		MOVF	TEMP_READL, 0			;Вычисляем десятичную часть 
		ANDLW	B'00001111'
		SUBWF	NumH, 0
		ANDLW	B'00001111'
L50		MOVWF	NumL
		CLRF	NumH
		MOVLW	.6			
		MOVWF	A
L63		MOVF	NumL, 0
		ADDWF	NumH, 1
		DECFSZ	A, 1
		GOTO	L63
		MOVF	NumH, 0
		MOVWF	NumL				
		CLRF	NumH
		CALL	Convert
		MOVLW	0x0A
		SUBWF	Tens, 0
		BTFSC	STATUS, Z
		CLRF	Tens
		MOVLW	.5						;Округление 
		SUBWF	Ones, 0
		BTFSC	STATUS, C
		INCF	Tens, 1
		MOVF	Tens, 0
		MOVWF	TL
	
   		;Сравнение температур	
   		BTFSC		T_ALARM, 7	; Проверяем уставку
   		GOTO		L72		;Уставка ниже нуля, значит переход 
   		MOVF		T_ALARM, 0	;Уставка выше нуля
   		MOVWF		NumL		;Прибавим к NumL значение уставки и
   		MOVLW		.54		;добавим 54, чобы не мучиться при сравнении 
   		ADDWF		NumL, 1		;положительной температуры и отрицательной уставки (или наоборот)
   		GOTO		L73		;Переход 	
   L72	MOVLW		0xFF		;Появляемся здесь при условии отрицательной уставки
   		MOVWF		NumL
   		MOVF		T_ALARM, 0
   		SUBWF		NumL, 1
   L73	BTFSC		TEMP_READH, 7	; Проверяем считанный код с датчика температуры 
   		GOTO		L74		;Температура ниже нуля
   		MOVF		TH, 0		;Температура выше нуля и опять добавим 54,но 
   		MOVWF		NumH                    ;не к считанным с датчика данным,
   		MOVLW		.54		;а к целой части вычисленной температуры
   		ADDWF		NumH, 1
   		GOTO		L76		;Переход 
   L74	MOVF		TH ,0		;Появляемся здесь при условии отрицательной температуры
   		MOVWF		NumH
   		BTFSC   	PA, 3		;Проверим, включен ли нагреватель!
   		CALL		L2E		;включен, значит сходим, добавим гистерезис и вернемся
   		MOVF 		NumH, 0		;Нет не включен значит сравниваем, 
		DECF		NumL, 1
   		SUBWF		NumL, 0		; вычитая из уставки температуру	
   		BTFSC		STATUS, C			
   		GOTO		L2A		;Переход 
   L2B	BCF		PA, 3		;если измеренная температура ниже- включение нагревателя
   		MOVF		PA, 0
   		MOVWF		PORTA	
   		GOTO		L31		;Выход из подпрограммы
   L2A    	BTFSC		T_ALARM, 7	; Проверяем еще раз уставку, на случай положительной температуры, но
   		GOTO		L2C		; отрицательной уставки, чтобы не было проблем при переходе через 0
   		GOTO		L2B		; соответственно отключаем или включаем нагреватель
   L2C	BSF		PA, 3		;если измеренная температура выше- выключение нагревателя
   		MOVF		PA, 0
   		MOVWF   	PORTA
   		GOTO		L31		;Выход из подпрограммы
   L76	BTFSC   	PA, 3		;Появляемся здесь при условии положительной температуры
   		CALL		L2D		;Проверим, включен ли нагреватель? Да , сбегаем и добавим;гистерезис
   		MOVF		NumH, 0		;Нет не включен, значит сравниваем,
		DECF		NumL, 1	
   		SUBWF		NumL, 0		
   		BTFSC		STATUS, C	; вычитая из уставки температуру		 
   		GOTO		L88
   		BSF		PA, 3				
   		MOVF		PA, 0
   		MOVWF		PORTA	
   		GOTO		L31
   L2D	MOVF		DT_ALARM, 0	;Добавим 2 град. гистерезиса, чтобы выключить нагреватель 
   		SUBWF		NumL, 1		;на 2 град.выше
   		RETURN
   L2E	MOVF		DT_ALARM, 0	;Вычтем 2 град. гистерезиса, чтобы выключить нагреватель 
   		ADDWF		NumL, 1		;на 2 град.выше, при отрицательной температуре.
   		RETURN
   L88	BCF		PA, 3
   		MOVF		PA, 0
   		MOVWF		PORTA

		;Запись полученного значения температуры в экранный буфер
L31		BTFSS	TEMP_READH, 7
		GOTO	L36							;Температура выше нуля
		MOVF	TH, 0
		SUBLW	.19
		BTFSC	STATUS, C	
		GOTO	L36							;Температура выше минус 19 градусов	
		;при температуре меньше -19.9
		MOVF	TH, 0						;Занесение значения температуры в экранный буфер
		MOVWF	NumL				
		CLRF	NumH
		CALL	Convert
		MOVF	Ones, 0
		CALL	DS7SEG
		MOVWF	RAZR0
		MOVF	Tens, 0
		CALL	DS7SEG
		MOVWF	RAZR1
		MOVLW	0x0A
		CALL	DS7SEG
		MOVWF	RAZR2
		BCF		RAZR2, 6					;Включение знака минус при отрицательной температуре
		BCF		FLAGS, 6					;Отключить вывод десятичной точки
		RETURN
L36		MOVF	TH, 0
		SUBLW	.99
		BTFSC	STATUS, C	
		GOTO	L37							;Температура выше плюс 99 градусов
		MOVF	TH, 0						;Занесение значения температуры в экранный буфер
		MOVWF	NumL				
		CLRF	NumH
		CALL	Convert
		MOVF	Ones, 0
		CALL	DS7SEG
		MOVWF	RAZR0
		MOVF	Tens, 0
		CALL	DS7SEG
		MOVWF	RAZR1
		MOVF	Hund, 0
		CALL	DS7SEG
		MOVWF	RAZR2
		BCF		FLAGS, 6					;Отключить вывод десятичной точки
		RETURN
		;при температуре от -19.9 до 99.9
L37		MOVF	TL, 0						;Занесение значения температуры в экранный буфер
		MOVWF	NumL				
		CLRF	NumH
		CALL	Convert
		MOVF	Ones, 0
		CALL	DS7SEG
		MOVWF	RAZR0
		MOVF	TH, 0						;Занесение значения температуры в экранный буфер
		MOVWF	NumL				
		CLRF	NumH
		CALL	Convert
		MOVF	Ones, 0
		CALL	DS7SEG
		MOVWF	RAZR1
		MOVF	Tens, 0
		CALL	DS7SEG
		MOVWF	RAZR2
		BTFSC	TEMP_READH, 7				;Включение знака минус при отрицательной температуре
		BCF		RAZR2, 6
		BSF		FLAGS, 6					;Включить вывод десятичной точки
		RETURN

;Процедура считывает данные об измеренной температуре из DS18В20
READ_T	CALL	INIT
		MOVLW	0xCC						;Skip ROM 
		MOVWF	O_BYTE
		CALL	OUT_BYTE
		MOVLW	0xBE						;Read Scratchpad 
		MOVWF	O_BYTE
		CALL	OUT_BYTE
		;Прием данных
		CALL 	IN_BYTE
		MOVWF	TEMP_READL					;0
		CALL 	IN_BYTE
		MOVWF	TEMP_READH					;1
		CALL 	IN_BYTE						;2
		CALL 	IN_BYTE						;3
		CALL 	IN_BYTE						;4
		CALL 	IN_BYTE						;5
		CALL 	IN_BYTE						;6
		CALL 	IN_BYTE						;7
		CALL 	IN_BYTE						;8
		;Подсчет и сравнение контрольной суммы пропущено
		RETLW	0xFF

;Процедура выдает команду на старт измерения температуры для датчика DS18В20
START_DS
		CALL	INIT
		MOVLW	0xCC						;Skip ROM 
		MOVWF	O_BYTE
		CALL	OUT_BYTE
		MOVLW	0x44						;Convert T
		MOVWF	O_BYTE
		CALL	OUT_BYTE
		RETLW	0xFF
		
; The following are common 1-Wire routines used in all applications
INIT:   CALL	PIN_HI
        CALL	PIN_LO
		MOVLW	.50              	; 500 us delay
		CALL 	DELAY_10USEC
		CALL	PIN_HI		  
        MOVLW 	.50					; 500 usec delay
        CALL 	DELAY_10USEC
        RETURN

IN_BYTE:              				; returns byte in W
		MOVLW	.8
		MOVWF	 _N
        CLRF	I_BYTE
IN_BYTE_1:
		CALL PIN_LO					; momentary low on DATA_PIN
        NOP
		CALL PIN_HI
		NOP
		NOP
		NOP
		NOP
		NOP
        NOP
        MOVF	PORTB, W			; 7 usecs later, fetch from DATA_PIN
		MOVWF	TEMP                                                        
		BTFSS	TEMP, DATA_PIN
		BCF STATUS, C				; its a zero
		BTFSC	TEMP, DATA_PIN
		BSF STATUS, C				; its a one
        RRF	I_BYTE, F
		MOVLW .6					; now delay 60 usecs
        CALL	DELAY_10USEC
        DECFSZ	_N, F
        GOTO	IN_BYTE_1
        MOVF	I_BYTE, 0			; return the result in W
        RETURN

OUT_BYTE:
		MOVLW	.8
        MOVWF	_N
OUT_BYTE_1:
		RRF		O_BYTE, F
        BTFSS	STATUS, C
		GOTO	OUT_0
		GOTO	OUT_1	
OUT_BYTE_2:
		DECFSZ	_N, F
        GOTO	OUT_BYTE_1
        RETURN
OUT_0:	CALL	PIN_LO				; bring DATA_PIN low
		MOVLW	.6					; for 60 usecs
		CALL 	DELAY_10USEC
        CALL	PIN_HI
        GOTO	OUT_BYTE_2
OUT_1:	CALL	PIN_LO				; momentary low
        CALL	PIN_HI
        MOVLW 	.6
		CALL 	DELAY_10USEC
        GOTO	OUT_BYTE_2

PIN_HI:	BCF		INTCON,	GIE
		BSF		STATUS, RP0
        BSF		TRISB, DATA_PIN		; high impedance
        BCF		STATUS, RP0
        BSF		INTCON,	GIE
        RETURN
PIN_LO:	BCF		INTCON,	GIE
		BCF		PORTB, DATA_PIN
		BSF		STATUS, RP0
        BCF		TRISB, DATA_PIN		; low impedance zero
        BCF		STATUS, RP0
        BSF		INTCON,	GIE
        RETURN

DELAY_LONG
		MOVLW 	.250				; 250 msec delay
		MOVWF 	LOOP1
DELAY_N_MS:
OUTTER	MOVLW	.110				; close to 1.0 msec delay when set to .110
		MOVWF 	LOOP2
INNER	NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		DECFSZ	LOOP2, F			; decrement and leave result in LOOP2 
		GOTO 	INNER				; skip next statement if zero
		DECFSZ 	LOOP1, F
		GOTO 	OUTTER
		RETURN

DELAY_10USEC:						; provides a delay equal to W * 10 usecs
		MOVWF 	LOOP1
DELAY_100USEC_1:
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		DECFSZ 	LOOP1, F
		GOTO 	DELAY_100USEC_1
		RETURN


;*****************************************************************************
;Процедура сохраняет значение переменной T_ALARM
;в энергонезависимой памяти данных
SEEPROM	MOVLW	.50
		MOVWF	EEADR
		MOVF	T_ALARM, 0
		CALL	L21
		RETURN
L21		MOVWF	EEDATA				;Подпрограмма записи EEROM
		BCF		INTCON, GIE			;Запрещение всех прерываний
		BSF     STATUS, RP0			;Устанавливаем страницу памяти 1 
		BSF		EECON1, WREN		;Разрешаем запись в EEROM
		MOVLW	0x55				;Даем набор команд для записи
		MOVWF	EECON2
		MOVLW	0xAA
		MOVWF	EECON2
		BSF		EECON1, WR
L20		NOP							;Ожидаем завершения записи
		BTFSC	EECON1, WR
		GOTO	L20
		BCF		EECON1, WREN		;Запрещаем запись в EEROM
		BCF     STATUS, RP0			;Устанавливаем страницу памяти 0
		BSF		INTCON, GIE			;Разрешение всех прерываний
		INCF	EEADR, 1
		RETURN

;Процедура загружает значение переменной T_ALARM
;из энергонезависимой памяти данных
LEEPROM	MOVLW	.50
		MOVWF	EEADR	
		CALL	RROM
		MOVWF	T_ALARM
		RETURN
		;Подпрограмма считывания данных из EEROM
RROM	BSF     STATUS, RP0			;Устанавливаем страницу памяти 1 
		BSF		EECON1, RD			;Команда на чтение EEROM	
		BCF     STATUS, RP0			;Устанавливаем страницу памяти 0
		INCF	EEADR, 1
		MOVF	EEDATA, 0
		RETURN

		END							;Конец программы.
