avr asm LCD Problem

#6676513
Lesenswert?

Hallo,
ich brauche wieder mal Hilfe!

Ich habe mir eine Schaltung zur Visualisierung eines CO2 Sensors gebaut. 
Basis ist ein ATMega88 und die Datenübertragung erfolgt mit PWM. Die 
Daten zur grafischen Darstellung werden jede halbe Stunde im EEPROM 
gespeichert. Wie im ersten Bild zu sehen, funktioniert das auch so weit 
ganz ordentlich. Da das Programm doch sehr umfangreich geworden ist, 
verzichte ich aber vorerst auf eine Vorstellung.

Nun das Problem:
Wenn ich das Programm per ISP übertrage funktioniert alles normal, wenn 
ich aber die Stromzufuhr unterbreche und dann neu einschalte führt es zu 
Chaos (Bild2).

Ich vermute mal, daß es ein timing Problem ist, aber wo ansetzen?
Angehängte Dateien:
#6676861
Lesenswert?

Ich komme nicht wirklich weiter, auch wenn ich überall noch mehr Zeit 
dazwischen packe. Ergebnis siehe Bild.

Spess53 schrieb:
> Wenn man auf die BUSY-Abfrage verzichtet

Mit der Busy Abfrage habe ich mich bislang noch nicht beschäftigt. 
Sollte man die nach jedem Schreibbefehl einbauen? Wie ist es mit der 
Reset Abfrage?
Angehängte Dateien:
Gast #6678115
Lesenswert?

Bruno M. schrieb:
> Im Datenblatt steht, daß man den Reset Pin nach dem Einschalten kurz auf
> low ziehen soll. Andererseits habe ich an anderer Stelle gelesen, daß
> man Reset per Hardware auf high legen kann und so habe ich es auch
> realisiert. Könnte das die Ursache sein?

Ohne RESET ist er halt nicht in einem definierten Anfangszustand, wenn 
dein Programm neu startet ohne dass die Versorgungsspannung gerade 
eingeschaltet wurde.

Damit muss dann dein Programm bei der Initialisierungssequenz zurecht 
kommen. Kommt es offenbar nicht.
#6678125
Lesenswert?

Ich hatte zu diesem Problem einen neuen Beitrag
Beitrag "avr asm LCD Problem"
aufgemacht, da ich
1. nach den ersten Antworten den Eindruck hatte, daß der Titel nicht zur 
eigentlichen Problemstellung paßt und
2. ich aus Erfahrung weiß, daß der Begriff asm im Titel viele 
Interessierte abschreckt, was ja auch hier wieder bewiesen wird.

Man hätte also besser diesen Thread geschlossen und nicht den anderen.

Ich versuche aber mal einige der Fragen aus dem anderen Thread zu 
beantworten:

Das Datenblatt des Displays ist im Anhang. Lt. Lieferant handelt es sich 
um die Controller KS0108. Beim Datenblatt mußte ich aber sehr schnell 
feststellen, daß es nicht überall stimmt, da CS1 und CS2 nicht high 
aktiv sind, sondern low.

Das LCD wird im 8 bit Modus angesteuert.
Bei diesem Controller gibt es nicht viel zu initialisieren! LCD 
einschalten und Inhalt löschen, das wars. Evtl noch die Start line 
festlegen.

Ich bin aber der Frage warum es beim Programmieren funktioniert und beim 
Einschalten der Spannung nicht, keinen Schritt näher gekommen.
Angehängte Dateien:
Gast #6678128
Lesenswert?

Fange doch mal mit den üblichen Infos an:

- Schaltplan
- Fotos vom Aufbau (Leitungsführung)
- Quelltext (gerne reduziert auf ein Minimum, das den Fehler noch hervor 
ruft).

> ich aus Erfahrung weiß, daß der Begriff asm im Titel viele
> Interessierte abschreckt, was ja auch hier wieder bewiesen wird.

Die wirklich guten wird es nicht abschrecken.
#6678153
Lesenswert?

Stefan ⛄ F. schrieb:
> Fange doch mal mit den üblichen Infos an:
>
> - Schaltplan
> - Fotos vom Aufbau (Leitungsführung)
> - Quelltext (gerne reduziert auf ein Minimum, das den Fehler noch hervor
> ruft).

Schaltplan und Aufbau im Anhang.
Wenn ich beim Quelltext wüßte, was den Fehler hervorruft, wäre ich schon 
einen Schritt weiter. Klar ist nur, daß beim Aufbau der Grafik etwas 
passiert. Nach dem Tip das init zweimal aufzurufen, kommt eigentlich 
alles normal, nur der Inhalt der Grafik ist chaotisch (aber nur beim 
Einschalten!)
Angehängte Dateien:
Gast #6678165
Lesenswert?

Bitte reiche Bilder von den Plänen nach. Ich kann diese Dateien gerade 
nicht öffnen und darf die gewünschte Software nicht installieren. So 
geht es sicher einigen, die dir helfen könnten.

Bist du sicher, dass der Quelltext vollständig ist?

Ich vermisse da schon mal einen Delay am Programm-Anfang. Bist du 
sicher, dass das Display schneller betriebsbereit wird, als dein 
Mikrocontroller? Wo ist überhaupt die Initialisierungs-Sequenz des 
Displays?
#6678169
Lesenswert?

Bruno M. schrieb:
> 2. ich aus Erfahrung weiß, daß der Begriff asm im Titel viele
> Interessierte abschreckt, was ja auch hier wieder bewiesen wird.

Es bringt Dir nicht das Geringste, das Asm zu verschweigen. Es würde nur 
dann was bringen, wenn Du C nicht abgeneigt bist.

Ein Grafik-LCD ist ja doch ne ganze Menge Holz. Da wäre mir einfach die 
Zeit viel zu schade, eine spezielle Assembler-Lib zu schreiben, die ich 
auf keiner anderen CPU wieder verwenden kann.
Auch ist es in Assembler viel leichter, daß sich Fehler einschleichen 
und viel schwerer, diese zu entdecken.

Wenn Du Code postest, dann als Anhang das gesamte Projekt als ZIP und 
natürlich den echten getesteten Code, nicht irgendwas ähnliches.
Unbenutzte Zeilen gleich löschen und nicht als Leiche drinlassen, das 
verwirrt den Leser nur.

P.S.:
Schnipselchen zu posten ist so, wie ein Puzzle, wo Teile fehlen.
Laß es daher!
Moderator Persönliche Seite #6678196
Lesenswert?

Bruno M. schrieb:
> ich aus Erfahrung weiß, daß der Begriff asm im Titel viele Interessierte
> abschreckt, was ja auch hier wieder bewiesen wird.

Klar, was glaubst du, warum sich nur wenige so einen Masochismus antun 
wollen?

Weil es eben einfach verdammt viel Aufwand ist, ein Assemblerprogramm zu 
debuggen, erst recht das eines anderen.

Bruno M. schrieb:
> Bei diesem Controller gibt es nicht viel zu initialisieren!

Das Datenblatt deines LCDs verweist auf den KS0108B als 
Displaycontroller. Wenn du in dessen Datenblatt schaust, wirst du 
feststellen, dass der Hersteller eine minimale Verzögerung zwischen "Vdd 
ein" und "RSTB high" von 1 µs vorschreibt. Wie du das erreichen willst, 
wenn du /RST des Displays auf +5V hart anklemmst, bleibt vermutlich 
nicht nur mir ein Rätsel.

/RST gehört folglich an einen Controller-GPIO und sollte erst nach der 
Initialisierung des Controllers high werden. Dann ist mit Sicherheit 
mehr als 1 µs verstrichen.
#6678220
Lesenswert?

Stefan ⛄ F. schrieb:
> Bitte reiche Bilder von den Plänen nach

erledigt

Peter D. schrieb:
> Wenn Du Code postest, dann als Anhang das gesamte Projekt als ZIP und
> natürlich den echten getesteten Code, nicht irgendwas ähnliches.
> Unbenutzte Zeilen gleich löschen und nicht als Leiche drinlassen, das
> verwirrt den Leser nur.


