Forum: Mikrocontroller und Digitale Elektronik LCD mit PIC ansteuern 2 Zeile


von Mario Horvat (Gast)


Lesenswert?

Halloo Leute
ich verzweifle... wie kann ich eine etwas in die 2 Zeile meines Displays 
ausgeben.

Folgendes: Dieses Programm schreibt mir XiMiX nur ich will das in der 2 
Zeile zugleich EISTEE steht.... bitte um Hilfe

  list p=16f84


  #include <P16f84.INC>

  ERRORLEVEL      -302





loops    equ  0x20  ; Wartezeit für WAIT in Millisekunden
loops2    equ  0x21  ; interner timer für wait
LcdStatus  equ  0x22  ; Puffer für aus dem LCD ausgelesenes Statusbyte
LcdDaten  equ  0x23  ; Puffer für zum LCD zu schreibendes Byte
LcdDaten1  equ  0x4F
Taste    equ  0x24  ; Tastaturpuffer



#define  LcdE  PORTB,0    ; enable Lcd
#define  LcdRw  PORTB,3    ; read Lcd
#define  LcdRs  PORTB,2    ; Daten Lcd (nicht control)
#define LcdPort PORTB    ; Datenbus des LCD (obere 4 Bit)
; für Tastatur-Anschluß
#define  KRow1  PORTB,1    ;Keyboard 1 4 7 *
#define  KRow2  PORTB,2    ;Keyboard 2 5 8 0
#define  KRow3  PORTB,3    ;Keyboard 3 6 9 #
#define  KLine1  PORTB,4    ;Keyboard 1 2 3
#define  KLine2  PORTB,5    ;Keyboard 4 5 6
#define  KLine3  PORTB,6    ;Keyboard 7 8 9
#define  KLine4  PORTB,7    ;Keyboard * 0 #


Ini_con Equ  B'00000000'  ; Interupt disable
Ini_opt  Equ  B'00000010'  ; pull-up


;********************************************************
; Das Programm beginnt mit der Initialisierung

Init  bsf     STATUS, RP0  ; Bank 1
  movlw   Ini_opt       ; pull-up Wiederstände ein
  movwf   OPTION_REG
  movlw  B'00000000'  ; PortB alle outputs
  movwf  TRISB
  bcf     STATUS, RP0  ; Bank 0
  clrf  PORTB
  movlw   Ini_con       ; Interupt disable
  movwf   INTCON

;Display initialisieren
  call  InitLcd

mainloop
  call  Tastfrei  ; darauf warten, das keine Taste gedrückt ist
;  call  WAIT    ; entprellen nur bei schlechten Tasten nötig

drueck
  call  Tastatur  ; wird nun eine Taste gedrückt?
  movfw  Taste    ; Tastencode nach w; Taste=0 dann Z=1
  btfsc  STATUS, Z  ; skip wenn Taste<>0
  goto  drueck    ; Tastencode=0 d.h. keine Taste gedrückt, weiter 
warten

  call  OutLcdDaten  ; Tastencode am LCD ausgeben
  goto  mainloop  ; auf ein neues



;*****************************************************
;+++LCD-Routinen**************************************
;*****************************************************
;LCD initialisieren in 9 Schritten, Begrüßung ausgeben

