PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Display Probleme



skywalker1979
13.02.2007, 12:57
Hallo Leute

Programmiere gerade nen PIC16F876A und hab probleme mit der Displayansteuerung. Das RS-Pin wird gesetzt, aber sobald das Enable-Pin gesetzt wird, wird sofort das RS-Pin wieder gelöscht. Hab keine Idee woran es liegt (Betriebsblind). mit der Initialisierung klappt es ja, aber es zeigt einfach kein Text an.


;************************************************* *************
;*
;* Pinbelegung
;* ----------------------------------
;* PORTA: 0
;* 1
;* 2 E LC-Display
;* 3 RS LC-Display
;* 4
;* 5
;*
;* PORTB: 0 D0 LC-Display
;* 1 D1 LC-Display
;* 2 D2 LC-Display
;* 3 D3 LC-Display
;* 4 D4 LC-Display
;* 5 D5 LC-Display
;* 6 D6 LC-Display
;* 7 D7 LC-Display
;*
;* PORTC: 0
;* 1
;* 2
;* 3
;* 4
;* 5
;* 6
;* 7
;*
;************************************************* *************
;
; Prozessortakt: 8 MHz
; Eingangsspannung: 0V ... 5V (Vss ... Vdd)
;
;************************************************* *************
; Includedatei für den 16F876 einbinden

list p=16f876
#include <P16f876A.INC>

ERRORLEVEL -302 ;SUPPRESS BANK SELECTION MESSAGES

__CONFIG _CP_OFF&_WRT_OFF&_CPD_OFF&_LVP_OFF&_BODEN_OFF&_PWRTE_ON&_WDT_OFF&_HS_OSC

;************************************************* *********

; Variablen

loops equ 0x20
loops2 equ 0x21
ZWISCH0 equ 0x22

;Konstanten

LCDD equ PORTB ; LCD-Daten-Port
LcdE equ 2 ; enable Lcd
LcdRS equ 3 ; Daten Lcd (nicht control)

; Anfangsinitialisierung

init

BSF STATUS,RP0 ; Bank1
movlw b'00000000'
movwf TRISA
movlw b'00000000'
movwf TRISB
movlw b'00000000'
movwf TRISB
BCF STATUS,RP0 ; Bank 0
call lcdinit

;************************************************* *********
; Hauptprogrammschleife

Main

call anz

goto Main
;************************************************* *********
; Warteschleifen 1ms, 10ms, 15ms, 100ms, 250ms
;************************************************* *********
; Warteschleife 1 ms
wait1
movlw D'1' ; 1 ms Pause
movwf loops
goto wai

;************************************************* *********
; Warteschleife 10 ms
wait10
movlw D'10' ; 10 ms Pause
movwf loops
goto wai

;************************************************* *********
; Warteschleife 15 ms
wait15
movlw D'15' ; 15 ms Pause
movwf loops
goto wai

;************************************************* *********
; Warteschleife 250 ms
wait250
movlw D'250' ; 100 ms Pause
movwf loops
goto wai

wai
movlw .221 ; Zeitkonstante für 1ms
movwf loops2
wai2 nop
nop
nop
nop
nop
nop
decfsz loops2, F ; 1 ms vorbei?
goto wai2 ; nein, noch nicht
;
decfsz loops, F ; 250 ms vorbei?
goto wai ; nein, noch nicht
return ; das Warten hat ein Ende

