	TITLE  LCD & Temperature
	list 		p=16F877
	include	<p16F877.inc>
	__CONFIG _XT_OSC&_CP_OFF&_WDT_OFF&_BODEN_ON&_DEBUG_ON&_LVP_OFF 				
;----------------------------------------------------------
;Переименование портов и регистров, связанных с ЖКИ

#define	LCD_D4		PORTD, 0	
#define	LCD_D5		PORTD, 1
#define	LCD_D6		PORTD, 2
#define	LCD_D7		PORTD, 3
#define	LCD_D4_DIR	TRISD, 0	
#define	LCD_D5_DIR	TRISD, 1
#define	LCD_D6_DIR	TRISD, 2
#define	LCD_D7_DIR	TRISD, 3
#define	LCD_E		PORTA, 1	
#define	LCD_RW		PORTA, 2	
#define	LCD_RS		PORTA, 3	
#define	LCD_E_DIR	TRISA, 1	
#define	LCD_RW_DIR	TRISA, 2	
#define	LCD_RS_DIR	TRISA, 3

; Константа для работы звукового сигнала
;FLAGS	EQU 0x1A
;J		EQU	0x1B
;K		EQU	0x1C
;TIME0	EQU	0x1D
;TIME1	EQU	0x1E
;TIMER	EQU 0x1F

;----------------------------------------------------------
;Определение переменных	
		cblock 0x20
bufer_sen	;буфер передачи
bufer_recv	;буфер приёма
count_char	;счётчик символов
cmd_byte	
temperature	
LSD		
MsD		
MSD		
count_1
count_2
count_3
		endc
;----------------------------------------------------------
;Начало основной программы
		org		0x0000
		goto	Main
		org		0x004
		retfie
;----------------------------------------------------------
;Подпрограмма вывода сообщений
Message_Send
		call		Table
		banksel		count_char
		incf		count_char
		banksel		bufer_sen
		movwf		bufer_sen
		movf		bufer_sen,f
		btfsc		STATUS,Z
		goto		Message_End
		call		LCD_Data_Write
		goto		Message_Send
Message_End
		return
;----------------------------------------------------------
Table
		banksel		count_char
		movf		count_char,w
		banksel		PCL
		addwf		PCL
		dt			" LCD IS  READY     "	
		retlw		H'00'
		dt			"   Temperature   "
		retlw		H'00'
		dt			" Temp  =  "
		retlw		H'00'
		dt			" Temp_Now >T_Lim "
		retlw		H'00'
		dt			" Temp_Now <T_Lim "
		retlw		H'00'	

;----------------------------------------------------------
Main
;Задание функционального назначения выводов порта А
	movlw	b'00001110' ;выводы RA1, RA2,RA3 ;цифровые входы, вывод    RA0-аналоговый вход
	banksel	ADCON1		
	movwf	ADCON1
;----------------------------------------------------------
;Настройка управляющих выводов RA1, RA2,RA3
; и информационных выводов PORTD0, PORTD1, 	;PORTD2,PORTD3 на выдачу 
	banksel	TRISA		
	bcf		LCD_E_DIR
	bcf		LCD_RW_DIR
	bcf		LCD_RS_DIR
	bcf		LCD_D4_DIR
	bcf		LCD_D5_DIR
	bcf		LCD_D6_DIR
	bcf		LCD_D7_DIR
;----------------------------------------------------------
	banksel	count_char
	clrf	count_char	;очистка счётчика символв
;----------------------------------------------------------
		call		LCD_Init		;инициализация ЖКИ
		call		Message_Send	;вывод сообщения о го-товности ЖКИ
		call		LCD_String_2	;переход на 2-ую строку
		call		Message_Send	;Temperature
		call		delay_1s
		call		delay_1s
		call		MSSP_Init
		call		get_temp
		call		compare_temp