InitLcd
  movlw  D'255'    ; 250 ms Pause nach dem Einschalten
  movwf  loops
  call  WAIT

  movlw  B'00110000'  ; 1
  movwf  LcdPort
  bsf  LcdE
  nop
  bcf  LcdE

  movlw  D'50'    ; 50 ms Pause
  movwf  loops
  call  WAIT

  movlw  B'00110000'  ; 2
  call  Control8Bit
  movlw  B'00110000'  ; 3
  call   Control8Bit
  movlw  B'00100000'  ; 4
  call   Control8Bit

  movlw  B'00000001'  ; löschen und cusor home
  call  OutLcdControl
  movlw  B'00101000'  ; 5 function set, 4-bit  2-zeilig,  5x7
  call  OutLcdControl
  movlw  B'00001000'  ; 6 display off
  call  OutLcdControl
  movlw  B'00000110'  ; 7 entry mode, increment, disable display-shift
  call  OutLcdControl
  movlw  B'00000011'  ; 8 cursor home, cursor home
  call  OutLcdControl
  movlw  B'00001111'  ; 9 display on
  call  OutLcdControl

  movlw  'X'    ; 'XiMiX:' ausgeben
  call  OutLcdDaten
  movlw  'i'
  call  OutLcdDaten
  movlw  'M'
  call  OutLcdDaten
  movlw  'i'
  call  OutLcdDaten
  movlw  'X'
  call  OutLcdDaten


  movlw  'E'    ; 'EISTEE:' ausgeben
  call  OutLcdDaten
  movlw  'I'
  call  OutLcdDaten
  movlw  'S'
  call  OutLcdDaten
  movlw  'T'
  call  OutLcdDaten
  movlw  'E'
  call  OutLcdDaten
  movlw  'E'
  call  OutLcdDaten


  return

;*****************************************************
; ein Steuerbyte aus W 8-bittig übertragen
Control8Bit
  movwf  LcdPort
  bsf  LcdE
  nop
  bcf  LcdE
  movlw  D'10'
  movwf  loops
  call   WAIT
  return

;*****************************************************
; darauf warten, daß das Display bereit zur Datenannahme ist
; dazu wird das busy-Bit des LCD abgefragt
LcdBusy
        bsf     STATUS, RP0  ; make Port B4..7 input
  movlw  B'11110000'
  iorwf   TRISB, f
        bcf     STATUS, RP0
BusyLoop
  bcf  LcdRs    ; Steuerregister
  bsf  LcdRw    ; Lesen
  bsf  LcdE
  nop
  movf  LcdPort, w  ; 4 obere Bits lesen (D7..D4)
  movwf  LcdStatus  ; und in LcdStatus speichern
  bcf  LcdE
  nop
  bsf  LcdE
  nop      ; 4 untere Bits lesen (D3..D0) und ignorieren
  bcf  LcdE
  btfsc  LcdStatus, 7  ; teste bit 7
  goto  BusyLoop
  bcf  LcdRw
        bsf     STATUS, RP0  ; make Port B4..7 output
  movlw  B'00001111'
  andwf   TRISB, f
        bcf     STATUS, RP0
  return

;*****************************************************
; aus W ein Byte mit Steuerdaten zum Display übertragen
OutLcdControl
  movwf  LcdDaten  ; Byte in LcdDaten zwischenspeichern
  call  LcdBusy    ; warten bis Display bereit ist
  movf  LcdDaten, w  ; Byte zurück nach W holen
  andlw  H'F0'    ; low-Teil löschen
  movwf  LcdPort    ; Hi-teil Daten schreiben
  bsf  LcdE
  nop
  bcf  LcdE    ; Disable LcdBus
  swapf  LcdDaten, w  ; Byte verdreht nach W holen
  andlw  H'F0'    ; High Teil löschen
  movwf  LcdPort    ; Low-teil Daten schreiben
  bsf  LcdE
  nop
  bcf  LcdE    ; Disable LcdBus
  return

;*****************************************************
; aus W ein Datenbyte (zum Anzeigen) an's Display übertragen
OutLcdDaten
  movwf  LcdDaten  ; Byte in LcdDaten zwischenspeichern
  call  LcdBusy    ; warten bis Display bereit ist
  movf  LcdDaten, w  ; Byte zurück nach W holen
  andlw  H'F0'    ; low-Teil löschen
  movwf  LcdPort    ; Hi-teil Daten schreiben
  bsf  LcdRs    ; Daten
  bsf  LcdE    ; Enable LcdBus
  nop
  bcf  LcdE    ; Disable LcdBus
  swapf  LcdDaten, w  ; Byte verdreht nach W holen
  andlw  H'F0'    ; High Teil löschen
  movwf  LcdPort    ; Low-teil Daten schreiben
  bsf  LcdRs    ; Daten
  bsf  LcdE
  nop
  bcf  LcdE    ; Disable LcdBus
  bcf  LcdRs    ;
  return


