
; Vlaďouš test LCD displeje 2x16 znaku                                   7.4.2014
; Test LCD    Line 1    CZ znaky
; 1.0 2014    Line 2    šďěščřžZ

list	P=16F690, R=DEC
include p16f690.inc 

;	Konfigurace PIC16F84
__config (_XT_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _CP_ON & _BOR_ON & _IESO_OFF & _FCMEN_OFF)

RAM			equ	20h		; prvni adresa pameti RAM (PIC16F628, 16F88, 16F876, 16F690)
STISK		equ	RAM+1	; tlačítko stisknuto
;TMP_S		equ	RAM+2	; temp preruseni
;TMP_PCL	equ	RAM+3	; temp preruseni

SEC0		equ RAM+5	; sekundy jednotky
SEC1		equ RAM+6	; sekundy desítky
MIN0		equ RAM+7	; minuty jednotky
MIN1		equ RAM+8	; minuty desítky
HOD0		equ RAM+9	; hodiny jednotky
HOD1		equ RAM+10	; hodiny desítky
KLAVESA		equ RAM+11	; Stav tlacitka

TMP0		equ	RAM+12	; cekaci smycka
TMP1		equ	RAM+13	; cekaci smycka
TMP2		equ	RAM+14	; cekaci smycka
TMP3		equ	RAM+15	; cekaci smycka, stisk tlacitka

TEXT		equ	RAM+20	; zobrazeni textu na LCD
ZNAK		equ	RAM+21	; zobrazeni znaku na LCD
ADRESA		equ	RAM+22	; inicializace cestiny, adresa pro misto znaku
CISLO		equ	RAM+23	; pomocne cislo


#define	E	PORTA,0		; LCD displej: 0=klid, 1=Enable
#define	RS	PORTA,1		; LCD displej: 0=zapis instrukci, 1=zapis dat
#define	P_VYS	PORTC	; Port pro vystup LCD displeje

	org	0x2100			; prednastaveni dat v pameti EEPROM
	de	0x0A, 0x04, 0x0F, 0x10, 0x0E, 0x01, 0x1E, 0x00	; znak0 = 40h	š
	de	0x1D, 0x09, 0x0D, 0x13, 0x11, 0x13, 0x0D, 0x00	; znak1 = 48h	ď
	de	0x0A, 0x04, 0x0E, 0x11, 0x1F, 0x10, 0x0E, 0x00	; znak2 = 50h	ý
	de	0x0A, 0x04, 0x0E, 0x10, 0x0E, 0x01, 0x1E, 0x00	; znak3 = 58h	š
	de	0x0A, 0x04, 0x0E, 0x10, 0x10, 0x11, 0x0E, 0x00	; znak4 = 60h	č
	de	0x0A, 0x04, 0x16, 0x19, 0x10, 0x10, 0x10, 0x00	; znak5 = 68h	ř
	de	0x0A, 0x04, 0x1F, 0x02, 0x04, 0x08, 0x1F, 0x00	; znak6 = 70h	ž
	de	0x00, 0x04, 0x0E, 0x0E, 0x0E, 0x1F, 0x1F, 0x04	; znak8 = 78h   zvonek

	org	0x0000			; zacatek programu
	goto	INIT		; skok na zacatek inicializaci

;**************************************************************************
TAB_TXT	addwf	PCL,F
	retlw	'V'			; 0
	retlw	'l'
	retlw	'a'
	retlw	80h			;'ď'
	retlw	'o'			; 4
	retlw	'u'
	retlw	80h			;'š'
	retlw	' '			; 7
	retlw	't'
	retlw	'i'
	retlw	'm'
	retlw	'e'
	retlw	' '
	retlw	'L'
	retlw	'C'
	retlw	'D'
	retlw	80h			; konec textu
;-------------------------------
	retlw	'v'			; 17
	retlw	'e'
	retlw	'r'
	retlw	'z'
	retlw	'e'
	retlw	' '
	retlw	'1'
	retlw	'.'
	retlw	'0'
	retlw	' '
	retlw	'2'
	retlw	'0'
	retlw	'1'
	retlw	'4'
	retlw	80h			; konec textu