Loop	goto		Loop
;Конец основной программы
;----------------------------------------------------------
;ПОДПРОГРАММЫ
; Подпрограмма инициализации ЖКИ. Начальная инициализация ЖКИ	при 4-ёх разрядном управлении
; заключается в трёхкратном повторении кода 30Н, затем
; записи кода 20Н и только потом вводятся команды на	стройки ЖКИ.	
LCD_Init
	banksel	bufer_sen
	movlw	b'00110000'		
	movwf	bufer_sen		
	banksel	PORTA			 
	bcf		LCD_RS			
	call	LCD_Write_Nibble	 
	movlw	b'00110000'		
	movwf	bufer_sen
	bcf		LCD_RS
	call	LCD_Write_Nibble
	movlw	b'0011000'		
	movwf	bufer_sen
	bcf		LCD_RS
	call	LCD_Write_Nibble
	movlw	b'00100000'		;запись 20Н
	movwf	bufer_sen
	bcf		LCD_RS
	call	LCD_Write_Nibble
	movlw	b'00101000'		;Выбор ширины шины - 4р
	movwf	bufer_sen		;размера символа - 5х7 
	call	LCD_Instr_Write	;количества строк - 2
	movlw	b'00001111'		;Вкл. и выбор вида курсора
	movwf	bufer_sen		;курсор-мерцающее знакоместо  
	call	LCD_Instr_Write
	movlw	b'00000110'		;Курсор вправо
	movwf	bufer_sen		
	call	LCD_Instr_Write
	call	LCD_Clear		;очистка экрана
	return

;----------------------------------------------------------
;Подпрограмма записи символов в регистр данных ЖКИ
LCD_Data_Write
	call		LCD_Busy	
	banksel		PORTA
	bsf			LCD_RS
	call		LCD_Write_Nibble
	banksel		bufer_sen
	swapf		bufer_sen, f
	call		LCD_Write_Nibble
	banksel		bufer_sen
	swapf		bufer_sen,f
	return

;----------------------------------------------------------
;Подпрограмма записи команд в рег.инструкций ЖКИ
LCD_Instr_Write
		call		LCD_Busy
		banksel		PORTA
		bcf			LCD_RS
		call		LCD_Write_Nibble
		banksel		bufer_sen
		swapf		bufer_sen, f
		call		LCD_Write_Nibble
		banksel		bufer_sen
		swapf		bufer_sen,f
		return

;----------------------------------------------------------
;Подпрограмма перехода на первую строку ЖКИ
LCD_String_1
		banksel	bufer_sen
		movlw	0x80
		movwf	bufer_sen
		call	LCD_Instr_Write
		return

;----------------------------------------------------------
;Подпрограмма перехода на первую строку ЖКИ
LCD_String_2
		banksel	bufer_sen
		movlw	0xC0
		movwf	bufer_sen
		call	LCD_Instr_Write
		return
	
;----------------------------------------------------------
;Подпрограмма очистки экрана ЖКИ
LCD_Clear
		banksel	bufer_sen
		movlw	b'00000001'
		movwf	bufer_sen
		call	LCD_Instr_Write
		return
	
;----------------------------------------------------------
;Подпрограмма записи нибла
LCD_Write_Nibble
	banksel	PORTA
	bcf		LCD_RW			; Установка режима записи в ЖКИ
	banksel	TRISD
	bcf		LCD_D4_DIR		; Настройка выводов  
	bcf		LCD_D5_DIR		; порта D микроконтроллера на выдачу
	bcf		LCD_D6_DIR		
	bcf		LCD_D7_DIR
	banksel	PORTA
	bsf		LCD_E			; Включение строба
	banksel	PORTD
	btfss	bufer_sen, 7	; Установка выводов
	bcf		LCD_D7			; порта D по состоянию
	btfsc	bufer_sen, 7	; соответствующих разрядов буферного регистра
	bsf		LCD_D7			
	btfss	bufer_sen, 6	; передачи bufer_sen 
	bcf		LCD_D6	
	btfsc	bufer_sen, 6
	bsf		LCD_D6
	btfss	bufer_sen, 5
	bcf		LCD_D5	
	btfsc	bufer_sen, 5
	bsf		LCD_D5
	btfss	bufer_sen, 4
	bcf		LCD_D4
	btfsc	bufer_sen, 4
	bsf		LCD_D4	
	bsf		LCD_E
	NOP
	NOP
	bcf		LCD_E	; Выключение строба
	return