;*****************************************************
;+++Tastatur-Routinen*********************************
;*****************************************************
; warten darauf, daß keine Taste mehr gedrückt ist

Tastfrei      ; Warten auf freie Tastatur
  call  Tastatur  ; Tastencode nach Taste & W
  movfw  Taste    ; wenn code=0 dann Z=1
  btfss  STATUS, Z  ; wenn Z=1 dann skip
  goto  Tastfrei  ; weiter warten
  return      ; Tastatur ist frei

;*****************************************************
; ist eine Taste gedrückt? und welche?
; der Tastencode wird in W und Taste gespeichert (ASCII)
; wenn keine Taste gedrückt wurde, wird 0 zurückgegeben
;
; zur Erinnerung liste ich noch mal die weiter oben aufgeführten
; Definitionen auf
; mit denen ist festgelegt, an welche Pins des PortB die einzelnen
; Spalten und Zeilen der Tastatur abgeschlossen sind

;#define  KRow1  PORTB,1    ;Keyboard 1 4 7 *
;#define  KRow2  PORTB,2    ;Keyboard 2 5 8 0
;#define  KRow3  PORTB,3    ;Keyboard 3 6 9 #
;#define  KLine1  PORTB,4    ;Keyboard 1 2 3
;#define  KLine2  PORTB,5    ;Keyboard 4 5 6
;#define  KLine3  PORTB,6    ;Keyboard 7 8 9
;#define  KLine4  PORTB,7    ;Keyboard * 0 #

Tastatur
  ; zuerst müssen die Tastaturzeilen-Pins auf Eingang gestellt werden
  bsf     STATUS, RP0  ; Bank 1
  movlw   Ini_opt       ; pull-up Widerstände ein
  movwf   OPTION_REG
  movlw  B'11110000'  ; RB0 .. RB3 output, RB4 .. RB7 input
  movwf  TRISB
  bcf     STATUS, RP0  ; Bank 0

  ; das Enable-Pin des Displays muß auf Low stehen, damit das Display
  ; abgeschaltet ist solange wir die Tastatur abfragen
  clrf  PORTB    ; Display inaktiv am Bus

  ; w wird auf 0 gesetzt, dieser Wert wird durch ein ASSCI-Zeichen
  ; überschrieben, falls eine Taste gedrückt ist
  ; falls keine Taste gedrückt ist, bleibt 0 erhalten
  movlw  0    ; W=0

  bcf  KRow1    ; 1. spalte aktivieren
  bsf  KRow3
  bsf  KRow2

  call  key1    ; 1. Spalte abfragen

  bcf  KRow2    ; 2.Spalte aktivieren
  bsf  KRow1    ; 1.Spalte ausschalten

  call  key2    ; 2. Spalte

  bcf  KRow3    ; 3. Spalte aktivieren
  bsf  KRow2    ; 2. spalte ausschalten

  call  key3    ; 3. Spalte

  bsf  KRow3    ; 3. Spalte ausschalten
  movwf  Taste

  ; PortB wieder komplett zu Output machen
  bsf     STATUS, RP0  ; Bank 1
  movlw  B'00000000'  ; RB1 .. RB7 output
  movwf  TRISB
  bcf     STATUS, RP0  ; Bank 0
  return

key1
  btfss  KLine1
  retlw  '1'
  btfss  KLine2
  retlw  '4'
  btfss  KLine3
  retlw  '7'
  btfss  KLine4
  retlw  '*'
  return
