	LIST	P = 16F877, R = DEC
	#include	<p16f877.inc>	; mozno psat take : "include p16f877.in"

	__CONFIG	B'11111100111010'

;---------------------------------------------
;||||||||||| KONSTANTY PROGRAMU ||||||||||||||
;---------------------------------------------

OFFRAM	EQU	H'20'		; ZACATEK VOLNE PAMETI "RAM"

#DEFINE	DB4	PORTE,2		; PINY PRO OVLADANI DISPLEJE
#DEFINE	DB5	PORTE,1
#DEFINE	DB6	PORTE,0
#DEFINE	DB7	PORTA,4
#DEFINE	E	PORTB,1
#DEFINE	RW	PORTB,2
#DEFINE	RS	PORTB,3

ZNAK_0	EQU	B'00110000'	; ADRESA ZNAKU "NULA" (PRO DISPLEJ)
ZNAK_SP	EQU	B'00100000'	; ADRESA ZNAKU "MEZERA"

;---------------------------------------------
;||||||||||| PROGRAMOVE PROMENNE |||||||||||||
;---------------------------------------------

	CBLOCK	OFFRAM
	DDATA:1			; POMOCNA PROM. OBSLUHY DISPLEJE
	TMH:1			; POMOCNA PROM. DVOJITEHO "DELAY" CYKLU
	TML:1

	AA:2			; OPERANDY A VYSLEDEK DELENI
	BB:2
	CC:2
	ARIT00:1			; POMOCNA PROM. DELENI

	AD_TEMP:1			; POMOCNA PROM. A/D PROCEDURY
	ADRESH_:1			; KUMULACNI A/D BUFFER
	ADRESL_:1			; - || -
	AD_COUNT:1		; POCITADLO A/D CYKLU
	ADRESH_A:1		; POMOCNA PROM. A/D HYSTEREZE
	ADRESL_A:1		; - || -
	ADRESH_B:1		; VYSTUPNI PROM. A/D HYSTEREZE
	ADRESL_B:1		; - || -
	ENDC

;----------------------------------------
;||||||||||| HLAVNI PROGRAM |||||||||||||
;----------------------------------------

	ORG	0
	NOP			; PREDPOKLADAM 3 REZERVOVANA
	NOP			; SLOVA PRO ZAVADEC
	NOP

START	MOVLW	B'10000001'	; NASTAVENI A/D PREVODNIKU
	MOVWF	ADCON0		
	MOVLW	B'10000100'
	BSF	STATUS,RP0
	MOVWF	ADCON1
	MOVLW	B'00000000'
	MOVWF	OPTION_REG
	BCF	STATUS,RP0

	BSF	STATUS,RP0	; FLEXIBILNI NASTAVENI POZADOVANYCH "TRIS" REGISTRU
	BCF	DB4		; PRO POTREBY DISPLEJE
	BCF	DB5
	BCF	DB6
	BCF	DB7
	BCF	E
	BCF	RS
	BCF	RW
	BCF	STATUS,RP0

	CALL	INITDISP		; INICIALIZACE DISPLEJE
	
LOOP	MOVLW	0		; JDI NA NULTY ZNAK
	CALL	SETPOS

	MOVLW	3		; PROVED ZAKLADNI A/D PREVOD NA KANALU 3
	CALL	AD_PREV
	CALL	ZOBRAZ_AD		; ZOBRAZ VYSLEDEK A/D PREVODU NA DISPLEJI
	MOVLW	ZNAK_SP		; VLOZ MEZERU
	CALL	PUTZNAK
	MOVLW	ZNAK_SP		; VLOZ MEZERU
	CALL	PUTZNAK

	MOVLW	3		; PROVED NASOBNY 12BITOVY A/D PREVOD NA KANALU 3
	CALL	N_PREV_12
	CALL	ZOBRAZ_AD
	MOVLW	ZNAK_SP
	CALL	PUTZNAK
	MOVLW	ZNAK_SP
	CALL	PUTZNAK

	MOVLW	3		; PROVED STABILIZOVANY 13BITOVY A/D PREVOD NA KANALU 3
	CALL	H_PREV_13
	CALL	ZOBRAZ_AD
	MOVLW	ZNAK_SP
	CALL	PUTZNAK

	GOTO	LOOP	

;----------------------------------------
;||| A/D PREVOD (STANDARDNI 10-BITOVY)|||
;----------------------------------------

