www.mikrocontroller.net

Forum: Compiler & IDEs Wie mache ich eine Textausgabe 8Bit auf Display?


Autor: Jensgzm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich benutze einen Atmega16 und ein 4x20 Display, dass ich im 8-Bit Modus 
anspreche. Meine Kenntnisse im Programmieren sind noch nicht sehr weit 
fortgeschritten. Ich programmiere übrigens mit dem AVR Studio.
Ich würde mich sehr freuen, wenn mir jemand ein kleines Testprogramm 
hätte, in dem z.B. das Wort "Hallo Welt" oder ähnliches ausgegeben wird.
Mich interessiert lediglich der Block, in dem der Text ans Display 
gesendet wird. Die Init vom Display habe ich schon.
Ich verstehe nicht ganz, woher das Studio, bzw. der Compiler wissen 
soll, welche Signale er über die 8 Datenleitungen übertragen muß, damit 
der gewollte Text erscheint?
Ich hoffe auf eure Hilfe.

Gruß Jens

Autor: AVR Freund (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Programmieren in was ? C ? Assembler ?

http://www.mikrocontroller.net/articles/AVR-Tutorial
Vielleicht hilft dir das etwas weiter?

Autor: Jensgzm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi AVR Freund,

sorry, ich dachte es wäre klar dass ich in C programmieren will, weil 
ich meinen Thread im GCC Forum eingestellt habe.
Also, ich möchte gern in C programmieren.
Danke für deinen Link, das Tutorial kenne ich schon, beim Assembler hat 
es mir geholfen mein Display zu initialsieren, was ich nun in meinem 
C-Programm auch übertragen habe, aber leider ist in dem Tutorial keine 
Textausgabe dabei.
Habe das Forum auch schon nach möglichen Threads durchsucht. Bin auch 
weiterhin auf der Suche.

Gruß Jens

Autor: AVR Freund (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau mal da nach.
Beitrag "lib für Pollin LCD (WINTEK2704)"
vielleicht hilfts dir weiter?

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meinst du so was:
void LCD_puts (const char *lcd_string)  {
  while (*lcd_string)  {
    Zeichenausgabe (*lcd_string++);  // String auslesen -> LCD
  }
}

Wobei ich unterstelle das du eine "Zeichenausgabe" Funktion hast.

Für eine Ausgabe schreibst du dann LCD_Puts ("moin moin");

Alles klar ?

Autor: Jensgzm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Joe,

das sieht ja mal nicht schlecht aus.
Also, wenn  du mit Zeichenausgabe meinst, dass ich die Daten an den 
richtigen Port schicke, dann ja, allerdings halt momentan für einzelne 
Buchstaben und nicht für nen ganzen Text. Den Buchstabe schicke ich als 
hex-Wert ans Display. Deswegen tue ich mich schwer, mir vorzutellen, wie 
das bei einem langen Text geht.
Kannst du mir kurz erklären was deine Funktion da macht?
Ich verstehe es so, du übergibst der while-Schleife den lcd-string.
Und in der Schleife wird in der Funktion "Zeichenausgabe" der string 
hochgezählt. Aber was zählt er denn hoch? Die Buchstaben?
Wie du siehst, fehlt mir noch bissle Verständnis der Materie.
Aber wer nicht fragt wird nicht aufgeschlaut.

Gruß Jens

Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem ist warscheinlich das du noch nie was Pointern gehört hast?

Ein Pointer ist ein Zeiger auf eine Speicheradresse. Mit dem *-Operator 
kann man nun die Adresse dereferenzieren und erhält das Zeichen an der 
Stelle im Speicher. Mit dem ++-Operator wird nichts am Zeichen geändert 
dondern der Pointer zeigt nun auf das nächste Zeichen im Speicher.
Jedes Char-Array (so nent man diese "Strings") hat am Ende als Letztes 
Zeichen eine NULL. Soblad die dereferenzierung im Schleifenkopf zu 
dieser NULL führt wird die Schleife abgebrochen, da der String zu ende 
ist

Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
http://www.mikrocontroller.net/articles/AVR-Tutori...

Dort ist es eigenltich auch sehr gut erklärt. Warscheinlich macht der 
c-Cpmpiler aus der lcd_puts() auch so einen ählnichen assemblercode

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Also, wenn  du mit Zeichenausgabe meinst, dass ich die Daten an den
> richtigen Port schicke, dann ja, allerdings halt momentan für einzelne
> Buchstaben

Ja, das meine ich. Eine Erklärung hast du ja bereits von Ulrich 
bekommen. Probiers einfach mal aus, ist doch in 2 Minuten ausgestanden.

Autor: Jensgzm (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Danke an Ulrich für die gute Erklärung, hattest Recht, von Pointern 
wußte ich nichts.
Ich habe mal mein Programm angehängt. Ist bestimmt verbesserungswürdig 
aber darum gehts ja jetzt net.
Ich steh grad auf dem Schlauch, habe den Tip von Joe integriert, nun 
hänge ich grad an der Zeichenausgabe.
Vorher habe ich immer sowas geschrieben:

PORTC=0x57   // Entspricht dem Buchstaben "w"

Jetzt kann ich den Buchstaben ja nicht definieren, sondern will ja z. B. 
"moin moin" übergeben. Deswegen die Fragezeichen unter void 
Zeichenausgabe.
Was muß denn da alles rein?

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab mir deinen Code jetzt nicht angesehen aber was du nun brauchst ist 
eine Funktion welche die Zeichen aufnimmt, das RS BIT setzt und nach 
anlegen der Daten das ENABLE signalt schaltet.

Das sieht dann z.B. so aus:

void display_data_out (uint8_t dsp_char_out_)  {
  SETBIT (PORTB, DATA);          // Daten an Display => RS BIT=1
  PORTC = dsp_char_out_;
  SETBIT (PORTB, OENABLE);       // ENABLE = HIGH
  CLRBIT (PORTB, OENABLE);       // ENABLE = LOW, Datenübernahme des Displays
}


Bei den PORT PIN's mußt du natürlich deine verwenden.

Autor: Michael Glunz (glunzl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du könntest auf die fertige Lib von Fleury nutzen, zumindest mal 
reinschauen:

http://homepage.hispeed.ch/peterfleury/avr-softwar...

Gruß
Michael

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Du könntest auf die fertige Lib von Fleury nutzen, zumindest mal reinschauen:

Machs nicht, sorry Michael, aber er will lernen und als Ergebnis hat er 
dann seine eigene Routine.

Die Fleury LIB ist für einen Anfänger ne Zumutung. Wenn diese auch den 
Eindruck einer eierlegenden Wollmilchsau macht, ich find se Grotte.

Autor: Michael Glunz (glunzl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zum Reinschauen und Ausprobieren, gerade als Anfänger, fand ich die 
einzelnen Funktionen doch hilfreich. Aber das sollte jeder für sich 
entscheiden.

Gruß
Michael

Autor: Jensgzm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mahlzeit,

danke für den Tip mit der Fleury Lib, die hab ich mir schon angeschaut 
und wie Joe richtig vermutet hat, bin ich daraus nicht schlau geworden, 
eher im Gegenteil.
Okay, das mit Enable und RS weiß ich.
Du übergibst dann an den Port den Inhalt von dsp_char_out.

Jetzt muß ich doch den LCD_puts-Befehl irgendwie mit dem dsp_char_out 
verwurschteln, damit mein Text in der Variable dsp_char_out steht 
richtig?


Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, das ist schon geschehen:

Zeichenausgabe (*lcd_string++);  // String auslesen -> LCD

dsp_char_out (*lcd_string++);  // String auslesen -> LCD

Alles klar ? und wenn du nur ein einzelnes Zeichen ausgeben willst dann 
schreibst du:

dsp_char_out ('b'); oder dsp_char_out (0x57);

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, hab ich was übersehen ?

LCD_puts ist ja deine Funktion und an die übergibst du:

LCD_puts ("moin");

Vielleicht hast du es noch nicht erkannt ? Du übergibst einfach einen 
Wert oder Pointer an eine Funktion.

Autor: Jensgzm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey, klasse, das gefällt mir gut so.
Mein Studio meckert jetzt nur noch weil ich dsp_char_out_ und LCD_puts 
nicht deklariert habe.
Was für ein Typ sind die denn? Char? Int?
Das Prinzip habe ich schon mal verstanden.
Großes Lob an Joe !!

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deklarier sie so wie sie heißen:

void display_data_out (uint8_t dsp_char_out_);

wobei du nur die #include <stdint.h> ISO C99 Integer types noch 
hinzufügst.

Du kannst aber auch unsigned char verwenden.

Autor: Jensgzm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Joe du bist wirklich spitze.
Er hats geschluckt und er gibt genau den Text wieder, der in meinem Code 
steht.
Hatte noch ein paar Probleme im Code aber jetzt ist alles aufgeräumt.
Da wäre ich sicher nie drauf gekommen.
Jetzt werde ich mal bissle experimentieren.

Nochmals danke an Dich, Joe, speziell und die anderen.
So machts Spaß.

Grüße aus m Süden.


Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du mit Pointern noch auf Kriegsfuss stehst,
kann man das ganze auch mit Array Syntax schreiben.
Ev. hilft dir das besser zu verstehen, was da abgeht.
void LCD_puts (const char *lcd_string)
{
  int i = 0;

  while( lcd_string[i] != '\0' ) {
    Zeichenausgabe( lcd_string[i] );
    i++;
  }
}

Mit etwas Glück optimiert der Compiler beide Versionen
(Pointer / Array Indizierung) auf gleichwertigen
Code.

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
An der Initialisierung kann man noch einiges verbessern, stell mal den 
aktuellen Code rein und ich schau noch einmal drüber.

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, der Karl Heinz hat schon recht, die neue WINAVR Version würde 
meckern.

void LCD_puts (const char *lcd_string)

const char steht dafür das die Zeichenkette im Programmspeicher abgelegt 
wird.

Autor: Jensgzm (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ja, der Vorschöag von Heinz macht es etwas verstädnlicher.
Nebenbei könnte einer kurz erklären, woher das Programm weiß, wie es die 
Buchstaben in hex-Werte umzuwandeln hat?
Weil, ich seh dass es funktioniert, aber verstanden habe ich es soweit 
noch nicht.
Anbei mal der aktuelle Code.

Gruß jens

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jensgzm wrote:
> Ja, der Vorschöag von Heinz macht es etwas verstädnlicher.
> Nebenbei könnte einer kurz erklären, woher das Programm weiß, wie es die
> Buchstaben in hex-Werte umzuwandeln hat?

Das macht bereits der Compiler.
Ich verrat dir ein Geheimnis: Im Rechner gibt es keine
Buchstaben. Im Rechner gibt es nur Zahlen. Je nachdem
wie diese Zahlen verwendet werden, stellen die Zahlen
was anderes dar.

Deine Zeichenausgabe Funktion gibt keine Buchstaben aus.
Deine Zeichenausgabefunktion schickt zb. die Zahl 0x41 an
das Display. Im Display ist eine Tabelle eingebaut, in der
steht, welche Pixel beim Empfang der Zahl 0x41 aufleuchten
sollen. Aus der Tabelle folgt zb. dass das Muster so aussehen
soll

      . . * . .
      . * . * .
      . * . * .
      . * . * .
      .   * .
      . * . * .
      . . . . .

und dein Gehirn macht dann ein 'A' daraus. Nun könnte man
viele beliebige Zuordnungen machen. Bei 0x41 könnte man auch
andere 'Buchstaben' ausgeben. Daher hat man sich auf einige
Schemata geeinigt. Das am weitesten verbreitet ist sicherlich
das ASCII Schema.

http://de.wikipedia.org/wiki/ASCII

Wenn du also in deinem Programm den Text "Testtext" verwendest.
dann sind da keine Buchstaben gespeichert (Erinnerung: im
Rechner ist alles eine Zahl), sondern die Zahlenfolge:

0x54 0x65 0x73 0x74 0x74 0x65 0x78 0x74 0x00

Diese Zahlenfolge kann jetzt alles mögliche bedeuten.
Schickt man aber diese Zahlenfolge an ein Anzeigegerät
welches ASCII versteht, dann pinselt es "Testtext" hin.
(Das letzte 0x00 ist ein Zugeständnis an C. Daran wird in
C erkannt, dass ein Text zu Ende ist. Daher wird auch in
der weiter oben gezeigten Schleife abgeprüft, ob 0x00
schon erreicht wurde).

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jensgzm wrote:

> Anbei mal der aktuelle Code.

Ein wichtiger Punkt in der Programmierung, der leider von
Neueinsteigern immer unterschätzt wird, ist die Codeformatierung.

Gewöhn dir gleich von Anfang an an, eine ordentliches Einrückschema
sowie ein konssistentest { } Schema zu machen.
Auch wenn es oft belächelt wird, ist es doch wichtig das zu tun.

Weiters: In Standard-C gibt es keine funktionslokalen Funktionen.
Auch wenn gcc dies als Erweiterung erlaubt, würde ich dir doch
empfehlen, dich hier an Standard-C zu halten.
#include <avr/io.h> 
#include <stdint.h>         

void E_toggle (void) 
{
  for (i=0; i<1000; i++)
    ;
  PORTA |= (1<<5);           // Enable High

  for (i=0; i<500; i++)
    ;
  PORTA &= ~(1<<5);          // Enable Low
}

void dsp_char_out_ (uint8_t dsp_char_out_)  
{
  PORTA |= (1<<6);           // Daten an Display => RS BIT=1
  PORTC = dsp_char_out_;
  E_toggle();
}

void LCD_puts (const char *lcd_string)  
{
  while (*lcd_string)  
  {
    dsp_char_out_ (*lcd_string++);  // String auslesen -> LCD
  }
}

void LCD_init()
{
  DDRA  = 0xff;
  DDRC  = 0xFF;
  PORTA = 0x10;              // Beleuchtung ein
  PORTC = 0x00;

  PORTC = 0x38;              // 8 Bit, 4 Zeilen
  E_toggle();
  PORTC = 0x01;              // Display löschen
  E_toggle();
  PORTC = 0x0E;              // Display an, Cursor an, Blinken aus
  E_toggle();
  PORTC = 0x06;              // Entry Mode Set, Incrementieren, no Shift
  E_toggle();
  PORTC = 0x02;              // Cursor home
}

int main (void) 
{            
  unsigned long int i;

  for (i=0; i<10000; i++)
    ;   

  LCD_init();
  
  LCD_puts( "Druck und Temperatur" );
   
  while( 1 ) {                
    ;  
  }                         
 
   /* wird nie erreicht */
   return 0;                 
}

Sieht doch gleich viel besser aus. Mit den Warteschleifen
in E_toggle must du dir noch was überlegen. Spätestens
wenn du den Compiler optimieren lässt, fliegen die sowieso
raus. Zumindest die 2.te Warteschleife ist überflüssig. Das
Display ist schnell genug, sodass du den Pin nur setzten und
gleich darauf wieder löschen kannst.
void E_toggle (void) 
{
  for (i=0; i<1000; i++)
    ;
  PORTA |= (1<<5);           // Enable High
  PORTA &= ~(1<<5);          // Enable Low
}

Die erste Warteschleife ist wie gesagt problematisch. Zum
einen ist deren Ausführungszeit von der Taktfrequenz des µC
abhängig. D.h. die 1000 sind manchmal viel zu viel, und bei
einem schneller getaktetem µC sind sie viel zu wenig.
Zum anderen wird sie dir der Optimizer sowieso rauswerfen,
wenn er mal optimieren darf.

Für solche Warteschleifen gibt es in "delay.h" eigene Funktionen,
denen man die gewünschte Zeit übergibt und die sich ausrechnen,
wieviele Schleifenwiederholungen dafür notwendig sind.
Schau aber unbedingt in "delay.h" rein, denn diese Funktionen
haben eine beschränkung für die maximal mögliche Zeit.

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Daher wird auch in der weiter oben gezeigten Schleife abgeprüft, ob 0x00
> schon erreicht wurde).

Und das macht eben auch ne while Schleife, in C ist alles Null 
terminiert.

Autor: Jensgzm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Änderung des Codes, muß zugeben es sieht übersichtlicher 
aus.
Ich denke halt immer, dass ich es auch noch aufräumen kann wenn ich mal 
fertig bin, aber eigentlich ist das Programm ja nie fertig.
Werd versuchen mich dran zu halten.

Mit "keine funktionslokalen Funktionen" meinst du, dass du die Init
ausgelagert hast oder?

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, wir optimieren noch ein bischen. Du hast eine Funktion die Zeichen 
ausgibt und eine die Zeichenketten beherrscht. Machen wir doch noch eine 
für Steuerzeichen (für die Initialisierung und clear display, cursor 
home etc.).

void lcd_command (uint8_t dsp_control_out)  {    
  RS = LOW;                       // Steuersignale an Display (RS BIT=0)
  lcd_char (dsp_control_out);     // Steuersignal ausgeben
  _delay_ms (4.1);                // Warteschleife 4,1 mSec.
  RS = HIGH;                      // RS BIT=1 => Daten
}


Diese Funktion wird immer mit RS = 1 verlassen und somit ist innerhalb 
der Routine der Focus auf LCD Daten ausgeben. Du kannst also in 
lcd_char_out RS=1 weglassen.

Wenn du nun noch #define lcd_clear 0x01 verwendest dann schreibst du:

lcd_command (lcd_clear);

Der Code wird immer lesbarer und du kannst deine Initialisierung mittels 
dieser lcd_command Funktion durchführen.

Für die delays verwendest du den Tipp von Karl Heinz. Den delay Aufruf 
habe ich schonmal eingefügt.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jensgzm wrote:
>
> Mit "keine funktionslokalen Funktionen" meinst du, dass du die Init
> ausgelagert hast oder?

Dein ursprüngliches Pgm hat so ausgesehen
int main()
{
  void E_toggle (void)
  {
    ...
  }
 
  void dsp_char_out_ (uint8_t dsp_char_out_)
  {
    ...
  }

  void LCD_puts (const char *lcd_string)
  {
    ...
  }
 
  ...
}

d.h. die Funktionen E_toggle, dsp_char_out_ und LCD_puts waren
innerhalb von main() definiert (Siehst du, ohne konsequent
durchgezogene Einrückung hättest du das gar nicht gesehen).
Das ist aber in Standard-C nicht erlaubt.

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
muß natürlich heißen:

dsp_char_out_ (dsp_control_out);

Autor: Jensgzm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich aber den Vorschlag von Karl Heinz in meinem Studio compiliere, 
dann meckert es, weil das "i" in der E_Toggle nicht definiert ist. 
Deswegen hatte ich es vorhin auch unten angehängt. Eben nach der 
Definition von i. Mach ich da einen Fehler?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jensgzm wrote:
> Wenn ich aber den Vorschlag von Karl Heinz in meinem Studio compiliere,
> dann meckert es, weil das "i" in der E_Toggle nicht definiert ist.
> Deswegen hatte ich es vorhin auch unten angehängt. Eben nach der
> Definition von i. Mach ich da einen Fehler?

Nein. Ich hab nicht aufgepasst.
E_Toggle muss natürlich so aussehen:
void E_toggle (void) 
{
  uint16_t i;

  for (i=0; i<1000; i++)
    ;

  PORTA |= (1<<5);           // Enable High
  PORTA &= ~(1<<5);          // Enable Low
}

d.h. die Funktion E_toggle kriegt ihre eigene Variable i

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich will jetzt nicht zuviel Verwirrung hereinbringen aber ne seperate 
Togglefunktion braucht es nicht, man muß nur das Programm entsprechend 
aufbauen.

void dsp_char_out_ (uint8_t dsp_char_out_)

Hier gehört das Togglen mit hinein und die Wartezyklen packst du in die 
Steuerzeichenausgabe.

Denn togglen mußt du immer wenn du ein Zeichen an das LCD übergibst, ob 
Steuerzeichen oder Daten.

Ist das mit der Steuerzeichenausgabe klar ?

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine Initialisierung sieht dann so aus:

void lcd_init (void)  {
  uint8_t n = 3;                    // Init. Sequenz
  do  {                             // 3x 38H (0x38), init cycle 3x
        lcd_command (0x38);         //
  }while (--n);
  lcd_command (function_set_1);     // 8 Bit Modus
  lcd_command (on_off_control_1);   // Display An / Cursor Aus / Blink Aus
  lcd_command (clear_display);      // Clear Display
  lcd_command (entrymode_1);        // Cursor nach rechts / kein Shift
}


Vorrausgesetzt du hast dir alles in #Defines gepackt. Das Timing ist 
schon in der Steuerzeichenausgabe gelöst.

Autor: Jensgzm (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ja, das mit der Steuerzeichenausgabe ist klar.
Ich muß sagen Ihr legt ein gutes Tempo vor, aber bis jetzt komm ich noch 
mit.
So schnell bin ich bis jetzt noch nie voran gekommen. Mußte immer ewig 
suchen bis ich mal was hilfreiches (auf meinem Niveau) gefunden habe.
Hier mal wieder der aktuelle Code.
Das Delay mußte ich ausschalten, weil ich keine delay.h Datei habe. 
Konnte auch keine auf meiner Fetsplatte finden.

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich häng dir später mal meinen Code komplett hierein, aber du hast ja 
auch jetzt schon eine Menge gelernt.
#ifndef F_CPU
#define F_CPU 1000000UL       /* Quarz Frequenz = 1 MHz                      */
#endif

#include <util/delay.h>       /* delay Lib.


Die delay.h gehört zum WINAVR versuchs mal so und trage deine CPU 
Frequenz ein.

Autor: Jensgzm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja Tatsache, im WINAVR Ordner steckte die blöde Datei.
Dachte die müßte unter Atmel sein.
Nunja, also das mit dem Delay klappt auch.
Alles wunderbar.

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na dann, ab in die letzte Runde, her mit dem aktuellen Code und wir 
optimieren noch ein bischen ;-))

Autor: Jensgzm (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Man man, du bist ja unersättlich.
Aber es hilft ja.
Ich hoffe du bist öfters im Forum, denn ich muß noch ein paar Sachen 
umsetzen, die ich aber heute noch nicht umsetzen kann und da könnte ich 
deine Hilfe gut gebrauchen. ;-)

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void dsp_char_out (uint8_t dsp_char_out)  {
  uint16_t i;

  PORTC = dsp_char_out;
  PORTA |= (1<<5);           // Enable High
  PORTA &= ~(1<<5);          // Enable Low
  _delay_us (42);
}

int main (void)  {            
  _delay_ms (15);            // wait 15 mSec. after Power ON

  LCD_init();  
  LCD_puts( "Druck und Temperatur" );
   
  while( 1 );
}


Für die Zeichen reichen 42 uSec, und die Steuerzeichen haben ja ihre 4,1 
mSec. schon. Nach Power ON sinds dann 15 mSec.

Wenn du noch folgende #Defines hinzufügst:

#define cursor_line_1       0x80
#define cursor_line_2       0xC0

dann setzt dieser Befehl:

lcd_command (cursor_line_2);

Deine Ausgabe in die 2te Zeile.

Autor: Joe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine Zählvariable kann auch noch weg, und dann bitte noch einmal deinen 
Code als Anhang.

Autor: Jensgzm (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ja, dass mit dem Cursor wollte ich auch noch ausprobieren.
So ähnlich hab ich es mir vorgestellt.
Mittlerweile ist der Code echt übersichtlich und geschrumpft ist er 
auch.
Habe den Cursorsprung in die 4.Zeile gemacht.

Autor: Joe (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So stelle ich mir einen Display Code vor, gut gemacht ;-))

Nun Vergleiche mal die Codegröße mit irgendeiner LIB und du verstehst 
warum ich zum selber schreiben rate.

Im Prinzip ist es fertig aber man kann noch nen bischen dran schrauben.
void dsp_char_out (uint8_t dsp_char_out)  {
  
  PORTC = dsp_char_out;
  PORTA |= (1<<5);           // Enable High
  PORTA &= ~(1<<5);          // Enable Low
  _delay_us (42);
}

Auch die Anschlüsse RS und ENABLE können noch in ein #define. Wenn man 
es richtig macht dann kann man auch:

ENABLE = HIGH;
ENABLE = LOW;

schreiben. Im Anhang findest du meinen Code für eine 4 BIT Ansteuerung. 
Du wirst feststellen das deiner nun fast genauso aussieht ;-))

Hier findest du noch eine schöne Erklärung zu den PORT's & BIT's, wie du 
siehst lerne auch ich aus dem Forum.

Beitrag "sbit macro für avr-gcc"



Autor: Jensgzm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Joe,

ja, das Programm ähnelt schon ziemlich.
Werde weiterhin Optimierungen durchführen.
Wie gesagt, es gibt noch einiges zu tun.
Für heute ist aber mal Schluß.
Vielleicht treffen wir uns mal wieder in einem anderen Thread.
Nochmals danke für die Lehrstunde, ich bin heute weit gekommen.

Gruß Jens

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.