;========================================================================================
; LCD palubni pocitac pro RC model                                                5.2010 
; LCD 2x16 znaku, PIC16F84A, DS18B20, kmitocet 3.2768MHz                                    
;========================================================================================
;                           http://www.spirit-pro.com                        
;========================================================================================
;                                  PIC16F84                              
;                             --------\/--------                         
;                    LCD RS  -|RA2          RA1|-  LCD RW                
;                 LIGHT LCD  -|RA3          RA0|-  LCD E                 
;                  DS18B20   -|RA4         osc1|-  \ Krystal 4,00MHz     
;                       +5V  -|MCLR        osc2|-  /                     
;                        0V  -|Vss          Vdd|-  +5V                   
;                  LCD DB 4  -|RB0/INT  PGD/RB7|-  DATA  ICSP            
;                  LCD DB 5  -|RB1      PGC/RB6|-  CLOCK ICSP            
;                  LCD DB 6  -|RB2          RB5|-  LED TEMP                        
;                  LCD DB 7  -|RB3          RB4|-  Rx SIGNAL ENGINE                      
;                             ------------------                         
;                                                                      Martenss (c) 2010 
;========================================================================================
; Popis funkce programu a zarizeni
;========================================================================================
;
;
;
;========================================================================================
;****************************************************************************************
		LIST	P=16F84A, R=DEC
		INCLUDE	"p16f84a.inc"
	
;========================================================================================
; Ulozeni DAT v EERAM
;========================================================================================
	
		org	0x2100		; zacatek pameti EERAM
;
; ulozene hodnoty LINE1, LINE2
;		
		de	'T'		; LCD1
		de	'e'		; LCD2
		de	'm'		; LCD3
		de	'p'		; LCD4
		de	':'		; LCD5
		de	'-'		; T_ENG_1
		de	'-'		; T_ENG_2
		de	'-'		; T_ENG_3
		de	'.'		; LCD9
		de	'-'		; T_ENG_4
		de	0xDF		; LCD11
		de	'C'		; LCD12
		de	'/'		; LCD13
		de	'-'		; T_MAX_1
		de	'-'		; T_MAX_2
		de	'-'		; T_MAX_3
		
		
		de	0x5B		; LCD17
		de	'0'		; ENG_ST_1
		de	'3'		; ENG_ST_2
		de	'1'		; ENG_ST_3
		de	0x5D		; LCD21
		de	0x7E		; LCD22
		de	' '		; TIME_H1
		de	'0'		; TIME_H2
		de	'4'		; TIME_H3
		de	':'		; LCD26
		de	'5'		; TIME_M1
		de	'2'		; TIME_M2
		de	':'		; LCD29
		de	'3'		; TIME_S1
		de	'0'		; TIME_S2
		de	0x7F		; LCD32
		
		de	.70		; LED_LIGHT sviti pod 75°C
		de	.95		; LED_FLASH blika nad 95°C
		de	.30		; LED_OFF nesviti pod 45°C
		
		de	.255		; Konec dat v EEPROM
		
;========================================================================================
; Promenne a definice PIC
;========================================================================================

RAM		EQU	.12		; zacatek paměti RAM pro PIC16F84A - 68bajtů (0C-2F)

;===========================   LINE 1   =================================================
LCD1		EQU	RAM+1		; znak "T"
LCD2		EQU	RAM+2		; znak "e"
LCD3		EQU	RAM+3		; znak "m"
LCD4		EQU	RAM+4		; znak "p"
LCD5		EQU	RAM+5		; znak ":"
T_ENG_1		EQU	RAM+6		; jednotka stovek teploty
T_ENG_2		EQU	RAM+7		; jednotka desitek teploty
T_ENG_3		EQU	RAM+8		; jednotka teploty
LCD9		EQU	RAM+9		; znak "."
T_ENG_4		EQU	RAM+10		; jednotka pul/celeho stupne	
LCD11		EQU	RAM+11		; znak "°"
LCD12		EQU	RAM+12		; znak "C"
LCD13		EQU	RAM+13		; znak "/"
T_MAX_1		EQU	RAM+14		; jednotka stovek max teploty
T_MAX_2		EQU	RAM+15		; jednotka desitek max teploty
T_MAX_3		EQU	RAM+16		; jednotka max teploty

;===========================   LINE 2   =================================================
LCD17		EQU	RAM+17		; znak "("
ENG_ST_1		EQU	RAM+18		; jednotka stovek startu
ENG_ST_2		EQU	RAM+19		; jednotka desitek startu
ENG_ST_3		EQU	RAM+20		; jednotka startu
LCD21		EQU	RAM+21		; znak ")"
LCD22		EQU	RAM+22		; znak "sipka vpravo"
TIME_H1		EQU	RAM+23		; jednotka stovek motohodin
TIME_H2		EQU	RAM+24		; jednotka desitek motohodin
TIME_H3		EQU	RAM+25		; jednotka motohodin
LCD26		EQU	RAM+26		; znak ":"
TIME_M1		EQU	RAM+27		; jednotka desitek motominut
TIME_M2		EQU	RAM+28		; jednotka motominut
LCD29		EQU	RAM+29		; znak ":"
TIME_S1		EQU	RAM+30		; jednotka desitek motovterin
TIME_S2		EQU	RAM+31		; jednotka motovterin
LCD32		EQU	RAM+32		; znak "sipka vlevo"

;----------------------------------------------------------------------------------------

LED_LIGHT		EQU	RAM+33		; teplota kdy LED sviti
LED_FLASH		EQU	RAM+34		; teplota kdy LED blika
LED_OFF		EQU	RAM+35		; teplota kdy LED nesviti

