;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;argument przekazywany zmienną bajtową o nazwie "dane_do_wyslania"
Wyslij_do_LCD:
	bsf	PORT_EN_LCD, EN_LCD		;ustawienie EN
	;wysłanie 4 najstarszych bitów danych
	bcf	PORT_DB7_LCD, DB7_LCD	;zeruj linię DB7_LCD
	bcf	PORT_DB6_LCD, DB6_LCD	;zeruj linię DB6_LCD
	bcf	PORT_DB5_LCD, DB5_LCD	;zeruj linię DB5_LCD
	bcf	PORT_DB4_LCD, DB4_LCD	;zeruj linię DB4_LCD
	btfsc	dane_do_wyslania, 7	;pomiń nast. instrukcję, jeśli bit 7. = 0
	bsf	PORT_DB7_LCD, DB7_LCD	;ustawj linię DB7_LCD
	btfsc	dane_do_wyslania, 6	;pomiń nast. instrukcję, jeśli bit 6. = 0
	bsf	PORT_DB6_LCD, DB6_LCD	;ustawj linię DB6_LCD
	btfsc	dane_do_wyslania, 5	;pomiń nast. instrukcję, jeśli bit 5. = 0
	bsf	PORT_DB5_LCD, DB5_LCD	;ustawj linię DB5_LCD
	btfsc	dane_do_wyslania, 4	;pomiń nast. instrukcję, jeśli bit 4. = 0
	bsf	PORT_DB4_LCD, DB4_LCD	;ustawj linię DB4_LCD
	
	call Czekaj_1us				;zaczekaj 1 us
	;potwierdzenie wysłania danych (opadającym zboczem EN)
	bcf	PORT_EN_LCD, EN_LCD		;wyzerowanie EN

	;zaczekaj 1 us
	call Czekaj_1us
	
	bsf	PORT_EN_LCD, EN_LCD		;ustawienie EN
	;wysłanie 4 najmłodszych bitów danych
	bcf	PORT_DB7_LCD, DB7_LCD	;zeruj linię DB7_LCD
	bcf	PORT_DB6_LCD, DB6_LCD	;zeruj linię DB6_LCD
	bcf	PORT_DB5_LCD, DB5_LCD	;zeruj linię DB5_LCD
	bcf	PORT_DB4_LCD, DB4_LCD	;zeruj linię DB4_LCD
	btfsc	dane_do_wyslania, 3	;pomiń nast. instrukcję, jeśli bit 3. = 0
	bsf	PORT_DB7_LCD, DB7_LCD	;ustawj linię DB7_LCD
	btfsc	dane_do_wyslania, 2	;pomiń nast. instrukcję, jeśli bit 2. = 0
	bsf	PORT_DB6_LCD, DB6_LCD	;ustawj linię DB6_LCD
	btfsc	dane_do_wyslania, 1	;pomiń nast. instrukcję, jeśli bit 1. = 0
	bsf	PORT_DB5_LCD, DB5_LCD	;ustawj linię DB5_LCD
	btfsc	dane_do_wyslania, 0	;pomiń nast. instrukcję, jeśli bit 0. = 0
	bsf	PORT_DB4_LCD, DB4_LCD	;ustawj linię DB4_LCD
	
	call Czekaj_1us				;zaczekaj 1 us
	;potwierdzenie wysłania danych (opadającym zboczem EN)
	bcf	PORT_EN_LCD, EN_LCD		;wyzerowanie EN

	;;;;;;;;;;;;;;;;;;;;;\
	movlw   0			; \
	movwf   R3			;  \
	movlw   0			;   \
	movwf   R2			;    \
	movlw   0			;     >zaczekaj 40 us
	movwf   R1			;    /
	movlw   4			;   /
	movwf   R0			;  /
	call 	Czekaj_10us	; /
	;;;;;;;;;;;;;;;;;;;;;/

	return	;powrót z podprogramu
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CzyscLCD:
	bcf	PORT_RS_LCD, RS_LCD	;zeruj linię RS_LCD (wysyłamy rozkaz)
	;załaduj argument dla podprogramu
	movlw	1
	movwf	dane_do_wyslania
	;skocz do podprogramu
	call	Wyslij_do_LCD
	bsf	PORT_RS_LCD, RS_LCD	;ustaw linię RS_LCD 

	;;;;;;;;;;;;;;;;;;;;;\
	movlw   0			; \
	movwf   R3			;  \
	movlw   0			;   \
	movwf   R2			;    \
	movlw   0			;     >zaczekaj 1,64 ms
	movwf   R1			;    /
	movlw   0xA4		;   /
	movwf   R0			;  /
	call 	Czekaj_10us	; /
	;;;;;;;;;;;;;;;;;;;;;/
	 
	return	;powrót z podprogramu
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
WlaczLCD:
	;ustawienie kierunku wyjściowego linii podłączonych do LCD
	;(pamiętajmy o konfiguracji linii cyfrowych, jeśli korzystamy z linii analogowych)
	bsf	STATUS, 5		;ustaw 5. bit rejestru STATUS (przejdź do banku 1.)
	bcf	TRIS_RS_LCD, RS_LCD	
	bcf	TRIS_EN_LCD, EN_LCD	
	bcf	TRIS_DB7_LCD, DB7_LCD	
	bcf	TRIS_DB6_LCD, DB6_LCD	
	bcf	TRIS_DB5_LCD, DB5_LCD	
	bcf	TRIS_DB4_LCD, DB4_LCD	
	bcf	STATUS, 5		;wyzeruj 5. bit rejestru STATUS (przejdź do banku 0)

	;stan niski na liniach
	bcf	PORT_RS_LCD, RS_LCD	
	bcf	PORT_EN_LCD, EN_LCD	
	bcf	PORT_DB7_LCD, DB7_LCD	
	bcf	PORT_DB6_LCD, DB6_LCD	
	bcf	PORT_DB5_LCD, DB5_LCD	
	bcf	PORT_DB4_LCD, DB4_LCD	

	;zaczekaj co najmniej 45 ms na ustabilizowanie się napięcia
	;;;;;;;;;;;;;;;;;;;;;\
	movlw   0			; \
	movwf   R3			;  \
	movlw   0			;   \
	movwf   R2			;    \
	movlw   0x11		;     >
	movwf   R1			;    /
	movlw   0x94		;   /
	movwf   R0			;  /
	call 	Czekaj_10us	; /
	;;;;;;;;;;;;;;;;;;;;;/

	;1
	;ustaw linię EN
	bsf	PORT_EN_LCD, EN_LCD
	;załaduj sekwencję 0011
	bcf	PORT_DB7_LCD, DB7_LCD	;zeruj linię DB7_LCD
	bcf	PORT_DB6_LCD, DB6_LCD	;zeruj linię DB6_LCD
	bsf	PORT_DB5_LCD, DB5_LCD	;ustaw linię DB5_LCD
	bsf	PORT_DB4_LCD, DB4_LCD	;ustaw linię DB4_LCD
	;zaczekaj 1 us
	call	Czekaj_1us
	;potwierdź opadającym zboczem EN
	bcf	PORT_EN_LCD, EN_LCD

	;zaczekaj co najmniej 4,1 ms
	;;;;;;;;;;;;;;;;;;;;;\
	movlw   0			; \
	movwf   R3			;  \
	movlw   0			;   \
	movwf   R2			;    \
	movlw   1			;     >
	movwf   R1			;    /
	movlw   0x9A		;   /
	movwf   R0			;  /
	call 	Czekaj_10us	; /
	;;;;;;;;;;;;;;;;;;;;;/


	;2
	;ustaw linię EN
	bsf	PORT_EN_LCD, EN_LCD
	;zaczekaj 1 us
	call Czekaj_1us
	;potwierdź opadającym zboczem EN sekwencję 0011
	bcf	PORT_EN_LCD, EN_LCD
	
	;zaczekaj co najmniej 100 us
	;;;;;;;;;;;;;;;;;;;;;\
	movlw   0			; \
	movwf   R3			;  \
	movlw   0			;   \
	movwf   R2			;    \
	movlw   0			;     >
	movwf   R1			;    /
	movlw   d'10'		;   /
	movwf   R0			;  /
	call 	Czekaj_10us	; /
	;;;;;;;;;;;;;;;;;;;;;/
	
	;3
	;ustaw linię EN
	bsf	PORT_EN_LCD, EN_LCD
	;zaczekaj 1 us
	call Czekaj_1us
	;potwierdź opadającym zboczem EN sekwencję 0011
	bcf	PORT_EN_LCD, EN_LCD
	
	;zaczekaj co najmniej 100 us
	;;;;;;;;;;;;;;;;;;;;;\
	movlw   0			; \
	movwf   R3			;  \
	movlw   0			;   \
	movwf   R2			;    \
	movlw   0			;     >
	movwf   R1			;    /
	movlw   d'10'		;   /
	movwf   R0			;  /
	call 	Czekaj_10us	; /
	;;;;;;;;;;;;;;;;;;;;;/
 
	;4
	;ustaw linię EN
	bsf	PORT_EN_LCD, EN_LCD
	;ustawienie interfejsu 4-bitowego
	bcf	PORT_DB4_LCD, DB4_LCD
	;zaczekaj 1 us
	call Czekaj_1us
	;potwierdź opadającym zboczem EN
	bcf	PORT_EN_LCD, EN_LCD

	;ustaw parametry wyświetlacza
	;bit 4 = 0 (słowo danych ma 4 bity)
	;bit 3 = 1 (2 wiersze znaków)
	;bit 2 = 0 (matryca 5x8 pikseli)
	bcf	PORT_RS_LCD, RS_LCD
	;załaduj argument dla podprogramu
	movlw	b'00101000'
	movwf	dane_do_wyslania
	;skocz do podprogramu
	call	Wyslij_do_LCD
	bsf	PORT_RS_LCD, RS_LCD

	;włącz wyświetlacz
	;bit 2 = 1 (włączenie wyświetlania)
	;bit 1 = 0 (kursor nieaktywny)
	;bit 0 = 0 (kursor nie miga)
	bcf	PORT_RS_LCD, RS_LCD
	;załaduj argument dla podprogramu
	movlw	b'00001100'
	movwf	dane_do_wyslania
	;skocz do podprogramu
	call	Wyslij_do_LCD
	bsf	PORT_RS_LCD, RS_LCD

	;ustaw tryb pracy wyświetlacza
	;bit 2 = 1 (inkrementowanie adresu zapisu danych)
	;bit 1 = 1 (wyłączenie przesuwania w prawo)
	bcf	PORT_RS_LCD, RS_LCD
	;załaduj argument dla podprogramu
	movlw	b'00000110'
	movwf	dane_do_wyslania
	;skocz do podprogramu
	call	Wyslij_do_LCD
	bsf	PORT_RS_LCD, RS_LCD

	call CzyscLCD
	return	;powrót z podprogramu
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;argumenty dla podprogramu:
;napis - adres ciągu znaków (max. 16 bajtów) do wyświetlenia (0x20)
;ile - liczba znaków do wyświetlenia
WyswietlLCD:
	bcf	STATUS, 7	;zeruj bit IRP rejestru STATUS (adres banku 0)
	movlw	0x20	;adres zmiennej napis
	movwf	FSR		;ładujemy do rejestru FSR