;************************************************* *********************************************
; Vorbereitung des LCD: Portdefinition und Initialisierung ; RS = RA.3, E = RA.4
;************************************************* *********************************************
lcdinit
call wait15
bcf PORTA,LcdRS ; RS = 0: Steuerwort fuer Befehl schreiben
movlw 01 ; Anweisung fuer Loeschen
call ausgd
movlw 02 ; Anweisung fuer: Display Ein, Cursor Aus
call ausgd
movlw 06 ; Anweisung fuer: Adresse erhoehen, nicht schieben,
call ausgd
movlw 38 ; Anweisung fuer: 8 bit-Worte, 2 Zeilen
call ausgd ; und Zeichenformat 5 x 7 Pixel
return
;************************************************* *********************************************
; Ausgaberoutine fuer das LCD-Modul: Gibt Befehle bzw. Daten am LCD-Modul aus
;************************************************* *********************************************
ausg
movwf LCDD
bsf PORTA,LcdRS
bsf PORTA,LcdE
call wait10
bcf PORTA,LcdE
call wait10
bcf PORTA,LcdRS
return

ausgd
movwf LCDD
call wait10
bcf PORTA,LcdRS
bsf PORTA,LcdE
call wait1
bcf PORTA,LcdE
call wait10
return
;************************************************* *********************************************
; LCD-Anzeige vorbereiten
;************************************************* *********************************************
zeile1
movlw 80
movwf ZWISCH0
goto einf

zeile2
movlw 0C0
movwf ZWISCH0
goto einf

einf
movfw ZWISCH0 ; LCD-Adresse:
call ausgd
bsf PORTA,LcdRS
return

;************************************************* *********

anzaus
bcf PORTA,LcdRS
movlw 08
call ausgd
return

;************************************************* *********

anzein
bcf PORTA,LcdRS
movlw 0C
call ausgd
return

;************************************************* *********

anz
call zeile1
movlw 'H'
call ausg
movlw 'a'
call ausg
movlw 'l'
call ausg
movlw 'l'
call ausg
movlw 'o'
call ausg
call wait250
return


end

;************************************************* *********


Danke für eure hilfe!

Skywalker

SIGINT
13.02.2007, 16:49
Hi skywalker,
ich hab zwar lange nichtsmehr mit den PICs gemacht, aber war da nicht was mit "Read,Modify,Write" bei den bcf und bsf Befehlen??
Es kann sein, das bei "bsf PORTA,LcdE" in ausg der RS Eingang als LOW gelesen wird und deshalb zurückgesetzt wird... sollte aber eigentlich nicht möglich sein, da du zuvor ja ein HIGH ausgegeben hast. (vielleicht ist irgendwas mit deiner Schaltung aber nicht OK... mess mal die Spannung am PIN)

Gruß,
SIGINT

kalledom
13.02.2007, 16:54
Hallo,
was mir auf Anhieb auffällt, daß die beiden Subroutinen 'ausg' und 'ausgd' unterschiedlich sind, obwohl beide bis auf das Setzen / Rücksetzen von 'LcdRS' gleich sein müßten.
Warum wartest Du 2 mal 10 ms ? Es müßte doch 1 mal 10ms zwischen der Zeichenausgabe reichen und 1 ms zwischen Enable.
Dann ist mir nicht klar, warum 'LcdRS' auch noch an anderen Stellen im Programm gesetzt / gelöscht wird. Ist dieses Bit nicht für die Umschaltung zwischen Control und Data ?

Andre_S
13.02.2007, 22:10
Hallo Leute

Programmiere gerade nen PIC16F876A und hab probleme mit der Displayansteuerung. Das RS-Pin wird gesetzt, aber sobald das Enable-Pin gesetzt wird, wird sofort das RS-Pin wieder gelöscht. Hab keine Idee woran es liegt (Betriebsblind). mit der Initialisierung klappt es ja, aber es zeigt einfach kein Text an.