key2
  btfss  KLine1
  retlw  '2'
  btfss  KLine2
  retlw  '5'
  btfss  KLine3
  retlw  '8'
  btfss  KLine4
  retlw  '0'
  return
key3
  btfss  KLine1
  retlw  '3'
  btfss  KLine2
  retlw  '6'
  btfss  KLine3
  retlw  '9'
  btfss  KLine4
  retlw  '#'
  return


;*****************************************************************
;Zeitverzögerung um loops * 1 ms *********************************
;*****************************************************************
; universelle Warteschleife, sowas braucht man öfter
; z.B. für die LCD-Initialisierung
; in loops wird die Wartezeit in Millisekunden übergeben
;
; 10 MHz externer Takt bedeutet 2,5 MHz interner Takt
; also dauert 1 ms genau 2500 Befehle
; 250 Schleifen a 10 Befehle sind 2500 Befehle = 1 ms

WAIT
top     movlw   .250           ; timing adjustment variable (1ms)
        movwf   loops2
top2    nop                    ; warten und nichts tun
        nop
        nop
        nop
  nop
        nop
        nop
        decfsz  loops2, F      ; innere Schleife fertig?
        goto    top2           ; nein, noch mal rum
                               ;
        decfsz  loops, F       ; äußere Schleife fertig?
        goto    top            ; nein, noch mal rum
        retlw   0              ; FERTIG und return


  end

von Oliver J. (skriptkiddy)


Lesenswert?

Den DDRAM-Adress-Zeiger vor der Ausgabe von "EISTEE" auf die 2.Zeile 
setzen und es sollte funktionieren.

Gruß Skriptkiddy

von Spess53 (Gast)


Lesenswert?

Hi

Die 2.Zeile fängt bei den Meisten Displays auf der Adresse $40 an. Also 
nach der ersten Zeile DDRAM auf $40 setzen.

MfG Spess

von Mario Horvat (Gast)


Lesenswert?

dankeschön jungs
lg mariooo

von Mario Horvat (Gast)


Lesenswert?

ich verstehe nur nicht wie ich das auf diese Adresse setzte....

könntets ihr mir vl. eine Zeile vorschreiben
bittee

von Spess53 (Gast)


Lesenswert?

HI

>könntets ihr mir vl. eine Zeile vorschreiben

Ich kenne zwar PICs nicht, aber das sollte passen:

  movlw  B'11000000'
  call  Control8Bit

MfG Spess

von PIC N. (eigo) Benutzerseite


Lesenswert?

Wenn der Controller ein HD44780 ist, dann schick 0xC0 als Befehl und 
dein Wunsch geht in Erfüllung =)

von Oliver J. (skriptkiddy)


Lesenswert?

Im Datenbaltt des hd44780-Controllers steht wie ein Kommando zum setzen 
des DDRAM-Pointers auszusehen hat.
Ein Bisschen selber machen schadet ja nicht.

Ulrich Radig hat mal ne schöne Zusammenfassung [1] gerschrieben. Da 
steht alles drinne, was für die Charakter-LCDs wichtig ist.


[1] http://www.ulrichradig.de/home/uploads/File/AVR_LCD/LC.pdf


Gruß Skriptkiddy

von Klaus W. (mfgkw)


Lesenswert?

Skript Kiddy schrieb:
> Ulrich Radig hat mal ne schöne Zusammenfassung [1] gerschrieben. Da
> steht alles drinne, was für die Charakter-LCDs wichtig ist.
>
>
> [1] http://www.ulrichradig.de/home/uploads/File/AVR_LCD/LC.pdf

Ah, jetzt weiß ich endlich, warum hier soviele Leute "Standart" 
schreiben :-)

von Mario Horvat (Gast)


Lesenswert?

hy ich verzweifle,
habe 3stunden alles probiert nur...
ich bringe es nicht zam etwas in der 2 zeile darzustellen....
bitte um hilfee
dankee

von Klaus W. (mfgkw)


Lesenswert?

