Archiv verlassen und diese Seite im Standarddesign anzeigen : Zeichen nibbeln
Hi,
bin neu in C- Programmierung und WinAVR.
Wollte mal fragen, ob's nen netten Menschen gibt, der mir
beim "Nibbeln" der ASCII-Werte eines Zeichenstrings
mal auf die Sprünge helfen kann. Ist für die
4-Bit Ansteuerung eines 4x27 LC-Displays.
Hab mir schon folgendes Gerüst für eine Unterfunktion
zurechtgebastelt:
void Textausgabe(void)
{
uint8_t UpperNibble,LowerNibble,count;
//Massstab: "0xxxxxxxx1xxxxxxxxx2xxxxxx7"
char Text[27]="0xxxxxxxx1xxxxxxxxx2xxxxxx7";
for(count=1;count<28;++count)
{
//Ein Zeichen holen, Typumwandlung uint8_t => char ??? (weiss nicht,ob's das Gleiche ist.)
//Unteres Nibbel von Text(count) mit &0xf0 "vernichten", Oberes Nibbel /16 => nach unten (weiss nicht, wie man 4 Bit auf einmal shiftet)
//Nibbel ausgeben
//Oberes Nibbel "vernullen" ( in Bit 4 und 5 liegen bei mir E1 und E2 des Displays), dann Byte ausgeben.
}
}
Belegung LCDisp. an ATMega8: D4 - D7 an PC0 - PC3, E1 an PC4, E2 an PC5, RS an PB0, R/W an Masse.
Wär wie gesagt toll, wenn ich da einen "Anschubser" bekäme.
Vielen Dank schonmal,
tholan
SprinterSB
01.02.2006, 16:31
Hi,
bin neu in C- Programmierung und WinAVR.
Wollte mal fragen, ob's nen netten Menschen gibt, der mir
beim "Nibbeln" der ASCII-Werte eines Zeichenstrings
mal auf die Sprünge helfen kann. Ist für die
4-Bit Ansteuerung eines 4x27 LC-Displays.
Hab mir schon folgendes Gerüst für eine Unterfunktion
zurechtgebastelt...
So was in der Richtung? Die Ausgabe hab ich jetzt nicht ausgeführt, das ist abhängig vom Displaytyp/Treiber.
#include <inttypes.h>
void Nibbleausgabe (const uint8_t nibble);
void Textausgabe (const uint8_t*);
// Massstab: "0xxxxxxxx1xxxxxxxxx2xxxxxx7"
char text[] = "0xxxxxxxx1xxxxxxxxx2xxxxxx7";
void Textausgabe (const uint8_t *tx)
{
// Zeiger tx läuft durch den String
while (1)
{
uint8_t nibble;
// Ein Zeichen holen, Typumwandlung uint8_t => char ??? (weiss nicht,ob's das Gleiche ist.)
// Zeichen aus RAM lesen, Zeiger eins weiter
uint8_t zeichen = *(tx++);
// zeichen == 0 --> Stringende
if ('\0' == zeichen)
break;
// Unteres Nibbel von Text(count) mit &0xf0 "vernichten",
// Oberes Nibbel /16 => nach unten
nibble = zeichen >> 4;
// high Nibbel ausgeben
Nibbleausgabe (nibble);
// Oberes Nibbel "vernullen"
// (in Bit 4 und 5 liegen bei mir E1 und E2 des Displays),
// dann Byte ausgeben.
nibble = zeichen & 0x0f;
// low Nibbel ausgeben
Nibbleausgabe (nibble);
}
}
void Nibbleausgabe (const uint8_t nibble)
{
}
VIelleicht der Zusatz: SPrinter hat auf das "obere Nibble vernichten" verzichtet, da das
nibble = Zeichen >> 4
sowieso diese Bits löscht.
SprinterSB
01.02.2006, 16:59
Jau, dabei ist aber darauf zu achten, daß man die Zeichen als unsigned char (bzw. uint8_t) ausliest.
Ansonsten wird als oberes Bit beim Schieben nicht die 0 nachgeschoben, sondern das Vorzeichen. Bei Werten von 0x80..0xff bzw -128..-1 müsste man dann explizit noch mit einer Maske die oberen Bits löschen.
dann noch:
while (*tx)
und man kann die if -abfrage sparen
Das ausmaskieren des oberen Nibbles ist nur dann nötig, wenn die Portpins anderweitig benutzt und in Nibbleausgabe nicht gesetzt werden.
Na, dann noch ein's drauf: Es empfiehlt sich, das "Nibble löschen" gleich in die Nibble-Ausgabe zu verschieben, ein für allemal.
void Nibbleausgabe (const uint8_t nibble)
{
xxx = nibble & 0x0F;
.....
}
Super!
Ich denk, damit komm ich klar und weiter!
Bin halt ziemlich BASIC-versaut.
Zeichen mit Zeigern ausm RAM lesen und
Byte shiften gibts da halt nicht.
Danke nochmal,
tholan
SprinterSB
01.02.2006, 17:17
dann noch:
while (*tx)
und man kann die if -abfrage sparen.
Jo, damit spart man aber nur Quellcode, der erzeugte Code wird länger ;-)
Könnt ihr euch nochmal angucken, was ich jetzt verbrochen habe?
void Textausgabe(void)
{
const uint8_t *tx;
uint8_t nibble, zeichen;
char text[]="Lieber blau, als grau.";
while(1)
{
zeichen = *(tx++);
if ('\0' == zeichen)
break;
nibble = zeichen >> 4;
PORTC = nibble; //Zeichen anlegen...
Dat_tog_E1(); //und Feuer!
nibble = zeichen & 0x0f; //muss maskiert sein, wg. E1 / E2 an PC4 / PC5
PORTC = nibble;
Dat_tog_E1();
}
}
Der Compiler läuft durch und meckert nur noch, daß *tx evtl. nicht initialisiert ist
und das char text[] nicht benutzt wird (logisch).
Wie lasse ich jetzt *tx auf den String zeigen?
Der Cursor auf'm Display rutscht übrigens schon brav um eins weiter und malt
mir davor 'ne Hieroglyphe.
thx
Kollege (*tadel*) tx is ja auch nicht initialisiert, das gibt stunk beim Ablauf
Muttu machen:
char text[]="Lieber blau, als grau.";
const uint8_t *tx = (uint8_t)&text; // addresse von text reinschreiben
Is ja wohl nur eine Testroutine ?
Zeichen mit Zeigern ausm RAM lesen und Byte shiften gibts da halt nicht.
Sag das nicht !
Is logischer Weise nur 'n Test (wo issn' hier der Rot-werd-Smiley?).
Hab halt mit C noch ganz schön zu kämpfen.
Das Display könnte ich langsam per Hand mit 'nem
Mäuseklavier (Schiebeschalterreihe) initialisieren.
Mit Basic (CC1 Basic und Qbasic am Parallelport)
hat die Ansteuerung jedenfalls schon gut geklappt.
Jetzt will ich mich aber schon noch mit 'ner "richtigen"
Programmiersprache (WinAVR) und 'ner "richtigen" MCU
(ATMegaxx) auseinandersetzen.
Danke nochma,
tholan
p.s.
Bei Qbasic gibts glaub ich sowas wie "varptr()", braucht man aber nich :) .
SprinterSB
02.02.2006, 11:04
Kollege (*tadel*) tx is ja auch nicht initialisiert, das gibt stunk beim Ablauf
Muttu machen:
char text[]="Lieber blau, als grau.";
const uint8_t *tx = (uint8_t)&text; // addresse von text reinschreiben
Nö, wenn überhaupt, is da ne Brezel (&) zu viel und es muss heissen
const uint8_t *tx = (const uint8_t*) text;
Ausserdem hatte ich ober für Textausgabe definiert
void Textausgabe (const uint8_t *tx) ...
damit die Routine nicht auf einen String festgenagelt ist. Sie bekommt den String (bzw Anfangsadresse) als Parameter. Aufruf:
const char text[] = "...";
int main()
{
....
Textausgabe (text); // Text ausgeben
Textausgabe ("Hallo"); // "Hallo" ausgeben
}
Wenn du auf vielen Plattformen mit vielen verschiedenen Compilern arbeitest,gewöhnst du dir schnell an, eher zuviel als zuwenig Brezeln hinzuschreiben.
Aber der asteriks hat gefehlt, da hast du recht.
Jo, damit spart man aber nur Quellcode, der erzeugte Code wird länger
Bei mir aber nur bei -O0, bei -O2 ist er gleich lang. (Aber vielleicht sollten wir die Disukssion besser im C-Forum führen :) )
Schätze,
werd mich wohl noch ein bischen intensiver
dem gcc widmen müssen (bischen rumreferenzieren üben).
C scheint doch nicht Basic zu sein :) .
thx,
tholan
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.