AD_PREV	BCF	STATUS,RP0
	BCF	STATUS,RP1	;Nastavil jsem banku 0.
	MOVWF	AD_TEMP
	SWAPF	AD_TEMP,F
	RRF	AD_TEMP,W
	ANDLW	B'00111000'	;Ulozil jsem W do AD_TEMP a provedl pouhy posun o tri bity doleva, vystup skoncil ve W.
	BCF	ADCON0,5
	BCF	ADCON0,4
	BCF	ADCON0,3		;Bity, ktere definuji aktualni kanal je treba nejprve vynulovat.
	IORWF	ADCON0,F		;Pomoci W byl nastaven zadouci A/D kanal.
	MOVLW	34
	MOVWF	AD_TEMP
	DECFSZ	AD_TEMP,F
	GOTO	$ - 1		;Uplynula prodleva alespon 20 mikrosekund (tedy 100 cyklu).
	BSF	ADCON0,GO		;Zahajil jsem A/D prevod.
	BTFSC	ADCON0,GO
	GOTO	$ - 1		;cekam na konec prevodu (az se bit GO automaticky vynuluje).
	RETURN

;----------------------------------------
;|||| NASOBNY PREVOD (STALE 10-BIT) |||||
;----------------------------------------

N_PREV	BCF	STATUS,RP0
	BCF	STATUS,RP1
	MOVWF	AD_TEMP
	SWAPF	AD_TEMP,F
	RRF	AD_TEMP,W
	ANDLW	B'00111000'
	BCF	ADCON0,5
	BCF	ADCON0,4
	BCF	ADCON0,3
	IORWF	ADCON0,F
	CLRF	ADRESL_		; Priprav prazdnou sumu ADRES_
	CLRF	ADRESH_
	MOVLW	64
	MOVWF	AD_COUNT		; Nastav 64 opakovani
N_LOOP	MOVLW	34		; Zakladni A/D prevod
	MOVWF	AD_TEMP
	DECFSZ	AD_TEMP,F
	GOTO	$ - 1
	BSF	ADCON0,GO
	BTFSC	ADCON0,GO
	GOTO	$ - 1
	BSF	STATUS,RP0
	MOVF	ADRESL,W
	BCF	STATUS,RP0
	ADDWF	ADRESL_,F
	BTFSC	STATUS,C
	INCF	ADRESH_,F
	MOVF	ADRESH,W
	ADDWF	ADRESH_,F
	DECFSZ	AD_COUNT,F
	GOTO	N_LOOP
	RRF	ADRESH_,F		; 64 opakovani provedeno...
	RRF	ADRESL_,F		; ...proved deleni bitovym posunem
	RRF	ADRESH_,F
	RRF	ADRESL_,F
	RRF	ADRESH_,F
	RRF	ADRESL_,F
	RRF	ADRESH_,F
	RRF	ADRESL_,F
	RRF	ADRESH_,F
	RRF	ADRESL_,F
	RRF	ADRESH_,W
	ANDLW	B'00000011'	; oriznuti "necistot"
	MOVWF	ADRESH
	RRF	ADRESL_,W
	BSF	STATUS,RP0
	MOVWF	ADRESL
	BCF	STATUS,RP0	; vysledek je v ADRESL a ADRESH
	RETURN

;------------------------------------------------
;||||| NASOBNY PREVOD S 12BITOVYM VYSTUPEM ||||||
;------------------------------------------------

N_PREV_12	BCF	STATUS,RP0
	BCF	STATUS,RP1
	MOVWF	AD_TEMP
	SWAPF	AD_TEMP,F
	RRF	AD_TEMP,W
	ANDLW	B'00111000'
	BCF	ADCON0,5
	BCF	ADCON0,4
	BCF	ADCON0,3
	IORWF	ADCON0,F
	CLRF	ADRESL_
	CLRF	ADRESH_
	MOVLW	64
	MOVWF	AD_COUNT
N_LOOP_12	MOVLW	34
	MOVWF	AD_TEMP
	DECFSZ	AD_TEMP,F
	GOTO	$ - 1
	BSF	ADCON0,GO
	BTFSC	ADCON0,GO
	GOTO	$ - 1
	BSF	STATUS,RP0
	MOVF	ADRESL,W
	BCF	STATUS,RP0
	ADDWF	ADRESL_,F
	BTFSC	STATUS,C
	INCF	ADRESH_,F
	MOVF	ADRESH,W
	ADDWF	ADRESH_,F
	DECFSZ	AD_COUNT,F
	GOTO	N_LOOP_12
	RRF	ADRESH_,F
	RRF	ADRESL_,F
	RRF	ADRESH_,F
	RRF	ADRESL_,F
	RRF	ADRESH_,F
	RRF	ADRESL_,F
	RRF	ADRESH_,W
	ANDLW	B'00001111'
	MOVWF	ADRESH
	RRF	ADRESL_,W
	BSF	STATUS,RP0
	MOVWF	ADRESL
	BCF	STATUS,RP0
	RETURN

