Import programu pro LCD HD44780 z PIC16F877A na PIC18F4620

S novym procesorem stare problemy :slight_smile:

Na 16F877A mi LCD s radicem 44780 funguje bez problemu. Zkousim to “preimportovat” na 18F4620 a nevim co delam spatne, na display se mi nezobrazi co chci, jen “sviti” cely prvni radek, druhy radek nezobrazi zadny znak.

[code] LIST P=18F4620,r=hex,n=80,x=off,st=off
errorlevel -302

#include <P18F4620.INC>	

;****************************************************************************************
CONFIG OSC=INTIO67, PWRT=ON, BOREN=OFF, WDT=OFF, MCLRE=OFF, LPT1OSC=OFF, PBADEN=OFF
CONFIG LVP=OFF, XINST=OFF, DEBUG=OFF

;******************************************************************************
cblock 0x000
TMP0
TMP1
TMP2
TMP3
ZNAK
ENDC

;****************************************************************************************
ORG 0x0000
nop
bootup goto init ;go to start of main code

;****************************************************************************************
init movlw b’01100010’ ; set internal osc to 4 mhz
movwf OSCCON

	#define		ds				PORTC,0
	#define		RS				PORTD,1
	#define		E				PORTD,0
	#define		LCD_PORT		PORTD

; MACRO
LCDout macro _LCDout
movlw _LCDout
call WR_LCD
endm
LCDw macro
call WR_LCD
endm

call	ports
call	INI_LCD
goto	MAIN

; Nastaveni portu
;* PORTD: *
;* 0 - LCD E *
;* 1 - LCD RS *
;* 2 - *
;* 3 - *
;* 4 - LCD DB4 *
;* 5 - LCD DB5 *
;* 6 - LCD DB6 *
;* 7 - LCD DB7 *
ports clrf PORTA
clrf PORTB
clrf PORTC
clrf PORTD
clrf PORTE

	movlw	b'00001101'				; set portA 0 & 1 as adc input bit 7 rjust
	movwf	ADCON1					; by loading value to adcon1 reg
	movlw	b'00011011'				; set trisa direction is input
	movwf	TRISA					; bit0,1 adc,   bit2,5,6,7 DO,  bit3,4, DI 

	movlw	b'00000000'				; set portB as Outputs
	movwf	TRISB

	movlw	b'00110000'				; set portC as Outputs,  BITS 4 and 5 input for SPI
	movwf	TRISC

	movlw	b'00000000'				; vse je vystup - LCD display
	movwf	TRISD

	movlw	b'00001111'     		; set portE as Inputs
	movwf	TRISE

	return

MAIN
call LINE1
LCDout ‘a’
nop
GOTO MAIN

;**************************************************************************
; Podprogram na obsluhu LCD
;**************************************************************************
CLS_LCD
movlw .0
goto WR_CMD
LINE1
movlw 0x80
goto WR_CMD
LINE2
movlw 0xC0
goto WR_CMD
LINE3
movlw 0x94
goto WR_CMD
LINE4
movlw 0xD4
goto WR_CMD

WR_CMD
banksel 0
bcf RS ; RS=0, zápis instrukcí do LCD
goto $+4
;-------------------------------
WR_LCD
banksel 0
bsf RS ; RS=1, zápis dat do LCD
; ------------------------
movwf ZNAK ; ulozit W do ZNAK !!! data v registru W !!!
bsf E ; nastav Enable
; ------------------------
movf LCD_PORT,W ; zapamatovat stav PORTuD
; iorlw 0x0F ; !!! poslat na PORTD 0-3 !!! (vysledek je xxxx1111)
iorlw 0xF0 ; !!! poslat na PORTD 4-7 !!! (vysledek je 1111xxxx)
movwf TMP1 ; zapise W do TMP1
;-------------------------------
; swapf ZNAK,W ; !!! poslat na PORTD 0-3 !!!
; iorlw 0xF0 ; zamaskuje horní bity (vysledek je 1111xxxx)

movf	ZNAK,W			; !!! poslat na PORTD 4-7 !!!
iorlw	0x0F			; zamaskuje dolní bity (vysledek je xxxx1111)

