;******************************************************************************
;                                                                             *
;    Filename:         P_10a_merak pro nabijecku.asm                          *
;    Date:             5.4.2012                                              *
;    File Version:     001                                                    *
;                                                                             *
;    Author:           LeHa                                                   *
;                                                                             *
;******************************************************************************
;    Files Required: P16F88.INC                                               *
;******************************************************************************
;*                                                                            *
;*                                  PIC16F88                                  *
;*                        --------------\/-------------                       *
;*                       -|RA2/AN2/Vref-       RA1/AN1|- Napětí Uc12          *
;*                Uref+  -|RA3/AN3/Vref+       RA0/AN0|- Napětí Uc1           *
;*                       -|RA4/AN4  			   RA7|- čidlo DS18B20        *
;*                       -|RA5/MCLR  			   RA6|-                      *
;*                  0 V  -|VSS     				   VDD|- +5 V			      *
;*       LCD data bit 4  -|RB0  			   RB7/AN6|- Proud Ibat           *
;*       LCD data bit 5  -|RB1    			   RB6/AN5|- Napětí Uc13          *
;*		 LCD data bit 6	 -|RB2                     RB5|- LCD RS               *
;*		 LCD data bit 7  -|RB3                     RB4|- LCD E 				  *  		
;*                        -----------------------------                       *                                         
;*                                                                            *
;******************************************************************************
     LIST      p=16F88              ; list directive to define processor
     #INCLUDE <P16F88.INC>          ; processor specific variable definitions
;------------------------------------------------------------------------------
     __CONFIG    _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_IO
     __CONFIG    _CONFIG2, _IESO_OFF & _FCMEN_OFF
; VARIABLE DEFINITIONS
	CBLOCK 	0x20 ; Sample GPR variable registers allocated contiguously
			TMP_W				; temp preruseni
			TMP_S				; temp preruseni
			TMP_PCL				; temp preruseni
			TMP0				; cekaci smycka
			TMP1				; cekaci smycka
			TMP2				; cekaci smycka
			TMP3				; cekaci smycka
			TEXT				; zobrazeni textu na LCD
			ZNAK				; zobrazeni znaku na LCD
			ADRESA				; inicializace cestiny, adresa pro misto znaku
			d1			
			d2			
			ADP_L   			; registry pro převod hodnot z A/D převodníku 
			ADP_H  	 			; registry pro převod hodnot z A/D převodníku
			ADP_NM              ; ??,?_ V,A	
			ADP_DP  			; __,_? V,A
			ADP_NM1				; hodnota vyčtená z AD převodníki pro U1 (AN0)
			ADP_DP1				; hodnota vyčtená z AD převodníki pro U1 (AN0)
			ADP_NM12			; hodnota vyčtená z AD převodníki pro U12 (AN1)
			ADP_DP12			; hodnota vyčtená z AD převodníki pro U12 (AN1)
			ADP_NM13			; hodnota vyčtená z AD převodníki pro U13 (AN5)
			ADP_DP13			; hodnota vyčtená z AD převodníki pro U13 (AN5)
			ADP_NMI				; hodnota vyčtená z AD převodníki pro Ibat (AN6)
			ADP_DPI				; hodnota vyčtená z AD převodníki pro Ibat (AN6)
			PAUS1     			; 10s pauza
			PAUS2   	    
			PAUS3   	   
			DSDL1    			; komunikace s DS18B20
			DSREG1  	
			DSREG2  	
			TEMPL   	
			TEMPH   	
			TEMPNM  	  		; ???,  °C 
			TEMPDP 				;    ,? °C
	ENDC
; definování vstupů a výstupů
#define		E		PORTB,4			; E  - LCD displej
#define		RS		PORTB,5			; RS - LCD displej
#define		DSPIN	PORTA,7			; vstup pro čidlo DS18B20
; definování konstant pro časové články
D550US  	equ		.200        ; 550us
D90US   	equ		.25	        ; 90us
D1US    	equ		.1	        ; 3us
;--------------------------------------------------------------------------
	ORG     0x0000            	; processor reset vector
		CALL	INIT			; skok na počáteční inicalizaci
		CALL	INIT1
		ORG		0x004
		GOTO	PRERUS
;--------------------------------------------------------------------------
INIT1   MOVLW   0x7             ; komparator off 
       	MOVWF   CMCON