;------------------------------------------------------
;||||| NASOBNME SAMPLOVANI S 12BITOVYM VYSTUPEM |||||||
;|||||||||||||| A STABILIZACNIM FILTREM |||||||||||||||
;------------------------------------------------------

H_PREV_12	BCF	STATUS,RP0
	BCF	STATUS,RP1
	MOVWF	AD_TEMP
	SWAPF	AD_TEMP,F
	RRF	AD_TEMP,W
	ANDLW	B'00111000'
	BCF	ADCON0,5
	BCF	ADCON0,4
	BCF	ADCON0,3
	IORWF	ADCON0,F
	CLRF	ADRESL_
	CLRF	ADRESH_
	MOVLW	64
	MOVWF	AD_COUNT
H_LOOP_12	MOVLW	34
	MOVWF	AD_TEMP
	DECFSZ	AD_TEMP,F
	GOTO	$ - 1
	BSF	ADCON0,GO
	BTFSC	ADCON0,GO
	GOTO	$ - 1
	BSF	STATUS,RP0
	MOVF	ADRESL,W
	BCF	STATUS,RP0
	ADDWF	ADRESL_,F
	BTFSC	STATUS,C
	INCF	ADRESH_,F
	MOVF	ADRESH,W
	ADDWF	ADRESH_,F
	DECFSZ	AD_COUNT,F
	GOTO	H_LOOP_12

	MOVF	ADRESL_,W		; duplikace ADRES_
	MOVWF	ADRESL_A
	MOVF	ADRESH_,W
	MOVWF	ADRESH_A

	MOVF	ADRESL_B,W	; vypocet rozdilu
	SUBWF	ADRESL_A,F
	MOVF	ADRESH_B,W
	BTFSS	STATUS,C
	INCFSZ	ADRESH_B,W
	SUBWF	ADRESH_A,F
	BTFSC	STATUS,C
	GOTO	SKOK_00
	MOVF	ADRESH_A,W	; pokud je vysledek zaporny...
	XORLW	255		; ...bude preveden na kladny
	MOVWF	ADRESH_A
	MOVF	ADRESL_A,W
	XORLW	255
	MOVWF	ADRESL_A
	INCF	ADRESL_A,F
	BTFSC	STATUS,Z
	INCF	ADRESH_A,F
SKOK_00	MOVF	ADRESH_A,F	; Je vysledek dost velky?...
	BTFSS	STATUS,Z
	GOTO	SKOK_01
	MOVF	ADRESL_A,W
	ANDLW	B'11110000'
	BTFSC	STATUS,Z
	GOTO	SKOK_02
SKOK_01	MOVF	ADRESL_,W		; ...pokud ano, potom je nova hodnota pouzita
	MOVWF	ADRESL_B
	MOVF	ADRESH_,W
	MOVWF	ADRESH_B
SKOK_02	RRF	ADRESH_B,W	; deleni posunem a zapis do ADRESL,ADRESH
	MOVWF	ADRESH_
	RRF	ADRESL_B,W
	MOVWF	ADRESL_
	RRF	ADRESH_,F
	RRF	ADRESL_,F
	RRF	ADRESH_,F
	RRF	ADRESL_,F
	RRF	ADRESH_,W
	ANDLW	B'00001111'
	MOVWF	ADRESH
	RRF	ADRESL_,W
	BSF	STATUS,RP0
	MOVWF	ADRESL
	BCF	STATUS,RP0
	RETURN

;------------------------------------------------------
;||||| NASOBNME SAMPLOVANI S 13BITOVYM VYSTUPEM |||||||
;||||||||||||| A STABILIZACNIM FILTREM ||||||||||||||||
;------------------------------------------------------

H_PREV_13	BCF	STATUS,RP0
	BCF	STATUS,RP1
	MOVWF	AD_TEMP
	SWAPF	AD_TEMP,F
	RRF	AD_TEMP,W
	ANDLW	B'00111000'
	BCF	ADCON0,5
	BCF	ADCON0,4
	BCF	ADCON0,3
	IORWF	ADCON0,F
	CLRF	ADRESL_
	CLRF	ADRESH_
	MOVLW	64
	MOVWF	AD_COUNT