petla_wyswietlLCD:
	;załaduj argument dla podprogramu 
	;(adresowanie pośrednie - adres w FSR)
	movf	INDF, 0	;załaduj bajt spod adresu FSR do W
	movwf	dane_do_wyslania	;załaduj W do argumentu podprogramu
	;skocz do podprogramu
	call	Wyslij_do_LCD
	;inkrementuj adres
	incf	FSR, 1
	;zmniejsz licznik znaków, pomiń skok, jeśli jest 0
	decfsz	ile, 1
	goto	petla_wyswietlLCD

	return	;powrót z podprogramu
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;argumenty dla podprogramu:
;y - wiersz wyświetlacza
;x - kolumna qyświetlacza
UstawKursorLCD:
	;ustal nowy adres pamięci DD RAM
	decf	x, 1		;x = x - 1
	decf	y, 1		;y = y - 1
	movf	y, 0		;y -> W
	btfss	STATUS, 2	;pomiń nast. instrukcję, jeśli W = 0
	addlw	0x40		;W = W + 0x40
	addwf	x, 0		;W = W + x

	;ustaw kod
	iorlw	b'10000000'	;najstarszy bit danych ustawiony
	
	;wyślij rozkaz ustawienia nowego adresu DD RAM
	bcf	PORT_RS_LCD, RS_LCD
	movwf	dane_do_wyslania
	call	Wyslij_do_LCD
	bsf	PORT_RS_LCD, RS_LCD
	
	return	;powrót z podprogramu
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