;**************************************************************************
TAB_TXT	ADDWF	PCL,F
		RETLW	'N'				; 0			
		RETLW	'a'
		RETLW	'b'
		RETLW	'i'
		RETLW	'j'
		RETLW	'e'
		RETLW	'c'
		RETLW	'k'
		RETLW	'a'
		RETLW	' '
		RETLW	'L'
		RETLW	'i'
		RETLW	'P'
		RETLW	'o'
		RETLW	'l'
		RETLW	' '
		RETLW	'b'
		RETLW	'a'
		RETLW	't'
		RETLW	'.'
		RETLW	80h				; konec textu
;-------------------------------
		RETLW	'L'				; 21
		RETLW	'e'
		RETLW	'H'
		RETLW	'a'
		RETLW	' '
		RETLW	'P'
		RETLW	'I'
		RETLW	'C'
		RETLW	'1'
		RETLW	'6'
		RETLW	'F'
		RETLW	'8'
		RETLW	'8'
		RETLW	' '
		RETLW	'4'
		RETLW	'/'
		RETLW	'2'
		RETLW	'0'
		RETLW	'1'
		RETLW	'2'
		RETLW	80h				; konec textu
;**************************************************************************
;*                      preruseni kazdych 8,192ms (122Hz)                 *
;**************************************************************************
PRERUS	movwf	TMP_W			; (ulozeni hodnot registru W a STATUS)
		movf	STATUS,W		; prohodi nibble STATUS a ulozi do W
		clrf	STATUS			; nastaveni banky 0
		movwf	TMP_S			; ulozit STATUS
		movf	PCLATH,W
		movwf	TMP_PCL
		clrf	PCLATH			; nastaveni banky 0
;       ------------------------
		bcf		INTCON,TMR0IF		; vynulovat priznak preruseni (pretekl casovac TMR0)
;------------------------------- (obnovení hodnot registru W a STATUS)
INT_END movf	TMP_PCL,W
		movwf	PCLATH			; obnova PCLATH
		movf	TMP_S,W			; prohodi nibble TMP_S a ulozi do W
		movwf	STATUS			; obnova STATUS
		swapf	TMP_W,F			; prohodi nibble TMP_W a ulozi do W
		swapf	TMP_W,W			; obnova W
		retfie
;--------------------------------------------------------------------------
INIT	MOVLW	b'11111111'		;počáteční nastavení výstupů - záchytných
		MOVWF	PORTA			;registrů brány PortA – při nenulové hodnotě
		CLRF	PORTB
		BSF		STATUS,RP0
		MOVLW	b'01101011'
		MOVWF	ANSEL
		MOVLW	b'11111111'
		MOVWF	TRISA
		MOVLW	b'11000000'
		CLRF	TRISB
		MOVLW	b'11010000'
		MOVWF	OPTION_REG
		BSF		PIE1,ADIE
		BSF		INTCON,PEIE
		MOVLW	b'10100000'
		MOVWF	ADCON1
		MOVLW	b'01100000'
		MOVWF	OSCCON
		BCF		STATUS,RP0
		MOVLW	b'01000001'
		MOVWF	ADCON0
;------------------------------------	
		CALL	INI_LCD			; inicializace LCD
		CALL	VERZE			; úvodní nápis 
