PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : 4x27 LCD am P16F84A



stowoda
22.08.2005, 17:22
Hallo!

Mühe mich schon seit einiger Zeit ab, mit der Initialisierung eines LCDs mithilfe eines PICs.
Wie schon bemerkt handelt es sich um den P16F84A und ein 4x27 LCD mit 2xHD44780.
Hier ist übrigens etwas über die Vorgehensweise bei der Initialisierung des LCDs zu finden: http://home.arcor.de/stowoda/Text-LCDs.pdf


list p=16f84a

;************************************************* **************************
; PINBELEGUNG
;
;
; PORTA: 0 - RS
; 1 - RW
; 2 - E1 1.Controller
; 3 - E2 2.Controller
; 4 -
;
; PORTB: 0 - D0
; . - ..
; . - ..
; 7 - D7
;
;************************************************* *************************


#include <P16F84A.INC>


__CONFIG _PWRTE_ON & _WDT_OFF & _XT_OSC




;***********************************************
; VARIABLEN


schleife equ 0x20
schleife2 equ 0x21
schleife3 equ 0x22
Daten equ 0x23
count equ 0x24
count2 equ 0x25


#define RS PORTA, 0
#define RW PORTA, 1
#define E1 PORTA, 2
#define E2 PORTA, 3






;***********************
;Initialisierung

Init

bsf STATUS, RP0
movlw B'00000000'
movwf TRISA
movwf TRISB
bcf STATUS, RP0
clrf PORTA
clrf PORTB



;****************************
;LCD Initialisierung

LCD_Init


movlw 0x30
movwf Daten
movlw D'15' ; 15 ms
movwf count
call Wait_ms
call LCD_write_conf ; 30h ins Steuerregister
movlw D'5' ; 5 ms
movwf count
call Wait_ms
call LCD_write_conf ; 30h ins Steuerregister
call Wait_us ; 100 us
call LCD_write_conf ; 30h ins Steuerregister


movlw 0x30 ; System Set, eine Zeile
movwf Daten
call LCD_write_conf
movlw B'00001000' ; LCD off
movwf Daten
call LCD_write_conf
movlw B'00000001' ; LCD clear
movwf Daten
call LCD_write_conf
movlw B'00000110' ; Entry mode set
movwf Daten
call LCD_write_conf
movlw B'00001101' ; LCD on
movwf Daten
call LCD_write_conf

;************************************************* *
; TEST, sende den Buchstaben A zum LCD

movlw B'00110000'
movwf Daten
call LCD_write


Main
goto Main


;************************************************* ************
LCD_write_conf

bcf RS ; RS=0 --> Steuerregister
bcf RW ; RW=0 --> Schreiben
nop
bsf E1
nop
movf Daten, w
movwf PORTB
nop
bcf E1 ; fallende Flanke von E
nop
return


;************************************************* *****************
LCD_write

call Wait_us
call Wait_us
bsf RS
bcf RW
nop
bsf E1
nop
movlw Daten
movwf PORTB
nop
bcf E1
nop
return









;************************************************* *******
;Warteschleife

Wait_ms
movf count, 0
movwf schleife

Wait2
movlw .110 ; Konstante
movwf schleife2

Wait3
nop
nop
nop
nop
nop
nop ;
nop ;
decfsz schleife2, F ;
goto Wait3 ;

decfsz schleife, F
goto Wait2
return

;************************************************* **************
; Warteschleife 100us



Wait_us
movlw .25 ; Konstante
movwf schleife2

Wait_us2

nop
nop ;
nop ;
decfsz schleife2, F ;
goto Wait_us2 ;
return

end

Wenn ich den Saft einschalte dann seh ich manchmal einen Cursor und anschliessend ein Rautezeichen in der ersten Zeile, manchmal tauchen die Zeichen aber an anderen Stellen auf nicht immer am Anfang. Jedoch immer in der ersten Zeile.
Nach mehrmaliger Betätigung des Reset-Tasters sehe ich verschiedene Resultate und der Cursor springt, anscheinend zufällig in der ersten Zeile rum.

Kann es sein, dass in meinem Code das Timing nicht stimmt?
Könnte das jemand nachprüfen ( ob die Verzögerungsschleifen richtig gebaut sind? )

mfg und thx

stowoda
25.08.2005, 13:12
Endlich habe ich alles in den Griff bekommen! :)

Habe nun alle "Bugs" gefunden und bin nun in der Lage Zeichen auf dem LCD anzeigen zu lassen. Nach Tagen... ](*,)

Hier der neue CODE:

list p=16f84a