erledigt, das artet richtig in Arbeit aus (-:

Jörg W. schrieb:
> dass der Hersteller eine minimale Verzögerung zwischen "Vdd
> ein" und "RSTB high" von 1 µs vorschreibt

danke für den Hinweis, das könnte die Lösung des Problems sein.

Jörg W. schrieb:
> Das Datenblatt deines LCDs verweist auf den KS0108B als
> Displaycontroller. Wenn du in dessen Datenblatt schaust

Ich muß gestehen, daß ich nicht mehr in das Datenblatt des Controllers 
geschaut habe, da ich meinte alle Informationen zur Programmierung aus 
dem Datenblatt des LCD nehmen zu können.
Angehängte Dateien:
Moderator Persönliche Seite #6678245
Lesenswert?

Bruno M. schrieb:
> Ich muß gestehen, daß ich nicht mehr in das Datenblatt des Controllers
> geschaut habe, da ich meinte alle Informationen zur Programmierung aus
> dem Datenblatt des LCD nehmen zu können.

Mich hatte stutzig gemacht, dass in dessen Datenblatt rein gar nichts 
dazu steht, wie das Ding anzuschalten ist. Angesichts dessen, dass du 
nach solchen Problemen suchst, habe ich mir daher das des KS0108 halt 
genau angesehen.
Gast #6678261
Lesenswert?

Bruno M. schrieb:
>> Bitte reiche Bilder von den Plänen nach
> erledigt

Mir fällt da spontan auf, dass deine GND Leitung eine langen Weg im 
Kreis um die Bauteile herum macht, an der alles wie bei einer 
Perlenkette aneinander gereiht ist. Das ist exakt das Gegenteil von dem, 
wie man es machen soll.

Es ist deswegen schlecht weil
a) Der Laststrom jeder "Perle" das GND Potential aller dahinter 
liegenden Bauteile anhebt. Am Ende ist GND gar nicht mehr gleich GND vom 
Anfang, und das verursacht schnell allerlei Probleme.
b) Der kreisförmige Leitung ist eine Spule, die elektromagenetische 
Wellen empfängt, insbesondere Radiowellen, Funksignale und Spitzen die 
von Lichtbögen aus Schaltkontakten ausgehen.

Ich vermute zwar auch primär ein Problem bei der Initialisierung des 
Displays, aber die fehlerhafte (nicht sternförmige) GND Führung kommt 
direkt danach auf Rang 2.

Dein Assembler Quelltext wird deutlich verständlicher, wenn du über jede 
Prozedur (also alles was du mit rcall anspringst) einen Kommentar 
schreibt, wozu sie dient, welche Eingabeparameter sie erwartet und 
welche Ausgaben sie erzeugt. Ein Beispiel, wie ich das meine:
1
; Lies ein Byte aus dem EEPROM.
2
; Die Funktion wartet ggf. bis der vorherige Schreibzugriff beendet wurde.
3
; ZH/ZL: Adresse die gelesen werden soll
4
; Ausgabe:
5
; temp: Wert aus der Speicherzelle vom EEPROM
6
EEPROM_read:
7
  sbic    EECR,EEPE   ;prüfe ob der vorherige Schreibzugriff beendet ist
8
  rjmp    EEPROM_read
9
  out    EEARH, ZH
10
  out    EEARL, ZL
11
  sbi    EECR,EERE
12
  in    temp, EEDR     ;EEPROM Wert auslesen
13
  ret
Gast #6678300
Lesenswert?

Bruno M. schrieb:
> So war der Ursprungszustand vor dem Tip von von Karl B. (gustav) siehe
> weiter oben und dieser Tip hat tatsächlich etwas gebracht.

Einfacher Test: Reset von Controller bei Anliegen der Betriebsspannung 
auf GND ziehen und loslassen. Gibt's dann keinen Fehler, dann muss dem 
LCD einfach nur genügend Zeit gegeben werden, um nach Anliegen der 
Spannung hochzukommen.

Evtl. hilft es bereits die SUT1..0 Fuses bei internem RC auf 0x10, 14CK 
+ 65ms zu setzen?
Beitrag #6678332 wurde von einem Moderator gelöscht.
Beitrag #6678361 wurde von einem Moderator gelöscht.
Beitrag #6678368 wurde von einem Moderator gelöscht.
#6679018
Lesenswert?

Jörg W. schrieb:
> Klar, was glaubst du, warum sich nur wenige so einen Masochismus antun
> wollen?

Hi,
nur so nebenbei
was ist eigentlich aus BASCOM geworden, höre und sehe seit Jahren nichts 
mehr davon.
Sind es eventuell die aus der Zeit gefallenen Libs, die nicht mehr 
aktualisiert werden?


Ja, Fehlersuche bei ASMs.
Ein völlig sauberes Programm läuft nicht, je nachdem wie man es 
auflistet:
Weil zum Beispiel im Listing ein Abschnitt vor dem anderen steht.
Aber bei dem Target wird ein Sprungbefehl verwendet, dessen Sprungweite 
nicht so groß ist.
Da muss dann ein "Zwischenlabel" eingefügt und sozusagen zweimal 
gesprungen werden.
Das macht dann ein vernünftiger C-Compiler von sich aus.


ciao
gustav
Moderator Persönliche Seite #6679030
Lesenswert?

Karl B. schrieb:

> was ist eigentlich aus BASCOM geworden, höre und sehe seit Jahren nichts
> mehr davon.

Ich denke, das hat seine stabile Fan-Gemeinde.

> Sind es eventuell die aus der Zeit gefallenen Libs, die nicht mehr
> aktualisiert werden?

Naja, einer der Nachteile des Konzepts wird es sein, dass man für 
"exotische" Hardware nicht so schnell passende Libs bekommen wird wie 
für C. Aber die Frage müssen die Leute beantworten, die Bascom aktiv 
nutzen. Wenn dich das wirklich interessiert, mach einen eigenen Thread 
auf – hier werden die meisten dieser Leute eher nicht mitlesen, fürchte 
ich.

> Aber bei dem Target wird ein Sprungbefehl verwendet, dessen Sprungweite
> nicht so groß ist.

Das sollte allerdings zumindest der Assembler monieren.

Ist natürlich trotzdem lästig.

Außerdem hat man oft so eine negierte Logik, um genau dieses 
Sprungweitenproblem zu umgehen: "überspringe den nächsten Befehl bei 
folgender Bedingung", der nächste Befehl ist dann ein Sprungbefehl mit 
größerer Distanz, der bei der Negation der eigentlichen Bedingung 
ausgeführt werden soll. Da kann man schnell einen Knoten in der Birne 
bekommen …
#6679079
Lesenswert?

Hallo,

ich muß mich leider noch einmal melden. Ich war eigentlich fest davon 
überzeugt, daß Jörg die Lösung gefunden hat, aber leider Fehlanzeige.

Ich kann mir einfach nicht mehr erklären was den Unterschied ausmacht 
zwischen flashen und Spannung einschalten. Auch wenn ich nach dem 
Einschalten den ATMega resette, wird das Bild nicht besser.
#6679253
Lesenswert?

Bruno M. schrieb:
> ich muß mich leider noch einmal melden. Ich war eigentlich fest davon
> überzeugt, daß Jörg die Lösung gefunden hat, aber leider Fehlanzeige.

Das habe ich mir auch gedacht. Ein LCD muß auch ohne Resetpin 
funktionieren, wenn die Initsequenz korrekt ist.

Ich würde den Fehler eher in den vielen C&P-Abschnitten suchen. C&P 
schreit regelrecht nach Fehler machen.
Ich würde eine generische 8Bit-Ausgabefunktion schreiben, die überall in 
das LCD schreiben kann. Übergeben wird Position (X,Y) und Wert.
Und die wird dann nur noch aufgerufen, d.h. keine andere Funktion darf 
direkt auf das GLCD schreiben. Insbesondere die EEPROM-Sachen nicht.

Das LCD scheint 2 Controller zu haben. Ich sehe im lcd_init aber kein 
CS1, CS2 aktivieren.
Gast #6679339
Lesenswert?

Bruno M. schrieb:
> Basis ist ein ATMega88
Schreibfehler oder Realität?

Im Schaltplan ist ein ATMega8 eingezeichnet. Der 88er wäre zwar 
Pin-kompatibel, hat aber ein paar zusätzliche Features.

http://ww1.microchip.com/downloads/en/AppNotes/doc2553.pdf

Ansonsten bleibt noch das fröhliche Rätselraten, was macht die 
ISP-Schnittstelle so besonders?