;-------------------------------
	retlw	'C'			; 32
	retlw	'Z'
	retlw	' '
	retlw	'z'
	retlw	'n'
	retlw	'a'
	retlw	'k'
	retlw	'y'
	retlw	80h			; konec textu
;-------------------------------
	retlw	'N'			; 41
	retlw	'a'
	retlw	's'
	retlw	't'
	retlw	'a'
	retlw	'v'
	retlw	' '
	retlw	80h			; 'č'
	retlw	'a'			; 49
	retlw	's'
	retlw	' '
	retlw	80h			; konec textu
	retlw	'H'			; 53
	retlw	'H'
	retlw	'/'
	retlw	'M'
	retlw	'M'
	retlw	80h			; konec textu
;-------------------------------
	retlw	'V'			; 59
	retlw	'l'
	retlw	'a'
	retlw	80h			; 'ď'
	retlw	'o'			; 63
	retlw	'u'
	retlw	80h			;'š'
	retlw	' '			; 66
	retlw	't'
	retlw	'i'
	retlw	'm'
	retlw	'e'
	retlw	' '
	retlw	80h			; konec textu
;**************************************************************************
TAB_CZ	addwf	PCL,F	; tabulka ceskzch znaku pro LCD displej
;       ------------------------
	retlw	0x0A		; znak0 = 40h	š
	retlw	0x04
	retlw	0x0F
	retlw	0x10
	retlw	0x0E
	retlw	0x01
	retlw	0x1E
	retlw	0x00
;       ------------------------
	retlw	0x1D		; znak1 = 48h	ď
	retlw	0x09
	retlw	0x0D
	retlw	0x13
	retlw	0x11
	retlw	0x13
	retlw	0x0D
	retlw	0x00
;       ------------------------
	retlw	0x0A		; znak2 = 50h	ý
	retlw	0x04
	retlw	0x0E
	retlw	0x11
	retlw	0x1F
	retlw	0x10
	retlw	0x0E
	retlw	0x00
;       ------------------------
	retlw	0x0A		; znak3 = 58h	š
	retlw	0x04
	retlw	0x0E
	retlw	0x10
	retlw	0x0E
	retlw	0x01
	retlw	0x1E
	retlw	0x00
;       ------------------------
	retlw	0x0A		; znak4 = 60h	č
	retlw	0x04
	retlw	0x0E
	retlw	0x10
	retlw	0x10
	retlw	0x11
	retlw	0x0E
	retlw	0x00
;       ------------------------
	retlw	0x0A		; znak5 = 68h	ř
	retlw	0x04
	retlw	0x16
	retlw	0x19
	retlw	0x10
	retlw	0x10
	retlw	0x10
	retlw	0x00
;       ------------------------
	retlw	0x0A		; znak6 = 70h	ž
	retlw	0x04
	retlw	0x1F
	retlw	0x02
	retlw	0x04
	retlw	0x08
	retlw	0x1F
	retlw	0x00
;       ------------------------
	retlw	0x00		;znak8 = 78h	zvonek
	retlw	0x04
	retlw	0x0E
	retlw	0x0E
	retlw	0x0E
	retlw	0x1F
	retlw	0x1F
	retlw	0x04
;**************************************************************************
INIT	
  bcf STATUS,RP0
  bcf STATUS,RP1
  clrf PORTA
  clrf PORTB
  clrf P_VYS
  bsf  STATUS,RP0    	;select Register Page 1

  bcf OPTION_REG,7
;  movlw	b'01010100'	; PULL-UPy ON, 1:256
;  movwf	OPTION_REG	; f:4  :1  :250 = 4000Hz (250us)

  movlw	0xF0
  movwf TRISB
  movlw	0x00
  movwf TRISA
  movwf TRISC        	;make port C outputs
  bcf  STATUS,RP0    	;back to Register Page 0
  bsf  STATUS,RP1
  movwf ANSEL
  movwf ANSELH
  bcf  STATUS,RP1  
;       ------------------------
	movlw 0x30
	movwf HOD1
	movwf HOD0
	movwf MIN1
	movwf MIN0
	movwf SEC1
	movwf SEC0
	call	INI_LCD		; inicializace LCD displeje
	call	CESTINA		; ceske znaky do LCD displeje