H_LOOP_13	MOVLW	34
	MOVWF	AD_TEMP
	DECFSZ	AD_TEMP,F
	GOTO	$ - 1
	BSF	ADCON0,GO
	BTFSC	ADCON0,GO
	GOTO	$ - 1
	BSF	STATUS,RP0
	MOVF	ADRESL,W
	BCF	STATUS,RP0
	ADDWF	ADRESL_,F
	BTFSC	STATUS,C
	INCF	ADRESH_,F
	MOVF	ADRESH,W
	ADDWF	ADRESH_,F
	DECFSZ	AD_COUNT,F
	GOTO	H_LOOP_13

	MOVF	ADRESL_,W
	MOVWF	ADRESL_A
	MOVF	ADRESH_,W
	MOVWF	ADRESH_A

	MOVF	ADRESL_B,W
	SUBWF	ADRESL_A,F
	MOVF	ADRESH_B,W
	BTFSS	STATUS,C
	INCFSZ	ADRESH_B,W
	SUBWF	ADRESH_A,F
	BTFSC	STATUS,C
	GOTO	SKOK_03
	MOVF	ADRESH_A,W
	XORLW	255
	MOVWF	ADRESH_A
	MOVF	ADRESL_A,W
	XORLW	255
	MOVWF	ADRESL_A
	INCF	ADRESL_A,F
	BTFSC	STATUS,Z
	INCF	ADRESH_A,F
SKOK_03	MOVF	ADRESH_A,F
	BTFSS	STATUS,Z
	GOTO	SKOK_04
	MOVF	ADRESL_A,W
	ANDLW	B'11111000'
	BTFSC	STATUS,Z
	GOTO	SKOK_05
SKOK_04	MOVF	ADRESL_,W
	MOVWF	ADRESL_B
	MOVF	ADRESH_,W
	MOVWF	ADRESH_B
SKOK_05	RRF	ADRESH_B,W
	MOVWF	ADRESH_
	RRF	ADRESL_B,W
	MOVWF	ADRESL_
	RRF	ADRESH_,F
	RRF	ADRESL_,F
	RRF	ADRESH_,W
	ANDLW	B'00011111'
	MOVWF	ADRESH
	RRF	ADRESL_,W
	BSF	STATUS,RP0
	MOVWF	ADRESL
	BCF	STATUS,RP0
	RETURN

;---------------------------------------------
;|||||||||| JEDNODUCHA PRODLEVA ||||||||||||||
;---------------------------------------------

DELAY	MOVWF	TMH
	CLRF	TML
	DECFSZ	TML,F
	GOTO	$ - 1
	DECFSZ	TMH,F
	GOTO	$ - 3
	RETURN

;---------------------------------------------
;||||||||||  OBSLUHA DISPLEJE  |||||||||||||||
;---------------------------------------------

INITDISP	BCF	RS
	BCF	RW
	MOVLW	D'255'
	CALL	DELAY
	CALL	DELAY
	CALL	DELAY
	CALL	DELAY
	MOVLW	B'00110000'
	CALL	DOUT4
	MOVLW	D'97'
	CALL	DELAY
	MOVLW	B'00110000'
	CALL	DOUT4
	MOVLW	D'3'
	CALL	DELAY
	MOVLW	B'00110000'
	CALL	DOUT4
	MOVLW	D'1'
	CALL	DELAY
	MOVLW	B'00100000'
	CALL	DOUT4
	MOVLW	D'1'
	CALL	DELAY
	MOVLW	B'00101000'
	CALL	DOUT8
	MOVLW	D'1'
	CALL	DELAY
	MOVLW	B'00001000'
	CALL	DOUT8
	MOVLW	D'1'
	CALL	DELAY
	MOVLW	B'00001100'
	CALL	DOUT8
	MOVLW	D'1'
	CALL	DELAY
	MOVLW	B'00000001'
	CALL	DOUT8
	MOVLW	D'40'
	CALL	DELAY
	MOVLW	B'00000110'
	CALL	DOUT8
	MOVLW	D'1'
	CALL	DELAY
	RETURN


DOUT4	MOVWF	DDATA		; 4 bity na vystup
	BSF	E
	BCF	DB4
	BTFSC	DDATA,4
	BSF	DB4
	BCF	DB5
	BTFSC	DDATA,5
	BSF	DB5
	BCF	DB6
	BTFSC	DDATA,6
	BSF	DB6
	BCF	DB7
	BTFSC	DDATA,7
	BSF	DB7
	BCF	E
	RETURN

DOUT8	MOVWF	DDATA		; 8 bitu na vystup
	BSF	E
	BCF	DB4
	BTFSC	DDATA,4
	BSF	DB4
	BCF	DB5
	BTFSC	DDATA,5
	BSF	DB5
	BCF	DB6
	BTFSC	DDATA,6
	BSF	DB6
	BCF	DB7
	BTFSC	DDATA,7
	BSF	DB7
	BCF	E
	BCF	DB4
	BTFSC	DDATA,0
	BSF	DB4
	BCF	DB5
	BTFSC	DDATA,1
	BSF	DB5
	BSF	E
	BCF	DB6
	BTFSC	DDATA,2
	BSF	DB6
	BCF	DB7
	BTFSC	DDATA,3
	BSF	DB7
	BCF	E
	RETURN