TMR0_X		EQU	RAM+36		; pro obsluhu preruseni
TMR0_Y		EQU	RAM+37		; pro obsluhu preruseni
PC_STATUS		EQU	RAM+38		; stavove bity
COUNTER		EQU	RAM+39		; pocitadlo
ADRESA		EQU	RAM+40		; adresa
TMP_DATA		EQU	RAM+41		; pomocne - adresa EEPROM

;----------------------------------------------------------------------------------------

W_Copy		EQU	RAM+42		; temp preruseni
ST_Copy		EQU	RAM+43		; temp preruseni
TMP0		EQU	RAM+44		; cekaci smycka
TMP1		EQU	RAM+45		; cekaci smycka
TMP2		EQU	RAM+46		; cekaci smycka
TMP3		EQU	RAM+47		; cekaci smycka
TEXT		EQU	RAM+48		; zobrazeni textu na LCD
ZNAK		EQU	RAM+49		; zobrazeni znaku na LCD

;----------------------------------------------------------------------------------------

DSDL1		EQU	RAM+50          	; komunikace s DS18B20
DSREG1		EQU	RAM+51
DSREG2		EQU	RAM+52
TL		EQU	RAM+53
TH		EQU	RAM+54
D550US		EQU	.163             	; 550us
D90US		EQU	.20              	; 90us
D1US		EQU	.1               	; 3us

;----------------------------------------------------------------------------------------

TEMP_PR		EQU	RAM+58		; provozni teplota motoru
TEMP_MAX		EQU	RAM+59		; maximalni provozni teplota
T_PR		EQU	RAM+60
T_LI		EQU	RAM+61
T_FL		EQU	RAM+62
T_OF		EQU	RAM+63
T_MA		EQU	RAM+64
T_MAX_4		EQU	RAM+65
PC_STATUS_TEMP	EQU	RAM+66

;----------------------------------------------------------------------------------------

#define		E	PORTA,0		; Enable
#define		RW	PORTA,1		; Read/Write
#define		RS	PORTA,2		; Register Select
#define		SVITI	PORTA,3		; Rozsviceni LCD
#define		DSPIN	PORTA,4		; 1-Wire s DS18B20
#define		LED	PORTB,5		; LED Teplota    
#define		RX	PORTB,4		; RX signal ENGINE

#define		ENGINE_GO	PC_STATUS,0		; motor bezi?
#define		ENGINE_ST	PC_STATUS,1		; byl motor nastartovan?
#define		WRITE_ST	PC_STATUS,2		; byl zapsan start?
#define		LED_ENG_ON	PC_STATUS,3		; LED sviti?
#define		LED_ENG_FL	PC_STATUS,4		; LED blika?
#define		TEMP_RUN	PC_STATUS,5		; dosahl motor provozni teploty?
#define		WRT_EERAM	PC_STATUS,6		; povolen zapis do EEPROM?
#define		T1S	PC_STATUS,7		; ubehla 1 sekunda?

#define		RX_TEMP	PC_STATUS_TEMP,0	; bezi motor podle teploty
		
DELETE

;========================================================================================
; Definice MAKRO
;========================================================================================

jnz		MACRO	metka1            
		btfss	STATUS,Z           
		goto	metka1
		endm
		
jz		MACRO	metka2
		btfsc	STATUS,Z
		goto	metka2
		endm
				
jnc		MACRO	metka3            
		btfss	STATUS,C	  
		goto	metka3
		endm
				
jc		MACRO	metka4           
		btfsc	STATUS,C	   
		goto	metka4
		endm
				
mvi		MACRO	DEST2,CONST2       
		movlw	CONST2
		movwf	DEST2
		endm
		
mov		MACRO	DEST1,SOURCE1
		movf	SOURCE1,W
		movwf	DEST1
		endm		

;========================================================================================
; Konfigurace PIC
;========================================================================================

		__config _HS_OSC & _PWRTE_ON & _WDT_OFF & _CP_OFF

;========================================================================================
; Zacatek programu
;========================================================================================

		org	.0		; zacatek programu
		goto	INIT_PIC		; skok na inicializaci
		
;========================================================================================
; Obsluha preruseni
;========================================================================================

		org	.4		; obsluha preruseni kazdych 50ms
Preruseni		movwf	W_Copy		; pri obsluse preruseni	
		movf	STATUS, W		; se generuje kazdou minutu
		movwf	ST_Copy		; signal o uplynuti jedne sekundy
		movlw	.10		; bohuze pri tak vysoke frekvenci
		movwf	TMR0_Y		; nelze zajistit preruseni na delsi
Delay		decfsz	TMR0_Y, F		; cas, proto je vytvorena smycka
		goto	Delay		; TMR0_X, smycka TMR0_Y pouze
					; jemne doladuje presnost hodin
					; tolerance je cca 1s/240minut
					
Nastav_T1S		decfsz	TMR0_X, F		; snizuj pocet preruseni
		goto	Vrat_se	
		bsf	T1S		; prave ubehla 1 sekunda
		movlw	.13
		movwf	TMR0_X		; obnov pocitadlo
	
Vrat_se		movlw	.10
		movwf	TMR0		; nastav TMR0
		bcf	INTCON, T0IF	; nuluj priznak preteceni od TMR0
		movf	ST_Copy, W
		movwf	STATUS
		swapf	W_Copy, F
		swapf	W_Copy, W
		retfie
		
;****************************************************************************************
; Hlavni program LCD
;****************************************************************************************

;========================================================================================
; Tabulka definice textu po resetu a hlavni obrazovka
;========================================================================================