;-------------------------------
	call	VERZE		; zobrazi softwerovou verzi
	call	CEK2s		; cekej 2 sekundu
;**************************************************************************
; Nastavení hodin Tlačítka port B (B0 hodiny , B1 minuty , B2 enter)
;**************************************************************************
	call	C_LCD
	call	LINE2
	movlw	.41			; text 41
 	call	WR_TEXT
	movlw	04h
	call	WR_DATA
	movlw	.49			; text 49
 	call	WR_TEXT
TlacSmycka
	call CAS_ZOBR		;zobrazí čas na display
	movf PORTB,W			
	xorlw .0
    BTFSC STATUS,Z
	goto TlacSmycka	
	call CEK15m
	call CEK15m
	movf PORTB,W
	movwf KLAVESA
Tlac1
	movf PORTB,W			
	xorlw .16
    BTFSS STATUS,Z
	goto Tlac2
	; *** Akce tl.1 ***
	call Hodiny			;přičti 1 hodinu
	; *** **** **** ***
Tlac2
	movf PORTB,W
	xorlw .32
    BTFSS STATUS,Z
	goto Tlac3
	; *** Akce tl.2 ***	
	call Minuty			;přičti 1 minutu
	; *** **** **** ***
Tlac3
    movf PORTB,W
	xorlw .64 
    BTFSC STATUS,Z
	; *** Akce tl.3 ***
	goto MAIN				;start hodin
	; *** **** **** ***
	call CEK100m
	call CEK100m
	call CEK100m
	call CEK100m
	call CEK100m
	call CEK100m
	goto TlacSmycka
;**************************************************************************
MAIN		
	call	CAS_ZOBR
;       ------------------------
	call	LINE2
	movlw	.59			; text 59
	call	WR_TEXT
	movlw	01h
	call	WR_DATA
	movlw	.63			; text 63 pokračování
	call	WR_TEXT
	movlw	00h
	call	WR_DATA
	movlw	.66			; text 66 pokračování
	call	WR_TEXT
;       ------------------------
	call Sekundy
;       ------------------------
	call	CEK1s		; cekej 1 sekundu
;**************************************************************************
;	movlw	00h
;	call	WR_DATA
;	movlw	01h
;	call	WR_DATA
;	movlw	02h
;	call	WR_DATA
;	movlw	03h
;	call	WR_DATA
;	movlw	04h
;	call	WR_DATA
;	movlw	05h
;	call	WR_DATA
;	movlw	06h
;	call	WR_DATA
;	movlw	07h
;	call	WR_DATA
;	call	CEK2s		; cekej 2 sekundu
	goto	MAIN
;**************************************************************************
WR_TEXT	movwf	TEXT	; W -> TEXT
	call	TAB_TXT
	movwf	ZNAK		; W -> ZNAK
	sublw	0x80
	btfsc	STATUS,Z
	retlw	0x00		; pokud je znak = 80h, konec textu
;       ------------------------
	movf	ZNAK,W		; ZNAK -> W
	call	WR_DATA
;       ------------------------
	incf	TEXT,W		; TEXT + 1 -> W
	goto	WR_TEXT
;**************************************************************************
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, zapis instrukci do LCD
	goto	WR_LCD
;-------------------------------
WR_DATA	bsf	RS			; RS=1, zapis dat do LCD
	goto	WR_LCD
;-------------------------------
WR_LCD	movwf	ZNAK	; prepsat W do ZNAK	!!! data v registru W !!!

	bsf	E				; nastav Enable
	movf	P_VYS,W		; stav portu do W
	iorlw	0x0F		; zamaskuje dolni bity portu - iorlw 0x0F
	movwf	TMP1
;-------------------------------
	swapf	ZNAK,W		;swapf ZNAK,W
	iorlw	0xF0		; zamaskuje horni bity znaku

	andwf	TMP1,W		; posle vyssi 4 bity
	movwf	P_VYS		; !!! data zapsana na P_VYS0-3 !!! - movwf
	bcf	E				; zapise do LCD
