Forum: Mikrocontroller und Digitale Elektronik LCD Display cursor adresse auslesen?


von Robert R. (mikrorobert)


Lesenswert?

Guten Tag!

Ich habe mir vor ein paar Wochen ein LCD-Display von Samsung mit einem 
KS0073 Controller bei Reichelt angeschafft welches ich im 4-bit modus 
mit 4 Zeilen und einem Atmega8 betreibe. Nach ein paar 
Startschwierigkeiten läuft jetzt alles einwandfrei und ich hab bis jetzt 
auch 2 testprogramme zum laufen bekommen.

Hier nun mein Problem:

ich habe eine art Ladefortschrittsbalken programmiert und ich möchte nun 
für jeden fortschritt den der balken in der ersten Zeile macht, eine 
Prozentzahl in der zweiten Zeile erhöhen.

Aber wie könnte man das am besten realisieren? Ich hatte nun vor nach 
jedem Zeichen des Balkens die Adresse des Cursors (sprich den address 
counter) auszulesen, in einem Register zu speichern, meine 
cursorposition für die prozentzahl zu verändern, und danach wieder an 
die gespeicherte adresse zurückzuspringen.

doch alles was ich im datenblatt dazu gefunden hab ist der "Read Data" 
bzw. "Busy Flag / Address Read" befehl. doch wie kann ich ihn in diesem 
Fall anwenden?? =(

könnt ihr mir da vllt helfen oder habt ihr vllt. auch einen noch 
besseren vorschlag zur lösung meines kleinen Problems?


hier das datenblatt:
http://docs.google.com/viewer?url=http%3A%2F%2Fwww.mikrocontroller.net%2Fattachment%2F53806%2Fks0073.pdf

von spess53 (Gast)


Lesenswert?

Hi

Dann hast du hoffentlich R/W vom Display am Controller angeschlossen. 
Sonst wird das nichts.

Wenn du den Befehl 'Read Busy Flag and Address' ausführst bekommst du in 
den unteren sieben Bits die DDRAM-Adresse. Bit 7 ist das Busy-Flag. 
Alternativ kannst du einfach im Programm die ausgegebenen Zeichen 
mitzählen oder den Balken komplett neu schreiben.

MfG Spess

von Robert R. (mikrorobert)


Lesenswert?

Hi spess53,

vielen dank erstmal für deine antwort!

den R/W Pin hab ich an PD7 angeschlossen ja.
kannst du mir vllt ein beispielscript hier posten damit ich sehen kann 
wie der ablauf aussehen würde?

bis jetzt hab ich ja immer nur

ldi   temp1, 0bxxxxxxxx
rcall lcd_command

benutzt. funktioniert das bei diesem befehl genauso? oder muss ich ihn 
irgendwie anders an das lcd senden?

und wie kann ich dann die ausgelesenen DDRAM adresse in ein register 
(bsp. temp5) speichern?

Gruß Robert

von Helfer (Gast)


Lesenswert?

Robert Richter schrieb:
> bis jetzt hab ich ja immer nur
>
> ldi   temp1, 0bxxxxxxxx
> rcall lcd_command
>
> benutzt. funktioniert das bei diesem befehl genauso? oder muss ich ihn
> irgendwie anders an das lcd senden?

Das wird dir die Dokumentation zur von dir verwendeten Bibliothek (oder 
ein Blick in den Source code) verraten. Welche verwendest du denn?

von Joachim (Gast)


Lesenswert?

Also bei deiner Anwendung würde ich einfach anders vorgehen :) .

Annahme: erste Zeile 20 Zeichen für Ladefortschrittsbalken, Zweite Zeile 
Prozentangabe.

Wenn du alle 20 Zeichen der oberen Zeile benutzt weißt du, daß ein 
Zeichen 5% entspricht. Jetzt kannst du doch pro 5% immer ein Zeichen 
mehr anmachen! Du brauchst doch die Cursorposition als Rückführgröße gar 
nicht. Oder willst du die Position regeln ;) ?!