[Danke für eure hilfe!

Skywalker

Hallo,

äh, wieso bist Du so sicher, dass Deine Initialisierungsroutine so funktioniert? Meine Initialisierungen sind alle anders, kenne aber Dein Display nicht.
Auch sind Deine Wartezeiten unnötig hoch, da könntest Du einiges reduzieren, auch bei der Init musst Du nicht bei allen so lang warten, bei der Aussgabe schon gar nicht. (Das aber nur nebenbei)
Hast Du ein R/W ? Du liest ja nicht, liegt das fest auf Low?

Wenn Du Dir bei der Initalisierung sicher bist, (Aber Vergleich das noch mal!) nimm doch mal Deinen "Zeilen-Adressierungsaufruf" weg (habe ich so nie gemacht, bin jetzt nicht sicher ob das so stimmen kann) und gib mal nur ein Zeichen aus.

Noch ein kleiner Link zur Hilfe,... speziell Init...
http://www.sprut.de/electronic/lcd/index.htm


Gruß André

Andre_S
14.02.2007, 08:17
Hallo skywalker1979!

Ich vermute, das Dein Fehler an Deiner Konstanten-Definition liegt. Du hast als LCDE den PCL und als LSDRS STATUS festgelegt. Es sollte aber (angeblich) so sein:

LcdE equ PORTA,2 ; enable Lcd
LcdRS equ PORTA,3 ; Daten Lcd (nicht control)

Weiter habe ich nicht analisiert, da ich immer nur bis zum ersten mir auffalenden Fehler suche.

MfG

sehe ich Programmtechnisch (soweit die Zuordnungen stimmen) nicht als Fehler,
dass mache ich aus so... (übersichtlicher)

Die Konstante LcdE ist 2 !

im Programm ist der Befehl dann:
bcf PORTA,LcdE
statt
bcf PORTA,2


Gruß André

@PICture
wieso löscht Du Deinen Beitrag plötzlich wieder..., dass irretiert doch bei darauf folgenden Antworten

skywalker1979
14.02.2007, 08:25
Hallo @ All

ich habe die Zeiten mit absicht unnötig hoch gemacht, damit ich auf dem Signal-Analyzer die gesendeten Daten auf dem ersten Blick sehe ohne un endlich weit rein zu Zoomen.

@PICture

hatte ich schon ausprobiert weil ich den Fehler dort auch vermutete aber wenn ich diese Ergänzung mache dann kommen Fehlermeldungen vom Assembler.

@Andre_S

hab ein bisschen Quellkode von Dieter Kohtz und von von Sprut "geklaut" und die haben fast die selbe Initialisierung! Außerdem, wen ich die schaltung in Betrieb nehme ist nicht mehr nur die obere Zeile Schwarz sondern es sind beide "Grau"! R/W ist fest auf Low!

Mfg

skywalker

Andre_S
14.02.2007, 09:45
Hallo @ All
...

@Andre_S

hab ein bisschen Quellkode von Dieter Kohtz und von von Sprut "geklaut" und die haben fast die selbe Initialisierung! Außerdem, wen ich die schaltung in Betrieb nehme ist nicht mehr nur die obere Zeile Schwarz sondern es sind beide "Grau"! R/W ist fest auf Low!

Mfg

skywalker

Was hast Du für ein Display

movlw 02 ; Anweisung fuer: Display Ein, Cursor Aus
call ausgd


02 -> schaltet bei mir Definitiv kein Display ein...


Gruß André

skywalker1979
14.02.2007, 10:48
YeHAAA!

Danke Andre!!

Hab die Initialisierung umgebastelt und schon funzt es!!!!!!

Mfg skywalker

PICture
15.02.2007, 09:05
Hallo Andre_S!

Sorry, aber ich habe festgestellt, dass meine Vermutung falsch war.

MfG

Andre_S
15.02.2007, 09:29
Hallo Andre_S!

Sorry, aber ich habe festgestellt, dass meine Vermutung falsch war.

MfG

Hallo,

Du kannst Dir ja eventuell mein verdutztes Gesicht vorstellen, als ich als nichts mehr da war,... einen Moment lang hatte ich gezweifelt... :-k


Gruß André

BMS
15.02.2007, 11:37
Hi

Wenn grad das Thema angesprochen wird - bei mir funktioniert das LCD auch nicht wirklich.
Ich hab das blaue LCD 1x16 vom Reichelt. Einen Adapter für LPT gelötet und entsprechendes Ansteuerungsprogramm geschrieben (mit BlitzPlus und lib). Das hat soweit ganz gut funktioniert :)

