Hi,
spiel hier grad mit nem PIC18F25K22 rum.
[laber]
Bei der Gelegenheit wollte ich der bisher hervorragend funktionierenden
LCD-Routine, das dämliche 2ms warten austreiben. Ergebnis Display tot.
Ziemlich dumm auf den wahrscheinlich funktionierenden Code gestarrt...
OK alles retoure (Backup), noch mehr blöd guck... Als der Hamster wieder
auf dem Rad war, hab ich das fehlende Häkchen im Codeconfigurator
eindeckt... grr.. Erst mal'n Pfeif... ähh ne Zigarette angezündet.
So ab nu wird's lustig. Alles, bis auf eine Kleinigkeit, funktioniert
alles wie vorher.
[/laber]
Folgender Code produziert nicht wie gehabt die Ausgabe:
"xx.x°C"
Sondern:
"xx.x°B"
Also ASCII+1. Alle anderen Ausgaben auf dem LCD, sind Korrektor.
Ich habe nicht die geringste Idee wo ich da den Fehler suchen sollte?
Teo D. schrieb:> char PBuff[5]
Wie viele Zeichen möchtest du da gleich ausgeben, einschließlich
des terminierenden Nullzeichens?
> PBuff[++n] = NULL;
NULL ist per Konvention ein Zeiger, aber kein Nullzeichen. Das heißt
entweder einfach 0, oder wenn du's kompliziert magst, '\0'.
Jörg W. schrieb:> Wie viele Zeichen möchtest du da gleich ausgeben, einschließlich> des terminierenden Nullzeichens?
3(char) + 2(.,C) + 1(NULL) = 6
...°
Naja, die Rechnung stimmt wenigstens :(
DANKE
(kann mich garnicht erinnern da rumgepfuscht zu haben. Zeiger... hat
wahrscheinlich bisher nur zufällig funktioniert)
Jörg W. schrieb:> NULL ist per Konvention ein Zeiger, aber kein Nullzeichen. Das heißt> entweder einfach 0, oder wenn du's kompliziert magst, '\0'.
Hmm... laut Manual vom XC8 ist das auch (?) der Nullterminator für
"Strings"
Teo D. schrieb:> Hmm... laut Manual vom XC8 ist das auch (?) der Nullterminator für> "Strings"
Dann benutz' das Manual zum Entzünden des nächsten Lagerfeuers.
Vielleicht eignet es sich ja wenigstens dafür. ;-)
Teo D. schrieb:> Hmm... laut Manual vom XC8 ist das auch (?) der Nullterminator für> "Strings"
Ja. Numerisch sind NULL, 0, '\0' alles dasselbe. Eine binäre 0.
Aber die Intention von NULL ist es, einen ungültigen Pointer Wert
anzuzeigen. Die Betonung liegt auf Pointer. NULL wird also per
Konvention im Umfeld von Pointern verwendet. Niemand klopft dir auf die
Finger, wenn du es in einem anderen Umfeld benutzt. Aber die Verwirrung
ist gross. Denn was hat denn der Inhalt einer char Variablen mit einem
Pointer zu tun? Gar nichts.
Das ist ungefähr so, wie wenn du schreibst
1
doubleradius='a';
2
doubleumfang=2*radius*3.1415926;
kannst du machen. Als Character hat 'a' einen Ascii Code, diese Codezahl
wird zu einem double gewandelt und zugewiesen. Syntaktisch ist da nichts
falsch drann.
Trotzdem ist es wohl in den meisten Fällen verwirrend.
Solche Dinge fallen unter den Oberbegriff der 'aktiven
Arbeitsplatzsicherung'.
Teo D. schrieb:> Da hab ich wohl zu sehr den Ausdruck "null terminated" mit "#define NULL> '\0'" assoziiert :)>> OK, also lieber "=0" oder "='\0'".
Probier mal, ob dein System ein #define für NUL (mit 1 L) hat. Das wäre
dafür gedacht, den 0-Character auszudrücken.
Nö, hat er nich. Egal, schreib den Mist ja eh nur für mich.
Momentan nervt mich mehr daß mir das,
1
boolLCD_Bussy(void){
2
boolx;
3
LCD_D3_SetDigitalInput();
4
LCD_RS_LAT=0;
5
LCD_RW_LAT=1;
6
// __delay_us(25);
7
x=LCD_D3_PORT;
8
LCD_D3_SetDigitalOutput();
9
return(x);
10
}
scheinbar kein BussyFlag aus dem LCD entlockt. Liest ständig Hi ein!
Nicht mein Tag Heute, steh sicher wiedermal nur auf'm Schlauch :(
PS:Dabla nach Besonderheiten der Pins durchforstet! Nix.
Morgen mal den "Code Configurator" überprüfen, ob der auch wirklich
alles so wie gewollt generiert hat. Wär nicht das erste mal das nicht.
neuer PIC Freund schrieb im Beitrag #4295017:
> Müsste es nicht>> 3(char) + 3(.,C,°) + 1(NULL) = 7>> heißen?
Jup und dank Jörg W. ist's mir auch aufgefallen das da was fehlt.
Lustig ist halt, das das mehrere Tage problemlos funktioniert hat (trotz
ständigen Programmänderungen).
Teo D. schrieb:> Jup und dank Jörg W. ist's mir auch aufgefallen das da was fehlt.> Lustig ist halt, das das mehrere Tage problemlos funktioniert hat (trotz> ständigen Programmänderungen).
Merke.
Nicht jeder Fehler führt sofort zu einem Problem.
Durch Testen kann man immer nur die Anwesenheit von Fehlern feststellen.
Nie die Abwesenheit.
Teo D. schrieb:> Hmm... laut Manual vom XC8 ist das auch (?) der Nullterminator für> "Strings"
Ich wette da steht "NUL" und nicht "NULL".
Teo D. schrieb:> Momentan nervt mich mehr daß mir das,> bool LCD_Bussy(void) {> bool x;> LCD_D3_SetDigitalInput();> LCD_RS_LAT = 0;> LCD_RW_LAT = 1;> // __delay_us(25);> x = LCD_D3_PORT;> LCD_D3_SetDigitalOutput();> return (x);> }> scheinbar kein BussyFlag aus dem LCD entlockt. Liest ständig Hi ein!
Busy schreibt mal üblicherweise mit nur einem s.
Funktioniert es wenn das 25us Delay NICHT ausgeklammert ist? Ich kenne
zwar dein uC nicht, aber kann mir vorstellen das er sich ein bisschen
Zeit nehmen möchte um die Port-Richtung zu ändern.
beric schrieb:> Busy schreibt mal üblicherweise mit nur einem s.
Ubs, (danke)
Klar hab ich das getestet, deshalb steht das ja auch noch da. Kommt zum
weiter testen aber wieder rein. Hab kein original Dabla, nur
Pinbelegung, Spannungen und "kompatibel mit HD47...". Pollin Zeugs halt.
Wer weiß wie lang das teil zum umladen der Gatekapazität braucht.
beric schrieb:
Ich weis ja nicht, welches LCD du benutzt, aber das kommt mir komisch
vor
1
boolLCD_Bussy(void){
2
boolx;
3
LCD_D3_SetDigitalInput();
4
LCD_RS_LAT=0;
5
LCD_RW_LAT=1;
6
// __delay_us(25);
7
x=LCD_D3_PORT;
8
...
kein Übernahmepuls? Oder sonst irgendeine Benachrichtigung nach dem
Muster 'jetzt gilts'?
Einfach nur R/S auf 0 setzen, RW auf 1 und das wars?
Kann ich mir nicht vorstellen.
>> kein Übernahmepuls? Oder sonst irgendeine Benachrichtigung nach dem> Muster 'jetzt gilts'?> Einfach nur R/S auf 0 setzen, RW auf 1 und das wars?> Kann ich mir nicht vorstellen.
Schaun wir mal, wie Grossmeister Fleury das macht
1
staticuint8_tlcd_waitbusy(void)
2
3
{
4
registeruint8_tc;
5
6
/* wait until busy flag is cleared */
7
while((c=lcd_read(0))&(1<<LCD_BUSY)){}
ok. also die Funktion lcd_read macht das.
1
staticuint8_tlcd_read(uint8_trs)
2
{
3
uint8_tdata;
4
5
6
if(rs)
7
lcd_rs_high();/* RS=1: read data */
8
else
9
lcd_rs_low();/* RS=0: read busy flag */
10
lcd_rw_high();/* RW=1 read mode */
11
12
blablabla
13
14
lcd_e_high();
15
lcd_e_delay();
16
data=PIN(LCD_DATA0_PORT)<<4;/* read high nibble first */
17
lcd_e_low();
18
19
...
AHA!!!
Also doch einmalig mit dem E-Pin wackeln.
Ist auch logisch so.
Woher soll denn das LCD wissen, wann du fertig bist mit dem Einstellen
der Steuerleitungen.
Karl H. schrieb:> AHA!!!> Also doch einmalig mit dem E-Pin wackeln.
Davon steht aber in meinem Dabla nix :(
OK, sorry, ist kein original HD47... Hat wohl etwas gelitten, beim
abschreiben und übersetzen. Sieht aber dem Original zum verwechseln
ähnlich. Werd das mal genauer vergleichen.
Werd's später mal wackeln lassen :)
> Ist auch logisch so.> Woher soll denn das LCD wissen, wann du fertig bist mit dem Einstellen> der Steuerleitungen.
Ich dachte, das hat wohl nichts direkt mit dem Prozessor zu tun, sondern
da antwortet ein einfaches Logikgatter.
Ach ja....
beric schrieb:> Ich wette da steht "NUL" und nicht "NULL".
VERLOREN ;P
Da steht was von "Nullterminator, null terminated" und '\0'. "NUL" oder
"NULL" wird da nirgends erwähnt.
"NUL" ist im xc8 nicht definiert.
Teo D. schrieb:> Ich dachte, das hat wohl nichts direkt mit dem Prozessor zu tun, sondern> da antwortet ein einfaches Logikgatter.
Das Datenblatt ist da etwas seltsam. Zum einen suggeriert es das,
was du da rausgelesen hast, andererseits siehe Bild, die read operation
bekommt in den Timing-Diagrammen ganz normal ihre Timing-Werte.
Ich hab' sie jedenfalls bisher auch immer als kompletten Buszyklus
(mit E-Impuls und allem) behandelt, und das hat funktioniert. ;-)
Ach, ihr streitet euch mal wieder um des Kaisers Bart.
Offenbar geht es darum, daß der TO eine Art Dezimalpunkt in seine
Zeichenfolge haben möchte, aber sich scheut, deswegen auf float
umzusteigen. Nun ja, dann eben so:
Hab's mal aus einem steinalten Projekt herausgekramt.
Aber nochwas: Der Titel des Threads ist voll daneben. Sowas hat mit
LCD's überhaupt nichts zu tun, sondern nur mit des TO's Problem beim
Einfügen eines Zeichens. Besser: "wie füge ich ein Zeichen in eine
Zeichenkette ein?"
W.S.
W.S. schrieb:> Offenbar geht es darum, daß der TO eine Art Dezimalpunkt in seine> Zeichenfolge haben möchte, aber sich scheut, deswegen auf float> umzusteigen.
Nein, das war geklärt. Mittlerweile geht's um das Busy-Flag eines
HD44780.
W.S. schrieb:> Ach, ihr streitet euch mal wieder um des Kaisers Bart.
Äh.. NÖ
> Offenbar geht es darum, daß der TO eine Art Dezimalpunkt in seine> Zeichenfolge haben möchte,
Nein, ging es NIE!
> aber sich scheut, deswegen auf float umzusteigen.
NUR um da einen Dezimalpunkt zu erhalten und dann doch noch die zwei
extra Zeichen dazu pfuschen? NEIN, da stell ich mich doch lieber
neben's LCD und pinsle das mit der Hand drauf ;)
W.S. schrieb:> Aber nochwas: Der Titel des Threads ist voll daneben.
Ämmm... JA.
> Besser: "wie füge ich ein Zeichen in eine> Zeichenkette ein?"
NEIN, darum ging's hier NIE
Jörg W. schrieb:> Teo D. schrieb:>> Ich dachte, das hat wohl nichts direkt mit dem Prozessor zu tun, sondern>> da antwortet ein einfaches Logikgatter.>> Das Datenblatt ist da etwas seltsam. Zum einen suggeriert es das,> was du da rausgelesen hast, andererseits siehe Bild, die read operation> bekommt in den Timing-Diagrammen ganz normal ihre Timing-Werte.
Dazu kommt noch die Angabe von 0µs als Antwortzeit!? Ist aber sicher
ein Fehler in meinem Ausdruck, da hat sich wohl ne Zahl verflüchtigt
:)
Alles wackeln am Enable-Pin, auf die eine o. andren Art, hat erst mal
nix genutzt.
Werde da erstmal ein vertrauenswürdigeres LCD dranhängen.
Hab obiges noch im Original gefunden.
Ergibt bei mir sicher >7µs. Da bisher nicht beachtet, haut das natürlich
in meinem Progrämmchen nicht hin (höchstens 2-4µs).
Übrigens lässt mich der Original Dabla wieder glauben das da nicht am
Enable gewackelt werden muss. Da ist noch ein Blockschaltbild zu sehen,
in dem die Enable-Funktion als gesonderter Block dargestellt wird!?
http://www.alldatasheet.com/datasheet-pdf/pdf/63673/HITACHI/HD44780.html
Teo D. schrieb:> Hab obiges noch im Original gefunden.
Das ist aber nur der Update des Adresszählers, falls du ihn
abfragen willst.
Eine Seite davor ist die interessante Stelle (ich bin jetzt gerade
anderweitig drüber gestolpert):
1
Table 6 Instructions
2
Execution Time
3
Code (max) (when f cp or
4
Instruction RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0 Description f OSC is 270 kHz)
5
…
6
Read busy 0 1 BF AC AC AC AC AC AC AC Reads busy flag (BF) 0 µs
7
flag & indicating internal operation
8
address is being performed and
9
reads address counter
10
contents.
Das heißt, dass das Lesen des Busy-Flags (und des Adresszählers)
ein ganz normaler Befehl wie jeder andere ist, also RS = 0 (da Befehl
und nicht Daten), R/W = 1 (da gelesen werden soll). Implizit ist
dabei wie bei jeder anderen Aktion ein Impuls an E. Wesentlicher
Unterschied gegenüber allen anderen Befehlen ist, dass er keine
eigene Ausführungszeit benötigt, d. h. es darf sofort danach ein
neuer Befehl gesendet werden.
Aber einfach nur RW auf 1 setzen und RS auf 0 genügt nicht.
So, inzwischen läuft meine eigene Implementierung auch auf dem SAMD20.
Da ich sowieso zum Vergleich noch das Diagramm meiner älteren
AVR-Implementierung auf dem LA hatte, hier dieses mal zur Illustration.
Es wird zuerst das Zeichen 'A' (0x41) ausgegeben, jeweils beide
Halbbytes. Danach werden immer zwei Halbbytes gelesen, die das Busyflag
sowie den aktuellen Adresszähler beinhalten. Man sieht gut, wie das
von anfangs 0x84 auf danach 0x05 weitergeht.
Danke für die Infos :)
Hatte bisher keinen Bock mich mit dem Mist zu beschäftigen.
Tabelle 6 klärt fast alles auf. Auf Grund meiner bisherigen
Versuche, stellt sich mir noch die Frage:
Welches Nibble purzelt den da zuerst raus?
Ich bin bisher davon ausgegangen das es das Hi-Nbble ist. Das Dabla
schweigt sich darüber leider aus.
Teo D. schrieb:> Ich bin bisher davon ausgegangen das es das Hi-Nbble ist.
Wenn du dir den LA-Trace oben ansiehst, kannst du recht gut erkennen,
dass es genau so auch ist. Da kommt eine 4 gefolgt von einer 1 (0x41
für den Buchstaben 'A'), danach 8 - 4, 8 - 4, 0 - 5.
Ich hab' nochmal rote Striche an die relevanten Zeitpunkte gezeichnet.
Jörg W. schrieb:> Da kommt eine 4 gefolgt von einer 1 (0x41> für den Buchstaben 'A'), danach 8 - 4, 8 - 4, 0 - 5.
Jup, Danke.
(Die 1 dazwischen kommt sicher von deinem Prozi (letztes Write))
So, genug gelöchert, nu wird's Zeit mich da mal wieder selber zu
bemühen. Hab schon einen Verdacht, wo noch so ein "ich dachte",
zugeschlagen hat. Aber was will man sonst auch tun, wenn das Dabla nicht
mehr hergibt :(
Muss nur noch alle größeren Werkzeuge, explizit die Hämmer, verräumen :)
Teo D. schrieb:> (Die 1 dazwischen kommt sicher von deinem Prozi (letztes Write))
Ja, der schaltet ja anschließend die Pins wieder auf Ausgang, damit
sie nicht „in der Luft hängen“. In dem Moment wird dann wieder das
auf den Bus gelegt, was als letztes ausgegeben worden war.
Entscheidend ist immer nur, was zum Zeitpunkt des E-Impules passiert.