;************************************************* ******************************
;* PIN Belegung
;*
;* PORTA: 0 - RS
;* 1 - RW
;* 2 - E1
;* 3 - TEST LED
;*
;* PORTB: 0..7 - D0..D7
;*
;************************************************* ******************************
;************************************************* ******************************

#include <p16f84a.inc>


;************************************************* ******************************
;* Config

__CONFIG _PWRTE_ON & _WDT_OFF & _XT_OSC



;************************************************* *****************************
; Variablen

count equ 0x20
time equ 0x21
confg equ 0x22
daten equ 0x23
flag equ 0x24

; Konstanten

#define RS PORTA, 0
#define RW PORTA, 1
#define E1 PORTA, 2
#define LED PORTA, 3



;_________________________________________________ ____________________________
;************************************************* ****************************
; PROGRAMM START



;**************************
;* PIC Initialisierung *
;**************************

Init
bsf STATUS, RP0 ; Bank 1
movlw B'00000000' ; RA0 ..RA4 outputs
movwf TRISA ;
movlw B'00000000' ; PortB alle outputs
movwf TRISB
bcf STATUS, RP0 ; Bank 0
clrf PORTA
clrf PORTB



;**************************
;* LCD Initialisierung *
;**************************


InitLCD
movlw D'255' ; 250 ms Pause nach dem Einschalten
movwf time
call w_ms

movlw B'00110000'
movwf PORTB
bsf E1
nop
bcf E1

movlw .5 ; 5 ms Pause
movwf time
call w_ms
movlw B'00110000'
movwf PORTB
bsf E1
nop
bcf E1
movlw .20 ; 100 mikro sekunden warten
movwf time
call w_us
movlw B'00110000'
movwf PORTB
bsf E1
nop
bcf E1

movlw B'00110000' ; function set, 8-bit 2-zeilig, 5x7
call Lcd_set
movlw B'00001000' ; off
call Lcd_set
movlw B'00000110' ; entry mode, increment, cursr shift
call Lcd_set
movlw B'00000011' ; cursor home
call Lcd_set
movlw B'00001111' ; on
call Lcd_set
;**********************************************
;* Zeichen Test *
;* *
;* (test)!! *
;**********************************************


bsf LED
call w_ms
bcf LED


movlw '1'
movwf daten
call wrte

bsf LED
bcf LED

movlw '2'
movwf daten
call wrte


bsf LED
bcf LED

movlw '3'
movwf daten
call wrte


bsf LED
bcf LED

movlw '4'
movwf daten
call wrte

bsf LED
bcf LED

movlw '5'
movwf daten
call wrte

bsf LED
bcf LED

noend
goto noend
;************************************
;* LCD Config (write) *
;* Steuerbefehle ausführen *
;************************************

Lcd_set ; OK
movwf confg
call BusyFlag ; !! RS RW = 0 zu dem Zeitpunkt !!
movf confg, w
movwf PORTB ; Daten schreiben
bsf E1
nop
bcf E1 ; Disable LcdBus
return
;***********************************
;* LCD Ausgabe *
;* Zeichen ausgeben *
;***********************************


wrte
bsf LED ; Test LED on
movwf daten
call BusyFlag
movf daten, w
movwf PORTB ; Daten schreiben
bsf RS ; Daten
bsf E1 ; Enable LcdBus
nop
bcf E1 ; Disable LcdBus
bcf RS ;
bcf LED ; Test LED off
return
;**************************
;* CHCK BusyFlag *
;**************************

BusyFlag
bsf LED ; Test LED on
bsf STATUS, RP0 ; make Port B0..7 input
movlw B'11111111'
movwf TRISB
bcf STATUS, RP0

BusyLoop
bcf RS
bsf RW ; LESEN
bsf E1
nop
movf PORTB, w
movwf flag
bcf E1
nop
bsf E1 ; Enable
nop
bcf E1
btfsc flag, 7 ; teste bit 7
goto BusyLoop
bcf RW
bsf STATUS, RP0 ; make Port B4..7 output
movlw B'00000000'
andwf TRISB, f
bcf STATUS, RP0
bcf LED ; Test LED off
return
;*************************
;* Warteschleife µs *
;*************************

w_us

loop nop
nop
decfsz time, f
goto loop
return
;*************************
;* Warteschleife ms *
;*************************

w_ms

movlw .112
movwf count

loop_ms nop
nop
nop
nop
nop
nop
decfsz count, f
goto loop_ms

decfsz time, f
goto w_ms
return




end

falls es jemandem irgendwie weiterhelfen sollte...

Gruß

Lukas