TAB_TXT		addwf	PCL,F		; uvodni obrazovka po zapnuti
		retlw	' '		; 0	LINE 1
		retlw	' '
		retlw	' '
		retlw	'R'
		retlw	'a'
		retlw	'p'
		retlw	't'
		retlw	'o'
		retlw	'r'
		retlw	' '
		retlw	'6'
		retlw	'0'
		retlw	' '
		retlw	' '
		retlw	' '
		retlw	' '
		retlw	80h		; konec textu
	
		retlw	' '		; 17	LINE 2
		retlw	'S'
		retlw	'p'
		retlw	'i'
		retlw	'r'
		retlw	'i'
		retlw	't'
		retlw	'-'
		retlw	'p'
		retlw	'r'
		retlw	'o'
		retlw	'.'
		retlw	'c'
		retlw	'o'
		retlw	'm'
		retlw	' '
		retlw	80h		; konec textu
		
;========================================================================================
; Tabulka znaku cislovek pro zobrazeni na LED displeji
;========================================================================================
		
DC7		clrf	PCLATH
		addwf	PCL,F		
		retlw	.48		 ; 0
		retlw	.49		 ; 1
		retlw	.50		 ; 2
		retlw	.51		 ; 3
		retlw	.52		 ; 4
		retlw	.53		 ; 5
		retlw	.54		 ; 6
		retlw	.55		 ; 7
		retlw	.56		 ; 8
		retlw	.57		 ; 9
		retlw	.58	        	 ; 5
		
		
;****************************************************************************************
; Hlavni program PIC
;****************************************************************************************


MAIN_PIC		btfss	T1S		; ubehla 1 sekunda?

Cekani_na_vterinu	goto	MAIN_PIC		; NE cekej, ANO pokracuj
		
Cti_teplotu		call	DS_READ		; nacte teplotu z cidla		
	
Testuj_motor	call	ENGINE		; testuje beh, start a zapis startu

Hodiny		call	TIMER_ENG		; aktualizace motohodin

Converze_Temp	call	TMPCNV		; prevod z DS do byte TH a TL

Max_Min_Temp	call	MAXMIN		; testuje MAX teplotu

Dekodovani_TEMP	call	Prevod_Temp_LCD	; dekoduje teplotu TEMP_PR

Zobraz_LCD		call	LCD		; zobraz data z RAM na LCD

Zapis_EERAM		call	WRITE_EERAM		; zapis RAM do EERAM

Signalizace		call	LED_TEMP		; signalizace teploty LEDkou

Aktivuj_ledku	call	LED_SET		; nastav LED podle bit Light a Flash	

Start_DS		call	DS_START		; PRESENT pulz DS

		bcf	T1S		; nuluj priznak sekundy
		
Opakovani		goto 	MAIN_PIC		; opakuj cyklus
	
;========================================================================================
; Inicializace procesoru a LCD 2x16 znaku
;========================================================================================

INIT_PIC		movlw	b'00000000'
		movwf	PORTA		; prednastaveni PORTu A
		movlw	b'00000000'
		movwf	PORTB		; prednastaveni PORTu B
		bsf	STATUS,RP0		; nastaveni BANKY 1
		movlw	b'00010000'		; RA4 vstup, ostatni OUT
		movwf	TRISA
		movlw	b'00000111'		; PULL-UPy ON, 1:256
		movwf	OPTION_REG
		movlw	b'11010000'		; RB4,6,7 vstup, ostatni OUT
		movwf	TRISB
		bcf	STATUS, RP0		; nastaveni BANKY 0
		bcf	STATUS, RP1		; nastaveni BANKY 0, kompatibilita
		clrf	PORTA
		clrf	PORTB
		clrw
		clrf	PC_STATUS		; nuluje stavove bity
		clrf	PC_STATUS_TEMP	; nuluje stavove bity
		movlw	.0
		movwf	TEMP_PR		; ulozi nulovou pocatecni hodnotu
			
;========================================================================================
; Inicializace LCD
;========================================================================================

INIT_LCD		call	CEK15m		; 4-bitova inicializace displeje LCD
		bcf	RS		; RS=0, zapis instrukci do LCD
		movlw	03h
		movwf	PORTB
		bsf	E
		bcf	E		; zapise do LCD
		call	CEK15m		; !! pro zjednoduseni dano 15ms !!
		bsf	E
		bcf	E		; zapise do LCD
		call	CEK100		; cekej 100 us
		bsf	E
		bcf	E		; zapise do LCD
		call	CEK1m6		; cekej 1,6 ms
		movlw	02h
		movwf	PORTB
		bsf	E
		bcf	E		; zapise do LCD
		call	CEK1m6		; cekej 1,6 ms
		movlw	28h		; 00101000 - počet bitů, 2 radky, 5x7 znak
		call	WR_CMD
		movlw	0Ch		; 00001100 - display ON, kurzor OFF, blikani OFF
		call	WR_CMD
		movlw	01h		; 00000001 - smaze displej
		call	WR_CMD
		movlw	06h		; 00000110 - smer kurzoru, posunu displeje
		call	WR_CMD	
			
;========================================================================================
; Uvod programu
;========================================================================================

UVOD_LCD		bsf	LED		; rozsvit LED_ENG
		bsf	SVITI
		call	C_LCD		; smaz LCD displej, 1 radek a 1 znak
		movlw	.0		; text 0
		call	WR_TEXT
		call	LINE2
		movlw	.17		; text 17
		call	WR_TEXT
		call	CEK2s		; cekej 2s
		
;========================================================================================
; Prenos dat z EEPROM do RAM
;========================================================================================		
				
READ_EERAM		movlw	.0		; pocatek EEPROM
		movwf	TMP_DATA
		movlw	.35	
		movwf	COUNTER		; pocitadlo prenosu 35 byte
		movlw	.13
		movwf	FSR		; pocatek RAM
		clrw
			
