Hallo, habe jetzt endlich mein LCD zum laufen gebracht. Die Ausgabe von Strings ist mal schon kein Problem mehr. Habe jetzt den Wert "x" aus dem ADC, in dem die Binärzahl zum eingelesenen Wert gespeichert ist. (Nicht im angehängten Programm dabei) Nun möchte ich "x" auf das LCD schreiben (bzw. den Inhalt von "x") Lösungsvorschläge für Programmerweiterung Danke
Das wurde doch hier schon 'zigmal gefragt und beantwortet. http://www.mikrocontroller.net/forum/forum.php?query=%2Blcd+%2Bzahl+%2Bascii&forums%5B%5D=1&number=100&action=sendsearch ...
Naja, danke aber das Hilft mir nicht weiter keine Vorschläge wie ich mein Programm bzw. die Routine erweitern kann.? schaut euch mal mein programm an bitte.
Warum kein lesbarer Klartext? Meist du, ich lade mir ein Archiv herunter, entpacke es und mülle mir die Platte zu??? Was der Browser nicht direkt anzeigt, das schau ich mir nicht an. Denn nicht ich habe Interesse daran, mir das anzuschaun, sondern du. - Sorry, ist aber so. ...
/* LCD Include-Datei * PC4 = RS * PC5 = Enable * PC0-PC3 = D4-D7 * R/W ist n.c. */ #include <avr/io.h> #include <avr/delay.h> #define delay(us) _delay_loop_2 (((12000000/4000)*us)/1000) // wartet µs // Enable-Leitung toggeln void lcd_flash_e () { PORTD = PORTD | ( 1<<DDC5 ) ; // Enable = HIGH delay(1); // kurz warten, damit Flanke entsteht PORTD = PORTD & ~( 1<<DDC5 ) ; // Enable = LOW delay(64); // Warten, bis der durch Enable angelegte Befehl hoffentlich verarbeitet wurde } // Kommando oder Zeichen an Display senden: rs=0 => Kommando, rs=1 => Zeichen void lcd_write (uint8_t data, uint8_t rs) { uint8_t dataBits ; if (rs) // write data (RS=1, RW=0) dataBits=0x10; // RS liegt an Pin 4 = B 0001 0000 = H 10 else // write instruction (RS=0, RW=0) dataBits=0; PORTD = dataBits |(data>>4); // output high nibble first, zzgl. Zustand für RS-Leitung lcd_flash_e (); PORTD = dataBits | (data&0x0F); // output low nibble, zzgl. RS-Leitung lcd_flash_e (); delay(2000); } // Display loeschen void lcd_cls () { lcd_write(0x02,0); // B 0000 0010 => Display loeschen delay(2000); // dauert eine Weile, Wert ausprobiert lcd_write(0x01,0); // B 0000 0001 => Cursor Home delay(2000); // dauert eine Weile, Wert ausprobiert } // Zeichenausgabe void lcd_writechar ( char zeichen) { lcd_write (zeichen, 1); } // gibt eine Zeichenkette auf dem LCD aus void lcd_writetext ( char *text) { uint8_t i = 0; while (text[i]!=0) { lcd_writechar(text[i]); i++; } } // Zeilenwechsel void lcd_gotoline (uint8_t zeile) { if (zeile == 1) lcd_write(0x80,0); // B 1000 0000 => DD-RAM Adress Set 1. Zeile/1.Spalte if (zeile == 2) lcd_write(0xC0,0); // B 1100 0000 => DD-RAM Adress Set 2. Zeile/1.Spalte (B x100 0000 = H 40) } // Cursorpositionieren (Zeile, Spalte) void lcd_gotopos (uint8_t zeile, uint8_t spalte) { if (zeile == 1) lcd_write(0x80+spalte-1,0); // DD-RAM Adress 1. Zeile + Spalte if (zeile == 2) lcd_write(0xC0+spalte-1,0); // DD-RAM Adress 2. Zeile + Spalte } // Display initialisieren. Einmal als erstes aufrufen void lcd_ini () { DDRD = 0x3F; // setze Portrichtung (1 = Ausgang): 0011 1111 PORTD=0x00; // alle Leitungen LOW delay(10000); // 10ms warten bis LCD wirklich bereit (max. Wert lt. Datenblatt) lcd_write(0x38,0); // B 0010 1000 => 8-Bit-Modus aktivieren, Ist wichtig, falls LCD schon im 4-Bit Modus war und dann // nach einem Programm-Reset vergeblich versucht würde, den 4-Bit Modus erneut zu aktivieren lcd_write(0x2,0); // B 0000 0010 => mit 8-Bit-Command in 4-Bit-Modus umschalten lcd_flash_e (); // Enable delay(1000); // sicherheitshalber warten // ab jetzt 4-Bit-Modus lcd_write(0x28,0); // B 0010 1000 => Function Set: 4Bit (kein 8-Bit Bus), zweizeiliges Display, 5x7 Dots/Zeichen (kein 5x10) lcd_write(0x0C,0); // B 0000 1100 => Display On/Off: Display ein, Cursor aus, Blinken aus lcd_write(0x06,0); // B 0000 0110 => Entry Mode Set: DD-RAM autom. inkr., Cursor bewegen lcd_cls(); // Display löschen } PROGRAMM: #include "lcd_routine.h" void main() { lcd_ini(); lcd_gotopos (1, 6); lcd_writetext ("Test"); lcd_gotopos (2, 5); lcd_writetext ("Klappt!"); while(1); } ------------------------------------------------------------------ SO. DANKE
Sorry, da muss ich dich leider enttäuschen. Von C habe ich keine Ahnung, ich programmiere in ASM, das ist für mich übersichtlicher und verständlicher. Ein Beispiel für formatierte Ausgabe von Zahlen sowie Ausgabe von indizierten Menütexten findest du hier: http://www.hanneslux.de/avr/zuenduhr/index.html Allerdings wird da nicht der ADC-Wert ausgegeben. Aber vielleicht findet sich ja jetzt, wo dein Quelltext lesbar ist, Hilfe von Jemandem, der C versteht. ...
Was Du brauchst, ist eine Funktion, die einen int nimmt, daraus eine String-Repraesentierung deiner Zahl baut und diesen String dann ueber die vorhandene String- Ausgabe-Funktino ausgibt. Schau Dir mal die C-Funktion sprintf() an. Und Hannes hat recht: Das wird so ziemlich >15 mal pro Woche gefragt. Wenn du ernsthaft programmieren willst, dann wirst du lernen muessen, Informationen zu suchen und anderer Leute Code zu analysieren. Vor allem wenn Dir Hannes bereits eine Link-Liste mit relevanten Threads vorgibt.
Kann es sein, dass diese Funktion Integer TO Ascii wandeln soll und daher den "sprechenden Namen" "ITOA" hat??? 8-) Ich kann immer noch kein C, aber wenn man lange genug mit shit beschmissen wird, fängt man eines Tages an zu stinken... ...
Koennte sein :-) Das Problem ist, dass _itoa() oder itoa() keine Standardfunktion ist. D.h. sein Compiler kann sie haben, muss aber nicht. Ein Blick in die Doku kann das klaeren.
Waschen hilft... Man kann sich ITOA auch selber basteln, wenn man es schon nicht selber findet. Vielleicht sollten gewisse Leute lieber die Programmiersprache (oder sogar die Tätigkeit) wechseln, wenn sie nicht gewillt sind, sich selber um die Lösung trivialer Probleme zu kümmern. Komischerweise liegt meine C-Bibel immer mit auf dem Schreibtisch...
> Waschen hilft... :-) Ich meinte damit aber, dass im Laufe der Zeit etwas im Gedächtnis hängen bleibt, weil ja diese Fragen und Antworten häufiger auftreten. > Man kann sich ITOA auch selber basteln, wenn man es schon nicht > selber findet. Nunja, ich bastele meine Routinen grundsätzlich selber und wenn ich mir mal einen "gefundenen" Algorithmus zu eigen mache, dann habe ich ihn zumindest verstanden. Dadurch sind meine Programme zwar nicht optimal, aber selbstgemacht und selbst verstanden. > Komischerweise liegt meine C-Bibel immer mit auf dem Schreibtisch. Das ist bei mir das Englisch-Wörterbuch, was das Lesen der Datenblätter relativ mühsam macht. Und trotzdem erwische ich mich immer wieder dabei, dass ich in AVR-Datenblättern nachschaue, um hier Fragen zu beantworten, bei denen der Fragesteller es selbst nicht für nötig hielt, ins Datenblatt zu schaun. ...
www.dict.cc <== liegt auch quasi auf meinem Schreibtisch (ich meinte den in der Firma; zuhause liegen die Sachen auf der Fensterbank, weil der Schreibtisch schon voll ist...). Prinzip von ITOA (jetzt mal so aus den Fingern gesogen): nimm die Zahl, gucke nach, ob sie negativ ist -> -Zeichen Nimm den Betrag der Zahl, teile sie durch die grösste 10er-Potenz (also bei 16-Bit-Integer 10000) Das Ergebnis + '0' ist das erste Zeichen in deinem String Multipliziere das Ergebnis mit der 10er-Potenz und subtrahiere es von der Zahl. Mit der nächst kleineren 10er-Potenz macht man das gleiche,... bis die 10er-Potenz = 1 ist. dann wird nur noch Zahl + '0' an den String angehängt. Das kann man bestimmt auch eleganter lösen, hab ich mir aber eben nur mal so aus den Fingern gesogen. Ich übernehme auch keine Gewähr, dass das so problemlos funktioniert.. (es gibt hier im Forum bestimmt eine schönere Lösung...) @Datenblatt: Mit manchen Problemen hat man ja noch nichts zutun gehabt, deswegen gucke ich dann auch gerne mal ins Datenblatt. So lernt man wieder was...
Hallo Ich verfolge den Thread mit Interesse und etwas Abscheu ;-) > nimm die Zahl, gucke nach, ob sie negativ ist Wie man DAS bewerkstelligt war mir noch nie klar! WIE geht das bei den AVRs, mit den negativen Zahlen und dem Rechnen damit? Dürfte wohl nicht allzu kompliziert zu verstehen sein, aber leider habe ich noch nirgends eine Quelle gefunden, die es kurz und schlüssig erklären könnte. Datenblatt und Befehlscode helfen da auch nicht wirklich weiter. Gruss Michael
Google nach 2-er Komplement Grundsaetzlich und in Kuerze: Dem Prozessor sind negative Zahlen sch...egal, genauso wie ihm Character oder sonstiges egal sind. Tief im Inneren ist alles eine ganze Zahl (auch Befehle!) Wie kommen dann negative Zahlen, etc. ins Spiel? Das ist alles eine Frage der Interpretation, d.h. wie ich als Programmierer eine Zahl ansehe und verwende. Eine Zahl die ich dem Prozessor zum Frass vorwerfe, wird vom Prozessor als Befehl eine bestimmte Aktion auszufuehren interpretiert. Schicke ich dieselbe Zahl an ein Terminal, dann stellt dieses vielleicht dafuer eine kleine Minigraphik (Pixel an/aus) dar, dass fuer mein Gehirn wie der Buchstabe 'A' aussieht. Andere Zahlen sind einfach nur dass: Zahlen. Zahlen kommen in 2 Kategorien: mit und ohne Vorzeichen. Wiederum: ob eine Zahl ein Vorzeichen hat oder nicht, kann man der Zahl nicht ansehen, ist alles eine Frage der Interpretation. Mit anderen Worten das bestimme ich, der Programmierer. Und so funktionierts konkret bei Verwendung des 2-er Komplements: Sagen wir mal, dass unsere Zahlen aus 8 Bit bestehen sollen. 0000 0000 Hier sind sie. Dann kann man ja mit diesen 8 Bit durch unterschiedliche 1 Bits die Zahlen von 0 bis 255 darstellen. Ich kanns aber auch anders machen. Ich kann ganz einfach ein Bit dafuer reservieren, dass es mir anzeigt, ob diese Zahl nun negativ ist oder nicht. Meist nimmt man dazu das MSB (most significant bit, oder ganz einfach das am weitesten links stehende Bit). 1000 0101 das koennte jetzt die Zahl (ohne Vorzeichen) 0x85, dez. 133 sein, oder aber es koennte die Zahl -5 sein (msb gesetzt, der Rest ergibt 5, msb gesetzt bedeutet - ) Ist eine Moeglichkeit. Die benutzt man in der Praxis aber nicht wirklich, da es eine bessere Moeglichkeit gibt, negative Zahlen darzustellen: das 2-er Komplement Dabei werden alle Bits umgedreht ( 0->1, 1->0) und dann noch 1 dazugezaehlt. Wenn ich also das Bitmuster fuer -5 im 2-er Komplement bestimmen will, dann geht das so: 5 hat das Bitmuster 0000 0101 alle Bits umdrehen 1111 1010 und 1 addieren 1111 1011 Die Bitdarstellung von -5 lautet also: 1111 1011 Das MSB zeigt mir wiederum an, dass es sich um eine negative Zahl handelt. Aber nur wenn ich das so interpretieren will. Wenn ich das nicht will, dann ist 1111 1011 ganz einfach die Dezimalzahl 251. OK. Ein paar Beispiele Grundlage 2-er Komplement: 0001 0011 Das MSB ist 0, also ist das eine positive Zahl Welche? 1 + 2 + 16 -> 19. Also +19 1001 0011 Das MSB ist 1, also ist das eine negative Zahl Welche? Dazu wenden wir wieder das 2-er Komplement an: alle Bits umdrehen 0110 1100 und 1 addieren 0110 1101 1 + 4 + 8 + 32 + 64 -> 109 Das Bitmuster entspricht also der Zahl -109 Warum macht man so komische Verrenkungen mit dem 2-er Komplement. Ganz einfach: Weil man dann bei Addition und Subtraktion nichts spezielles beruecksichtigen muss. Man Addiert oder Subtrahiert einfach dahin und hinten kommt alles richtig raus: Bsp: -3 + 5 -3 ( 0000 0011 -> 1111 1100 -> 1111 1101 ) +5 ( 0000 0101 ) --------------------------------------------- 1 0000 0010 Da wir nur ein 8 Bit Ergebnis kriegen koennen, faellt das Bit ganz links (das 9. Bit) weg, und wir erhalten 0000 0010 oder +2 dezimal. 20 - 78 20 ( 0001 0100 ) -78 ( 0100 1110 -> 1011 0001 -> 1011 0010 ) ------------------------------------------- 1100 0110 Da in diesem Ergebnis das MSB gesetzt ist, handelt es sich wieder um eine negative Zahl. Nur welche? 1100 0110 -> 0011 1001 -> 0011 1010 Und das ist das Bitmuster fuer 58. Also ist 1100 0110 das Bitmuster fuer -58 Wiederrum: Wenn ich das so interpretieren will! Wenn ich das nicht so interpretieren will, dann steht das MSB ganz einfach seiner Bitposition entsprechend fuer 128 und 1100 0110 ist ganz einfach die Zahl 198. -3 + 5
>> nimm die Zahl, gucke nach, ob sie negativ ist >Wie man DAS bewerkstelligt war mir noch nie klar!
1 | if( Zahl < 0 ){ |
2 | // tue was
|
3 | }
|
Was ist denn daran so schwer ? Peter
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.