;----------------------------------------------------------
;Подпрограмма проверки готовности ЖКИ
LCD_Busy
		call	LCD_Instr_Read
		banksel	bufer_recv
		btfsc	bufer_recv,7
		goto	LCD_Busy
		return
;----------------------------------------------------------
;П/п чтения содержимого регистра инструкций ЖКИ
LCD_Instr_Read
		banksel	PORTA
		bcf		LCD_RS
		call	LCD_Read
		return
;----------------------------------------------------------
;П/п чтения внутреннего регистра ЖКИ
LCD_Read
		banksel	TRISD			;Настройка выводов 
		bsf		LCD_D4_DIR		;порта D на приём
		bsf		LCD_D5_DIR
		bsf		LCD_D6_DIR
		bsf		LCD_D7_DIR
		banksel	PORTA
		bsf		LCD_RW			;Установ. режима чтения
		bsf		LCD_E			;Включение строба
		btfss	LCD_D7			; 
		bcf		bufer_recv, 7
		btfsc	LCD_D7			;Установка разрядов 
		bsf		bufer_recv, 7
		btfss	LCD_D6		 	;буферного регистра
		bcf		bufer_recv, 6
		btfsc	LCD_D6			;приёмника 
		bsf		bufer_recv, 6
		btfss	LCD_D5			; bufer_recv		
		bcf		bufer_recv, 5
		btfsc	LCD_D5			;по состоянию 
		bsf		bufer_recv, 5
		btfss	LCD_D4			; выводов
		bcf		bufer_recv, 4
		btfsc	LCD_D4			;порта  D
		bsf		bufer_recv, 4
		bcf		LCD_E			;Выключение строба
		NOP
		NOP
		bsf		LCD_E			;Приём младшего нибла
		btfss	LCD_D7			; 
		bcf		bufer_recv, 3
		btfsc	LCD_D7
		bsf		bufer_recv, 3
		btfss	LCD_D6			
		bcf		bufer_recv, 2
		btfsc	LCD_D6
		bsf		bufer_recv, 2
		btfss	LCD_D5			
		bcf		bufer_recv, 1
		btfsc	LCD_D5
		bsf		bufer_recv, 1
		btfss	LCD_D4			
		bcf		bufer_recv, 0
		btfsc	LCD_D4
		bsf		bufer_recv, 0
		bcf		LCD_E
		banksel	TRISD
		bcf		LCD_D4_DIR
		bcf		LCD_D5_DIR
		bcf		LCD_D6_DIR
		bcf		LCD_D7_DIR
		return
; Инициализация последовательного синхронного порта
MSSP_Init	
	banksel	TRISC			
	bsf		TRISC,3
	bsf		TRISC,4
	movlw	B'00101000'
	banksel	SSPCON
	movwf	SSPCON
	banksel	SSPSTAT
	bsf		SSPSTAT,SMP
	movlw	.5
	movwf	SSPADD
	return
; Чтение  показаний термометра с предварительной 
; проверкой  готовности
get_temp
	banksel	cmd_byte
	movlw	0x01		;запись адреса регистра 
	movwf	cmd_byte	; конфигурации ТС74
	
; Чтение содержимого внутренних регистров  ТС74
; через шину  I2C
Read_registors_of_TC74
; Подготовка к чтению из ТС74
; Выдача адреса ТС74 для записи
	banksel	SSPCON2			;формирование старт-сигнала
	bsf		SSPCON2,SEN
	btfsc	SSPCON2,SEN
	goto	$-1	
	movlw	B'10011010'		;адрес  TC74 (для записи)
	banksel	SSPBUF	
	movwf	SSPBUF
	call	ssprw			;проверка окнчания переда-чи
	banksel	SSPCON2
	btfsc	SSPCON2,ACKSTAT	;проверка подтвержде-ния
	goto	$-1
;-------------------------------------------------------------------------------
; Выдача адреса внутреннего регистра термодатчика
	banksel	cmd_byte
	movf	cmd_byte,w		;передача адреса внутр. регистра
	banksel	SSPBUF
	movwf	SSPBUF
	call	ssprw			;проверка окончания передачи	
	banksel	SSPCON2
	btfsc	SSPCON2,ACKSTAT	;проверка подтверждения
	goto	$-1

;---Выдача адреса  ТС74 для чтения---------
	bsf		SSPCON2,RSEN	;рестарт
	btfsc	SSPCON2,RSEN
	goto	$-1
	movlw	B'10011011'		;адрес  TC74 (для чтения)
	banksel	SSPBUF
	movwf	SSPBUF
	call	ssprw			;проверка окончания передачи
	banksel	SSPCON2
	btfsc	SSPCON2,ACKSTAT	;проверка подтверждения

;---Настройка МК на чтение из ТС74------------------------------
	bsf		SSPCON2,RCEN		;начало чтения
	btfsc	SSPCON2,RCEN
	goto	$-1					;Проверка окончания чтения
;------------------------------------------------------
	banksel	SSPBUF		;копирование информации
	movf	SSPBUF,w
	
;---Формирование подтверждения------------------------------------------------------
	banksel	SSPCON2			;подтверждение  NOT-ACK
	bsf		SSPCON2,ACKDT
	bsf		SSPCON2,ACKEN
	btfsc	SSPCON2,ACKEN	;проверка окончания 
	goto	$-1				;формирования подтверждения
;--------------------------------------------------------------------------			
	bsf		SSPCON2,PEN		;формирование стоп-сигнала
	btfsc	SSPCON2,PEN
	goto	$-1
	;-----------------------------------------------------------------
; Анализ  характера считанной информации	
	banksel	cmd_byte		;байт из регистра конфигурации
	btfss	cmd_byte,0		;или рег. температуры? Если темп., то
	goto	convert_temp	;преобразование, иначе
;-------------------------------------------------------------------------------
; Анализ готовности
	andlw	0x40		
	sublw	0x40
	btfss	STATUS,Z				;Есть ли  готовность? 
	goto	get_temp				;Нет, повторить проверку
	movlw	0x00					;Есть, сосчитать содержимое регистра
	banksel	cmd_byte				;температуры
	movwf	cmd_byte
	goto	Read_registors_of_TC74
;---------------------------------------------------------------------
;Преобразование и вывод на ЖКИ
convert_temp
	movwf	temperature
	call	bin_bcd			;переход к преобразованию
	call	LCD_Clear
	call	delay_1s
	call	Message_Send 	;Temp =
	call	delay_1s	
	movlw 	A'+'	
	movf	MSD,w			;вывод старшей цифры
	movwf	bufer_sen
	call	LCD_Data_Write
	movf	MsD,w			;вывод средней цифры
	movwf	bufer_sen
	call	LCD_Data_Write
	movf	LSD,w			;вывод младшей цифры
	movwf	bufer_sen
	call	LCD_Data_Write
	movlw	A'C'			;вывод символа  "C"( Цельсия)
	movwf	bufer_sen	
	call	LCD_Data_Write
	call	LCD_String_2
	call	delay_1s	
	call	Message_Send	;Temp_Now>Temp_Lim
	return	
;---Проверка освобождения шины I2C
ssprw				
	movlw	0x00
	banksel	SSPCON2
	andwf	SSPCON2,w
	sublw	0x00
	btfss	STATUS,Z
	goto	$-4
	btfsc	SSPSTAT, R_W
	goto	$-1
	return
;Преобразование из двоичного в двоично-десятичный код
bin_bcd
;----Обнуление регистров результата-----------
	banksel	MSD
	clrf	MSD	;регистр сотен
	banksel	MsD
	clrf	MsD	;регистр единиц
