mikrocontroller.net

Forum: Compiler & IDEs Suche eine kleine LCD library für den ATTiny26


Autor: Bernd E. (edi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
stehe gerade vor dem Problem, dass mein hex File für den AtTiny26 obwohl 
im eigentlichen Programm nicht viel getan wird durch die LCD Ausgabe 
viel zu groß wird (9kB), gibt es da eine ganz abgespeckte Version für 
die Ausgabe am LCD (HD44780U komp. 2x16 LCD), die ich im Tiny verwenden 
könnte, oder wie macht ihr das?

Autor: Jens B. (sio2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Selber schreiben ;) ist ja eigentlich auch kein akt. oder du nimmst dir 
aus den sourcen nur das was du brauchst.

Autor: Bernd E. (edi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
hab meine (die ich normalerweise verwende) selbst geschrieben, aber aus 
Zeitgründen dachte ich, vielleicht hat ja jemand eine abgespeckte 
Version für den Tiny parat!

Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da kann man nix abspecken. Da kann an nur das rauswerfen was man nicht 
braucht....

Autor: Karl-j. B. (matrixman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was brauchst du denn für Befehle an dein LCD?
und welche Sprache?

mfg Karl

Autor: Bernd E. (edi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Im Grunde brauch ich nur eine Ausgabe von Strings und vielleicht eine 
für int. Das ganze natürlich in C.

Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sowas kommt eh nicht in die lcd-libary. Da werden nur funktionen mit dem 
namen putc und puts nach ausen zur verfügung gestellt....

Autor: Bernd E. (edi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
das ist schon klar, aber in meiner lcd.c muss ich die Sachen ja auch 
ausprogrammieren!

Habe jetzt einige Sachen auch meiner lcd.h und lcd.c gelöscht, die Größe 
des hex-Files ist jedoch nicht kleiner geworden.

Wie verhält es sich eigentlich mit dem einbinden von Headerfiles, wenn 
ich z.B. nur itoa() aus stdlib verwende, wird dann auch nur der Code 
itoa() ins hexfile aufgenommen, oder alle Funktionen von stdlib?

Autor: fieser, klugscheissender Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>wird dann auch nur der Code itoa() ins hexfile aufgenommen
und das, was itoa() zum wandeln braucht.

Autor: Bernd E. (edi)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Könnte ich vielleicht übers Makefile noch was rausholen, verwende 
nämlich ein Standard Hex File von MFile generiert, habs mal angehängt!

Autor: fieser, klugscheissender Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zeich doch mal deinen Code! Da lässt sich vielleicht an Stellen drehen, 
wo du es selber nicht siehst (ist einfach so, passiert mir und anderen 
genauso).




("Zeich" = Kielerisch/Norddeutsch für "zeig")

Autor: Bernd E. (edi)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier ist mein Code!

Autor: fieser, klugscheissender Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Float-Berechnung kostet natürlich auch Speicher...
"dtostrf" erscheint mir sehr, sogar zu mächtig...

Und dann schluckt die LCD-Library vermutlich auch eine ganze Menge 
Speicher.

Sehe ich es richtig, dass du eine (Spannung) bzw. zwei (Strom) Stellen 
vor und 2 nach dem Komma darstellen willst?

Das mache ich so:

zehner = '0';
einer = '0';
zehntel = '0';
hundertstel = '0';
f = spg;
while (f>0.0) {f -= 1.0; einer++;)
while (f>0.1) {f -= 0.1; zehntel++;}
while (f>0.01) {f-= 0.01; hundertstel++;)

Die Zehner-Stelle genauso...
Durch '0' wird die float gleich in ASCII-Zeichen gewandelt.
Führende Nullen kann man auch noch herausfiltern...

Autor: Bernd E. (edi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
es wird in der ersten Zeile einfach ein Stromwert (zur Zeit auch noch 
der dazu gehörige ADC WErt) angezeigt und in der zweiten Zeile der 
Spannungswert.

Entstehen dann in den char Variablen zehner, einer,... die einzelnen 
Ziffern als Character?

Würde das für die Zehnerstelle so aussehen?
while (f>10.0) {f -= 10.0; zehner++;)

Solll ich statt double dann auch lieber float nehmen?

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Und dann schluckt die LCD-Library vermutlich auch eine ganze Menge
> Speicher.

Das ist aber nicht viel. Die Fleury Lib ist ziemlich einfach
gestrickt:
  Basisfunktionen zur Byte-Ausgabe
  Initialisierung
  Ausgabe eines Charcater
  Ausgabe eines String
Mit ein paar Zig Bytes ist man da dabei.

Das meiste wird wohl durch die floating point Arithmetik +
die Formatierfunktionen draufgehen.

Autor: fieser, klugscheissender Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Würde das für die Zehnerstelle so aussehen?
>while (f>10.0) {f -= 10.0; zehner++;)

ja.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Solll ich statt double dann auch lieber float nehmen?

Das bringt mit gcc nichts.
float und double sind dort gleich gross und haben
daher auch dieselbe Implementierung.

Wenn du die floating point Library wegbekommen willst,
dann musst du komplett auf float bzw. double verzichten.

Ist aber kein Problem:
Deine Berechnung sieht so aus:

  spg = (adc_str * 5.0) / 1024.0;

Das kannst du auch mit Fixkommaarithmetik im long
Bereich machen:

  spg = ( adc_str * 500L ) / 1024;

(spg ist dann eine int Variable. Die long Rechnerei braucht
man nur deshalb, damit adc_str * 500 nicht den int Zahlen-
bereich überläuft).

Anstatt Zahlen im Bereich 0 bis 5 (als float) kommen da
jetzt Zahlen im Bereich 0 bis 500 heraus. Die Zehner- und
Einerstelle sind dabei deine ursprünglichen Nachkommastellen.
D.h. Wenn du jetzt bei der Ausgabe zwischen Hunderterstelle
und Zehnerstelle ein '.' einschmuggelst dann sieht die
Ausgabe aus wie vorher. Nur halt ohne Floating Point
berechnet.

  lcd_putint( spg / 100 );
  lcd_putc( '.' );
  lcd_putint( spg % 100 );

Was ähnliches kann man noch mit der anderen Berechnung machen
und schon fällt die Floting Point Library aus deinem Program
raus.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sehe gerade, dass in deiner 2-ten Berechnung auch Tausendstel
vorkommen, und dass die aus spg ausgerechnet werden.

Anstatt '*100' bietet es sich dann an, einfach alles *1000
zu nehmen um überall ganze Zahlen zu haben.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich mir die Größe der beiden Module hd44780.o und lcd.o aus
dem stdiodemo der avr-libc ansehe, dann sind das:
% avr-size *.o
   text    data     bss     dec     hex filename
    210       0       0     210      d2 hd44780.o
    102       0       1     103      67 lcd.o

Sollte also durchaus auch in einen ATtiny26 passen.

Autor: Bernd E. (edi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
danke erstmal für eure super Ratschläge!

Deine Idee gefällt mir sehr gut Karl Heinz, hättest du die das bei der 
zweiten Berechnung so vorgestellt?

strom = ((spg - 2.5) *1000L) / 0.025;

Autor: Bernd E. (edi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab das mit dem Strom jetzt mal so gelöst:
strom = ((spg - 250) ) / 0.025;
lcd_gotoxy(11, 0);
lcd_putint( strom / 100 );
lcd_putc( '.' );
lcd_putint( strom % 100 );

Bin jetzt immerhin von 9kB auf 6kB runter gekommen!


Ich benutze  in meiner lcd.c auch noch stdlib für itoa, kann(soll) ich 
das auch noch rausbekommen? Hier mal meine Ausgabe für int am lcd:

void lcd_putint(int value)
{
  char string[4];

  itoa(value, string, 10);
  lcd_puts(string);
}

Autor: fieser, klugscheissender Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>/ 0.025;

Würde ich durch "*40" ersetzen...

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> strom = ((spg - 2.5) *1000L) / 0.025;

Denk nach. Da sind immer noch Kommazahlen drinn!

Ich geh mal davon aus, dass du

  spg = ( adc_str * 5000L ) / 1024;

gemacht hast. spg hat also einen Wertebereich 0 bis 5000

Aus den 2.5 muessen dann klarerweise 2500 werden

   spg - 2500

sind dann Zahlen im Bereich -2500 bis +2500

Die durch 25 dividieren ( 0.025 * 1000) liefert
-100 bis +100.

Wenn ich mich jetzt nicht vertan habe (Chef war am
Telefon), dann sind das -0.1 Ampere bis +0.1 Ampere.
D.h. '.' wieder an der richtigen Stelle einschmuggeln.


Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Bin jetzt immerhin von 9kB auf 6kB runter gekommen!

Wenn du floating point komplett weg hast, müsstest
du nochmal einen grossen Sprung sehen.

itoa()
Ich denke, wenn floating point weg ist, hast du keine
Notwendigkeit mehr darüber nachzudenken. Ausserdem:
itoa() ist nicht soooo teuer. Irgendeine Umwandlung
brauchst du sowieso und ob du die jetzt selbst schreibst
oder ob du itoa() benutzt sollte Jacke wie Hose sein.

Autor: Bernd E. (edi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
habe die Änderungen noch übernommen und bin jetzt auf 5kB.

Habe mir jetzt auch einmal die Größe anzeigen lassen, nur in was wird da 
gemessen, Byte?

I:\AVR Programme\UILogger>avr-size *.o
text    data     bss     dec     hex filename
 458       0       0     458     1ca lcd.o
 566      17       3     586     24a uilogger.o

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, Byte

> habe die Änderungen noch übernommen und bin jetzt auf 5kB.
Wo liest du die 5K ab?
Doch hoffentlich nicht von der Größe der .hex Datei.


Wenn ich dein Pgm jetzt durch meinen Compiler jage,
dann lande ich bei
  Program:  1218 bytes (59.5% Full)
  Data:       25 bytes (19.5% Full)

Das reicht dann schon um gebrannt werden zu können.
Mit Floating Point waren die Daten übrigens:
  Program:  5916 bytes (288.9% Full)
  Data:       33 bytes (25.8% Full)

Kleine Umstellung, grosse Wirkung

Autor: Bernd E. (edi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich glaube die Ausgaben ans LCD fressen so viel Platz, denn wenn ich 
alle Ausgaben wegmache komme ich auf 3kB runter, wenn ich rein Strom und 
Spannungswert ausgebe bin ich auf 4 kB

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernd Edlinger wrote:
> Ich glaube die Ausgaben ans LCD fressen so viel Platz, denn wenn ich
> alle Ausgaben wegmache komme ich auf 3kB runter, wenn ich rein Strom und
> Spannungswert ausgebe bin ich auf 4 kB

Nochmal:
Du darfst nicht nach der Größe des .hex Files gehen.

Dein Program ist zur Zeit 1218 Bytes gross und füllt
den Tiny zu rund 60% aus.

Autor: Bernd E. (edi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mann bin ich blöd...
Danke für den Hinweis, dann werd ich es gleich mal testen.

Wie sehe ich denn die Größe beim Compiler?

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

Bewertung
0 lesenswert
nicht lesenswert
Ich benutze den WinAVR im Rahmen des AVR-Studios. Dessen
Build Funktion gibt die Statistik im Abschluss aus.

Autor: Malte __ (malte) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch zwei Sachen:
Du verwendest alle globalen Variablen als volatile -soweit OK.
1. Du beschreibst "adc_str" in einem Interrupt - das ist eine 16Bit 
Variable.
Wenn die Anzeige einigermaßen Zuverlässig sein sollte, musst du die 
Interrupts deaktiveren bevor du die an die LCD Libray übergibst. Sonst 
könnte es in seltenen Fällen dazu kommen dass die erste Hälfte es alten 
Wertes mit dr zweiten 8 Bit Hälfte des neuen Wertes auf dem Display 
angezeigt wird.
2. Wenn du volatile Variablen lokal mehrfach verwendet lohnt es sich 
eine lokale Kopie anzulegen um unnötige RAM Zugriffe zu vermeiden.

Also:
cli();
uint16_t adc_str_l = adc_str;
sei();
lcd_putint(adc_str_l);
Bei 8 Bit Variablen ist das natürlich nicht unbedingt nötig.

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.