;-------------------------------
	bsf	E				; nastav Enable
	movf	ZNAK,W		;movf ZNAK,W
	iorlw	0xF0		; zamaskuje horni bity znaku

	andwf	TMP1,W		; posle nizsi 4 bity
	movwf	P_VYS		; !!! data zapsana na P_VYS0-3 !!! - movwf
	bcf	E				; zapise do LCD
;-------------------------------
	btfsc	RS
	goto	CEK40		; RS=1, zapis dat - cekej 40 us
;       ------------------------
	movlw	04h			; instrukce 1, 2 a 3 - cekej 1,64 ms
	subwf	ZNAK,W
	btfss	STATUS,C
	goto	CEK4m		; C=0, instrukce CLEAR - cekej 1,64 ms !!! LCD 4x40 !!!
	goto	CEK40		; C=1, zapis dat - cekej 40 us
;**************************************************************************
INI_LCD	call	CEK15m	; 4-bitova inicializace displeje LCD
	call	CEK15m		; cekej 15 ms
	bcf	RS				; zapis ridicich instrukci do LCD
;-------------------------------
	movlw	03h			; !!! poslat 03h na P_VYS0-3 (vstupy LCD DB4-DB7) !!!
	movwf	P_VYS
;       ------------------------
	bsf	E
	bcf	E
	call	CEK4m		; cekej 4,1 ms
;       ------------------------
	bsf	E
	bcf	E
	call	CEK100		; cekej 100 us
;       ------------------------
	bsf	E
	bcf	E
	call	CEK40		; cekej 40 us
;-------------------------------
	movlw	02h			; !!! poslat 02h na P_VYS0-3 (vstupy LCD DB4-DB7) !!!
	movwf	P_VYS		; nastavena 4-bitova komunikace
;       ------------------------
	bsf	E
	bcf	E
	call	CEK40		; cekej 40 us
;-------------------------------
	movlw	2Ch			; 00101000 - pocet bitu, 2 radky, 5x10 znaky
	call	WR_CMD
	movlw	0Ch			; 00001100 - display ON, kurzor OFF, blikani OFF
	call	WR_CMD
	movlw	01h			; 00000001 - smaze displej, kurzor na pozici 0
	call	WR_CMD
	movlw	06h			; 00000110 - smer kurzoru, posunu displeje
	call	WR_CMD
;       ------------------------
	return
;**************************************************************************
 CESTINA	movlw 0x00	; adresa prvniho CZ znaku v EEPROM
	movwf	EEADR
	movlw	0x40		; adresa prvniho znaku v LCD displeji (40h-7Fh)
	movwf	ADRESA
;-------------------------------
	movf	ADRESA,W
	call	WR_CMD
	call	RD_MEM		; cteni z pameti EEPROM
	call	WR_DATA
;       ------------------------
	banksel	EEADR
	incf	EEADR,F
	banksel	0x00
	incf	ADRESA,F
	movf	ADRESA,W
	sublw	0x80		; adresa posledniho znaku v LCD displeji
	btfss	STATUS,Z
	goto	$-11
;       ------------------------
	return
;******************************************************
; Read EEPROM (nastav EEADR)
RD_MEM
	BANKSEL EECON1
	BCF		EECON1, EEPGD	;bod na DATA paměť
	BSF		EECON1, RD		;EE Přečtěte si
	BANKSEL EEDAT;
	MOVF	EEDAT, W		;W = EEDAT
	BCF		STATUS, RP1		; Bank 0
   return
;**************************************************************************
; casy pro frekvenci krystalu 4,00Mhz
; casy jsou spocitane od call CEKxxm do navratu na volani CEKxxm
; celkovy vypocet  = 2+6+(2+(TMP0-1)*3+2)+3)*TMP1-1+2
; zkraceny vypocet = 8+((TMP0-1)*3+7)*TMP1+1
; mala smycka = (TMP2-1)*3+2
;-------------------------------
CEK1s	movlw	.9		; TMP2 = 20  cekej 2 sekundu
	movwf	TMP3
	call CEK15m
	call CEK15m
	call CEK15m
	call CEK15m
	call CEK15m
	call CEK15m
	call CEK4m
	call CEK4m
	call CEK100
	call CEK100
	call CEK100
	call CEK100
	call CEK40

	movlw	05h	; cas = 38 mikrosekund
	movwf	TMP0
	decfsz	TMP0,F
	goto	$-1
	nop
	nop
	goto	SMYCKA2
