Прошей вот это 100% работает.
http://www.cmail.cz/doveda/programy/pic_lcd.zip
; verze 1.0 - 24.7.2003
; PIC16F628 a krystal 4,00MHz
; Test LCD displeje 2 x 16 znaku
;************************************************* *************************
;*
http://www.cmail.cz/doveda *
;************************************************* *************************
;* PIC16F628 *
;* --------\/-------- *
;* -|RA2 RA1|- LCD RS *
;* -|RA3 RA0|- LCD E *
;* PODSVICENI LCD -|RA4ck osc1|- \ Krystal 4,00MHz *
;* +5V -|MCLR osc2|- / *
;* 0V -|Vss Vdd|- +5V *
;* LCD data bit 4 -|RB0/INT PGD/RB7|- *
;* LCD data bit 5 -|RB1 PGC/RB6|- *
;* LCD data bit 6 -|RB2 RB5|- *
;* LCD data bit 7 -|RB3 RB4|- *
;* ------------------ *
;* DOVEDA BOYS (c) 1997-2003 *
;************************************************* *************************
list p=16f628, R=DEC
include "p16f628.inc"
RAM equ 20h ; prvnн adresa pamмti RAM pro PIC16F628 - 224bajtщ (20h-7Fh)
TMP_W equ RAM+1 ; temp preruseni
TMP_S equ RAM+2 ; temp preruseni
TMP_PCL equ RAM+3 ; temp preruseni
TMP0 equ RAM+4 ; cekaci smycka
TMP1 equ RAM+5 ; cekaci smycka
TMP2 equ RAM+6 ; cekaci smycka
TMP3 equ RAM+7 ; cekaci smycka
TEXT equ RAM+10 ; zobrazeni textu na LCD
ZNAK equ RAM+11 ; zobrazeni znaku na LCD
ADRESA equ RAM+12 ; inicializace cestiny, adresa pro misto znaku
CISLO equ RAM+13 ; pomocne cislo
EE_ADR equ 7Eh ; !!! 70h - 7Fh pro vsechny banky !!!
#define E PORTA,0 ; E - LCD displej
#define RS PORTA,1 ; RS - LCD displej
#define SVITI PORTA,4 ; Podsviceni LCD displeje (0=nesviti, 1=sviti)
org 0x2007 ; adresa konfigurace PIC16F627 a 628
dw _BODEN_OFF & _CP_OFF & _PWRTE_OFF & _WDT_OFF & _LVP_OFF & _MCLRE_ON & _XT_OSC
org 0x2100 ; pшednast. hesla v EEPROM
de 0x02, 0x04, 0x1E, 0x01, 0x0F, 0x11, 0x0F, 0x00 ; znak0 = 40h a s carkou
de 0x02, 0x04, 0x0C, 0x04, 0x04, 0x04, 0x0E, 0x00 ; znak1 = 48h i s carkou
de 0x0A, 0x04, 0x0E, 0x11, 0x1F, 0x10, 0x0E, 0x00 ; znak2 = 50h e s hackem
de 0x0A, 0x04, 0x0E, 0x10, 0x0E, 0x01, 0x1E, 0x00 ; znak3 = 58h s s hackem
de 0x0A, 0x04, 0x0E, 0x10, 0x10, 0x11, 0x0E, 0x00 ; znak4 = 60h c s hackem
de 0x0A, 0x04, 0x16, 0x19, 0x10, 0x10, 0x10, 0x00 ; znak5 = 68h r s hackem
de 0x0A, 0x04, 0x1F, 0x02, 0x04, 0x08, 0x1F, 0x00 ; znak6 = 70h z s hackem
de 0x02, 0x04, 0x11, 0x11, 0x0F, 0x01, 0x0E, 0x00 ; znak7 = 78h y s carkou
org 0x0000 ; zacatek programu
goto INIT ; skok na poибteиnн inicalizaci
org 0x0004 ; vektor pшeruљenн
goto PRERUS
;************************************************* *************************
TAB_TXT addwf PCL,F
retlw 'T' ; 0
retlw 'e'
retlw 's'
retlw 't'
retlw ' '
retlw 'L'
retlw 'C'
retlw 'D'
retlw 80h ; konec textu
;-------------------------------
retlw '1' ; 9
retlw '.'
retlw '0'
retlw '-'
retlw '2'
retlw '0'
retlw '0'
retlw '3'
retlw 80h ; konec textu
;-------------------------------
retlw 'L' ; 18
retlw 'i'
retlw 'n'
retlw 'e'
retlw ' '
retlw ' '
retlw '1'
retlw ' '
retlw 80h ; konec textu
;-------------------------------
retlw 'L' ; 27
retlw 'i'
retlw 'n'
retlw 'e'
retlw ' '
retlw ' '
retlw '2'
retlw ' '
retlw 80h ; konec textu
;-------------------------------
retlw 'C' ; 36
retlw 'Z'
retlw ' '
retlw 'z'
retlw 'n'
retlw 'a'
retlw 'k'
retlw 'y'
retlw 80h ; konec textu
;************************************************* *************************
TAB_CZ addwf PCL,F ; definovбnн иeskэch znakщ pro LCD
; ------------------------
retlw 0x02 ; znak0 = 40h б
retlw 0x04
retlw 0x1E
retlw 0x01
retlw 0x0F
retlw 0x11
retlw 0x0F
retlw 0x00
; ------------------------
retlw 0x02 ; znak1 = 48h н
retlw 0x04
retlw 0x0C
retlw 0x04
retlw 0x04
retlw 0x04
retlw 0x0E
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 0x02 ; znak7 = 78h э
retlw 0x04
retlw 0x11
retlw 0x11
retlw 0x0F
retlw 0x01
retlw 0x0E
retlw 0x00
;************************************************* *************************
;* preruseni kazdych 8,192ms (122Hz) *
;************************************************* *************************
PRERUS movwf TMP_W ; (ulozeni hodnot registru W a STATUS)
movf STATUS,W ; prohodi nibble STATUS a ulozi do W
clrf STATUS ; nastaveni banky 0
movwf TMP_S ; ulozit STATUS
movf PCLATH,W
movwf TMP_PCL
clrf PCLATH ; nastaveni banky 0
; ------------------------
bcf INTCON,T0IF ; vynulovat priznak preruseni (pretekl casovac TMR0)
;-------------------------------
; !!! zde napiste co ma preruseni vykonat !!!
;------------------------------- (obnovenн hodnot registru W a STATUS)
INT_END movf TMP_PCL,W
movwf PCLATH ; obnova PCLATH
movf TMP_S,W ; prohodi nibble TMP_S a ulozi do W
; swapf TMP_S,W ; prohodi nibble TMP_S a ulozi do W
movwf STATUS ; obnova STATUS
swapf TMP_W,F ; prohodi nibble TMP_W a ulozi do W
swapf TMP_W,W ; obnova W
retfie
;************************************************* *************************
INIT movlw b'00000'
movwf PORTA ; pшednastavenн PORTu A
movlw b'00000000'
movwf PORTB ; pшednastavenн PORTu B
movlw b'00000111' ; digitalni vstupy na PORTu A (PIC16F627 a 628)
movwf CMCON
; ------------------------
bsf STATUS,RP0 ; nastavenн BANKY 1
movlw b'01100' ; portA 4-0, 2vstupy, 3vystupy
movwf TRISA
movlw b'11010100' ; PULL-UPy OFF, preddelic=1:32 pripojen k TMR0
movwf OPTION_REG ; f:4 :32 :256 = 122,1Hz (8,192ms)
movlw b'00000000' ; portB 7-0, 0vstupy, 8vystupy
movwf TRISB
bcf STATUS,RP0 ; nastavenн BANKY 0
; ------------------------
call INI_LCD ; inicializace LCD
call CESTINA ; ceske znaky do LCD (presun pameti EEPROM)
; call CZ_INI ; ceske znaky do LCD (presun pomoci TAB_CZ)
call VERZE ; zobrazн softwerovou verzi
;-------------------------------
; movlw b'10100000' ; povolena vљechna pшeruљenн a od pшeteиenн TMR0
; movwf INTCON
;************************************************* ************
MAIN call C_LCD ; smaz LCD displej, 1 radek a 1 znak
movlw .18 ; text 18 - Line 1
call WR_TEXT
; ------------------------
call LINE2
movlw .27 ; text 27 - Line 2
call WR_TEXT
; ------------------------
bsf SVITI ; zapni podsvнcenн
call CEK2s ; cekej 2 sekundu
;-------------------------------
call C_LCD ; smaz LCD displej, 1 radek a 1 znak
movlw 'C'
call WR_LCD
movlw 'Z'
call WR_LCD
movlw ' '
call WR_LCD
movlw 'z'
call WR_LCD
movlw 'n'
call WR_LCD
movlw 'a'
call WR_LCD
movlw 'k'
call WR_LCD
movlw 'y'
call WR_LCD
; ------------------------
call LINE2
movlw 00h
call WR_LCD
movlw 01h
call WR_LCD
movlw 02h
call WR_LCD
movlw 03h
call WR_LCD
movlw 04h
call WR_LCD
movlw 05h
call WR_LCD
movlw 06h
call WR_LCD
movlw 07h
call WR_LCD
bcf SVITI ; vypni podsvнcenн
call CEK2s ; cekej 2 sekundu
;-------------------------------
goto MAIN
;************************************************* *************************
VERZE call C_LCD ; smaz LCD displej, 1 radek a 1 znak
movlw .00 ; text 0 - jmeno sofware
call WR_TEXT
; ------------------------
call LINE2
movlw .09 ; text 9 - verze, datum
call WR_TEXT
; ------------------------
call CEK2s ; cekej 2 sekundu
return
;******************************** PIC16F628 *******************************
READ bsf STATUS,RP0 ; banka 1 !!! nastav EE_ADR !!!
movf EE_ADR,W
movwf EEADR
bsf EECON1,RD ; cteni EEPROM
movf EEDATA,W ; nactena data z pameti EEPROM do registru W
bcf STATUS,RP0 ; banka 0
;-------------------------------
return ; !!! data v registru W !!!
;******************************** PIC16F628 *******************************
WRITE bsf STATUS,RP0 ; banka 1 !!! nastav EE_ADR !!!
movwf EEDATA ; prepsat W -> EEDATA
movf EE_ADR,W
movwf EEADR
bsf EECON1,WREN ; povolit zapis do EEPROM
bcf INTCON,GIE ; zakazat vsechna preruseni
; ------------------------; aktivace zapisu
movlw 0x55 ; odblokovani zapisu (povinna povolovaci sekvence)
movwf EECON2
movlw 0xAA
movwf EECON2
bsf EECON1,WR ; spustit zapis
; ------------------------; konec aktivace
bsf INTCON,GIE ; povolit vsechna preruseni
btfsc EECON1,WR ; pockat na konec zapisu
goto $-1 ; =1
bcf EECON1,WREN ; zakazat zapis do EEPROM
bcf STATUS,RP0 ; banka 0
; ------------------------
return
;************************************************* *************************
WR_TEXT movwf TEXT ; W -> TEXT
call TAB_TXT
movwf ZNAK ; W -> ZNAK
sublw 80h
btfsc STATUS,Z
retlw 00h ; pokud je znak = 80h, konec textu
; ------------------------
movf ZNAK,W ; ZNAK -> W
call WR_LCD
; ------------------------
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, zбpis instrukcн do LCD
goto $+2
;-------------------------------
WR_LCD bsf RS ; RS=1, zбpis dat do LCD
; ------------------------
movwf ZNAK ; ulozit W do ZNAK !!! data v registru W !!!
bsf E ; nastav Enable
; ------------------------
movf PORTB,W ; zapamatovat stav PORTuB
iorlw 0x0F ; !!! poslat na PORTB 0-3 !!! (vysledek je xxxx1111)
; iorlw 0xF0 ; !!! poslat na PORTB 4-7 !!! (vysledek je 1111xxxx)
movwf TMP1 ; zapise W do TMP1
;-------------------------------
swapf ZNAK,W ; !!! poslat na PORTB 0-3 !!!
iorlw 0xF0 ; zamaskuje hornн bity (vysledek je 1111xxxx)
; movf ZNAK,W ; !!! poslat na PORTB 4-7 !!!
; iorlw 0x0F ; zamaskuje dolnн bity (vysledek je xxxx1111)
andwf TMP1,W ; poљle vyљљн 4 bity na PORTB
movwf PORTB
bcf E ; zapнљe do LCD
;-------------------------------
bsf E ; nastav Enable
movf ZNAK,W ; !!! poslat na PORTB 0-3 !!!
iorlw 0xF0 ; zamaskuje hornн bity (vysledek je 1111xxxx)
; swapf ZNAK,W ; !!! poslat na PORTB 4-7 !!!
; iorlw 0x0F ; zamaskuje dolnн bity (vysledek je xxxx1111)
andwf TMP1,W ; poљle niћљн 4 bity na PORTB
movwf PORTB
bcf E ; zapнљe do LCD
;-------------------------------
btfsc RS
goto CEK40 ; RS=1, zбpis dat - иekej 40 us
; ------------------------
movlw 04h ; instrukce 1, 2 a 3 - иekej 1,64 ms
subwf ZNAK,W
btfss STATUS,C
goto CEK1m6 ; C=0, instrukce CLEAR - иekej 1,64 ms
goto CEK40 ; C=1, zбpis dat - иekej 40 us
;************************************************* *************************
INI_LCD call CEK15m ; cekej 15ms
bcf RS ; zapis ridicich instrukci do LCD
;-------------------------------
; movlw 30h ; !!! poslat 03h na PORTB 4-7 (vstupy LCD DB4-DB7) !!!
movlw 03h ; !!! poslat 03h na PORTB 0-3 (vstupy LCD DB4-DB7) !!!
movwf PORTB
; ------------------------
bsf E
bcf E
call CEK4m ; cekej 4,1ms
; ------------------------
bsf E
bcf E
call CEK100 ; cekej 100us
; ------------------------
bsf E
bcf E
call CEK40 ; cekej 40us
;-------------------------------
; movlw 20h ; !!! poslat 03h na PORTB 4-7 (vstupy LCD DB4-DB7) !!!
movlw 02h ; !!! poslat 03h na PORTB 0-3 (vstupy LCD DB4-DB7) !!!
movwf PORTB ; nastavena 4-bitova komunikace
; ------------------------
bsf E
bcf E
call CEK40 ; cekej 40us
;-------------------------------
movlw 28h ; 00101000 - poиet bitщ, 2 шбdky, 5x7 znaky
call WR_CMD
movlw 0Ch ; 00001100 - display ON, kurzor OFF, blikбnн OFF
call WR_CMD
movlw 01h ; 00000001 - smaћe displej, kurzor na pozici 0
call WR_CMD
movlw 06h ; 00000110 - smмr kurzoru, posunu displeje
call WR_CMD
; ------------------------
return
;************************************************* *************************
CESTINA movlw 00h ; adresa prvnнho CZ znaku v EEPROM procesoru
movwf EE_ADR
movlw 40h ; adresa prvnнho znaku v LCD displeji (40h-7Fh)
movwf ADRESA
;-------------------------------
movf ADRESA,W
call WR_CMD
call READ
call WR_LCD
; ------------------------
incf EE_ADR,F
incf ADRESA,F
movf ADRESA,W
sublw 80h ; adresa poslednнho znaku v LCD displeji
btfss STATUS,Z
goto $-9
;-------------------------------
return
;************************************************* ************
CZ_INI clrf ADRESA
movlw 0x40 ; prvni adresa znaku v LCD displeji
call WR_CMD
;-------------------------------
CZ_INC movf ADRESA,W
call TAB_CZ
call WR_LCD
; ------------------------
incf ADRESA,F
movlw 0x40 ; aћ ADRESA dosбhne 40h tak je konec
subwf ADRESA,W
btfss STATUS,Z
goto CZ_INC
;-------------------------------
return
;************************************************* *************************
; иasy pro frekvenci krystalu 4,00Mhz
; иasy jsou spoинtanй od call CEKxxm do nбvratu na volбnн CEKxxm
; celkovэ vэpoиet = 2+6+(2+(TMP0-1)*3+2)+3)*TMP1-1+2
; zkrбcenэ vэpoиet = 8+((TMP0-1)*3+7)*TMP1+1
; malб smyиka = (TMP2-1)*3+2
;-------------------------------
CEK2s movlw .20 ; TMP2 = 20 cekej 2 sekundu
movwf TMP3
goto SMYCKA2
;-------------------------------
CEK1s movlw .10 ; TMP2 = 10 cekej 1 sekundu
movwf TMP3
goto SMYCKA2
;-------------------------------
CEK100m movlw 0CFh ; cas = 100,009 ms
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 ; nejvмtљн smyиka
goto SMYCKA2
retlw 00h
;-------------------------------
SMYCKA movf TMP0,W
movwf TMP2
; ------------------------
SMYCKA1 decfsz TMP2,F ; malб smyиka
goto SMYCKA1
; ------------------------
decfsz TMP1,F ; velkб smyиka
goto SMYCKA
; ------------------------
retlw 00h
;************************************************* *************************
end