;**************************************************************************
START	CALL	READ_ADP		; vyčtení hodnot z analogových vstupů
		CALL    DSSTART     	; start prevodu teploty v cidlu
		CALL    DSREAD      	; vyčtení teploty z cidla
   		CALL    TMPCNV       	; prevod binarni teploty na hodnotu
   		CALL    ZOBRAZ         	; odeslani hodnoty napětí a teplty do LCD
		CALL    PAUSE        	; (10s
   		GOTO    START	
;*************************************************************
; Odeslání hodnot pro zobrazení
;*************************************************************
ZOBRAZ 
;---- Náhled 1 - 1. řádek-------------------------------------
		CALL	C_LCD
		CALL	LINE1
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	'U'
		CALL	WR_LCD
		MOVLW	'b'
		CALL	WR_LCD
		MOVLW	'a'
		CALL	WR_LCD
		MOVLW	't'
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	'='
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
; ---- Unab = U12 - U13, jeli výsledek záporný zobrazí U13, jeli výsledek kladný zobrazí U12
		MOVF	ADP_NM13,0
		SUBWF	ADP_NM12,0
		BTFSC	STATUS,C
		GOTO    $+6
		MOVF	ADP_NM13,0
		MOVWF	ADP_NM
		MOVF	ADP_DP13,0
		MOVWF	ADP_DP
		GOTO    $+5
		MOVF	ADP_NM12,0
		MOVWF	ADP_NM
		MOVF	ADP_DP12,0
		MOVWF	ADP_DP
		CALL	ZOBRAZ_NAPETI
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	'V'
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
; ***************************************************
; ---- Náhled 1 - 2. řádek --------------------
		CALL	LINE2
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	'I'
		CALL	WR_LCD
		MOVLW	'n'
		CALL	WR_LCD
		MOVLW	'a'
		CALL	WR_LCD
		MOVLW	'b'
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	'='
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
; ---- Zobrazení hodnoty nabíjecího proudu -------------
		MOVLW	b'00000000'
		MOVWF	ADP_NM
		MOVWF	ADP_DP
		MOVF	ADP_NMI,0
		MOVWF	ADP_NM
		MOVF	ADP_DPI,0
		MOVWF	ADP_DP
		CALL	ZOBRAZ_NAPETI
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	'A'
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
;-----------------------------
		CALL	CEK2s
		CALL	CEK2s
;---- Náhled 2 - 1. řádek-------------------------------------
		CALL	C_LCD
		CALL	LINE1
		MOVLW	'U'
		CALL	WR_LCD
		MOVLW	'c'
		CALL	WR_LCD
		MOVLW	'1'
		CALL	WR_LCD
		MOVLW	'='
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	'U'
		CALL	WR_LCD
		MOVLW	'c'
		CALL	WR_LCD
		MOVLW	'2'
		CALL	WR_LCD
		MOVLW	'='
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	'U'
		CALL	WR_LCD
		MOVLW	'c'
		CALL	WR_LCD
		MOVLW	'3'
		CALL	WR_LCD
		MOVLW	'='
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
;---- Náhled 2 - 2. řádek-------------------------------------		
		CALL	LINE2
;-------- zobrazení napětí U1 -------
		MOVLW	b'00000000'
		MOVWF	ADP_NM
		MOVWF	ADP_DP
		MOVF	ADP_NM1,0
		MOVWF	ADP_NM
		MOVF	ADP_DP1,0
		MOVWF	ADP_DP
		CALL	ZOBRAZ_NAPETI
		MOVLW	'V'
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
;-------- zobrazení napětí U2 = U12 - U1 -------
		MOVLW	b'00000000'
		MOVWF	ADP_NM
		MOVWF	ADP_DP	
		MOVF	ADP_NM1,0
		SUBWF	ADP_NM12,0
		MOVWF	ADP_NM
		MOVF	ADP_DP12,0
		MOVWF	ADP_DP
		CALL	ZOBRAZ_NAPETI
		MOVLW	'V'
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
;-------- zobrazení napětí U3 = U13 - U12 -------
		MOVLW	b'00000000'
		MOVWF	ADP_NM
		MOVWF	ADP_DP	
		MOVF	ADP_NM12,0
		SUBWF	ADP_NM13,0
		MOVWF	ADP_NM
		MOVF	ADP_DP13,0
		MOVWF	ADP_DP
		CALL	ZOBRAZ_NAPETI
		MOVLW	'V'
		CALL	WR_LCD
;---------------------------------
		CALL	CEK2s
		CALL	CEK2s
; **************************************************************
;---- Náhled 3 - 1. řádek --------------------------------------
		CALL	C_LCD
		CALL	LINE1
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	'T'
		CALL	WR_LCD
		MOVLW	'e'
		CALL	WR_LCD
		MOVLW	'p'
		CALL	WR_LCD
		MOVLW	'l'
		CALL	WR_LCD
		MOVLW	'o'
		CALL	WR_LCD
		MOVLW	't'
		CALL	WR_LCD
		MOVLW	'a'
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	'b'
		CALL	WR_LCD
		MOVLW	'a'
		CALL	WR_LCD
		MOVLW	't'
		CALL	WR_LCD
		MOVLW	'e'
		CALL	WR_LCD
		MOVLW	'r'
		CALL	WR_LCD
		MOVLW	'i'
		CALL	WR_LCD
		MOVLW	'e'
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
;---- Náhled 3 - 2. řádek --------------------------------------
		CALL	LINE2
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
; ---- zobrazení znaménka záporné hodnoty ----
		MOVLW   200
   		SUBWF   TEMPNM,1
 		BTFSS   STATUS,C
		GOTO    $+4
    	MOVLW   '-'             ; -
    	CALL    WR_LCD
    	GOTO    $+2
    	ADDWF   TEMPNM,1
; ---- zobrazení stovek stupňů -------------
    	MOVLW   .100
        SUBWF   TEMPNM,1
        BTFSS   STATUS,C
	    GOTO    $+4
        MOVLW   '1'             ; 100°C
        CALL    WR_LCD
        GOTO    $+2
        ADDWF   TEMPNM,1
; ---- zobrazení desítek stupňů ------------        
    	CLRF    TEMPH
        MOVLW   10
        SUBWF   TEMPNM,1
        BTFSS   STATUS,C
        GOTO    $+3
        INCF    TEMPH,1
        GOTO    $-4
        ADDWF   TEMPNM,1
        MOVF    TEMPH,0
        ADDLW   0x30
        CALL    WR_LCD          ; 10°C
; ---- zobrazení jednotek stupňů -----------
		CLRF    TEMPH
        MOVLW   1
        SUBWF   TEMPNM,1
        BTFSS   STATUS,C
        GOTO    $+3
        INCF    TEMPH,1
        GOTO    $-4
        ADDWF   TEMPNM,1
        MOVF    TEMPH,0
        ADDLW   0x30
        CALL    WR_LCD          ; 1°C
; ---- zobrazení desetinné čárky -------------   
    	MOVLW   ','             ; ,
    	CALL    WR_LCD
; ---- zobrazení desetin stupňů ---------------
    	CLRF    TEMPH
        MOVLW   1
        SUBWF   TEMPDP,1
        BTFSS   STATUS,C
        GOTO    $+3
        INCF    TEMPH,1
        GOTO    $-4
        ADDWF   TEMPDP,1
        MOVF    TEMPH,0
        ADDLW   0x30
        CALL    WR_LCD          ; 0,1°C
; ------------------------------------------ 
		MOVLW   0xDF            ; °
        CALL    WR_LCD
        MOVLW   'C'             ; C
        CALL    WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW   ' '             
        CALL    WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
		MOVLW	' '
		CALL	WR_LCD
;--------------------------------------------
		CALL	CEK2s			; cekej 2 sekundy
		CALL	CEK2s
;-------------------------------
		RETURN
;**************************************************************************
VERZE	CALL	C_LCD			; smaz LCD displej, 1 radek a 1 znak
		MOVLW	.00				; text 0 - jmeno sofware
		CALL	WR_TEXT
;       ------------------------
		CALL	LINE2
		MOVLW	.21				; text 21 - verze, datum
		CALL	WR_TEXT
;       ------------------------
		CALL	CEK2s			; cekej 2 sekundu
		CALL	CEK2s
		RETURN
;******************************** PIC16F676 ********************************
WR_TEXT	MOVWF	TEXT			; W -> TEXT
		CALL	TAB_TXT
		MOVWF	ZNAK			; W -> ZNAK
		SUBLW	80h	
		BTFSC	STATUS,Z
		RETLW	00h				; pokud je znak = 80h, konec textu
;       ------------------------
		MOVF	ZNAK,W			; ZNAK -> W
		CALL	WR_LCD
;       ------------------------
		INCF	TEXT,W			; TEXT + 1 -> W
		GOTO	WR_TEXT
; ========================================================================
; ---- Obsluha displeje LCD 2x20 -----------------------------------------
; ========================================================================
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, zápis instrukcí do LCD
		GOTO	$+2
;-------------------------------
WR_LCD 	BSF		RS				; RS=1, zápis dat do LCD
;       ------------------------
		MOVWF	ZNAK			; ulozit W do ZNAK	!!! data v registru W !!!
		BSF		E				; nastav Enable
;       ------------------------
		MOVF	PORTB,W			; zapamatovat stav PORTuC
		IORLW	0x0F			; !!! poslat na PORTB 0-3 !!! (vysledek je xxxx1111)
		MOVWF	TMP1			; zapise W do TMP1
;-------------------------------
		SWAPF	ZNAK,W			; !!! poslat na PORTB 0-3 !!!
		IORLW	0xF0			; zamaskuje horní bity (vysledek je 1111xxxx)
		ANDWF	TMP1,W			; pošle vyšší 4 bity na PORTC
		MOVWF	PORTB
		BCF		E				; zapíše do LCD
;-------------------------------
		BSF		E				; nastav Enable
		MOVF	ZNAK,W			; !!! poslat na PORTB 0-3 !!!
		IORLW	0xF0			; zamaskuje horní bity (vysledek je 1111xxxx)
		ANDWF	TMP1,W			; pošle nižší 4 bity na PORTC
		MOVWF	PORTB
		BCF		E				; zapíše do LCD
;-------------------------------
		BTFSC	RS
		GOTO	CEK40			; RS=1, zápis dat - čekej 40 us
;       ------------------------
		MOVLW	04h				; instrukce 1, 2 a 3 - čekej 1,64 ms
		SUBWF	ZNAK,W
		BTFSS	STATUS,C
		GOTO	CEK1m6			; C=0, instrukce CLEAR - čekej 1,64 ms
		GOTO	CEK40			; C=1, zápis dat - čekej 40 us
;*************************************************************************
INI_LCD CALL	CEK15m			; cekej 15ms
		BCF		RS				; zapis ridicich instrukci do LCD
;-------------------------------
		MOVLW	03h				; !!! poslat 03h na PORTC 0-3 (vstupy LCD DB4-DB7) !!!
		MOVWF	PORTB
;       ------------------------
		BSF		E
		BCF		E
		CALL	CEK4m			; cekej 4,1ms
;       ------------------------
		BSF		E
		BCF		E
		CALL	CEK100			; cekej 100us
;       ------------------------
		BSF		E
		BCF		E
		CALL	CEK40			; cekej 40us
;-------------------------------
		MOVLW	02h				; !!! poslat 03h na PORTC 0-3 (vstupy LCD DB4-DB7) !!!
		MOVWF	PORTB			; nastavena 4-bitova komunikace
;       ------------------------
		BSF		E
		BCF		E
		CALL	CEK40			; cekej 40us
;-------------------------------
		MOVLW	28h				; 00101000 - počet bitů, 2 řádky, 5x7 znaky
		CALL	WR_CMD
		MOVLW	0Ch				; 00001100 - display ON, kurzor OFF, blikání OFF
		CALL	WR_CMD
		MOVLW	01h				; 00000001 - smaže displej, kurzor na pozici 0
		CALL	WR_CMD
		MOVLW	06h				; 00000110 - směr kurzoru, posunu displeje
		CALL	WR_CMD
; ------------------------------
		RETURN
; ========================================================================
; ---- Vyčtení hodnot z regidstrů A/D převodníku a zpracování hodnot -----
; ========================================================================
READ_ADP
;---- uložení hodnoty do registrů pro hodnotu U1 (AN0)------
		MOVLW	b'00000000'
		MOVWF	ADP_NM1
		MOVWF	ADP_DP1
		BCF		STATUS,RP0
		MOVLW	b'01000001'		; nastaví vstup AN0
		MOVWF	ADCON0	
		CALL	READ_REG
		MOVF	ADP_NM,0
		MOVWF	ADP_NM1
		MOVF	ADP_DP,0
		MOVWF	ADP_DP1
;;---- uložení hodnoty do registrů pro hodnotu U12 (AN1)----
		MOVLW	b'00000000'
		MOVWF	ADP_NM12
		MOVWF	ADP_DP12
		BCF		STATUS,RP0
		MOVLW	b'01001001'		; nastaví vstup AN1
		MOVWF	ADCON0	
		CALL	READ_REG
		MOVF	ADP_NM,0
		MOVWF	ADP_NM12
		MOVF	ADP_DP,0
		MOVWF	ADP_DP12
;---- uložení hodnoty do registrů pro hodnotu U13 (AN5)-----
		MOVLW	b'00000000'
		MOVWF	ADP_NM13
		MOVWF	ADP_DP13
		BCF		STATUS,RP0
		MOVLW	b'01101001'		; nastaví vstup AN5
		MOVWF	ADCON0	
		CALL	READ_REG
		MOVF	ADP_NM,0
		MOVWF	ADP_NM13
		MOVF	ADP_DP,0
		MOVWF	ADP_DP13
;---- uložení hodnoty do registrů pro hodnotu Inab (AN6)-----
		MOVLW	b'00000000'
		MOVWF	ADP_NMI
		MOVWF	ADP_DPI
		BCF		STATUS,RP0
		MOVLW	b'01110001'		; nastaví vstup AN6
		MOVWF	ADCON0	
		CALL	READ_REG
		MOVF	ADP_NM,0
		MOVWF	ADP_NMI
		MOVF	ADP_DP,0
		MOVWF	ADP_DPI
;---- návrat z podprogramu ---------------------------------
		RETURN
;*****************************************************************************
READ_REG		
		CALL	CEK40
		BSF		ADCON0,GO		; spuštění A/D převodu
		BTFSC	ADCON0,GO
		GOTO	$-1
; ---- oddělení setiny a uloží do ADP_DP ----------------     
    	CLRF	ADP_DP			; vynuluje registr ADP_DP
		MOVF    ADP_DP,0		; přesune obsah ADP_DP do W
		BSF		STATUS,RP1
		BTFSC	ADRESL,0
    	ADDLW   .2				; když je bit 0=1, přičte dvojku k W
		BSF		STATUS,RP1
    	BTFSC   ADRESL,1			; přečte bit 1
    	ADDLW   .5				; když je bit 1=1, přičte pětku k W
    	MOVWF   ADP_DP			; uloží obsah W do ADP_DP
; ---- oddělení desetiny, jednotky a desítky a uloží do ADP_NM
    	CLRF	ADP_NM			; vynuluje registr ADP_NM
		MOVF    ADP_NM,0		; přesune obsah ADP_NM do W
		BSF		STATUS,RP1
    	BTFSC   ADRESL,2			; přečte bit 2
    	ADDLW   .1				; když je bit 2=1, přičte jedničku k W
    	BTFSC   ADRESL,3			; přečte bit 3
    	ADDLW   .2				; když je bit 3=1, přičte dvojku k W
    	BTFSC   ADRESL,4			; přečte bit 4
    	ADDLW   .4				; když je bit 4=1, přičte čtyřku k W
    	BTFSC   ADRESL,5			; přečte bit 5
    	ADDLW   .8				; když je bit 5=1, přičte osmičku k W
 		BTFSC   ADRESL,6			; přečte bit 6
    	ADDLW   .16				; když je bit 6=1, přičte šestnáctku k W
    	BTFSC   ADRESL,7			; přečte bit 7
    	ADDLW   .32				; když je bit 7=1, přičte třicetdvojku k W
		BCF		STATUS,RP0
    	BTFSC   ADRESH,0			; přečte bit 0
    	ADDLW   .64				; když je bit 0=1, přičte šedesátčtyři k W
    	BTFSC   ADRESH,1			; přečte bit 1
    	ADDLW   .128			; když je bit 1=1, přičte stodvacetosm k W
    	MOVWF   ADP_NM			; uloží obsah W do ADP_NM
; ----------   
    	RETURN
;*****************************************************************************
;---- převod hodnot na jednotlivé řády a poslání na displej -----
ZOBRAZ_NAPETI
; ---- zobrazení znaménka záporné hodnoty ----
		MOVLW   .255
		SUBWF   ADP_NM,1
 		BTFSS   STATUS,C
    	GOTO    $+4
    	MOVLW   '-'             ; -
    	CALL    WR_LCD
    	GOTO    $+2
    	ADDWF   ADP_NM,1
; ---- zobrazení desítek voltů -------------
    	CLRF    ADP_H
	    MOVLW   .100
	    SUBWF   ADP_NM,1
 		BTFSS   STATUS,C
    	GOTO    $+3
    	INCF    ADP_H,1
    	GOTO    $-4
    	ADDWF   ADP_NM,1
    	MOVF    ADP_H,0
    	ADDLW   0x30
    	CALL    WR_LCD           ; 10 V
; ---- zobrazení jednotek voltů ------------        
    	CLRF    ADP_H
    	MOVLW   .10
    	SUBWF   ADP_NM,1
    	BTFSS   STATUS,C
    	GOTO    $+3
    	INCF    ADP_H,1
    	GOTO    $-4
    	ADDWF   ADP_NM,1
    	MOVF    ADP_H,0
    	ADDLW   0x30
    	CALL    WR_LCD           ; 1 V
; ---- zobrazení desetinné čárky -------------   
    	MOVLW   ','             ; ,
    	CALL    WR_LCD
; ---- zobrazení desetin voltů -------------
    	CLRF    ADP_H
    	MOVLW   .1
    	SUBWF   ADP_NM,1
    	BTFSS   STATUS,C
    	GOTO    $+3
    	INCF    ADP_H,1
    	GOTO    $-4
    	ADDWF   ADP_NM,1
    	MOVF    ADP_H,0
    	ADDLW   0x30
    	CALL    WR_LCD           ; 0,1 V
; ---- zobrazení setin voltů ---------------
    	CLRF    ADP_L
    	MOVLW   .1
    	SUBWF   ADP_DP,1
    	BTFSS   STATUS,C
    	GOTO    $+3
    	INCF    ADP_L,1
    	GOTO    $-4
   		ADDWF   ADP_DP,1
    	MOVF    ADP_L,0
    	ADDLW   0x30
    	CALL    WR_LCD           ; 0,01 V
; ----------   
    	RETURN
; ************************************************************************
; časy pro frekvenci krystalu 4,00Mhz
; časy jsou spočítané od call CEKxxm do návratu na volání CEKxxm
; celkový výpočet  = 2+6+(2+(TMP0-1)*3+2)+3)*TMP1-1+2
; zkrácený výpočet = 8+((TMP0-1)*3+7)*TMP1+1
; malá smyčka = (TMP2-1)*3+2
;-------------------------------
CEK2s 	MOVLW	.20				; TMP2 = 20  cekej 2 sekundy
		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			; největší smyčka
		GOTO	SMYCKA2
		RETLW	00h