;-------------------------------
CEK2s	movlw	.20		; TMP2 = 20  cekej 2 sekundu
	movwf	TMP3
	goto	SMYCKA2
;-------------------------------
CEK100m	movlw	0CEh	; cas = 100,009 ms 0CFh
	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		; nejvetsi smycka
	goto	SMYCKA2
	retlw	00h
;-------------------------------
SMYCKA	movf	TMP0,W
	movwf	TMP2
SMYCKA1	decfsz	TMP2,F	; mala smycka
	goto	SMYCKA1

	decfsz	TMP1,F		; velka smycka
	goto	SMYCKA
	retlw	00h
;**************************************************************************
Sekundy
	incf SEC0,F
    MOVF SEC0,W
	XORLW 58 
    BTFSS STATUS,Z            ;je tych sekund 9 
    goto Pokrac2		          ;kdyz ne 
    movlw 0x30                ;kdyz ano 
	movwf SEC0

	incf SEC1,F
    MOVF SEC1,W
	XORLW 54 
    BTFSS STATUS,Z            ;je tych sekund 60 
    goto Pokrac2               ;kdyz ne 
    movlw 0x30                ;kdyz ano 
	movwf SEC1
Minuty
	incf MIN0,F
    MOVF MIN0,W
	XORLW 58 
    BTFSS STATUS,Z            ;je tych minut 9 
    goto Pokrac2            ;kdyz ne 
    movlw 0x30                ;kdyz ano 
	movwf MIN0

	incf MIN1,F
    MOVF MIN1,W
	XORLW 54 
    BTFSS STATUS,Z            ;je tych minut 60 
    goto Pokrac2               ;kdyz ne 
    movlw 0x30                ;kdyz ano 
	movwf MIN1
Hodiny
	incf HOD0,F
    MOVF HOD0,W
	XORLW 58 
    BTFSS STATUS,Z            ;je tych hodin 9 
    goto Pokrac               ;kdyz ne 
    movlw 0x30                ;kdyz ano 
	movwf HOD0
	incf HOD1,F
	Pokrac
	MOVF HOD0,W
	XORLW 52				;číslo4
    BTFSS STATUS,Z          ;je tych hodin 24 
    goto Pokrac2            ;kdyz ne 
    MOVF HOD1,W
	XORLW 50				;číslo2
    BTFSS STATUS,Z          ;je tych hodin 24 
    goto Pokrac2            ;kdyz ne 
	movlw 0x30              ;kdyz ano 
	movwf HOD0	
	movwf HOD1
	Pokrac2
	retlw 00h
;**************************************************************************
CAS_ZOBR
	call 	LINE1
	movf	HOD1,W			; Hodima 1
	call	WR_DATA
	movf	HOD0,W			; Hodina 0
	call	WR_DATA
	movlw	':'
	call	WR_DATA
	movf	MIN1,W			; Minuta 1
	call	WR_DATA
	movf	MIN0,W			; Minuta 0
	call	WR_DATA
	movlw	':'
	call	WR_DATA
	movf	SEC1,W			; Sekunda 1
	call	WR_DATA
	movf	SEC0,W			; Sekunda 0
	call	WR_DATA
	retlw 00h

VERZE	call	C_LCD	; smaz LCD displej, 1 radek a 1 znak
	movlw	.00			; text 0 - jmeno sofware
	call	WR_TEXT
	movlw	01h
	call	WR_DATA
	movlw	.04			; text 4 - jmeno sofware pokračování
	call	WR_TEXT
	movlw	00h
	call	WR_DATA
	movlw	.07			; text 7 - jmeno sofware pokračování
	call	WR_TEXT

	call	LINE2
	movlw	.17			; text 17 - verze, datum
	call	WR_TEXT

	call	CEK2s		; cekej 2 sekundu
	return
;**************************************************************************
	end