READ_EERAM_2	bcf	STATUS, RP0		; prenos z EEPROM do RAM
		movf	TMP_DATA, W
		movwf	EEADR		; v EEADR adresa EEPROM	
		bsf	STATUS, RP0
		bsf	EECON1, RD		; vlastni cteni byte
		bcf	STATUS, RP0
		movf	EEDATA, W		; uloz do W
		movwf	INDF		; prenes do RAM
		incf	FSR, F		; zvys adresu RAM
		incf	TMP_DATA, F		; zvys adresu EEPROM
		clrw
		decfsz	COUNTER, F		; prenos 35 byte
		goto	READ_EERAM_2		
		movlw	b'10100000'		; povol globalni preruseni
		movwf	INTCON		; povol preruseni od TMR0
		movlw	.13
		movwf	TMR0_X		; nastav 20x50ms=1S
		movlw	.10	
		movwf	TMR0		; casovac TMR0 na 50ms
		call	DS_START		; present pulz pro DS
		bcf	LED		; zhasni LED_ENG
		goto	MAIN_PIC
		
;========================================================================================
; Podprogram zapisu textu do LCD
;========================================================================================

WR_TEXT		movwf	TEXT		; W -> TEXT
		call	TAB_TXT
		movwf	ZNAK		; W -> ZNAK
		sublw	0x80
		btfsc	STATUS,Z
		retlw	0x00		; pokud je znak = 80h, konec textu
		movf	ZNAK,W		; ZNAK -> W
		call	WR_DATA
		incf	TEXT,W		; TEXT + 1 -> W
		goto	WR_TEXT

;========================================================================================
; Podprogramy pro LCD, Clear, Write, Line 1 , Line 2
;========================================================================================

LINE1		movlw	0x80		; 1 radek, 0 znak displeje
		goto	WR_CMD

LINE2		movlw	0xC0		; 2 radek, 0 znak displeje
		goto	WR_CMD

C_LCD		movlw	0x01		; smaz LCD a vrat se na pozici 0
		goto	WR_CMD

WR_CMD		bcf	RS		; RS=0, zapis instrukci do LCD
		goto	WR_LCD

WR_DATA		bsf	RS		; RS=1, zapis dat do LCD
		goto	WR_LCD

WR_LCD		movwf	ZNAK		; prepsat W do ZNAK	!!! data v registru W !!!
		bsf	E		; nastav Enable
		movf	PORTB,W		; stav portu do W
		iorlw	0x0F		; zamaskuje dolni bity portu
		movwf	TMP1
		swapf	ZNAK,W
		iorlw	0xF0		; zamaskuje horní bity znaku
		andwf	TMP1,W		; pošle vyšší 4 bity
		movwf	PORTB		; !!! data zapsana na PORTB 0-3 !!!
		bcf	E		; zapiše do LCD
		bsf	E		; nastav Enable
		movf	ZNAK,W
		iorlw	0xF0		; zamaskuje horni bity znaku
		andwf	TMP1,W		; posle nizsí 4 bity
		movwf	PORTB		; !!! data zapsana na PORTB 0-3 !!!
		bcf	E		; zapise do LCD
		btfsc	RS
		goto	CEK40		; RS=1, zapis dat - cekej 40 us
		movlw	0x04		; instrukce 1, 2 a 3 - cekej 1,64 ms
		subwf	ZNAK,W
		btfss	STATUS,C
		goto	CEK1m6		; C=0, instrukce CLEAR - cekej 1,64 ms
		goto	CEK40		; C=1, zapis dat - cekej 40 us

;========================================================================================
; Podprogram PAUSE pro LCD
;========================================================================================
;
; casy pro frekvenci krystalu 4,00Mhz
; casy jsou spocitane od call CEKxxm do navratu na volani CEKxxm
; celkovy vypocet  = 2+6+(2+(TMP0-1)*3+2)+3)*TMP1-1+2
; zkraceny vypocet = 8+((TMP0-1)*3+7)*TMP1+1
; mala smycka = (TMP2-1)*3+2
;

CEK2s		movlw	.20		; TMP2 = 20  cekej 2 sekundu
		movwf	TMP3
		goto	SMYCKA2
		
CEK1s		movlw	.10		; TMP2 = 10  cekej 1 sekundu
		movwf	TMP3
		goto	SMYCKA2	

CEK100m		movlw	0CFh		; cas = 100,009 ms
		movwf	TMP0
		movlw	0A0h
		movwf	TMP1
		goto	SMYCKA

CEK15m		movlw	0ABh		; cas = 15,002 ms
		movwf	TMP0
		movlw	01Dh
		movwf	TMP1
		goto	SMYCKA

CEK4m		movlw	0A5h		; cas = 4,001 ms
		movwf	TMP0
		movlw	008h
		movwf	TMP1
		goto	SMYCKA

CEK1m6		movlw	041h		; cas = 1,601 ms
		movwf	TMP0
		movlw	008h
		movwf	TMP1
		goto	SMYCKA
	
CEK100		movlw 	01Dh		; cas = 100 mikrosekund
		movwf	TMP0
		movlw	001h
		movwf	TMP1
		goto	SMYCKA

CEK40		movlw	009h		; cas = 40 mikrosekund
		movwf	TMP0
		movlw	001h
		movwf	TMP1
		goto	SMYCKA

SMYCKA2		call	CEK100m
		decfsz	TMP3,F		; nejvetsi smycka
		goto	SMYCKA2
		retlw	00h
	
SMYCKA		movf	TMP0,W
		movwf	TMP2
		
SMYCKA1		decfsz	TMP2,F		; mala smycka
		goto	SMYCKA1
		decfsz	TMP1,F		; velka smycka
		goto	SMYCKA
		retlw	00h