Noch hübscher wird es, wenn du nicht Zeichen für Zeichen (also immer 
ganze Klötzchen) anmachst, sondern bei den einzelnen Klötzchen noch jede 
Spalte einzelnd...

Gruß

von Robert R. (mikrorobert)


Lesenswert?

Joachim schrieb:
> Noch hübscher wird es, wenn du nicht Zeichen für Zeichen (also immer
> ganze Klötzchen) anmachst, sondern bei den einzelnen Klötzchen noch jede
> Spalte einzelnd...


Genau so hab ichs auch programmiert! =)

nur wie gesagt, ich muss in die mitte der 2. oder auch 3. Zeile den 
Cursor verschieben und danach wieder zurück zur vorherigen position.
nur weiß ich immernoch nicht genau wie =(
ich bin noch nicht solange dabei wisst ihr?


Helfer schrieb:
> Das wird dir die Dokumentation zur von dir verwendeten Bibliothek (oder
> ein Blick in den Source code) verraten. Welche verwendest du denn?

wie meinst du das genau? mehr als die erklärung des Befehls habe ich da 
auch nicht entdeckt. oder lest ihr dort etwas was ich übersehen hab?

vielen dank nochmal das ihr mir helft!

von spess53 (Gast)


Lesenswert?

Hi

>wie meinst du das genau? mehr als die erklärung des Befehls habe ich da
>auch nicht entdeckt. oder lest ihr dort etwas was ich übersehen hab?

Wo sollen wir etwas gelesen haben? Niemand weiß, welche Software du 
benutzt.

MfG Spess

P.S. Welche Programmiersprache benutzt du?

von Robert R. (mikrorobert)


Lesenswert?

Oh tut mir leid!

Ich bin davon ausgegangen ihr habt das Datenblatt, welches ich ganz am 
anfang dazu postete, mal angeschaut. mein fehler.

ich benutze Assembler und flashe mit dem Programmer mysmartusb mkII und 
dem myAVR Workpad Plus.

von A.H. (Gast)


Lesenswert?

Ohne lcd_command zu kennen, schätze ich aber, dass du damit nicht weiter 
kommst. Das Senden eines Befehls erfordert mehr oder weniger folgende 
Abfolge von Pin-Wacklern:

 - RS=LOW, RW=LOW
 - Obere 4 Datenbits an Pin D4-D7 anlegen
 - EN=HIGH
 - EN=LOW
 - Untere 4 Datenbits an Pin D4-D7 anlegen
 - EN=HIGH
 - EN=LOW

Während für Lesen von Busy-Flag und Adresse folgende Abfolge nötig ist:

 - RS=LOW, RW=HIGH
 - EN=HIGH
 - Obere 4 Datenbits von Pins D4-D7 ablesen
 - EN=LOW
 - EN=HIGH
 - Untere 4 Datenbits von Pins D4-D7 ablesen
 - EN=LOW

von spess53 (Gast)


Lesenswert?

Hi

>Ich bin davon ausgegangen ihr habt das Datenblatt, welches ich ganz am
>anfang dazu postete, mal angeschaut. mein fehler.

Dann sieh dir auf S.49 das Timing zur Busyflag-Abfrage an.

Ich habe mal etwas zusammenkopiert:
1
          in r16,lcdir
2
          andi r16,$F0
3
          out lcdir,r16
4
          sbi lcctl,lc_rw           ; Read
5
wrcmd10:  sbi lcctl,lc_e            ; Enable high
6
          in r16,lcpin              ; oberes Nibble
7
          cbi lcctl,lc_e            ; Enable low
8
          sbi lcctl,lc_e            ; Enable high
9
          in r17,lcpin              ; unteres Nibble
10
          cbi lcctl,lc_e            ; Enable low
11
12
          sbrc r16,3                ; Busy 0 ?
13
          rjmp wrcmd10
14
15
          andi r16,0b00000111       ; nur Datenbits
16
          andi r17,0b00001111
17
          swap r16
18
          or r16,r17                ; Adresse in r16

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

Ohne dich jetzt bremsen zu wollen:
Einfacher ist es meistens, wenn du dir ganz einfach im Programm merkst, 
wieviele Zeichden du schaon ausgegeben hast. Im Normalfall ist das 
einfach nur eine "Variable", die du in deiner Ausgabefunktion geeignet 
inkrementieren musst (nämlich dann, wenn deine Spaltenanalyse ergibt, 
dass das 'Zeichen' voll ist und das nächste Zeichen angefangen werden 
muss.

von Peter D. (peda)


Lesenswert?

Du must Dir garnichts merken und garnichts zurücklesen.

Du weißt, wo Du die %-Zahl hinschreiben willst, also schreibs einfach 
dahin.

Und Du weißt, wo Dein Balken anfängt, also schreib den Balken einfach 
dahin.
Schreib Dir ne Funktion, die die Länge des Balkens als Parameter erhält 
und die zeichnet dann den Balken komplett neu.

Wird mal ein kürzerer Balken geschrieben, fülle einfach mit Lehrzeichen 
auf. Die Balkenfunktion schreibt also immer eine gleiche Anzahl Zeichen.
Und die %-Ausgabe ebenso.


Peter

von Robert R. (mikrorobert)


Lesenswert?

Vielen dank erstmal für die vorschläge.

sicherlich könnte ich den Ladebalken auch so programmieren wie peter es 
vorgeschlagen hat. oder mir auch die Adresse merken und mitzählen.

allerdings wollte ich ja lediglich wissen, ob es eine möglichkeit gibt, 
die adresse auch auszulesen.

denn iwann kommt ein komplizierteres Projekt und dann steh ich wieder 
vor dem selben Problem...

@spess53:

was ist in deinem script "lcdir"?

gruß robert

von spess53 (Gast)


Lesenswert?

Hi

>was ist in deinem script "lcdir"?

DDR des Ports an dem das LCD hängt. Zum Lesen muss das Eingang sein.

MfG Spess

von spess53 (Gast)


Lesenswert?

Hi

Nachtrag:

>denn iwann kommt ein komplizierteres Projekt und dann steh ich wieder
>vor dem selben Problem...

Ich habe schon mehr als 10 Jahre solche Teile in den Fingern. Aber die 
DDRAM-Adresse habe ich noch nicht gebraucht. Das was ich gepostet habe 
war eigentlich nur zum Auslesen des Busy-Flags gedacht. Ich habe das nur 
schnell für die DDRAM-Adresse umgeschrieben.

MfG Spess

von holger (Gast)


Lesenswert?

>Ich habe schon mehr als 10 Jahre solche Teile in den Fingern. Aber die
>DDRAM-Adresse habe ich noch nicht gebraucht.

Dito. Und selbst das Busy Flag abfragen braucht man nicht
wirklich wenn man es richtig macht.

von spess53 (Gast)


Lesenswert?

Hi

>Dito. Und selbst das Busy Flag abfragen braucht man nicht
>wirklich wenn man es richtig macht.

Und wer bestimmt, was richtig ist?

MfG Spess

von holger (Gast)


Lesenswert?

>Und wer bestimmt, was richtig ist?

Das Programm?

von Peter D. (peda)


Lesenswert?

Robert Richter schrieb:
> denn iwann kommt ein komplizierteres Projekt und dann steh ich wieder
> vor dem selben Problem...

Gerade wenn es komplizierter wird, sollte man umso mehr vermeiden, sich 
Knoten in die Gedanken zu machen.

Bei größeren Programmen schreiben verschiedene Funktionen in 
verschiedene Bereiche des LCD. Da kann man nicht mehr erwarten, daß der 
Cursor immer noch so steht, wie beim Verlassen.

Also kleine in sich abgeschlossene Funktionen, die möglichst wenig 
Bedingungen voraussetzen (wo der Cursor gerade steht usw.).


Peter

von Robert R. (mikrorobert)


Lesenswert?

Ja vielen dank erstmal dass ihr mir so geholfen habt!

ich bin letztendlich doch zu dem Entschluss gekommen das ganze hin und 
herspringen mit einem incrementierenden register zu realisieren!

hier ist dann das fertige Ergebnis:


.include  "m8def.inc"
.def  temp1 = r16
.def  temp2 = r22
.def  temp3 = r23
.def  temp4 =  r17
.def  temp5 = r18
.def  temp6 = r19


.equ  LCD_PORT = PORTD
.equ  LCD_DDR  = DDRD
.equ  PIN_RS   = 4
.equ  PIN_E    = 5
.equ  PIN_RW  = 7

.ifndef  XTAL
.equ  XTAL = 4000000
.endif
  ldi  temp1,LOW(RAMEND)
  out  SPL,temp1
  ldi  temp1,HIGH(RAMEND)
  out  SPH,temp1


  ldi  temp1,0xFF
  out  LCD_DDR,temp1

  rcall  lcd_init





start:
  ldi  temp5, 0
  ldi  temp4, 20
  ldi  temp6, 0b10000001
schleife:

  rcall  Balken
  inc  temp6
  dec  temp4
  brne  schleife

  rcall  lcd_clear

  ldi  ZL,LOW(text*2)  ; Adresse des Strings in den
  ldi  ZH,HIGH(text*2)  ; Z-Pointer laden

  rcall  lcd_flash_string  ; Unterprogramm gibt String aus der
      ; durch den Z-Pointer adressiert wird




text:
.db  "    Testprogramm        Ladebalken &        Textausgabe",0


  ldi  temp5,160
loop1:
  rcall  wait
  dec  temp5
  brne  loop1
  rcall  lcd_clear
  rjmp  start

wait:
  ldi  temp1,60
wait1:
  ldi  temp2,255
wait2:
  dec  temp2
  brne  wait2
  dec  temp1
  brne  wait1
  ret
Balken:

  ldi  temp1,0b00000110
  rcall  lcd_command

  ldi  temp1, 0b11011010
  rcall  lcd_data

  rcall  Prozentzahl

  rcall  wait
  rcall  wait

  ldi  temp1,0b00000100
  rcall  lcd_command

  ldi  temp1, 0x20
  rcall  lcd_data

  ldi  temp1,0b00000110
  rcall  lcd_command

  ldi  temp1, 0b11011001
  rcall  lcd_data

  rcall  Prozentzahl

  rcall  wait
  rcall  wait

  ldi  temp1,0b00000100
  rcall  lcd_command

  ldi  temp1, 0x20
  rcall  lcd_data

  ldi  temp1,0b00000110
  rcall  lcd_command

  ldi  temp1, 0b11011000
  rcall  lcd_data

  rcall  Prozentzahl

  rcall  wait
  rcall  wait

  ldi  temp1,0b00000100
  rcall  lcd_command

  ldi  temp1, 0x20
  rcall  lcd_data

  ldi  temp1,0b00000110
  rcall  lcd_command

  ldi  temp1, 0b11010111
  rcall  lcd_data

  rcall  Prozentzahl

  rcall  wait
  rcall  wait

  ldi  temp1,0b00000100
  rcall  lcd_command

  ldi  temp1, 0x20
  rcall  lcd_data

  ldi  temp1,0b00000110
  rcall  lcd_command

  ldi  temp1, 0b11010110
  rcall  lcd_data

  rcall  Prozentzahl

  rcall  wait
  rcall  wait

  ret


Prozentzahl:


  ldi  temp1,0b11000111
  rcall  lcd_command

  inc  temp5

  mov  temp1,temp5
  rcall  lcd_number

  ldi  temp1, '%'
  rcall  lcd_data

  mov  temp1,temp6
  rcall  lcd_command

  ret

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.