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.