* Aber *
nun versuche ich, das ganze an mein BMS-Board2 anzuschließen. Als Controller verwende ich einen PIC16F74. Lässt sich programmieren, sonst ist auch alles ok. Zum Proggn verwende ich einen eigenen (Auch mit Blitz+) Compiler, der von einer Art Basic-Sprache zu ASM übersetzt. Das MPASM von Microchip mach daraus HEX und der PBrenner37 von sprut brennt das ganze in den PIC.

Das LCD wird im 4bit-modus angesteuert. Aus Layoutgründen musste ich die Pins:
RS = RC7
R/W = RC6
D4 = RC5
D5 = RC4
D6 = RD3
D7 = RD2
En = RD1
verwenden (ziemlich ungeschickt :( )
Auf der linken Hälfte des LCD sind Rechtecke zu sehen, so wie es sprut schreibt.

Und dazu kommt entsprechender Code (aus dem Header; auszugsweise):

Das ist die eigentliche Sendefunktion. Könnte da mal bitte einer drüber schauen? Kann das so funktionieren?


;LCD-Send-Funktion
;-----------------
;Bits in W: frei(nix),RS,frei(R/W),D4,D5,D6,D7,frei(En)
lcd_send
;Pins:
; RS = RC7
; (R/W = RC6)
; D4 = RC5
; D5 = RC4
; D6 = RD3
; D7 = RD2
; En = RD1
;Bits löschen, Enable erst mal auf high
bsf PORTD,1
bcf PORTC,7 ;RS
bcf PORTC,6 ;R/W [kann eigentlich immer auf >low< bleiben (lcd=slave), evtl auskommentieren :-)]
bcf PORTC,5 ;D4
bcf PORTC,4 ;D5
bcf PORTD,3 ;D6
bcf PORTD,2 ;D7
movwf lshelp ;sicherheitskopie
bcf W,3 ;bits maskieren
bcf W,2
bcf W,1
bcf W,0
iorwf PORTC,F ;Daten reinschreiben
movf lshelp,W ;sicherheitskopie abrufen
bcf W,7 ;bits maskieren
bcf W,6
bcf W,5
bcf W,4
bcf W,1
bcf W,0
iorwf PORTD,F ;Daten reinschreiben
nop
bcf PORTD,1 ;enable auf low -> lcd reagiert^^ (und leds auch)
call zykwait ;dem lcd ein bisschen zeit geben
bsf PORTD,1 ;enable auf high
return


Und dazu die entsprechende Initialisierung



lcd_init
;Bits: (frei), RS,(R/W),D4,D5,D6,D7,(Enable)
movlw B'00001000' ;4-bit mode
call lcd_send

movlw B'00001000' ;4-bit,2-zl,5x7-font
call lcd_send
movlw B'00000010' ;2.teil
call lcd_send

movlw B'00000000' ;display on, cursor on +blinken
call lcd_send
movlw B'00011110' ;2.teil
call lcd_send

movlw B'00000000' ;display löschen, cursor@home
call lcd_send
movlw B'00010000' ;2.teil
call lcd_send

movlw B'00000000' ;Auto-incr.
call lcd_send
movlw B'00001100' ;2.teil
return


Ach übrigens: es sind noch 4 leds+vorwiderstände an den datenleitungen angeschlossen.
Die Anoden der LEDs sind am Collector eines pnp-transistors angeschlossen, der bei En=LOW die leds ermöglicht (seltsamer satz^^ - wollte nicht nochmal enabled verwenden). Wenn eine Datenleitung auf low ist, leuchtet die entsprechende led.
-> vllt zieht die led das low-signal in den verbotenen ttl-bereich ???

Danke für jede Hilfe
Mit freundlichen Grüßen
BMS