WAIT_BF	BCF	RS		; cekani na radic displeje
	BSF	STATUS,RP0
	BSF	DB4
	BSF	DB5
	BSF	DB6
	BSF	DB7
	BCF	STATUS,RP0
	BSF	RW
	BSF	E
	NOP
	NOP
	BCF	DDATA,7
	BTFSC	DB7
	BSF	DDATA,7
	BCF	E
	NOP
	NOP
	BSF	E
	NOP
	NOP
	BCF	E
	NOP
	NOP
	BTFSC	DDATA,7
	GOTO	WAIT_BF
	BSF	STATUS,RP0
	BCF	DB4
	BCF	DB5
	BCF	DB6
	BCF	DB7
	BCF	STATUS,RP0
	BCF	RW
	RETURN

PUTZNAK	CALL	WAIT_BF		; vypsani znaku
	BSF	RS
	CALL	DOUT8
	RETURN

SETPOS	IORLW	B'10000000'	; nastaveni polohy
	CALL	WAIT_BF
	BCF	RS
	CALL	DOUT8
	RETURN

SETSGPOS	ANDLW	B'00111111'	; nastaveni SG-adresy (uzivatelske znaky)
	IORLW	B'01000000'
	CALL	WAIT_BF
	BCF	RS
	CALL	DOUT8
	RETURN

;----------------------------------------
;|||||| ZOBRAZENI 4-MISTNEHO CISLA ||||||
;----------------------------------------

ZOBRAZ_AD	MOVF	ADRESH,W
	MOVWF	AA+1
	BSF	STATUS,RP0
	MOVF	ADRESL,W
	BCF	STATUS,RP0
	MOVWF	AA
	MOVLW	1000 / 256
	MOVWF	BB+1
	MOVLW	1000 % 256
	MOVWF	BB
	CALL	DIV16U		; deleno 1000
	MOVF	CC,W
	ADDLW	ZNAK_0
	CALL	PUTZNAK		; vysledna cislice zapsana
	CLRF	BB+1		; zbytek po deleni je v AA...
	MOVLW	100
	MOVWF	BB
	CALL	DIV16U		; ...dale delime cislem 100
	MOVF	CC,W
	ADDLW	ZNAK_0
	CALL	PUTZNAK		; vysledek je vypsan
	MOVLW	10
	MOVWF	BB
	CALL	DIV16U		; delime cislem 10
	MOVF	CC,W
	ADDLW	ZNAK_0
	CALL	PUTZNAK		; vysledek je vypsan...
	MOVF	AA,W
	ADDLW	ZNAK_0
	CALL	PUTZNAK		; ...a zbytek take
	RETURN

;----------------------------------------
; DELENI [AAH:AAL]/[BBH:BBL] = [CCH:CCL]
;    a zbytek po deleni = [AAH:AAL]
;----------------------------------------

DIV16U	CLRF	ARIT00
	CLRF	CC
	CLRF	CC+1
	BCF	STATUS,C
	BTFSC	BB+1,7
	GOTO	$ + 7
	RLF	BB,F
	RLF	BB+1,F
	INCF	ARIT00,F
	BTFSC	ARIT00,4
	RETURN
	GOTO	$ - 7
	INCF	ARIT00,F
	MOVF	BB+1,W
	SUBWF	AA+1,F
	BSF	CC,0
	BTFSC	STATUS,C
	GOTO	$ + 4 ;
	ADDWF	AA+1,F
	BCF	CC,0
	GOTO	$ + D'16'
	BTFSS	STATUS,Z
	GOTO	$ + D'10'
	MOVF	BB,W
	SUBWF	AA,F
	BTFSC	STATUS,C
	GOTO	$ + D'10'
	ADDWF	AA,F
	MOVF	BB+1,W
	ADDWF	AA+1,F
	BCF	CC,0
	GOTO	$ + 5
	MOVF	BB,W
	SUBWF	AA,F
	BTFSS	STATUS,C
	DECF	AA+1,F
	DECF	ARIT00,F
	BTFSC	STATUS,Z
	RETURN
	BCF	STATUS,C
	RRF	BB+1,F
	RRF	BB,F
	RLF	CC,F
	RLF	CC+1,F
	GOTO	$ - D'31'

	END