andwf	TMP1,W			; pošle vyšší 4 bity na PORTD
movwf	LCD_PORT
bcf		E				; zapíše do LCD

;-------------------------------
bsf E ; nastav Enable

; movf ZNAK,W ; !!! poslat na PORTD 0-3 !!!
; iorlw 0xF0 ; zamaskuje horní bity (vysledek je 1111xxxx)

swapf	ZNAK,W			; !!! poslat na PORTD 4-7 !!!
iorlw	0x0F			; zamaskuje dolní bity (vysledek je xxxx1111)

andwf	TMP1,W			; pošle nižší 4 bity na PORTD
movwf	LCD_PORT
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 PORTD 4-7 (vstupy LCD DB4-DB7) !!!
; movlw 03h ; !!! poslat 03h na PORTD 0-3 (vstupy LCD DB4-DB7) !!!
movwf LCD_PORT
; ------------------------
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 LCD_PORT ; 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

;**************************************************************************
; č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
;-------------------------------
CEK3s movlw .30 ; TMP2 = 30 cekej 2 sekundu
movwf TMP3
goto SMYCKA2
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

[/code]
Poradi mi nekdo kde delam chybu ? U 16F844A jsem pouzival krystal 4MHz, na 18F4620 chci pouzit interni oscilator (je dobre prejit z krystalu na oscilator ?).
Dekuji za kazdou pomoc/radu.

:arrow_right: administrator: přejmenováno z "18F4620 a 44780"

Pomuze mi nekdo, ? Neni mi jasne proc to nefunguje.

No pokud ti pořád svítí jeden řádek tak to značí, že LCD není zinicializováno. Sedí ti ty čekací rutiny správně ? Ono když na to půjdeš rychleji tak to většinou pak nefachá.

Chtěl jsem napsat to samé, ale caven mě předběhl… :smiley:

Zkus tohle

[code] LIST P=18F4620,r=DEC
errorlevel -302

#include <P18F4620.INC>

;****************************************************************************************
CONFIG OSC=INTIO67, PWRT=ON, BOREN=OFF, WDT=OFF, MCLRE=OFF, LPT1OSC=OFF, PBADEN=OFF
CONFIG LVP=OFF, XINST=OFF, DEBUG=OFF

;******************************************************************************
cblock 0x008
TMP0
TMP1
TMP2
TMP3
ZNAK
ENDC

;NASTAVENI A promenne pro LCD + MACRa
CONSTANT LCDL1 = 0x80
CONSTANT LCDL2 = 0xC0
CONSTANT LCDL3 = 0x94
CONSTANT LCDL4 = 0xD4

LCDout macro _LCDout
movlw _LCDout
call WR_LCD
endm
LCDw macro
call WR_LCD
endm
LCDcmd macro _LCDcmd
movlw _LCDcmd
nop
nop
nop
nop
call WR_CMD
endm
LCDc macro
movlw .1
call WR_CMD
endm

LCDline macro line_num
IF (line_num == 1)
LCDcmd LCDL1 ; first line
ELSE
IF (line_num == 2)
LCDcmd LCDL2 ; second line
ELSE
IF (line_num == 3)
LCDcmd LCDL3 ; third line
ELSE
IF (line_num == 4)
LCDcmd LCDL4 ; fourth line
ELSE
ERROR “Za LCDLINE nasleduje cislo 1 - 4!!”
ENDIF
ENDIF
ENDIF
ENDIF
endm

  #define      ds            PORTC,0
  #define      RS            PORTD,1
  #define      E            PORTD,0
  #define      LCD_PORT      PORTD

; Nastaveni portu
;* PORTD: *
;* 0 - LCD E *
;* 1 - LCD RS *
;* 2 - *
;* 3 - *
;* 4 - LCD DB4 *
;* 5 - LCD DB5 *
;* 6 - LCD DB6 *
;* 7 - LCD DB7 *

;****************************************************************************************
ORG 0x0000
goto init ;go to start of main code
;****************************************************************************************
init movlw b’01100010’ ; set internal osc to 4 mhz
movwf OSCCON

