
;*************************************************************************
;                                                                     
;
;*************************************************************************
        CONSTANT  FUNCTSET8 = b'00110000'  ; 8 Bitni nacin rada, 2 linije
        CONSTANT  FUNCTSET4 = b'00100000'  ; 4 Bitni nacin rada, 2 linije
        CONSTANT  DDZERO    = b'10000000'  ; Upis 0 u DDRAM

        CONSTANT  LCD2L   = b'00101000' 
        CONSTANT  LCDCONT = b'00001100' 
                                        
        CONSTANT  LCDSH   = b'00101000' 

;Komande  za rad sa LCD displejom
        CONSTANT  LCDCLR  = b'00000001' ; obrisi displej, kursor na pocetak
        CONSTANT  LCDCH   = b'00000010' ; cursor home
        CONSTANT  LCDCL   = b'00000100' ; pomeri kursor u levo
        CONSTANT  LCDCR   = b'00000110' ; pomeri kursor u desno
        CONSTANT  LCDSL   = b'00011000' ; pomeri sadrzaj displeja u levo
        CONSTANT  LCDSR   = b'00011100' ; pomeri sadrzaj displeja u desno
        CONSTANT  LCDL1   = b'10000000' ; selektuj liniju 1
        CONSTANT  LCDL2   = b'11000000' ; selektuj liniju 2


;*************************************************************************
;	pre nego sto se pristupi LCD-om mora se izvrsiti inicijalizacija
;	pomocu makroa lcdinit
;****************************************************************

lcdinit macro 

        bank1
        clrf   LCDdsport			;LCDdsport na kome je LCD je izlazni
        bank0 

        call    Delay1ms			;Pauza od 4 ms
        call    Delay1ms
        call    Delay1ms
        call    Delay1ms  
      	  movlw   FUNCTSET8           ;pocni inicijalizaciju sa osmobitnim 
        call    SendW   		     ;nacinom rada     
      


        call    Delay1ms              ;Pauza od 2 ms
        call    Delay1ms
        movlw   DDZERO               ;Upisi nula u DDRAM
        call    SendW  


      	  movlw   FUNCTSET4    	;Od sada LCD radi u cetvorobitnom rezimu  
        call    SendW  
;Komande za pocetnu inicijalizacija LCDa
        lcdcmd  LCD2L         ;
        lcdcmd  LCDCONT       ;
        lcdcmd  LCDSH         ;
        lcdcmd  LCDCLR        ;Obrisi LCD    
        endm



;*************************************************************************
;	lcdcmd salje LCD-u komandu (vidi tabelu na prethodnoj strani)
;	lcdclr je isto sto i lcdcmd 0x01
;*************************************************************************
lcdcmd  macro   LCDcommand 		;Posalji komandu na lcd 
	  movlw   LCDcommand
        call    LCDcomd
        endm
lcdclr  macro   			 	;Posalji komandu za brisanje na lcd 
        movlw   LCDCLR
        call    LCDcomd
        endm

LCD_DDAdr macro DDRamAddress
Local   value = DDRamAddress | 0x80      ; Start of DDRAM-a
        movlw   value
        call    LCDcomd
        endm

LCDcomd clrf    LCDbuf         
        goto    LCDwr

LCDdata clrf    LCDbuf
        bsf     LCDbuf,RS      

LCDwr   movwf   LCDtemp        
        andlw   b'11110000'    
        iorwf   LCDbuf,w      
        call    SendW  

       
	 
	  swapf   LCDtemp,w     
        andlw   b'11110000'    
        iorwf   LCDbuf,w       
        call    SendW  
        return

SendW   				;Ispisuje sadrzaj W registra na LCD
        clrf    LCDdsport
        movwf   LCDdsport
        call    Delay1ms
        bsf     LCDdsport,EN     
        bcf     LCDdsport,EN
        call    Delay1ms
        clrf    LCDdsport
        return

;*************************************************************************
;lcdtext ispisuje tekst velicine do 16 karaktera koji je zadat kao ;argument makroa. Prvi argument sekect bira liniju od cijeg pocetka se
;ispisuje tekst. Ako je select 0 tekst se ispisuje od mesta trenutne ;vrednosti kursora.                                                                     
;*************************************************************************
lcdtext macro select, text  ;Ovaj makro ispisuje tekst zadat u argumentu 
			        ;velicine do 16 karaktera od mesta na kome 
local Poruka			  ;se nalazi kursor
local Start
local Exit
local i=0
	goto Start
Poruka   dt text	;Formiraj lookup tabelu od argumenta
	   dt 0
Start
	if select==1 
	lcdcmd LCDL1
	else
	if select==2
	lcdcmd LCDL2
	endif
	endif
while i<16			;Uslovno prevodjenje programa - ponovi 16 puta
	call Poruka+i		;Citaj lookup tabelu i smesti vrednost u W
	addlw 0
	bz Exit		;sve dok se ne procita nula
   	call    LCDdata	;Pozovi rutinu koja ispisuje W na LCD
	i=i+1			
endw
Exit
endm

;*************************************************************************; ovaj makro ispisuje promenjljivu velicine 1 bajt na LCD
; pri cemu ne ispisuje vodece nule.
;*************************************************************************

lcdbyte macro arg0
	digbyte arg0		;Cifra sti=otina je u Dig1, desetica u Dig2
				;a jedinica u Dig3
	movf Dig1,w
	btfsc STATUS,Z	;Ako je nula pomeri kursor
	movlw 0xf0		;Ako nije nula prikazi cifru stotina
	addlw 0x30
   	call    LCDdata

	movf Dig2,w		;Ako je nula pomeri kursor
	btfsc STATUS,Z	;Ako nije nula prikazi  cifru desetica
	movlw 0xf0
	addlw 0x30
   	call    LCDdata

	movf Dig3,w
	addlw 0x30
  	call    LCDdata
	
endm

Delay1ms:				;Pauza od 1ms
	movlw .100
	movwf LOOPcnt
Delay10us:
	nop		;1us
	nop 		;1us
	nop		;1us
	nop		;1us
	nop 		;1us
	nop		;1us
	nop		;1us
	
	decfsz LOOPcnt,f		;1us
	goto Delay10us		;2us

	return