Programmierst Du auch jeweils das EEProm beim Flashen?

Laut Schaltplan versorgt der Programmer nicht den Controller, wo kommen 
die 5V her, extern über 9V & IC2? Wenn extern, wie ist das Verhalten bei 
Anschluss über 9V & IC2?

Was passiert, wenn das ISP-Kabel dran ist und der Programmer "nur" einen 
Reset auslöst? Müsste über "identify chip" erreicht werden können.

> Ich wäre doch davon ausgegangen, daß ein SW-Fehler auch beim
> flashen zuschlägt und nicht nur beim Einschalten.

Ein Einschalten nach dem Flashen ist der zweite Start, es wäre daher 
interessant, ob eingestellt ist, dass das EEProm beim Flashen mit 
beschrieben wird.
#6679368
Lesenswert?

MWS schrieb:
>> Basis ist ein ATMega88
> Schreibfehler oder Realität?

Realität!

> Programmierst Du auch jeweils das EEProm beim Flashen?

Nein, das EEPROM bleibt unverändert.

> Laut Schaltplan versorgt der Programmer nicht den Controller, wo kommen
> die 5V her, extern über 9V & IC2? Wenn extern, wie ist das Verhalten bei
> Anschluss über 9V & IC2?

JP1 ist ein Jumper. Damit habe ich die Wahl zwischen Netzteil oder 
Batterie. Das Verhalten ist identisch.
#6679381
Lesenswert?

Peter D. schrieb:
> Das LCD scheint 2 Controller zu haben. Ich sehe im lcd_init aber kein
> CS1, CS2 aktivieren

Ich hatte das mal probeweise im init, habe es aber wieder rausgenommen, 
da es nichts gebracht hat. In der SW kommt es aber x-mal vor, da ich CS1 
und CS2 immer dann aktivieren muß, wenn ich eine Hälfte anspreche. Beide 
Hälften zu aktivieren bringt nichts, da die Adresse jeweils bei 0 
anfängt.
Gast #6679484
Lesenswert?

Bruno M. schrieb:
> Realität!

Und der Assembler hat auch das richtige 88er INC?

> In der SW kommt es aber x-mal vor, da ich CS1 und CS2
> immer dann aktivieren muß, wenn ich eine Hälfte anspreche.

Da Du beim Reset nichts gezielt aktivierst/deaktivierst hast Du beim 
Aufruf der lcd_init beide CS aktiviert.
1
  ldi    temp, 0b111110    ;alles Ausgang außer 0
2
  out    LCDDC, temp
3
  ldi    temp, 0b000001    ;PORTC0 Eingang mit pullup
4
  out    LCDC, temp
Ab hier sind CS1 & CS2 Low (aktiv).
Bis zur Init kommt nur für's LCD unwesentlicher Code.
1
lcd_init:
2
...
3
  ldi    Daten, LCD_START_LINE  ;Start Display Line = 0
4
  rcall  lcd_writecom
Ob lcd_writecom dann noch Erfolg hat, beide Hälften gleichzeitig zu 
beschreiben, steht in Frage. Also solltest Du die Hälften mal einzeln 
über CS ansprechen und einzeln initialisieren.
Gast #6679610
Lesenswert?

Rainer V. schrieb:

> Karl B. schrieb:
>> Das macht dann ein vernünftiger C-Compiler von sich aus.
>
> Das macht ein vernünftiger ASM-Programmierer mit einem kleinen Macro :-)

Nö, gerade dieses Problem mit der automatischen Erweiterung von 
Verzweigungen läßt sich leider nicht so einfach mit einem Macro lösen. 
Das funktioniert gut, wenn das Verzweigungsziel zum Zeitpunkt der 
Übersetzung der Verzweigung bereits bekannt ist. Es funktioniert aber 
leider nicht, wenn das nicht der Fall ist, weil das Verzweigungsziel 
"weiter unten" im Code ist.

Für diesen Fall hat man in dem Macro zwei Möglichkeiten: entweder diese 
Verzweigungen grundsätzlich als "far" erzeugen (ineffizienter als nötig) 
oder pokern und händisch nachbessern.

Man könnte meinen, dass die Tatsache, dass der Assembler mit zwei Pässen 
arbeitet, irgendwie hilfreich wäre, um das Problem zu lösen. Das ist 
aber leider nicht der Fall. Blöderweise benötigt die "far" Variante 
nämlich nicht nur mehr Takte, sondern auch ein Wort mehr im 
Programmspeicher. Das führt dann dazu, dass aller folgende Code um ein 
Word verrutscht und damit auch alle folgenden Labels.

Was erstens dem Assembler überhaupt nicht passt, wenn das zwischen den 
beiden Läufen passiert und zweitens ein rekursives Problem aufwirft, 
denn bereits als "near" erfolgreich übersetzte Verzweigungen könnten 
dadurch wiederum zu weit werden und die Notwendigkeit aufwerfen, in 
"far" gewandelt zu werden...

Nö, bei diesem Problem ist und bleibt Handarbeit angesagt. Nix Macro. 
Macro nur insofern, als dass das Umswitchen zwischen "near" und "far" 
mit dem einfügen eines kleinen "f" vor dem Mnemonic der Verzweigung 
erledigt werden kann. Es gibt also z.B. ein Macro namens "fbrne". Und 
immer, wenn der Assembler bei einem "brne" meckert, dass das Ziel zu 
weit entfernt wäre, schreibt man einfach das "f" vor das "brne" und der 
Drops ist gelutscht. Naja, bis auf die Rekursion natürlich, dadurch kann 
es passieren, dass nunmehr wieder andere Verzweigungen angemeckert 
werden. Dann muss man die halt auch noch entprechend nachbehandeln. Usw. 
usf. Mehr als zwei Iterationen habe ich noch nie erlebt.

Nach demselben Prinzip behandle ich auch calls und jumps. Da kann es 
sogar noch komplizierter werden, aber zum Glück nicht beim Mega8(8), da 
reicht immer rcall/rjmp.
#6679623
Lesenswert?

Also gehört ja jetzt nicht hierher, aber ich gehe davon aus, dass ich in 
meinem Programm weiß, wann ich (für meinen Controller) einen kurzen oder 
einen weiten Sprung machen kann und das kann ich in ein Macro packen. 
Ist doch einfach eine Adressberechnung. Wenn es das nicht sein sollte, 
dann ist sicher mehr Gehirnschmalz erforderlich :-)
Gruß Rainer
Gast #6679642
Lesenswert?

Rainer V. schrieb:

> Also gehört ja jetzt nicht hierher

Ja, stimmt eigentlich. Ist eine extreme Dehnung des Thread-Themas. Aber: 
er hat "asm" gesagt...

> aber ich gehe davon aus, dass ich in
> meinem Programm weiß, wann ich (für meinen Controller) einen kurzen oder
> einen weiten Sprung machen kann und das kann ich in ein Macro packen.
> Ist doch einfach eine Adressberechnung.

Eine Adressberechnung mit einem Parameter, der u.U. erst in der Zukunft 
bekannt werden wird. Das ist das Problem...
Gast #6679675
Lesenswert?

Bruno M. schrieb:
> CS1 und CS2 haben erst dann einen Einfluß, wenn ich ins Display etwas
> schreiben will. LCD_START_LINE (nicht zu verwechseln mit Adresse!) ist
> ein Befehl und daher von CS! und CS2 unabhängig. Im Normalgebrauch kann
> man sich diesen Befehl auch ganz schenken.

Wenn die Befehle CS-unabhängig sind, wrum haust Du die dann hier 
insgesamt 16 mal in LCD_clear_1/2: raus?
1
  ldi    Daten, LCD_SET_ADDRESS  ;Y auf 0
2
  ldi    Daten, LCD_SET_PAGE    ;Reihe auf 0
Ich hab' mir nicht Deine LCD-clear Routine angesehen, aber für ein 
LCD-Init würde es reichen, wenn einmal:

LCD_ON
LCD_START_LINE
LCD_SET_ADDRESS
LCD_SET_PAGE

gesendet werden.
K.A. ob sich das negativ in der Schleife auswirkt, andererseits wird 
hier das Unwahrscheinliche gesucht, denn das Wahrscheinliche haben wir 
bereits durch.

