;***************************************************************************************!!!!
;                                                                                                                                       
;    FESZÜLTSÉGMÉRŐ PROGRAM                                                                
;    ----------------------                                                                                                      
;    Az A/D konverzió eredményét világító fénycsík formájában               
;    az LCD kijelzőn jeleníti meg. A megjelenítés formája U betükből álló sor					                                         
;    A mintavétel gyakoriságát a TMR0 túlcsordulása határozza meg.              
;    Működik !!!!                                                                                                                                 
;****************************************************************************************
;
;
;
	list      p=16F877            
	#include <p16F877.inc>         
	__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _LVP_OFF
	RADIX DEL
;------------------------------------------------------------------------------
;
Timer1                equ     32
Timer2                equ     33
Counter		equ	34
OvfCntr		equ	35
;-------------------------------------------------------------------------------
; PORTE kivezetések
;
RS               equ     0               ; 0= utasítás, 1= adat reg. választás
RdWr	 equ	  1		; R/W=0 LCD írás, R/W=1 LCD memória olvasás
E                   equ    2               ; 0= LCD tiltás, 1= engedélyezés

; ================================ FŐPROGRAM ==================================

		org     0             	; reset vektor
		nop
; =========================== Port beállítás ==================================
;
		bcf	STATUS,RP0	             ; bank0 kiválasztás
		bcf	STATUS,RP1              ; 
		movlw	B'11000001'	   ; RC oszcillátor, A/D engedélyezés
		movwf	ADCON0		   ; 0. csatorna (RA0) kiválasztás
	           clrf    PORTD                           ; F-nullázása
                      clrf    PORTE                           ; PORTE nullázása
		bsf	STATUS,RP0	             ; bank1 kiválasztás
		movlw	B'10000111'	   ; TMR0 előosztó= 1:256
		movwf	OPTION_REG
		movlw	B'00001110'
		movwf	ADCON1		  ; RA0 analóg bemenet !!!
		movlw	B'11111111'	  ; PORTA bemenet
		movwf	TRISA                   ; Mozgasd a W- adatait F-be
		clrf	           TRISD		  ; PORTD kimenet
		clrf	           TRISE		  ; PORTE kimenet
		bcf	            STATUS,RP0  ; bank0 kiválasztás
		movlw	B'00000111'            ; túlcsordulás számláló kezdeti értéke 
		movwf	OvfCntr		

; ========================== LCD kijelző inicializálása ======================== 
;
	      bcf	PORTE,RS	; LCD parancs következik
	     movlw   B'00111000'        ; 38h, 8 bit interface set
                call    Write                        ; Szubrutin hívása
                call    Kesl		           ; Busy flag olvasását "helyettesíti"
                movlw   B'00111000'
                call    Write                        ; Szubrutin hívása ; 
                movlw   B'00000110'        ; 06h, Entry mode set: increment
                call    Write                        ; Szubrutin hívása
                movlw   B'00001111'        ; 0dh, Display on, cursor/blink off
                call    Write                         ; Szubrutin hívása ; 
                movlw   B'00010000'        ; 10h, Display/cursor shift: cursor
                call    Write                         ; Szubrutin hívása 
                movlw  B'00000001'                              ; 01h, Display clear
                call    Write                         ; Szubrutin hívása 
                call    Kesl2	                       ; Busy flag olvasását "helyettesíti"
;-------------------------------------------------------------------------------
; A TMR0 túlcsordulás nem okoz megszakítást, (hiszen azt nem is engedélyeztük)
; de bekövetkeztét a T0IF flag vizsgálatával figyeljük.
; A/D konverziót minden 7. TMR0 túlcsordulásra végzünk (kb 0,1 mp-ként).
;
Start		btfss	INTCON,T0IF	; TMR0 túlcsordulás volt?
		goto	Start		   ; még nem