;-------------------------------
SMYCKA	MOVF	TMP0,W
		MOVWF	TMP2
;       ------------------------
SMYCKA1	DECFSZ	TMP2,F			; malá smyčka
		GOTO	SMYCKA1
;       ------------------------
		DECFSZ	TMP1,F			; velká smyčka
		GOTO	SMYCKA
;       ------------------------
		RETLW	00h
;-------------------------------------------
; čekací smyčka aso 0,5 s 
DELAY	MOVLW	0x05
		MOVWF	d2
DELAY1	DECFSZ	d1,f
		GOTO	DELAY1
		DECFSZ	d2,f
		GOTO	DELAY1
		RETURN
; ========================================================================
; ---- DS18B20 rutiny ----------------------------------------------------
; ========================================================================
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    TEMPL           ; vycteni teploty z cidla
        CLRF    TEMPH
        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   TEMPL
        CALL    DSREC
        MOVWF   TEMPH
        RETURN
;--------------------- pin DSPIN do L -----------------
DSPINL  BSF     STATUS,RP0      ; nastaví BANK0 
        BCF     DSPIN			; nastaví vstup DSPIN (RA5) jako výstupní
        BCF     STATUS,RP0		; nastaví BANK1
        BCF     DSPIN			; nastaví vstup DSPIN (RA5) jako výstupní
        RETURN