An Deiner Stelle hätte ich CS1 und CS2 Im Code vertauscht:
1
.equ CS2      =2
2
.equ CS1      =1
Und dann geschaut, wo der optische Fehler auftaucht. Ist er immer noch 
im selben Segment, hat der KS0108 'ne Macke und man kann sich das 
Rätselraten schenken.
Beitrag #6679676 wurde von einem Moderator gelöscht.
#6679682
Lesenswert?

MWS schrieb:
> An Deiner Stelle hätte ich CS1 und CS2 Im Code vertauscht:.equ CS2
> =2
> .equ CS1      =1
> Und dann geschaut, wo der optische Fehler auftaucht.

Aus meiner Erfahrung sollte man - egal ob nach Start, Reset, oder 
Watchdog-Reset immer eine Initialisierung durchführen und das Display 
komplett löschen. Dann ist man - aus meiner Sicht - auf der sicheren 
Seite, wenn man mit den Aktionen mindestens 500 ms wartet. Das Teil 
braucht ein wenig Zeit, um wach zu werden.

Eine Busy-Abfrage (bei moderatem Timing) ist für mich überflüssig und 
den Reset-Pin würde ich fest auf high (mit Kondensator nach GND) legen.
Beitrag #6679695 wurde von einem Moderator gelöscht.
Beitrag #6679696 wurde von einem Moderator gelöscht.
Beitrag #6679735 wurde von einem Moderator gelöscht.
Beitrag #6679754 wurde von einem Moderator gelöscht.
Beitrag #6679812 wurde von einem Moderator gelöscht.
Beitrag #6679818 wurde von einem Moderator gelöscht.
Beitrag #6679821 wurde von einem Moderator gelöscht.
Beitrag #6679822 wurde von einem Moderator gelöscht.
Beitrag #6679825 wurde von einem Moderator gelöscht.
Beitrag #6679833 wurde von einem Moderator gelöscht.
Beitrag #6679834 wurde von einem Moderator gelöscht.
Beitrag #6679850 wurde von einem Moderator gelöscht.
#6680313
Lesenswert?

Peter D. schrieb:
> Das KS0108B Datenblatt ist da eindeutig.
> CS muß bei Daten und Befehlen aktiv sein:
> "When CS1B to CS3 are in the active mode, R/W and RS select the input
> register."

Ich meine die Diskusion dreht sich um des Kaisers Bart. In der Regel muß 
ich natürlich immer erst angeben auf welche Hälfte ich mich beziehe. 
Insofern ist die Aussage sicherlich richtig. Es gibt aber auch Befehle, 
die das LCD betreffen wie on/off oder DISPLAY START LINE wo CS keine 
Rolle spielt.
#6680330
Lesenswert?

In der Zwischenzeit habe ich etwas experimentiert und habe die 
Systematik des Dateneintrags in die Grafik grundlegend geändert. Ich 
konnte ja schon vorher feststellen, daß alles vernünftig angezeigt 
wurde, außer den Daten in der Grafik. Die ursprüngliche Methodik war, 
die Daten in der untersten Zeile (Page) der Reihe nach einzutragen und 
bei höheren Werten in die entsprechende Page zu springen.
Jetzt habe ich es so geändert, daß die jeweiligen Werte fortlaufend von 
der obersten bis zur untersten Page eingetragen werden. Dadurch wird das 
Programm zwar nicht einfacher, aber das LCD müßte es eigentlich leichter 
haben. Zum Testen habe ich aber vorerst nur die oberste und unterste 
Page beschrieben.
Wie die Bilder zeigen, hat das aber gar nichts gebracht.
Angehängte Dateien:
Beitrag #6680361 wurde von einem Moderator gelöscht.
Beitrag #6680369 wurde von einem Moderator gelöscht.
#6680419
Lesenswert?

Hi,
so wie ich das sehe, ist das ein "Locate"-Problem.
Die meisten Displays haben "Automatismen", wie Cursor move, Shift etc., 
die das Programmieren vereinfachen sollen, sich hier offenbar als 
hinderlich zeigen.
Z.B. Eine Messwertlegende ändert sich nicht, der Wert aber schon.
Jetzt schreibt man nicht alles inclusive Legende jedesmal 
gebetsmühlenartig neu, sondern übergibt nur den Messwert. Dazu muss man 
direkt die
Steuerbefehle für Position der Zelle angeben.
@Peda gab oben schon die Tipps, die in die richtige Richtung zeigen:

Bruno M. schrieb:
> Da das Programm doch sehr umfangreich geworden ist,
> verzichte ich aber vorerst auf eine Vorstellung.

Peter D. schrieb:
> Wenn Du Code postest, dann als Anhang das gesamte Projekt als ZIP und
> natürlich den echten getesteten Code, nicht irgendwas ähnliches.

Und auf der Zielgeraden:

Peter D. schrieb:
> Ich würde eine generische 8Bit-Ausgabefunktion schreiben, die überall in
> das LCD schreiben kann. Übergeben wird Position (X,Y) und Wert.
> Und die wird dann nur noch aufgerufen, d.h. keine andere Funktion darf
> direkt auf das GLCD schreiben. Insbesondere die EEPROM-Sachen nicht.

Nehme an, evtl. irgendein Interrupt ist da noch unerwünscht aktiv.

Bei 44780-ern sieht das vielleicht so aus.
locate2c:      ; Zeile 2, Spalte 15
push  temp
ldi  temp, 0xCE
rcall  comd2lcd
pop  temp
ret
Bei Cursor move right würde ich die ganze Zeile neu schreiben müssen.
So spar ich mir das.
Hab ich Display clear vorab gesendet, ist die "Legende" natürlich auch 
weg. Nur das, was explizit auf die Position geschrieben wurde, erscheint 
dann.

ciao
gustav
#6680562
Lesenswert?

Karl B. schrieb:
> Dazu muss man
> direkt die
> Steuerbefehle für Position der Zelle angeben.

Ich habe mir meinen Ursprungscode daraufhin nochmals angesehen. Genau 
das mache ich eigentlich:
1
;Ausgabe in Page 7 der linken Hälfte
2
Kurve_L:
3
  cbi    LCDC, CS1          ;CS1 eingeschaltet
4
  sbi    LCDC, CS2          ;CS2 ausgeschaltet
5
  clr    Daten
6
  ldi    Daten, LCD_SET_ADDRESS+25    
7
  add    Daten, Cnt
8
  rcall  lcd_writecom
9
  ldi    Daten, LCD_SET_PAGE+7    ;X setzen
10
  rcall  lcd_writecom  
11
  ldi    ZL,Low(Wertigkeit*2)
12
  ldi    ZH,High(Wertigkeit*2)
13
  add    ZL, temp
14
  adc    ZH, R8
15
  lpm    Daten, Z
16
  ori    Daten, 0b10000000      ;Nulllinie erhalten
17
  rcall  lcd_writebyte
18
Kurve_L_exit:
19
rjmp  Back_loop_L

Mit
1
ldi  Daten, LCD_SET_ADDRESS+25    
2
add  Daten, Cnt
stelle ich den Adresspointer punktgenau
#6680669
Lesenswert?

Bruno M. schrieb:
> cbi    LCDC, CS1          ;CS1 eingeschaltet
> sbi    LCDC, CS2          ;CS2 ausgeschaltet

Alleine die beiden Zeilen verursachen schon leichtes Unwohlsein, und die 
stehen häufig in deinem Code.

Bitte (er-)kläre, ob CS1/CS1 active high oder active low sind, an 
welchem Pin welches LCD angeschlossen ist, und ob LCD1 links oder rechts 
ist.

Oliver
#6680682
Lesenswert?

Oliver S. schrieb:
> Bitte (er-)kläre, ob CS1/CS1 active high oder active low sind, an
> welchem Pin welches LCD angeschlossen ist, und ob LCD1 links oder rechts
> ist.

Das oben eingefügte Codesegment ist überschrieben mit:
;Ausgabe in Page 7 der linken Hälfte

und dann steht:
cbi    LCDC, CS1          ;CS1 eingeschaltet
sbi    LCDC, CS2          ;CS2 ausgeschaltet

Es handelt sich also um die linke Hälfte und mit CS1 wurde es 
eingeschaltet (aktiv). Eingeschaltet wurde es mit cbi, d.h. low ist 
aktiv.
Moderator Persönliche Seite #6680737
Lesenswert?