;------------------------------------------------------------------------------
		bcf	INTCON,T0IF	   ; igen, flag törlés
		decfsz	OvfCntr,1	   ; túlcsordulás számláló dekrementálása
		goto	Start		   ; még nem 0
;------------------------------------------------------------------------------
		 movlw B'00000110'        ; mintavétel 10 túlcsordulásonként
		 movwf	OvfCntr	     ; számláló visszaállítás
		 bsf	ADCON0,GO	     ; A/D konverzió start
Wait		 btfss	PIR1,ADIF   ; várakozás a teljes konverzióra
	           goto	Wait                ; visszaugrik Wait szubrutinra

; ======================== Szintkijelzés az LCD kijelzőn ======================
;
		bcf	PORTE,RS	        ; LCD parancs
                     movlw   B'00000001'                              ; 01h, Display clear
                     call    Write                          ; Szubrutin hívása
                     call    Kesl2		        ; Szubrutin hívása
		bsf	PORTE,RS	        ; LCD adat következik
		swapf	ADRESH,0     ; ADRESH felső félbájt másolás W-be
		andlw	B'00001111'      ;a konstans és a W bitenkénti "ÉS"
		movwf	Counter           ; betölti a W-be a Counter adatait
		xorlw	B'00000000'     ; ha a felső 4 bit 0, nincs kijelzés
		btfsc	STATUS,Z     ; Bit teszt ugrik, ha B=0
		goto	Start                             ; Visszaugrik a Start Szubrutinra
;------------------------------------------------------------------------------
Kijelzes	movlw	B'10110000'      ; itt lehet kiválasztani, hogy milyen karakter jelenjen meg
                     call             Write                  ; Szubrutin hívás
		decfsz	Counter,1         ; Számlálót 1-el csökkenti, ha nulla akkor ugrik
		goto 	Kijelzes            ; visszaugrik a szubrutin elejére
;------------------------------------------------------------------------------
		goto	Start

; ====================================================== SZUBRUTINOK ============================================

; LCD írás lépései:
; -----------------
;   1/   RS, R/W beállítása
;   2/   E=1
;   3/   adat kiküldés
;   4/   késleltetés (100us)
;   5/   E=0
;
Write           movwf   PORTD                 ; a W adatait áttesz az F-be
		  bsf     PORTE,E                  ; a PORTE-t 1-re állítja
                       call    Kesl100		; Busy flag olvasását "helyettesíti"
                       bcf     PORTE,E                  ; a PORTE-t 0-ra állítja
                       return                                       ; visszaugrk a főprogramba
;------------------------------------------------------------------------------- Késletetések --------------------------------------------------------------------------------------------------
Kesl100        movlw   165		; 100us késleltetés
                          movwf   Timer1     ; Mozgasd a W-t az F-be 
Kesl1	     decfsz  Timer1,1  ;F-1; ugrik, ha b=0
                          goto    Kesl1            ; Visszaugrik a Kesl1 cimkére
                          return                          ; Visszaugrik a főprogramba
;-------------------------------------------------------------------------------
Kesl2             clrf    Timer1		 ; 2ms késleltetés
                          movlw	20                  ; Betölti a W-be
		     movwf   Timer2      ; W adatát átteszi az F-be
Kesl21           call	Kesl100     ; Szubrutin hívás
                          decfsz  Timer2,1    ; F-1; ugrik, ha b=0
                          goto    Kesl21           ; visszaugrik Kesl21 cimkére
                          return                           ; Visszaugrik a főprogramba
;---------------------------------------------------------------------------- 5x2ms késleltetés ----------------------------------------------------------------------------------------------
Kesl	            call	  Kesl2                    ; Szubrutin hívás
                      call    Kesl2                   ; Szubrutin hívás
                      call    Kesl2                    ; Szubrutin hívás
                      call    Kesl2                    ; Szubrutin hívás
                      call    Kesl2                    ; Szubrutin hívás
		return			; 5x2ms késleltetés
;------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
		end		