Im Datenblatt mal schauen, an welcher Adresse die zweite Zeile beginnt?

von Karl H. (kbuchegg)


Lesenswert?

Spess53 schrieb:
> HI
>
>>könntets ihr mir vl. eine Zeile vorschreiben
>
> Ich kenne zwar PICs nicht, aber das sollte passen:
>
>   movlw  B'11000000'
>   call  Control8Bit
>


Hmm.
SOllte da nicht ein Aufruf von

  movlw  B'11000000'
  call  OutLcdControl

sein?


Control8Bit wird laut Initialisierung verwendet, wenn das LCD noch nicht 
durch die Initialisierung durch ist. Nachdem es auf 4 BIt umgeschaltet 
wurde, wird nur noch OutLcdControl verwendet

von Oliver J. (skriptkiddy)


Lesenswert?

Karl heinz Buchegger schrieb:
> Hmm.
> SOllte da nicht ein Aufruf von
>
>   movlw  B'11000000'
>   call  OutLcdControl
>
> sein?

Würde ich auch sagen.

von Mario Horvat (Gast)


Lesenswert?

die 2 Zeile beginnt bei 40 bis 4F

von Mario Horvat (Gast)


Lesenswert?

dankee leutee ich habs gschafft :D

von Maik W. (werner01)


Lesenswert?

zieh Dir mal den Stoff hier rein ist echt gut. 
http://www.sprut.de/electronic/lcd/index.htm#2x16

Spess hat ja schon richtig gesagt '11000000' mußt Du an dein Display als
Kommando senden nicht als Daten .Man beachte also die RS-Leitung glaube 
ich.

lcd_command    MOVWF  command

        movF  command,0
        andlw  b'11110000'
        iorwf  PORTB,1

        CALL  lcd_enable

        swapf  command,0
        andlw  b'11110000'
        iorwf  PORTB,1

        CALL  lcd_enable
        call  wait_2ms

        RETLW  0

lcd_enable
        nop
        BSF    PORTB,3
        nop
        nop
        nop
        nop
        nop
        nop
        BCF    PORTB,3
        nop
        nop
        nop
        clrf  PORTB
        RETLW  0

Kannst Dir ja mal meinen Cod anschauen ,vieleicht bringts was!

von Klaus W. (mfgkw)


Lesenswert?

Spess53 schrieb:
> HI
>
>>könntets ihr mir vl. eine Zeile vorschreiben
>
> Ich kenne zwar PICs nicht, aber das sollte passen:
>
>   movlw  B'11000000'
>   call  Control8Bit
>
> MfG Spess

Ich habe von PIC mindestens noch weniger Ahnung, aber
wenn ich mir den Quelltext anschaue, dann eher OutLcdControl
als Control8Bit (OutLcdControl überträgt nibbleweise, Control8Bit
byteweise).

von Mario Horvat (Gast)


Lesenswert?

Dankee an euch allee
lg Mario

von Klaus W. (mfgkw)


Lesenswert?

Mario Horvat schrieb:
> dankee leutee ich habs gschafft :D

na toll, und dafür habe ich versucht nachzudenken :-)

Was wars?

von Karl H. (kbuchegg)


Lesenswert?

Klaus Wachtler schrieb:
> Spess53 schrieb:
>> HI
>>
>>>könntets ihr mir vl. eine Zeile vorschreiben
>>
>> Ich kenne zwar PICs nicht, aber das sollte passen:
>>
>>   movlw  B'11000000'
>>   call  Control8Bit
>>
>> MfG Spess
>
> Ich habe von PIC mindestens noch weniger Ahnung,

Gehts dir wie mir :-)

> aber
> wenn ich mir den Quelltext anschaue, dann eher OutLcdControl
> als Control8Bit (OutLcdControl überträgt nibbleweise, Control8Bit
> byteweise).