Spess53 schrieb:
> Bei den mir bekannten 128x64 Displays sind die CS-Signale H-Aktiv.

Wobei der KS0108 halt drei CS-Signale hat, von denen zwei low- und das 
dritte high-aktiv sind. Scheint also eine Frage zu sein, welche davon 
der jweilige Display-Hersteller hart vorverdrahtet und welcher er nach 
draußen führt.
#6680752
Lesenswert?

vielleicht ist es ja problematisch das das Display gleich los will der 
µC Reset aber mit 64mSek verzögert wird. Vielleicht die Stromversorgung 
des LCDs über den µC mittels Transistor einschaltet und dann die 
geforderte mSek ausführen nachdem der µC schon da ist.

Ich hoffe ihr versteht was ich meine. Also nachdem der µC voll da ist, 
das Display erst einschalten und dann die geforderte mSek warten.
#6680758
Lesenswert?

Thomas O. schrieb:
> vielleicht ist es ja problematisch das das Display gleich los will der
> µC Reset aber mit 64mSek verzögert wird.

Das ist ja nun kompletter Humbug.

> Vielleicht die Stromversorgung
> des LCDs über den µC mittels Transistor einschaltet und dann die
> geforderte mSek ausführen nachdem der µC schon da ist.
>
siehe oben
#6680760
Lesenswert?

Jörg W. schrieb:
> Spess53 schrieb:
>> Bei den mir bekannten 128x64 Displays sind die CS-Signale H-Aktiv.
>
> Wobei der KS0108 halt drei CS-Signale hat, von denen zwei low- und das
> dritte high-aktiv sind. Scheint also eine Frage zu sein, welche davon
> der jweilige Display-Hersteller hart vorverdrahtet und welcher er nach
> draußen führt.

Genau das ist mir bei den Dingern unklar.
Aber könnte die Anzeige beim TE überhaupt soweit kommen, wenn er hier 
etwas verwechselt hätte?

Ich tippe daher nach wie vor auf allgemein nicht korrekten Init des 
Displays und der beiden Controller.
#6680791
Lesenswert?

Cyblord -. schrieb:
> Ich tippe daher nach wie vor auf allgemein nicht korrekten Init des
> Displays und der beiden Controller.

Es wurde ja schon gesagt, aber halt nochmal: Der ks0108 hat und braucht 
kein Init. Strom dran, Reset auf high, die gewünschten Befehle schicken, 
das war’s. Hilfreich ist es natürlich, als erstes den Einschaltbefehl zu 
schicken, aber da das Display ja prinzipiell was anzeigt, kann’s daran 
nicht liegen.

Ich vermute eher ein beim Programmstart nicht initialisiertes Register 
oder eine Variable im RAM. Da ein Reset beim AVR die nicht auf Null 
zurücksetzt, können solche Effekte auftreten.

Das aber in dem Assemblerwust zu finden, ist Aufgabe des TO.

Oliver
#6680805
Lesenswert?

Spess53 schrieb:
> Ist mir bekannt. Aber ich habe 16 Datenblätter von 128x8 Displays hier
> auf meinem Rechner. Und alle mit KS0107/KS0108 (oder kompatiblen) haben
> H-Aktive CS-Signale.

Als ich mit diesem, für mich unbekanntem Display angefangen habe, habe 
ich natürlich nicht gleich losprogrammiert, sondern habe alles mögliche 
getestet und es hat ne Weile gebraucht bis ich realisiert hatte, das das 
Datenblatt falsch ist.
U.a. habe ich auch ähnliche Datenblätter dieses Herstellers gelesen 
(siehe oben) und festgestellt, daß auch dort CS auf low aktiv ist.
Angehängte Dateien:
#6680832
Lesenswert?

Cyblord -. schrieb:
> Ich tippe daher nach wie vor auf allgemein nicht korrekten Init des
> Displays und der beiden Controller.

Ich versuche natürlich auch alles Mögliche. So habe ich den Aufbau der 
Grafik so verzögert, daß ich zuschauen kann, wie die Linie aufgebaut 
wird.

Die Einschaltsequenz sieht inzwischen so aus:
1
rcall  delay100us
2
  sbi    PORTB, 1
3
  rcall  delay100us
4
  cbi    PORTB, 1
5
  rcall  delay100us
6
  sbi    PORTB, 1
7
  rcall  _LCD_ON
8
  rcall  _LCD_OFF
9
  rcall  LCD_init
und
1
lcd_init:
2
  rcall  _LCD_ON
3
  ldi    Daten, LCD_START_LINE  ;Start Display Line = 0
4
  rcall  lcd_writecom
5
  rcall  delay50ms
6
  rcall  LCD_clear
7
ret
8

9
;*****************************************************************************************
10
_LCD_ON:
11
  cbi    LCDC, CS1        ;CS1 eingeschaltet
12
  cbi    LCDC, CS2        ;CS2 eingeschaltet
13
  ldi    Daten, LCD_ON
14
  rcall  lcd_writecom
15
  rcall  delay500ms
16
ret
17

18
;*****************************************************************************************
19
_LCD_OFF:
20
  sbi    LCDC, CS1        ;CS1 ausgeschaltet
21
  sbi    LCDC, CS2        ;CS2 ausgeschaltet
22
  ldi    Daten, LCD_OFF
23
  rcall  lcd_writecom
24
  rcall  delay500ms
25
ret

mehr geht nun wirklich nicht
#6680855
Lesenswert?

ICh habs jetzt mal durch meinen Simulator geschickt. Der ist zwar nicht 
unbedingt fehlerfrei, da selbstgeschrieben, aber er zeigt doch das 
Verhalten ähnlich wie oben: Nach power on funktioniert es, nach einem 
Reset wird die linke untere Hälfte überschrieben (die ist zunächst auch 
richtig, die eeprom-Schreib-Routine überschreibt das dann)

Grund könnten diese diese Zeilen hier sein:
1
                                 ;Werte der aktuellen Spalte in der linken Hälfte löschen
2
                                 Wert_loesch_L:
3
000532 9842                        cbi    LCDC, CS1          ;CS1 eingeschaltet
4
000533 9a41                        sbi    LCDC, CS2          ;CS2 ausgeschaltet
5
000534 e559                        ldi    Daten, LCD_SET_ADDRESS+25    
6
000535 0f53                        add    Daten, Cnt
7
000536 dce3                        rcall  lcd_writecom
8
000537 eb5b                        ldi    Daten, LCD_SET_PAGE+3    ;X setzen

Der Zähler Cnt (=r19) wird meiner Meinung nach nach einem Reset nirgends 
auf Null zurückgesetzt.

Oliver
#6680889
Lesenswert?

Oliver S. schrieb:
> Der Zähler Cnt (=r19) wird meiner Meinung nach nach einem Reset nirgends
> zurückgesetzt nicht zurückgesetzt.

Im Code wird er zurückgesetzt:
1
Ende_loop:
2
  clr    Cnt
3
ret
4

5
;Werte aus SRAM lesen und im LCD ausgeben
6
;linke Hälfte
7
EE_Read_L:                
8
  clr    Cnt
9
EE_Read_L_loop:
10
  clr    Flag_3
11
  rcall  Wert_loesch_L        ;die aktuelle Spalte erst löschen, bevor der neue Wert eingetragen wird
12
  ldi    ZL, low(alle_ppm_L)      ;Zeiger auf SRAM Adresse
13
  ldi    ZH, high(alle_ppm_L)
14
  add    ZL, Cnt            ;Zähler addieren
15
  adc    ZH, R8  
16
  ld    temp, Z
17
  cpi    temp, 8            ;je Page nur 8 Werte möglich
18
  brlo  Kurve_L            ;Sprung zur Ausgabe in der richtigen Page
19
  cpi    temp, 8
20
  brsh  Kurve2_L
21
Back_loop_L:
22
  inc    Cnt
23
  cpi    Cnt, 39            ;Ende der linken Hälfte erreicht?
24
  breq  EE_Read_R
25
rjmp  EE_Read_L_loop
26

27
;rechte Hälfte
28
EE_Read_R:                
29
  ldi    Cnt, 39            ;Startwert für rechte Hälfte
30
EE_Read_R_loop:
31
  rcall  Wert_loesch_R        ;die aktuelle Spalte erst löschen, bevor der neue Wert eingetragen wird
32
  ldi    ZL, low(alle_ppm_L)      ;Zeiger auf SRAM Adresse