;--------------------- pin DSPIN do H (pull-up)--------
DSPINH  BSF     STATUS,RP0      ; nastaví BANK0
        BSF     DSPIN			; nastaví vstup DSPIN (RA5) jako vstupní
        BCF     STATUS,RP0		; nastaví BANK1
        RETURN
;--------------------- prodleva pro komunikaci ----------------------
DSDEL   MOVWF   DSDL1			; přesune hodnotu z W do registru DSDL1
        DECFSZ  DSDL1,1			; když je hodnota registru DSDL1 0, následující instrukce se přeskočí
        GOTO    $-1				; jde o krok zpět
        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
;------------------ Vycteni jednoho bytu z DS18B20 do W ---------------
DSREC   CLRF    DSREG1          ; vynulování registru DSREG1
        MOVLW   8				; ulož do střadače číslo 8
        MOVWF   DSREG2			; přesune hodnotu z W do registru DSREG2
DSREC1  RRF     DSREG1,1		; rotace registru DSREG1 vpravo přes 1
        CALL    DSPINL			; skok do podprogramu
        CALL    DSPINH			; skok do podprogramu
        MOVLW   D1US			; přesune hodnotu z D1US do W
        CALL    DSDEL			; skok do podprogramu
        BCF     DSREG1,7		; nastaví bit 7 registru DSREG1 do 0
        BTFSC   DSPIN			; když je hodnota registru DSPIN 0, přeskočí jednu instrukci
        BSF     DSREG1,7		; nastaví bit 7 registru DSREG1 do 1
        MOVLW   D90US			; přesune hodnotu z D90US do W
        CALL    DSDEL			; skok do podprogramu
        DECFSZ  DSREG2,1		; když je hodnota registru DSREG2 0, následující instrukce se přeskočí
        GOTO    DSREC1			; jde na DSREC1
        MOVLW   D90US			; přesune hodnotu z D90US do W
        CALL    DSDEL			; skok do porprogramu 
        MOVF    DSREG1,0		; přesun registru DSREG1 do W
        RETURN