Find ich immer wieder faszinierend, wenn Programmierer ihre eigenen 
Funktionen nicht kennen. Oder sollte er am Ende gar nicht ....

von Klaus W. (mfgkw)


Lesenswert?

Karl heinz Buchegger schrieb:
> call  OutLcdControl

Mist, wieso ist der wieder schneller?

von Klaus W. (mfgkw)


Lesenswert?

Karl heinz Buchegger schrieb:
> Oder sollte er am Ende gar nicht ....

Ganz deiner Meinung.

von Mario Horvat (Gast)


Lesenswert?

ich hab statt
movlw  B'11000000'
call  Control8Bit
geschrieben statt

movlw  B'11000000'
call  OutLcdControl

von Klaus W. (mfgkw)


Lesenswert?

Damit ist KHB der PIC-König?

von Karl H. (kbuchegg)


Lesenswert?

Klaus Wachtler schrieb:
> Karl heinz Buchegger schrieb:
>> call  OutLcdControl
>
> Mist, wieso ist der wieder schneller?

Bin doch grad erst online gekommen!


@TO
Mich hat der 8-er in Control8Bit stutzig gemacht, also hab ich 
hochgescrollt. Der Rest war reine Logik und programmieren durch 
'vorhandenen Code ansehen' und 'vergleichende Verhaltensfor... ääääh 
Programmierung'. Funktioniert meistens ganz gut, sich einfach mal 
ansehen, wie an anderen Stellen im Code Commandos gesendet werden. Und 
dann 2 und 2 zusammenzählen.

von Karl H. (kbuchegg)


Lesenswert?

Mario Horvat schrieb:
> ich hab statt
> movlw  B'11000000'
> call  Control8Bit
> geschrieben statt
>
> movlw  B'11000000'
> call  OutLcdControl

Wahnsinn, Und da bist du 3 Stunden lang nicht draufgekommen, dass du den 
falschen Call hast? Respekt.

von Mario Horvat (Gast)


Lesenswert?

jaa keine ahnung...
bin noch Schüler, und sowas haben wir bis jz. noch nie gemacht...

von Spess53 (Gast)


Lesenswert?

Hi

>>Karl heinz Buchegger schrieb:
>> Hmm.
>> SOllte da nicht ein Aufruf von
>>
>>   movlw  B'11000000'
>>   call  OutLcdControl
>>
>> sein?

>Würde ich auch sagen.

Ich jetzt auch. War die falsche Stelle aus der ich die Zeilen kopiert 
hatte.
Zumindest hat es, dank aufmerksamer Mitleser, etwas zur Lösung 
beigetragen.

MfG Spess

von Klaus W. (mfgkw)


Lesenswert?

War bestimmt Absicht, damit der TO auch etwas mitdenkt :-)

von Spess53 (Gast)


Lesenswert?

Hi

>War bestimmt Absicht, damit der TO auch etwas mitdenkt :-)

Eher Mitleid.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

Mario Horvat schrieb:
> jaa keine ahnung...
> bin noch Schüler, und sowas haben wir bis jz. noch nie gemacht...

Darum gehts eigentlich gar nicht.
Klar, man übernimmt schon mal Code.
Was aber in der Programmierung gar nicht geht: Code übernehmen, ohn ihn 
sich nicht wenigstens einmal anzusehen.
Und wo Code ungeschaut zu übernehmen überhaupt nicht geht, das ist in 
der Assembler-Programmierung. Du musst wissen welche Funktionen du 
übernimmst, was sie machen und welche Register sie verwenden.
Abschreiben, so wie man eine Mathe-Hausaufgabe abschreiben kann, führt 
gerade in der Assembler-Programmierung unweigerlich ins Desaster.
Oder eben so wie bei dir: zu 3 verlorenen Stunden

von Klaus W. (mfgkw)


Lesenswert?

Wenn er was gelernt hat, war es doch nicht verloren, zumindest nicht für 
ihn.

Du bist doch sonst so geduldig?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.