33
  ldi    ZH, high(alle_ppm_L)
34
  add    ZL, Cnt            ;Zähler addieren
35
  adc    ZH, R8  
36
  ld    temp, Z
37
  cpi    temp, 8
38
  brlo  Kurve_R
39
  cpi    temp, 8
40
  brsh  Kurve2_R
41
Back_loop_R:
42
  inc    Cnt
43
  cpi    Cnt, 99            ;Ende der rechten Hälfte erreicht?
44
  breq  Ende_loop
45
rjmp  EE_Read_R_loop

das Codesegment rcall  Wert_loesch_L wird hier bei jedem Cnt 
angesprungen, und nach Durchlauf wird Cnt mit Ende_loop wieder auf 0 
gesetzt.

Was meinst du aber mit nach einem Reset?
Gast #6680914
Lesenswert?

Bruno M. schrieb:

> Was meinst du aber mit nach einem Reset?

Ich vermute mal, dass er das meint, wofür man in C zumindest als Warnung 
um die Ohren gehauen bekommen würde: ein Lesezugriff auf eine nicht 
initialisierte Variable (in diesem Fall natürlich ein Register, aber das 
spielt bezüglich der Auswirkungen keine Rolle).

Ob das wirklich so ist, habe ich nicht überprüft, es erscheint mir aber 
angesichts der Fehlerbeschreibung recht plausibel, dass sowas die 
Ursache sein könnte.

Für dieses Problem ist übrigens eine Untersuchung des Codes mittels 
Simulator auch nicht gerade sehr hilfreich, denn der initialisiert (im 
Unterschied zur realen Maschine) alle Register "ordentlich" auf Null, 
was so einen Fehler sehr schön verdecken kann. Wenn halt Null der Inhalt 
ist, den die Variable bzw. das Register beim ersten Lesezugriff haben 
sollte.
Moderator Persönliche Seite #6680921
Lesenswert?

c-hater schrieb:

> Ob das wirklich so ist, habe ich nicht überprüft, es erscheint mir aber
> angesichts der Fehlerbeschreibung recht plausibel, dass sowas die
> Ursache sein könnte.

Es erklärt aber nicht völlig den Unterschied, warum es nach einer 
Programmierung geht – der Programmer fasst ja keine CPU-Register an.

> Für dieses Problem ist übrigens eine Untersuchung des Codes mittels
> Simulator auch nicht gerade sehr hilfreich, denn der initialisiert (im
> Unterschied zur realen Maschine) alle Register "ordentlich" auf Null

Hängt vom Simulator ab. Ich habe auch schon welche gesehen, die (ählich 
wie bei Hardware-Simulatoren üblich) die Register alle auf 'X' gesetzt 
haben und so dann zeigen konnten, wenn auf Werte zugegriffen wird, die 
nicht vorher geschrieben worden sind.
Gast #6680955
Lesenswert?

Jörg W. schrieb:

> Es erklärt aber nicht völlig den Unterschied, warum es nach einer
> Programmierung geht – der Programmer fasst ja keine CPU-Register an.

Er selber nicht, aber der bereits vor der Programmierung im Flash 
vorhandene Code. Dann läuft die Geschichte nämlich so: besagter Code 
läuft und schreibt irgendwann auch irgendeinen Wert in das fragliche 
Register/die fragliche Speicherstelle. Und zwar mit einer gewissen 
Wahrscheinlichkeit einen, der der in seinem Kontext irgendeinen Sinn 
ergibt.

So, nun wird eine neue Version desselben Programms geflasht. Die 
Register werden dadurch, wie du richtig angemerkt hast, nicht 
beeinflußt. Nach dem Ende des Flashens startet nun die neue 
Programmversion. Die Register haben aber in dieser Situation immer noch 
den Wert, den die alte hinterlassen hat, eben gerade dadurch, dass das 
Flashen sie nicht anfasst.

So, und nun kommt ein Powercycle (hinreichender Länge). Damit ist die 
heile Welt der mehr oder weniger korrekt vorinitialisierten Register 
beendet...

Hätte nicht gedacht, dass man jemandem wie dir diesen Mechanismus 
erklären muss...

> Hängt vom Simulator ab.

Wer sinnvoll AVR programmiert, benutzt nur einen Simulator, den von 
Atmel. Der ist zwar auch weit davon entfernt, perfekt zu sein, aber 
immer noch um ein Vielfaches besser als jede real existierende 
Alternative.
#6680979
Lesenswert?

Oliver S. schrieb:
> Nur springst du direkt auf EE_Read_L_loop, und damit knallt das dann
> nach Reset unter Power.

Kannst du das so erklären, daß es auch ein Laie versteht?

> Letztendlich ist’s mir egal, ist dein Code und dein Problem.

Egal sollte dir das eigentlich nicht sein, Wozu machen wir sonst die 
ganze Aktion.

> Da werden
> sicherlich noch mehr solche Bugs drinstecken.

Das ist überhaupt nicht auszuschließen, aber vielleicht kommen wir 
dahinter.
Moderator Persönliche Seite #6680982
Lesenswert?

c-hater schrieb:
>> Hängt vom Simulator ab.
>
> Wer sinnvoll AVR programmiert, benutzt nur einen Simulator, den von
> Atmel.

Kann sein. Ich habe ihn noch nie benutzt. ;-)

Zum Test irgendwelcher Algorithmen genügt mir jeder Simulator, solange 
er die Befehle sauber umsetzt. Zum Test realer Firmware fehlt in einem 
Simulator typischerweise all das, was ringsum angeschlossen ist und dann 
auf die Firmware einwirkt.
Gast #6680998
Lesenswert?

Jörg W. schrieb:

> Kann sein. Ich habe ihn noch nie benutzt. ;-)

Selbst Schuld. Wer sich wegen idiotischer selbst auferlegter 
ideologischer Beschränkungen vom realen Leben abkoppelt, hat es nicht 
besser verdient.

> Zum Test irgendwelcher Algorithmen genügt mir jeder Simulator, solange
> er die Befehle sauber umsetzt.

Du simulierst nur den MCU-Core. Das ist lächerlich.

> Zum Test realer Firmware fehlt in einem
> Simulator typischerweise all das, was ringsum angeschlossen ist und dann
> auf die Firmware einwirkt.

Nö. Dagegen haben die die "Stimuli" erfunden. Man kann damit das 
Verhalten eines Programmes auch mit ganz realen Eingangsdaten 
nachvollziehen. Und das ist genau das Schicke (im Vergleich zu einem 
Debugger). Man kann das beliebig oft tuen, mit den immer wieder gleichen 
Daten. Bis man halt den Scheiß-Bug gefunden hat, der mit eben diesen 
Daten Mist produziert...

Du hast ganz offensichtlich niemals die ganze Macht eines Simulators 
nutzen gelernt, weil du durch eigene Schuld niemals einen (zumindest 
halbwegs) brauchbaren benutzt hast...

Mo mercy...
#6681016
Lesenswert?

Bruno M. schrieb:
> Kannst du das so erklären, daß es auch ein Laie versteht?

Jetzt mal ganz blöd gefragt: hast du das dein Programm selber 
geschrieben, oder nicht?

Aber egal, verstehen musst du nicht, was du da tust. Schreib alt an den 
Anfang des Programms ein „clr Cnt“, und schau, das dann passiert.

Guter Programmierstil wäre es dann, alle verwendeten Variablen/Register 
zu Programmbeginn zu initialisieren. Das mag überflüssig erscheinen, 
zahlt sich aber irgendwann as.

Oliver
Moderator Persönliche Seite #6681018
Lesenswert?

c-hater schrieb:

>> Zum Test irgendwelcher Algorithmen genügt mir jeder Simulator, solange
>> er die Befehle sauber umsetzt.
>
> Du simulierst nur den MCU-Core. Das ist lächerlich.

Was sonst sollte bei einem Algorithmus passieren?

> Nö. Dagegen haben die die "Stimuli" erfunden.

Bei alldem, was ich in den letzten 1,5 Jahrzehnten so gemacht habe, 
hätte ich niemanden gehabt, der mir die nötigen "Stimuli" hätte liefern 
können.
Beitrag #6681030 wurde von einem Moderator gelöscht.
Gast #6681062
Lesenswert?

Jörg W. schrieb:

> Ich wollte dir gerade was antworten – aber mit der Ausdrucksweise hast
> du hier im Forum nichts verloren. Außerdem ist das für den Thread eh
> völlig off-topic.

Aha, schon wieder mal erfolgreich die offensichtliche Wahrheit 
unterdrückt.

Mach' ruhig weiter weiter so. Als Moderator kann man das ja, das lädt ja 
geradezu zum Machtmißbrauch ein...

Also ersetze meinetwegen "Wichse" durch "Mist" oder eine noch zarteren 
Ausdruck, der dir gefällt, aber immer noch meine negative Wertung der 
entsprehchenden Software-Werke deutlich darstellt und stelle das Posting 
wieder online.

Alles andere zeigt nur, dass du an einer Diskussion nicht wirklich 
interessiert bist. Jedenfalls nicht, wenn sie deiner Ideologie und 
deinen Intentionen widerspricht...

Dass es nicht in den Thread passt, ist natürlich ein vorgeschobenes 
Argument. Wenn das wirklich der Grund wäre, hättest ja auch du dein Maul 
halten müssen, denn du warst es ja selber, der diesen Zweig der 
Diskussion angestoßen hat...

Also, komm mal runter von deiner Zensor-Bank und lerne, dich mit dem 
realen Leben auseinader zu setzen. Ja, das ist kein Ponyhof.
Moderator Persönliche Seite #6681065
Lesenswert?

c-hater schrieb:
> Jörg W. schrieb:
>
>> Ich wollte dir gerade was antworten – aber mit der Ausdrucksweise hast
>> du hier im Forum nichts verloren. Außerdem ist das für den Thread eh
>> völlig off-topic.
>
> Aha, schon wieder mal erfolgreich die offensichtliche Wahrheit
> unterdrückt.

Nein, aber deine ungehobelte Ausdrucksweise darfst du für dich behalten.

Die Inhalte, die du rüber bringen willst, kannst du auch in einer 
vernünftigen Wortwahl formulieren.

In diesen Thread gehört das eh nicht rein. Falls dich eine Erklärung 
wirklich interessiert, warum die Geschichte mit den Stimuli nicht 
machbar war, dann kannste mir gern eine Mail schreiben. Wenn diese auf 
Fäkal- und vergleichbare Worte verzichtet, schreibe ich dir eine 
sachliche Antwort.
#6681148
Lesenswert?

c-hater schrieb:
> wofür man in C zumindest als Warnung
> um die Ohren gehauen bekommen würde: ein Lesezugriff auf eine nicht
> initialisierte Variable (in diesem Fall natürlich ein Register, aber das
> spielt bezüglich der Auswirkungen keine Rolle).

Um Überraschungen zu vermeiden, kann man am Anfang RAM und Register 
löschen. Viel Code ist das nicht:
1
setstack:
2
    ldi r16, low(RAMEND)  ; 4c, 8b Stack
3
    out SPL, r16
4
    ldi r16, high(RAMEND)
5
    out SPH, r16
6
ramnull:                 ; RAM -> 0, 18b
7
    ldi  ZL,Low(SRAM_START)
8
    ldi  ZH,High(SRAM_START)
9
    clr  r16
10
ramnull_:  
11
    st   Z+,r16
12
    cpi  ZH,High(RAMEND+1)
13
    brne  ramnull_
14
 
15
    cpi  ZL,Low(RAMEND+1)
16
    brne  ramnull_
17
regnull:                    ; Reg ->0 156c 10b
18
    ldi  ZL, 30                
19
    clr  ZH                
20
    dec  ZL
21
    st  Z, ZH
22
    brne PC-2
So kann man sicher sein, daß alle Variablen nach Reset 0 haben und 
nichts sonst.
#6681309
Lesenswert?

Oliver S. schrieb:
> Da ein Reset beim AVR die nicht auf Null
> zurücksetzt, können solche Effekte auftreten.

Hi,
genau dies wurde in einem anderen Thread als Esotherik verschrien.
Beitrag "Re: Initialisierung 204b LCD mit ST7066U"
Ich mache bei meinen LCDs-Progs immer folgendes:
Nach Stapelzeiger Init, SRAM löschen.
Dann Routinen für LCD-Init
dann Routinen für Zahlenumrechnung
ASCII Encoder abfragen,
dann zeigt mir das Display z.B. 65 ....A an.
So weiß ich, dass das Display und Programmroutinen laufen.
Erst dann kommen Init Sequenzen für UART init, etc. pp.

ciao
gustav
Angehängte Dateien:
#6681343
Lesenswert?

Oliver S. schrieb:
> Nur springst du direkt auf EE_Read_L_loop, und damit knallt das dann
> nach Reset unter Power.

Auch wenn ich diesen Hinweis noch immer nicht verstehe, meine ich 
zumindest das angesprochene Problem verstanden zu haben.

> Schreib alt an den
> Anfang des Programms ein „clr Cnt“, und schau, das dann passiert.

Du hast offensichtlich übersehen was am Anfang steht:
1
EE_Read_L:                
2

3
  clr    Cnt
4

5
EE_Read_L_loop:

Das Cnt nach EE_Read_L_loop: zu löschen macht keinen Sinn.

Maxim B. schrieb:
> Um Überraschungen zu vermeiden, kann man am Anfang RAM und Register
> löschen. Viel Code ist das nicht:

das werde ich mal versuchen.
#6681364
Lesenswert?

Wie schon gesagt, ich hab da keine Lust, sämtliche C&P Varianten des 
GLCD für links, rechts, page, EEPROM usw. zu prüfen.
Man macht sich das Leben deutlich einfacher, wenn das nur eine einzige 
Funktion ausklamüsert. Die Applikation ruft dann überall nur das eine 
generische out_xy_val auf.
Dann kann man auch erstmal diese eine Funktion gründlich testen, ob da 
Mist passiert. D.h. man testet jede einzelne Funktion für sich und 
betrachtet nicht das ganze Programm als einen großen monolithischen 
Block.

Aber das bleibt ganz Dir überlassen, weiter erfolglos den Fehler zu 
suchen.

Es ist natürlich nicht schön, daß es zu dem LCD kein vernünftiges 
Datenblatt gibt. Für mich wäre das ein Grund, es wegzuschmeißen bzw. 
erst gar nicht zu kaufen.
Diese Raterei, welcher der 3 Chips auf welche Kombination der CSx hört, 
ist nicht gerade prickelnd. Natürlich könnte man das mit einem 
Testprogramm erstmal ausprobieren, z.B. über die UART.
#6681393
Lesenswert?

Bruno M. schrieb:
> Hurra, es ist geschafft! Das war der entscheidende Hinweis und damit
> habe ich wieder etwas gelernt.

Du solltest trotzdem untersuchen, welche Speicherstelle Du verwendest, 
ohne sie zu initialisieren und sie dann explizit initialisieren.

Assembler initialisiert nichts automatisch und warnt nicht bei 
uninitialisierter Verwendung. Wieder ein Grund, zu C zu wechseln.
Gast #6681418
Lesenswert?

S. Landolt schrieb:
> das ständige Anpreisen von Assembler

Dieses ständige Herum-Eiern mit Assembler bei Hardware die es
eher verdient hat mit einer Batch-, BasicInterpreter- oder
Script-Datei gesteuert zu werden .....

Dieses ständige Herum-Eiern von Assembler-Programmierern die es
nicht schaffen die Programm-Bedingungen so einzurichten dass es
dem Assembler-Programmieren gerecht wird .....
#6681496
Lesenswert?

Bruno M. schrieb:
> Oliver S. schrieb:
>> Nur springst du direkt auf EE_Read_L_loop, und damit knallt das dann
>> nach Reset unter Power.
>
> Auch wenn ich diesen Hinweis noch immer nicht verstehe, meine ich
> zumindest das angesprochene Problem verstanden zu haben.
>
>> Schreib alt an den
>> Anfang des Programms ein „clr Cnt“, und schau, das dann passiert.
>
> Du hast offensichtlich übersehen was am Anfang steht:EE_Read_L:
>   clr    Cnt
> EE_Read_L_loop:
>
> Das Cnt nach EE_Read_L_loop: zu löschen macht keinen Sinn.

Du hast das Problem nicht verstanden.

Dein Programm startet so:
1
...
2
  sbi    LCDC, CS1        ;CS1 eingeschaltet