;========================================================================================	
; Nulovani cislic, RESET LED, podprogram pro TEMP_PR
;========================================================================================

Prevod_Temp_LCD	rrf	TH,F
		rrf	TL,F
		rrf	TH,F
		rrf	TL,F
		rrf	TH,F
		rrf	TL,F	
	
Null_LED		movlw	.32
		movwf	T_ENG_1		 
		movwf	T_ENG_2
		movwf	T_ENG_3
		movwf	T_ENG_4
		movlw	.46
		movwf	LCD9
		clrw

;========================================================================================
; Testuje zapornou teplotu, zobrazi znamenko MINUS na prvni pozici
;========================================================================================

Minus		btfss	TH,2			 
		goto	T100_label		
		mvi	T_ENG_1, .45
		comf	TL,F			 
		incf	TL,F			 
		goto	Tshow_label		 

;========================================================================================
; Testuje teplotu vetsi jak 100°C, zobrazi JEDNICKU na prvni pozici
;========================================================================================

T100_label		bcf	STATUS,C
		rrf	TL,W			 	
		addlw	D'156'
		jnc	Tshow_label		 
		movlw	D'200'		 
		subwf	TL,F			
		mvi	T_ENG_1,.49
		movlw	.48
		movwf	T_ENG_4	

;========================================================================================
; Podprogram pro dekodovani cislic teploty
;========================================================================================

Tshow_label		bcf	STATUS,C
		rrf	TL,W		 	 
		movwf	TMP2
		
Divide		clrf	T_ENG_3		; 00X0
		movf	TMP2,W		 
		movwf	TMP1                 
		bsf	STATUS,C             

Div_label		movf	TMP1,W
		movwf	T_ENG_4         	; 000X     
		incf	T_ENG_3,F             	; 00X0
		movlw	D'10'               
		subwf	TMP1,F               
		jc	Div_label             
		decf	T_ENG_3,F		; 00X0	
		movlw	.49
		xorwf	T_ENG_2,W		; 0X00	 
		jnz	High_label		 
		movf	T_ENG_3,W		; 00X0
		call	DC7
		movwf	T_ENG_3		; 00X0
		movf	T_ENG_4,W		; 000X
		call	DC7
		movwf	T_ENG_4		; 000X
		goto	Finish_label

;========================================================================================
; Testuje pul stupen, tedy pokud neni teplota vyssi jak 100°C a dekoduje cislice
;========================================================================================

High_label		movf	T_ENG_3,W		; 00X0
		call	DC7
		movwf	T_ENG_2		; 0X00
		movf	T_ENG_4,W		; 000X
		call	DC7
		movwf	T_ENG_3		; 00X0
		bcf	T_ENG_3,7		; 00X0
		mvi	T_ENG_4,.48		; znak nuly
		movlw	.53		; znak petky
		btfsc	TL,0
		movwf	T_ENG_4	
	
Finish_label	return
		
;========================================================================================
; Vypocet maximalni teploty motoru a ulozeni do TEMP_MAX
;========================================================================================

MAXMIN		btfsc	ENGINE_GO
		goto	MAX_1
		return
		
MAX_1		btfsc	TEMP_RUN
		goto	MAX_2
		return
		
MAX_2		mov	T_PR, TEMP_PR
		mov	TMP3, TEMP_MAX
		bsf	STATUS, C		; nastav priznak C
		movf	T_PR, W		
		subwf	TMP3, F		; testuj, PR vetsi jak TEM3
		btfsc	STATUS, C
		return			; NE vrat se
		mov	TEMP_MAX, T_PR	; ANO ulož T_PR do TEMP_MAX
		
;========================================================================================
; Podprogram pro dekodovani MAXimalni teploty a zobrazeni na LCD
;========================================================================================
		
CNV_MAX_TEMP	movlw	.32
		movwf	T_MAX_1		 
		movwf	T_MAX_2
		movwf	T_MAX_3
		movwf	T_MAX_4
		mov	T_MA, TEMP_MAX
		decfsz	T_MA, F	
		clrw
		bcf	STATUS,C
		rlf	T_MA	 

;========================================================================================
; Testuje teplotu vetsi jak 100°C, zobrazi JEDNICKU na prvni pozici
;========================================================================================

T100_label_2	bcf	STATUS,C
		rrf	T_MA, W	 	
		addlw	D'156'
		jnc	Tshow_label_2		 
		movlw	D'200'		 
		subwf	T_MA,F			
		mvi	T_MAX_1,.49
		movlw	.48
		movwf	T_MAX_4	

;========================================================================================
; Podprogram pro dekodovani cislic MAX teploty
;========================================================================================

Tshow_label_2	bcf	STATUS,C
		rrf	T_MA,W
		movwf	TMP2
		
Divide_2		clrf	T_MAX_3		; 00X0
		movf	TMP2,W		 
		movwf	TMP1                 
		bsf	STATUS,C             

Div_label_2		movf	TMP1,W
		movwf	T_MAX_4         	; 000X     
		incf	T_MAX_3,F             	; 00X0
		movlw	D'10'               
		subwf	TMP1,F               
		jc	Div_label_2             
		decf	T_MAX_3,F		; 00X0	
		movlw	.49
		xorwf	T_MAX_2,W		; 0X00	 
		jnz	High_label_2		 
		movf	T_MAX_3,W		; 00X0
		call	DC7
		movwf	T_MAX_3		; 00X0
		movf	T_MAX_4,W		; 000X
		call	DC7
		movwf	T_MAX_4		; 000X
		goto	Finish_label_2

;========================================================================================
; Testuje pul stupen, tedy pokud neni teplota vyssi jak 100°C a dekoduje cislice
;========================================================================================