;-------------------------------------------------------------
	movwf	LSD			;передача темп. в регистр LSD
	movwf	temperature
;---Определение сотен-----------------------------------
ghundreth	
	movlw	.100		;вычитание 100 из LSD
	subwf	LSD,w
	btfss	STATUS,C	;исх. величина больше,чем  100?
	goto	gtenth		;НЕТ, переход к вычислению десятков
	movwf	LSD			;ДА
	incf	MSD,f		;инкремент регистра сотен
	goto	ghundreth
;---Определение десятков-------------------------		
gtenth
	movlw	.10			;вычитание  десятков
	subwf	LSD,w
	btfss	STATUS,C
	goto	over		;окончание преобразования
	movwf	LSD
	incf	MsD,f		;инкремент регистра десят-ков
	goto	gtenth
	
;преобразование десятичных цифр в ASCII-коды символов
over			
	movf	MSD,w		 
	xorlw	0x30		
	movwf	MSD
	movf	MsD,w
	xorlw	0x30
	movwf	MsD	
	movf	LSD,w
	xorlw	0x30	
	movwf	LSD
	retlw	0
;Процедура подачи звукового сигнала
;SIGNAL	MOVLW	.10			;Количество звуковых посылок
;		MOVWF	K
;L17		CALL	SOUND1
;		CLRF	TIME1
;L16		CLRWDT
;		MOVF	TIME1, 0
;		SUBLW	.1		;Время между звуковыми посылками
;		BTFSC	STATUS, C	
;		GOTO	L16
;		BTFSC	FLAGS, 0
;		RETURN
;		DECFSZ	K
;		GOTO	L17
;		RETURN

;Процедура формирования звукового сигнала
;SOUND1  BCF		INTCON, GIE					
;		MOVLW	.250						
;		MOVWF	J
;L13		MOVF	TMR0, 0
;		SUBLW	.2		;Частота звука, время импульса
;		BTFSC	STATUS, C	
;		GOTO	L13	
;		BCF		PORTA, 3
;		CLRF	TMR0		
;L15		CLRWDT
;		MOVF	TMR0, 0
;		SUBLW	.70							
;		BTFSC	STATUS, C	
;		GOTO	L15	
;L14		DECFSZ	J
;		GOTO	L14
;		BCF		PORTA, 3
;		BSF		INTCON, GIE					
;		RETURN
;-----------------------------------------------------------------	
;Мерцание светодиодов, подключённых к порту В
LEDs
	banksel TRISB		;Настройка выводов на выдачу
	bcf		TRISB,3
	bcf		TRISB,2
	bcf		TRISB,1
	banksel PORTB
	bsf		PORTB,1	;Включение  1-госветодиода
	call	delay_100ms
	call	delay_100ms
	banksel PORTB
	bcf		PORTB,1	;Выключеие 1-го светодиода
	bsf		PORTB,2
	call	delay_100ms
	call	delay_100ms
	banksel PORTB
	bcf		PORTB,2
	bsf		PORTB,3
	call	delay_100ms
	call	delay_100ms
	banksel PORTB
	bcf		PORTB,3
	
;--Сравнение текущей температуры с заданной-(170C	)
compare_temp
	banksel	temperature
	movf	temperature,w		
	sublw	B'00010001'		;17
	btfss	STATUS,0
;    goto	SIGNAL
	goto	LEDs
	call	LCD_Clear
	call	delay_100ms
	call	Message_Send



;------------------ 100ms Delay --------------------------------
delay_100ms
	banksel	count_2
	movlw	.83
	movwf	count_2
	movlw	0xFF
	movwf	count_1
again	
	decfsz	count_1,f
	goto	$-1
	decfsz	count_2,f
	goto	again
	return
;---------------- 1s Delay -----------------------------------
delay_1s
	banksel	count_3
	movlw	.10
	movwf	count_3
povt
	call	delay_100ms
	decfsz	count_3	
	goto	povt
	return			
;--------------------------------------------------------------------	
	END