; ========================================================================
; Prevod binarni hodnoty ziskane z cidla na velikost teploty
; ------------------------------------------------------------------------
TMPCNV  MOVLW	b'00000000'
		CLRF    TEMPNM			; vynuluje registr
        CLRF    TEMPDP			; vynuluje registr
        BTFSS   TEMPH,7			; když je bit 7 v registru TEMPH 1, skočí dále
        GOTO    $+5				; jde na pátou následující instrukci
        COMF    TEMPH,1			; vytvoří opačné bity z TEMPH a uloží do TEMPH
        COMF    TEMPL,1			; vytvoří opačné bity z TEMPL a uloží do TEMPL
        MOVLW   .200			; přesune číslo 200 do W
        MOVWF   TEMPNM			; přesune číslo z W do TEMPNM
        MOVF    TEMPDP,0		; přesune hodnotu registru TEMPDP do W 
        BTFSC   TEMPL,1			; když je bit 1 v registru TEMPL 0, skočí dále
        ADDLW   .1				; přičte jedničku k W a uloží do W
        BTFSC   TEMPL,2			; když je bit 2 v registru TEMPL 0, skočí dále
        ADDLW   .2				; přičte dvojku k W a uloží do W
        BTFSC   TEMPL,3			; když je bit 3 v registru TEMPL 0, skočí dále
        ADDLW   .5				; přičte pětku k W a uloží do W
        MOVWF   TEMPDP			; přesune obsah W do registru TEMPDP
        MOVF    TEMPNM,0		; přesune hodnotu registru TEMPNM do W 
        BTFSC   TEMPL,4			; když je bit 4 v registru TEMPL 0, skočí dále
        ADDLW   .1				; přičte jedničku k W a uloží do W
        BTFSC   TEMPL,5			; když je bit 5 v registru TEMPL 0, skočí dále
        ADDLW   .2				; přičte dvojku k W a uloží do W
        BTFSC   TEMPL,6			; když je bit 6 v registru TEMPL 0, skočí dále
        ADDLW   .4				; přičte čtyřku k W a uloží do W
        BTFSC   TEMPL,7			; když je bit 7 v registru TEMPL 0, skočí dále
        ADDLW   .8				; přičte osmičku k W a uloží do W
        BTFSC   TEMPH,0			; když je bit 0 v registru TEMPH 0, skočí dále
        ADDLW   .16				; přičte šestnáctku k W a uloží do W
        BTFSC   TEMPH,1			; když je bit 1 v registru TEMPH 0, skočí dále
        ADDLW   .32				; přičte třicetdvojku k W a uloží do W
        BTFSC   TEMPH,2			; když je bit 2 v registru TEMPH 0, skočí dále
        ADDLW   .64				; přičte šedesátčtyřku k W a uloží do W
        MOVWF   TEMPNM			; přesune obsah W do registru TEMPNM
        RETURN
; ========================================================================
; Prodleva cca. 10s (při hodnotě 50)
; ------------------------------------------------------------------------
PAUSE   MOVLW   .10
        MOVWF   PAUS3
        CLRF    PAUS2
        CLRF    PAUS1
        DECFSZ  PAUS1,1
        GOTO    $-1
        DECFSZ  PAUS2,1
        GOTO    $-3
        DECFSZ  PAUS3,1
        GOTO    $-5
        RETURN
; ------------------------------------------------------------------------
		END