High_label_2	movf	T_MAX_3,W		; 00X0
		call	DC7
		movwf	T_MAX_2		; 0X00
		movf	T_MAX_4,W		; 000X
		call	DC7
		movwf	T_MAX_3		; 00X0
		bcf	T_MAX_3,7		; 00X0
		mvi	T_MAX_4,.48		; znak nuly
		movlw	.53		; znak petky
		btfsc	T_MA,0
		movwf	T_MAX_4	
	
Finish_label_2	return


;****************************************************************************************
; Hlavni program TIME_COUNTER, nacita motohodiny
;****************************************************************************************

TIMER_ENG		btfsc	ENGINE_GO		; bezi motor?		
		goto	TM_ENG_3		; ANO pokracuj
		return			; NE vrat se
		
TM_ENG_3		movf	TIME_S2, W		; pricti sekundu
		sublw	.57		
		btfsc	STATUS, Z
		goto	TM_ENG_4
		incf	TIME_S2, F
		goto	TM_ENG_END
		
TM_ENG_4		movlw	.48
		movwf	TIME_S2
		movf	TIME_S1, W		; pricti deset sekund
		sublw	.53		
		btfsc	STATUS, Z
		goto	TM_ENG_5
		incf	TIME_S1, F
		goto	TM_ENG_END
		
TM_ENG_5		bsf	WRT_EERAM		; uloz do EEPROM kazdou 1m
		movlw	.48
		movwf	TIME_S1
		movf	TIME_M2, W		; pricti minutu
		sublw	.57		
		btfsc	STATUS, Z
		goto	TM_ENG_6
		incf	TIME_M2, F
		goto	TM_ENG_END	
		
TM_ENG_6		movlw	.48
		movwf	TIME_M2
		movf	TIME_M1, W		; pricti deset minut
		sublw	.53		
		btfsc	STATUS, Z
		goto	TM_ENG_7
		incf	TIME_M1, F
		goto	TM_ENG_END
		
TM_ENG_7		movlw	.48
		movwf	TIME_M1
		movf	TIME_H3, W		; pricti hodinu
		sublw	.57		
		btfsc	STATUS, Z
		goto	TM_ENG_8
		incf	TIME_H3, F
		goto	TM_ENG_END
		
TM_ENG_8		movlw	.48
		movwf	TIME_H3
		movf	TIME_H2, W		; pricti deset hodin
		sublw	.57		
		btfsc	STATUS, Z
		goto	TM_ENG_9
		incf	TIME_H2, F
		goto	TM_ENG_END
		
TM_ENG_9		movlw	.48
		movwf	TIME_H2
		movf	TIME_H1, W		; pricti sto hodin
		sublw	.57		
		btfsc	STATUS, Z
		goto	TM_ENG_NULL
		
		movf	TIME_H1, W		; prvni stovka hodin?
		sublw	.32
		btfsc	STATUS, Z
		goto	TM_ENG_H1_1
		incf	TIME_H1, F
		goto	TM_ENG_END
		
TM_ENG_H1_1		movlw	.49		; nastav stovku hodin		
		movwf	TIME_H1
		goto	TM_ENG_END		
		
TM_ENG_NULL		movlw	.48		; nuluj displej hodin
		movwf	TIME_S2
		movwf	TIME_S1
		movwf	TIME_M2
		movwf	TIME_M1
		movwf	TIME_H3
		movwf	TIME_H2
		movlw	.32
		movwf	TIME_H1		
		
TM_ENG_END		return			; vrat se


;****************************************************************************************
; Hlavni program ENGINE_START/RUN, nacita pocet startu a testuje beh motoru
;****************************************************************************************

		
ENGINE		goto	ENG_A		; testuje motor

ENG_TEMP		mov	T_PR, TEMP_PR	; rutina pro start podle teploty
		mov	T_OF, LED_OFF
		bsf	STATUS, C
		movf	T_PR, W
		subwf	T_OF, F
		btfss	STATUS, C
		goto	RX_ANO
		goto	RX_NE
		
RX_ANO		bsf	RX_TEMP
		goto	ENG_A
		
RX_NE		bcf	RX_TEMP
		goto	ENG_A

ENG_A		btfsc	RX		; bezi motor? (RX)(RX_TEMP)
		goto	ENG_C		; ANO pokracuj
		
		bcf	ENGINE_GO		; nastav ze motor stoji
		btfsc	ENGINE_ST		; motor jiz bezel?
		goto	ENG_B
		bcf	WRT_EERAM		; nebezel = nezapisuj
		return
		
ENG_B		bsf	WRT_EERAM		; pokud nebezel, zakaz zapis
		bcf	ENGINE_ST		; nastav ze nebyl spusten
		return			; NE vrat se

ENG_C		bsf	ENGINE_GO		; nastav ze motor bezi
		bcf	WRT_EERAM		; pokud motor bezi, zakaz zapis do EEPROM
		bsf	ENGINE_ST		; nastav ze motor byl spusten
				
		btfsc	WRITE_ST		; byl zapsan start?
		return			; ANO vrat se
		
ENG_D		movf	ENG_ST_3, W		; je v ENG_ST_3 "9"?	
		sublw	.57
		btfsc	STATUS, Z
		goto	ST_3_plus		; ANO nuluj ST3 a pokracuj
		incf	ENG_ST_3, F		; NE pricti +1 a vrat se
		goto	ST_YES
					
ST_3_plus		movlw	.48		
		movwf	ENG_ST_3		
		movf	ENG_ST_2, W		; je v ENG_ST_2 "9"?	
		sublw	.57
		btfsc	STATUS, Z
		goto	ST_2_plus		; ANO nuluj ST3 a pokracuj
		incf	ENG_ST_2, F		; NE pricti +1 a vrat se
		goto	ST_YES		
	
ST_2_plus		movlw	.48		
		movwf	ENG_ST_2		
		movf	ENG_ST_1, W		; je v ENG_ST_1 "9"?	
		sublw	.57
		btfsc	STATUS, Z
		goto	ST_1_plus		; ANO nuluj ST3 a pokracuj
		incf	ENG_ST_1, F		; NE pricti +1 a vrat se
		goto	ST_YES	

ST_1_plus		movlw	.48		; pokud 999 startu, tak nuluj
		movwf	ENG_ST_1
		movwf	ENG_ST_2
		movwf	ENG_ST_3		

ST_YES		bsf	WRITE_ST		; start uz byl pripsan	
		bsf	WRT_EERAM		; povol zapis do EEPROM
		return
		
		
;****************************************************************************************
; Podprogram prenos dat z RAM do LCD
;****************************************************************************************

LCD		call	C_LCD		; Nuluj LCD
		movlw	.16
		movwf	COUNTER		; prenes 16 znaku LINE 1
		movlw	.13
		movwf	FSR		; pocatek RAM v PIC
		call	LCD_RAM		
		call	LINE2		; prenes 16 znaku LINE 2	
		movlw	.16
		movwf	COUNTER
		movlw	.29
		movwf	FSR
		call	LCD_RAM
		return

LCD_RAM		movf	INDF, W		; vlastni prenos do LCD
		movwf	TMP_DATA
		call	WR_DATA
		incf	FSR, F
		decfsz	COUNTER, F
		goto	LCD_RAM	
		return	
		
;****************************************************************************************
; Podprogram pro nastaveni provozu LED Engine, urci pravidla kdy LED sviti nebo blika
;****************************************************************************************

LED_SET		btfsc	ENGINE_GO		; bezi motor?
		goto	LED_SET_2		; ANO pokracuj
		bcf	LED		; NE zhasni LED
		return			; a vrat se
		
LED_SET_2		btfsc	LED_ENG_ON		; ma LED svitit?
		goto	LED_SET_3		; ANO pokracuj
		goto	LED_SET_4		; NE zhasni LED
		
LED_SET_3		bsf	LED		; rozsvit LED
		return			; vrat se
		
LED_SET_4		btfsc	LED_ENG_FL		; ma LED blikat?
		goto	LED_SET_5		; ANO pokracuj
		bcf	LED		; 
		return			; vrat se

LED_SET_5		btfsc	LED		; sviti LED?
		goto	LED_SET_6		; ANO zhasni LED
		bsf	LED		; NE rozsvit LED						
		return			; vrat se
		
LED_SET_6		bcf	LED		; zhasni LED
		return			; vrat se

;========================================================================================
; Definice stavu sviceni, nastavi dle teplot bity urcujici sviceni nebo blikani LED
;========================================================================================

LED_TEMP		btfss	ENGINE_GO		; bezi motor?
		return			; NE vrat se
			
LT_CNV_X		mov	T_PR, TEMP_PR
		mov	T_LI, LED_LIGHT
		mov	T_FL, LED_FLASH
		mov	T_OF, LED_OFF 
		
		btfsc	TEMP_RUN		; ANO pokracuj
		goto	LT_LIGHT
		bsf	STATUS, C		; nastav priznak C
		movf	T_PR, W		; NE testuj teplotu OFF
		subwf	T_OF, F		; testuj, PR vetsi jak OF
		btfss	STATUS, C
		goto	LT_OFF_A		; ANO pokracuj
		
LT_OFF_N		return			; NE vrat se
				
LT_OFF_A		bsf	TEMP_RUN		; ANO nastav ze byl zahraty
		mov	TEMP_MAX, LED_OFF	
		bsf	LED_ENG_ON		; rozsvit LED
			
LT_LIGHT		bsf	STATUS, C		; nastav priznak C
		movf	T_PR, W		; NE testuj teplotu LIGHT
		subwf	T_LI, F		; testuj, PR vetsi jak LI
		btfss	STATUS, C
		goto	LT_LIGHT_A
		goto	LT_LIGHT_N
		
LT_LIGHT_A		bcf	LED_ENG_ON
		goto	LT_FLASH	

LT_LIGHT_N		bsf	LED_ENG_ON
		goto	LT_FLASH

LT_FLASH		bsf	STATUS, C		; nastav priznak C
		movf	T_PR, W		; NE testuj teplotu FLASH
		subwf	T_FL, F		; testuj, PR vetsi jak FL
		btfss	STATUS, C
		goto	LT_FLASH_A
		goto	LT_FLASH_N
		
LT_FLASH_A		bsf	LED_ENG_FL
		return	

LT_FLASH_N		bcf	LED_ENG_FL
		return		
		
		
;****************************************************************************************
; Hlavni program DS18B20, prevod teploty v DS a jeji vycteni do TH a TL
;****************************************************************************************

DS_START		call	DSSTART         	; start prevodu teploty v cidlu
        		return
        		
DS_READ    		call	DSREAD		; vyctení teploty z cidla
		return
		
;========================================================================================
; Podprogramy DS18B20 
;========================================================================================

DSSTART		CALL	DSPINL          	; start prevodu teploty
        		MOVLW	D550US          	; reset pulse
        		CALL	DSDEL
        		CALL    	DSPINH
        		MOVLW   	D90US
        		CALL    	DSDEL
        		BTFSC   	DSPIN
        		RETURN                  	; bez odpovedi - konec
        		MOVLW   	D550US
        		CALL    	DSDEL
        		MOVLW   	0xCC
        		CALL    	DSSEND
       		MOVLW   	0x44
        		CALL    	DSSEND
        		RETURN
        
;========================================================================================

DSREAD  		CLRF    	TL           	; vycteni teploty z cidla
        		CLRF    	TH	
        		CALL    	DSPINL
        		MOVLW   	D550US          	; reset pulse
        		CALL    	DSDEL
        		CALL    	DSPINH
        		MOVLW   	D90US
        		CALL    	DSDEL
        		BTFSC   	DSPIN
        		RETURN                  	; bez odpovedi - konec
        			
        		MOVLW   	D550US
        		CALL    	DSDEL
        		MOVLW   	0xCC
        		CALL    	DSSEND
        		MOVLW   	0xBE
        		CALL    	DSSEND
        		CALL    	DSREC
        		MOVWF   	TL
        		CALL    	DSREC
        		MOVWF   	TH
        		RETURN
        
DSPINL  		BSF     	STATUS,RP0      	; pin DSPIN do L
       		BCF     	DSPIN
       		BCF     	STATUS,RP0
        		BCF     	DSPIN
        		RETURN
        
DSPINH  		BSF     	STATUS,RP0      	; pin DSPIN do H (pull-up)
        		BSF     	DSPIN
        		BCF     	STATUS,RP0
        		RETURN
        
DSDEL   		MOVWF   	DSDL1		; prodleva pro komunikaci
        		DECFSZ  	DSDL1,1
        		GOTO   	$-1
        		RETURN

;========================================================================================

DSSEND  		MOVWF   	DSREG1          	; odeslani jednoho bytu z W do DS18B20
        		MOVLW   	.8
        		MOVWF   	DSREG2
DSSND1  		CALL    	DSPINL
        		BTFSC   	DSREG1,0
        		CALL    	DSPINH
        		MOVLW   	D90US
        		CALL    	DSDEL
        		CALL    	DSPINH
        		RRF     	DSREG1,1
        		DECFSZ  	DSREG2,1
        		GOTO    	DSSND1
        		MOVLW   	D90US
        		CALL    	DSDEL
        		RETURN
        
;========================================================================================
        
DSREC   		CLRF    	DSREG1          	; vycteni jednoho bytu z DS18B20 do W
        		MOVLW   	.8
        		MOVWF   	DSREG2
        		
DSREC1  		RRF     	DSREG1,1
        		CALL    	DSPINL
        		CALL    	DSPINH
        		MOVLW   	D1US
        		CALL    	DSDEL
        		BCF     	DSREG1,7
        		BTFSC   	DSPIN
        		BSF     	DSREG1,7
        		MOVLW   	D90US
        		CALL    	DSDEL
        		DECFSZ  	DSREG2,1
        		GOTO    	DSREC1
        		MOVLW   	D90US
        		CALL    	DSDEL
        		MOVF    	DSREG1,0
        		RETURN

; =======================================================================================
;  Prevod binarni hodnoty ziskane z cidla na velikost teploty do TEMP_PR
;========================================================================================

TMPCNV  		CLRF    	TEMP_PR
        		BTFSS   	TH,7
        		GOTO    	$+5
        		COMF    	TH,1
        		COMF    	TL,1
        		MOVLW  	.200
        		MOVWF   	TEMP_PR
        
        		MOVF    	TEMP_PR,0
        		BTFSC   	TL,4
        		ADDLW   	.1
        		BTFSC   	TL,5
        		ADDLW   	.2
        		BTFSC   	TL,6
        		ADDLW  	.4
        		BTFSC   	TL,7
        		ADDLW   	.8

        		BTFSC   	TH,0
        		ADDLW   	.16
        		BTFSC   	TH,1
        		ADDLW   	.32
        		BTFSC   	TH,2
        		ADDLW   	.64
        		MOVWF   	TEMP_PR
        		incfsz	TEMP_PR, F
      
        		RETURN
        		
;========================================================================================
; Prenos dat z RAM do EEPROM
;========================================================================================		
				
WRITE_EERAM		btfss	WRT_EERAM		; je povolen zapis?
		return
		movlw	.10		; nuluj TMR0
		movwf	TMR0		; casovac TMR0 na 50ms
		movlw	.16		; adresa EEPROM do EEADR
		movwf	TMP_DATA
		movlw	.17	
		movwf	COUNTER		; pocitadlo prenosu LINE2
		movlw	.29
		movwf	FSR		; obsah RAM do EEDATA
		clrw
			
WRITE_EERAM_2	movf	TMP_DATA, W		; nastav adresu EEPROM
		movwf	EEADR
		movf	INDF, W		; nastav data z RAM
		movwf	EEDATA

WRITE_EERAM_3	bsf	STATUS, RP0		; prenos dat z RAM do EEPROM
		
		bcf	INTCON, GIE		; zakaz globalni preruseni
		bsf	EECON1, WREN	; povol zapis do EEPROM
		movlw	H'55'		; kod 55h
		movwf	EECON2
		movlw	H'AA'		; kod AAh
		movwf	EECON2
		bsf	EECON1, WR		; zapis do EEPROM
		
WRITE_EERAM_4	btfsc 	EECON1,WR		; testuje dokonceni zapisu
    		goto	WRITE_EERAM_4
		
		bsf	INTCON, GIE		; povol preruseni
		bcf	EECON1, EEIF	; nuluj priznak dokonceni zapisu	
		bcf	EECON1, WREN	; zakaz zapis do EEPROM
		bcf	STATUS, RP0		; prepni do BANKy 0
		
		incf	FSR, F		; zvys adresu v RAM
		incf	TMP_DATA, F		; zvys adresu v EEPROM
		clrw
		decfsz	COUNTER, F		; prenos 16 byte pouze LINE2
		goto	WRITE_EERAM_2
		bcf	WRT_EERAM		; zakaz zapis do EEPROM
		return

;========================================================================================
; Konec programu
;========================================================================================

		end