clrf   PORTA
  clrf   PORTB
  clrf   PORTC
  clrf   PORTD
  clrf   PORTE

  movlw   b'00001101'            ; set portA 0 & 1 as adc input bit 7 rjust
  movwf   ADCON1               ; by loading value to adcon1 reg
  movlw   b'00011011'            ; set trisa direction is input
  movwf   TRISA               ; bit0,1 adc,   bit2,5,6,7 DO,  bit3,4, DI

  movlw   b'00000000'            ; set portB as Outputs
  movwf   TRISB

  movlw   b'00110000'            ; set portC as Outputs,  BITS 4 and 5 input for SPI
  movwf   TRISC

  movlw   b'00000000'            ; vse je vystup - LCD display
  movwf   TRISD

  movlw   b'00001111'           ; set portE as Inputs
  movwf   TRISE
call	INI_LCD   

MAIN
LCDline .1 ;line 1
LCDout ‘r’
LCDout ‘a’
LCDout ‘d’
LCDout ‘e’
LCDout ‘k’
LCDout ’ ’
LCDout ‘1’

LCDline	.2		;line 2
LCDout	'r'
LCDout	'a'
LCDout	'd'
LCDout	'e'
LCDout	'k'
LCDout	' '
LCDout	'2'

LCDline	.3		;line 3
LCDout	'r'
LCDout	'a'
LCDout	'd'
LCDout	'e'
LCDout	'k'
LCDout	' '
LCDout	'3'

LCDline	.4		;line 4
LCDout	'r'
LCDout	'a'
LCDout	'd'
LCDout	'e'
LCDout	'k'
LCDout	' '
LCDout	'4'


GOTO MAIN

;**************************************************************************
; Podprogram na obsluhu LCD
;**************************************************************************
WR_CMD
banksel 0
bcf RS ; RS=0, zápis instrukcí do LCD
goto $+8
;-------------------------------
WR_LCD
banksel 0
bsf RS ; RS=1, zápis dat do LCD
; ------------------------
movwf ZNAK ; ulozit W do ZNAK !!! data v registru W !!!
bsf E ; nastav Enable
; ------------------------
movf LCD_PORT,W ; zapamatovat stav PORTuD
; iorlw 0x0F ; !!! poslat na PORTD 0-3 !!! (vysledek je xxxx1111)
iorlw 0xF0 ; !!! poslat na PORTD 4-7 !!! (vysledek je 1111xxxx)
movwf TMP1 ; zapise W do TMP1
;-------------------------------
; swapf ZNAK,W ; !!! poslat na PORTD 0-3 !!!
; iorlw 0xF0 ; zamaskuje horní bity (vysledek je 1111xxxx)

movf ZNAK,W ; !!! poslat na PORTD 4-7 !!!
iorlw 0x0F ; zamaskuje dolní bity (vysledek je xxxx1111)

andwf TMP1,W ; pošle vyšší 4 bity na PORTD
movwf LCD_PORT
bcf E ; zapíše do LCD
;-------------------------------
bsf E ; nastav Enable

; movf ZNAK,W ; !!! poslat na PORTD 0-3 !!!
; iorlw 0xF0 ; zamaskuje horní bity (vysledek je 1111xxxx)

swapf ZNAK,W ; !!! poslat na PORTD 4-7 !!!
iorlw 0x0F ; zamaskuje dolní bity (vysledek je xxxx1111)

andwf TMP1,W ; pošle nižší 4 bity na PORTD
movwf LCD_PORT
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 PORTD 4-7 (vstupy LCD DB4-DB7) !!!
; movlw 03h ; !!! poslat 03h na PORTD 0-3 (vstupy LCD DB4-DB7) !!!
movwf LCD_PORT
; ------------------------
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 LCD_PORT ; 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

;**************************************************************************
; č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
;-------------------------------
CEK3s movlw .30 ; TMP2 = 30 cekej 2 sekundu
movwf TMP3
goto SMYCKA2
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 [/code]

Timto bych velice rad podekoval uzivateli honza3 za pomoc, LCD funguje jak ma.