3
  sbi    LCDC, CS2        ;CS2 ausgeschaltet
4
  rcall  LCD_init
5
  rcall  delay500ms
6
  rcall  LCD_init
7
  rcall  Bild_Aus
8
  rcall  Grafik
9
  rcall  EE_Read_L_loop    ;damit Grafik sofort angezeigt wird
10
  rjmp  Start

Du springst direkt auf EE_Read_L_loop, damit wird Cnt nicht gelöscht. 
EE_Read_L_loop schreibt damit Unsinn auf das Display.

Ich habe jetzt deine ganze Hardware nicht, daher kann ich nichts sagen, 
ob das mit einem Sensor, der den Capture-ISR auslöst, kurz darauf wieder 
richtig geschrieben würde. Das musst du schon selber rausfinden.

Auch im weiteren Ablauf sind einige Dinge fraglich:
1
Start:              ;Timerwert steigende Flanke verarbeiten
2
  lds  temp, Marke2H
3
  tst  temp
4
  breq  Start
5
...
Marke2H wird nie auf Null gesetzt, sonder nur in der Capture-ISR in 
_IN_Capt: beschrieben.
1
;Interrupt zur Erfassung der PWM Werte des Sensors
2
IN_Capt:            
3
;mit steigender Flanke wird der Timer gestartet
4
  push  temp
5
  push  temp1
6
  in    temp1, SREG
7
  cpi    Flag, 1        ;Flag H, L gesetzt?
8
  brsh  _IN_Capt
9
  clr    temp
10
  sts    TCNT1H, temp    ;Timerwerte löschen
11
  sts    TCNT1L, temp
12
  ldi    temp, (1<<ICNC1)|(1<<ICES1)|(1<<CS12)  ;Timer 1 auf Input Capture steigende Flanke und prescaler 256
13
  sts    TCCR1B, temp
14
  inc    Flag
15
  out    SREG, temp1
16
  pop    temp1
17
  pop    temp
18
reti
Du ahnst vermutlich schon, was jetzt kommt: Flag wird natürlich auch nie 
gelöscht, ob und wann und warum damit _IN_Capt: überhaupt jemals 
angsprungen wird, keine Ahnung. Wie gesagt, ist deine Software, nicht 
meine.

Da aber izwischen von allen Seiten sehr deutlich gesagt wurde, was das 
Problem ist, lös es einfach.

Oliver
#6681672
Lesenswert?

Hallo Oliver,

danke für die verständliche Erklärung.

Das clr Cnt am Anfang ist logisch und sollte nicht passieren. Ich meine 
ich hatte es auch mal, aber bei nachträglichen Änderungen ist es 
verloren gegangen.

Was Marke2H angeht, muß ich allerdings nochmals nachhaken. Ich war 
bisher davon aussgegangen, daß ich nicht vorher löschen muß, wenn ich 
der Variablen sofort einen Wert zuweise. Wenn das nicht stimmt, dann 
müßte ich ja auch temp ganz am Anfang auf Null setzen.
#6681776
Lesenswert?

Bruno M. schrieb:
> Hurra, es ist geschafft! Das war der entscheidende Hinweis und damit
> habe ich wieder etwas gelernt.

Nur was SP betrifft: will man Code universell verwenden, sollte man 
berücksichtigen, daß manche Tinys ohne SPH sind. Außerdem sind bei zwei 
Tinys in ihren *.def statt SPL SP geschrieben. Deshalb wäre bessere 
SP-Einstellung am Anfang (hier als Macro) so:
1
#ifdef _4433DEF_INC_
2
  #define SPL SP
3
#endif
4
#ifdef _TN26DEF_INC_
5
  #define SPL SP
6
#endif
7

8
.set _MITSPH_ = 0
9

10
#ifdef _TN4DEF_INC_
11
  .set _MITSPH_ = 1
12
#endif
13
#ifdef _TN5DEF_INC_
14
  .set _MITSPH_ = 1
15
#endif
16
#ifdef _TN9DEF_INC_
17
  .set _MITSPH_ = 1
18
#endif
19
#ifdef _TN10DEF_INC_
20
  .set _MITSPH_ = 1
21
#endif
22
#ifdef _TN20DEF_INC_
23
  .set _MITSPH_ = 1
24
#endif
25

26
.macro setstack
27
  .if SRAM_SIZE > 0
28
    .if (SRAM_SIZE > 128)  || _MITSPH_
29
      ldi r16, low(RAMEND)  ; 4c, 8b     Stack
30
      out SPL, r16
31
      ldi r16, high(RAMEND)
32
      out SPH, r16
33
    .else 
34
      ldi r16, RAMEND      ; 2c, 4b
35
      out SPL, r16
36
    .endif
37
  .endif
38
.endm
#6681877
Lesenswert?

Oliver S. schrieb:
> Da aber izwischen von allen Seiten sehr deutlich gesagt wurde, was das
> Problem ist, lös es einfach.

Hab ich inzwischen gemacht. Testen will ich jetzt aber nicht mehr, 
nachdem ich die Löschroutine von Maxim B. an den Anfang gesetzt habe, 
funktioniert es ja.

Ich habe ja schon so einiges programmiert, aber mir wurde noch nie so 
deutlich eine mangelhafte Initialisierung - im wahrsten Sinne des Wortes 
- vor Augen geführt.
Gast #6681981
Lesenswert?

Cyblord -. schrieb:
> Und wieder andere hätte vielleicht Ahnung, aber absolut keine Lust sich
> den ASM Krampf reinzuziehen.

Ich finde es ist nett, etwas zum Laufen zu bringen und so hat es mich 
gefreut, dass das Ding letztendlich lief. Nicht jedem gefällt des TE's 
Code im Stile eines Dorian Gray Bildnisses, aber das muss man nicht 
pausenlos kundtun.
#6682166
Lesenswert?

MWS schrieb:
> Cyblord -. schrieb:
>> Und wieder andere hätte vielleicht Ahnung, aber absolut keine Lust sich
>> den ASM Krampf reinzuziehen.
>
> Ich finde es ist nett, etwas zum Laufen zu bringen und so hat es mich
> gefreut, dass das Ding letztendlich lief. Nicht jedem gefällt des TE's
> Code im Stile eines Dorian Gray Bildnisses, aber das muss man nicht
> pausenlos kundtun.

Wo tue ich das Pausenlos? Aber wenn man etwas öffentlich stellt muss man 
mit der Kritik leben. Es gibt halt keine Grund für das ASM Geraffel. Es 
macht den Code unnötig unübersichtlich ohne jeden Vorteil. Das nutzen 
nur Leute die es nicht anders können. Einmal ASM gelernt, nie wieder 
über den Tellerrand geschaut. Scheuklappen eben.
Gast #6682202
Lesenswert?

Cyblord -. schrieb:
> Wo tue ich das Pausenlos? Aber wenn man etwas öffentlich stellt muss man
> mit der Kritik leben.

Der TE hätte das nicht freiwillig öffentlich gestellt, wenn er selber 
noch weiter gewusst hätte. Da mache ich einen Unterschied zu jemandem, 
der solcherlei in Projekte & Code einstellt.

> Es gibt halt keine Grund für das ASM Geraffel. Es

Nein, für diesen Fall gibt es keinen Grund für ASM, außer eben den, dass 
sich der TE das angeeignet hat und sich mit seinen Fähigkeiten das eine 
oder andere zusammengestoppelt hat.

> macht den Code unnötig unübersichtlich ohne jeden Vorteil. Das nutzen
> nur Leute die es nicht anders können.

Es gibt ASM Programmierer, die auf ihrem Gebiet und mit ihren 
hardwarenah erstellten Modulen sicher dem einen der anderen 
Programmierer höherer Sprachen das Wasser reichen oder davonziehen 
können.

Der hier gezeigte Code kann da nicht mithalten, denn man kann auch in 
ASM modular und mit Funktionen programmieren, statt nur Blöcke 
hintereinander zu kopieren und leicht abzuändern.

> Einmal ASM gelernt, nie wieder
> über den Tellerrand geschaut. Scheuklappen eben.

Das ist doch aus dem Code erkennbar, dass der TE das nicht richtig 
gelernt, sonder sich selbst beigebracht hat und damit zufrieden ist. Den 
muss man nicht missionieren.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren