Hallo zusammen :)
irgendwie habe ich gerade ein Verständnissproblem.
Schreibe ich außerhalb der main Funktion das hier, wir mein Programm
nicht mehr ausgeführt (der Compiler meckert nicht):
unsigned char virtual_LCD[SCREEN_HIGHT][SCREEN_WIDTH];
Was meiner Meinung nach dem hier entsprechen müsste ...
... schreibe das hier außerhalb der main Funktion
unsigned char **virtual_LCD;
und das hier in die main Funktion, funktioniert das Programm
virtual_LCD = malloc(SCREEN_HIGHT * sizeof(unsigned char*));
for (unsigned char idx = 0; idx < SCREEN_WIDTH; idx++)
virtual_LCD[idx] = malloc(SCREEN_WIDTH * sizeof(unsigned char));
Nun meine Frage:
was ist an diser Formulierung falsch?
unsigned char virtual_LCD[SCREEN_HIGHT][SCREEN_WIDTH];
SCREEN_HIGHT, SCREEN_WIDTH sind Konstanten
Vielen Dank!
devil13 schrieb:> und das hier in die main Funktion, funktioniert das Programm
Aber sicher nicht perfekt, denn hier sollte SCREEN_WIDTH durch
SCREEN_HIGHT ersetzt werden:
1
for(unsignedcharidx=0;idx<SCREEN_WIDTH;idx++)
> was ist an diser Formulierung falsch?> unsigned char virtual_LCD[SCREEN_HIGHT][SCREEN_WIDTH];
Nichts.
Damit hast du das Array statisch definiert, und es liegt zusammenhängend
im Speicher. Im anderen Fall wird die Datenstruktur dynamisch angelegt,
und die einzelnen Zeilenarrays können verstreut im Speicher liegen.
Wenn das Programm nicht läuft oder abstürzt, liegt es vielleicht daran,
dass du das Array falsch nutzt. Oder du hast wo ganz anders einen
Fehler.
Yalu X. schrieb:>> was ist an diser Formulierung falsch?>> unsigned char virtual_LCD[SCREEN_HIGHT][SCREEN_WIDTH];>> Nichts.
denn versteh ich aber nicht, warum es nicht geht ... ich verwende das
Array bisher nicht mal ... außer diese Zeile
unsigned char virtual_LCD[SCREEN_HIGHT][SCREEN_WIDTH];
taucht virtual_LCD nicht auf ...
lasse ich es weg, geht es, steht es mit drin, geht es nicht ...
Nebenbei bemerkt, ich möchte dieses Array in ein Modul packen.
es soll nicht in der Header Datei stehen, aber ich der dazugehörigen *.c
Datei ... kann das damit was zu tun haben oder muss ich dabei etwas
beachten?
devil13 schrieb:> SCREEN_HIGHT, SCREEN_WIDTH sind Konstanten
Dann gibt's allerdings keinen sinnvollen Grund, das Array und
die Subarrays dynamisch anzulegen. Funktionieren sollte es
natürlich trotzdem, auch wenn beide Ansätze nicht identisch sind
von der Benutzung.
devil13 schrieb:> es soll nicht in der Header Datei stehen, aber ich der dazugehörigen *.c> Datei ...
Speicherplatz alloziert man ohnehin nie in Headerdateien. Dort
muss also stehen:
extern unsigned char virtual_LCD[SCREEN_HIGHT][SCREEN_WIDTH];
und in einer der C-Dateien dann einfach
unsigned char virtual_LCD[SCREEN_HIGHT][SCREEN_WIDTH];
(auf globalem Niveau).
Jörg Wunsch schrieb:> Speicherplatz alloziert man ohnehin nie in Headerdateien. Dort> muss also stehen:>> extern unsigned char virtual_LCD[SCREEN_HIGHT][SCREEN_WIDTH];>> und in einer der C-Dateien dann einfach>> unsigned char virtual_LCD[SCREEN_HIGHT][SCREEN_WIDTH];
Nunja, da ich dieses Array nur in der *.c Datei des Moduls verwende und
es nach außen nich sichtbar sein soll. Glaube aber sowas wie private und
public gibt es in C noch nicht ... naja ... zur Not, kann auch alles
überall sichtbar sein ... die Variante mit extern in der *.h Datei führt
auch dazu, dass das Programm nicht mehr ausgeführt wird ...
devil13 schrieb:> denn versteh ich aber nicht, warum es nicht geht ... ich verwende das> Array bisher nicht mal ... außer diese Zeile
Der Programmfehler liegt nicht immer dort, wo man die letzte Änderung
vor Auftreten des Fehlverhaltens gemacht hat.
Vielleicht hast du woanders einen Array-Überlauf o.ä., so dass beim
Beschreiben des Arrays andere Variablen überschrieben werden. Fügst du
nun das virtual_LCD-Array hinzu, wird die Speicherposition anderer
Variablen verschoben, so dass durch den Überlauffehler jetzt vielleicht
andere Variablen überschrieben werden, die für den Programmablauf
besonders kritisch sind.
>Nunja, da ich dieses Array nur in der *.c Datei des Moduls verwende und>es nach außen nich sichtbar sein soll. Glaube aber sowas wie private und>public gibt es in C noch nicht ... naja ... zur Not, kann auch alles
Sowas gibt es schon, halt ein bissle anders:
"static unsigned char virtual_LCD[SCREEN_HIGHT][SCREEN_WIDTH];"
als globale Variable ist nur innerhalb der C-Datei, in der es definiert
wurde, sichtbar.
Was für ein System bzw. Controller verwendest Du?
Und wieviel anderes Zeugs wird in dem Projekt noch verwendet?
Yalu X. schrieb:> Vielleicht hast du woanders einen Array-Überlauf o.ä., so dass beim> Beschreiben des Arrays andere Variablen überschrieben werden. Fügst du> nun das virtual_LCD-Array hinzu, wird die Speicherposition anderer> Variablen verschoben, so dass durch den Überlauffehler jetzt vielleicht> andere Variablen überschrieben werden, die für den Programmablauf> besonders kritisch sind.
Habe das Problem mal an nem Beispiel reproduzieren können. Das Verhalten
ist bei mir genau das Beschriebene.
das geht
Matthias schrieb:> Sowas gibt es schon, halt ein bissle anders:>> "static unsigned char virtual_LCD[SCREEN_HIGHT][SCREEN_WIDTH];">> als globale Variable ist nur innerhalb der C-Datei, in der es definiert> wurde, sichtbar.
bedeutet dann static nicht auch unveränderlich? Oder gilt das nur für
die Array Größe, nicht aber für deren Inhalt?
devil13 schrieb:> (verwende übrigends nen Atmega8)
Scherzkeks.
Schon mal ausgerechnet, wie viele Bytes Dein Array im RAM belegt?
Und schon mal ins Datenblatt geschaut, wieviel RAM der ATmega8 hat?
Na?...
Patrick schrieb:> Scherzkeks.> Schon mal ausgerechnet, wie viele Bytes Dein Array im RAM belegt?> Und schon mal ins Datenblatt geschaut, wieviel RAM der ATmega8 hat?> Na?...
Hm ... muss gestehen, darüber habe ich mir garkeine Gedanken gemacht ...
erklärt aber das Problem ...
Danke für die Hilfe erstmal :)
Wie würdet ihr denn am Besten an mein Vorhaben rangehen?
Ich beschäftige mich gerade mit Grafik Displays. Habe auch alles so
hinbekommen, dass alles funktioniert. Jedoch muss ich z.B. um eine Linie
zu zeichnen immer ganz viele Punkte im LCD zeichnen lassen ... da dieser
aber immer 8 Bit Spalten besitzt, muss ich die 7 Bit die bleiben sollen
immer erst einlesen, das zu ändernde Bit ändern und dann wieder
zurückschreiben. Ich finde das sehr mühsam und umständlich.
Daher wollte ich mir im Atmega8 merken, was gerade auf dem LCD zu sehen
ist und dann nur noch zu schreiben ... bzw. ein kompletten Display im
Atmega vorzubereiten und ihn dann an das LCD senden. Das würde viel
schneller gehen.
Wieviele Pixel hat das Display, 32×122 oder 256×122? Ist letzteres der
Fall, gibt es keine Möglichkeit, den Displayinhalt lokal zu speichern,
und dir bleibt nur der umständlichere Weg. Aber auch dann kannst du die
Sache etwas optimieren, indem du erst einmal alle zu ändernden Pixel,
die zum selben Byte gehören, sammelst und dann erst den Displayzugriff
machst.
devil13 schrieb:> unsigned char virtual_LCD[SCREEN_HIGHT][SCREEN_WIDTH];>> Was meiner Meinung nach dem hier entsprechen müsste ...>> unsigned char **virtual_LCD;
Nö.
Das eine ist ein 2-dimensionales Array von 8-Bit Skalaren, das andere
ist ein Array von Zeigern.
Auf beide wird unterschiedlich und nicht-kompatibel zugegriffen
devil13 schrieb:> muss ich die 7 Bit die bleiben sollen> immer erst einlesen, das zu ändernde Bit ändern und dann wieder> zurückschreiben
Rate mal was der uC macht wenn das im internem RAM liegt? ;-)
Sei doch froh, dass das Grafikdisplay genug RAM mitbringt wo du den
Inhalt drin liegen hast.
Damit es komfortabler wird kann man sich ja Funktionen schreiben welche
den mühevollen Teil erledigen.
Yalu X. schrieb:> Wieviele Pixel hat das Display, 32×122 oder 256×122?
32×122 Pixel
Läubi .. schrieb:> Sei doch froh, dass das Grafikdisplay genug RAM mitbringt wo du den> Inhalt drin liegen hast.>> Damit es komfortabler wird kann man sich ja Funktionen schreiben welche> den mühevollen Teil erledigen.
dann werde ich mich wohl damit zufrieden geben ... allerdings dauert das
Zeichnen schon echt ganz schön lange ... naja ...
Yalu X. schrieb:> Aber auch dann kannst du die> Sache etwas optimieren, indem du erst einmal alle zu ändernden Pixel,> die zum selben Byte gehören, sammelst und dann erst den Displayzugriff> machst.
Das war ja auch mein Plan ... nur im schlechten Fall, kann sich ja alles
ändern und dafür brauche ich eben besagtes Arra, was zu groß ist um es
im Ram abzulegen, und der SRAM/EEPROM ist mir dafür zu schade ... weiß
nicht, wieviel zusätzliche Geschwindigkeit man gewinnt, wenn man einen
externen Ram nutzt ... dachte nur, weil das LCD mit 2 kHz arbeitet und
der Atmega mit 16 MHz wäre es besser, wenn der Atmel mehr arbeit macht
... vllt. wäre nen "größerer" Atmega oder nen anderes Display oder so ne
einfachere Lösung ...
devil13 schrieb:> bedeutet dann static nicht auch unveränderlich? Oder gilt das nur für> die Array Größe, nicht aber für deren Inhalt?
Du solltest die Programmiersprache deiner Wahl schon erstmal lernen,
bevor du versuchst, sie zu verwenden. "static" ist, wenn man es auf
globalem Niveau in einer Datei anwendet (also außerhalb aller
Funktionen) genau das "private", das du gesucht hast. "Statisch" (im
Sinne von permanent vergebenem Speicherplatz) ist auf diesem Niveau
nämlich ohnehin alles, nur ohne "static" sind Funktionen und Variablen
global.
Kann man als Designfehler der Sprache C ansehen. Eigentlich hätte
ohne Kennzeichnung alles privat sein sollen, und nur durch "export"
oder sowas global. Daher ist es auch guter Stil, dass man vor alles,
das nicht exportiert wird, prinzipiell "static" schreibt.
Mit "const" sollte man das alles außerdem nicht verwechseln.
Jörg Wunsch schrieb:> Du solltest die Programmiersprache deiner Wahl schon erstmal lernen,> bevor du versuchst, sie zu verwenden.
Ganz schön harte Worte ... aber ich muss zugeben nicht unberechtigt ...
... aber ich möchte dran erinnern, dass zwischen etwas nicht können und
etwas können immernoch etwas lernen liegt!
Dennoch ein Dickes Dankeschön, an alle, die mir so nett geholfen haben,
mein kleines Problem zu lösen :)
>> Wieviele Pixel hat das Display, 32×122 oder 256×122?>32×122 Pixel
Dann brauchst du für jeden Pixel nur ein Bit also nur 122*4 Byte. Die
einzelnen Pixel anzusprechen ist dann zwar etwas komplizierter, aber ich
vermute mal, dass dein Grafikdisplay die Daten genauso abspeichert, du
die Berechnungen also schon hast.
devil13 schrieb:> ... aber ich möchte dran erinnern, dass zwischen etwas nicht können und> etwas können immernoch etwas lernen liegt!
Ja, das ist dann gerade deine Aufgabe. ;-)
André Althaus schrieb:>>> Wieviele Pixel hat das Display, 32×122 oder 256×122?>>32×122 Pixel>> Dann brauchst du für jeden Pixel nur ein Bit also nur 122*4 Byte.
Eben. Genau deswegen habe ich nachgefragt.
Die Zugriffsfunktionen für das Array sind nicht besonders schwierig,
wenn nicht gerade jemand aus dem C-Buch die Seiten mit den Bitoperatoren
herausgerissen hat:
Yalu X. schrieb:> André Althaus schrieb:>>>> Wieviele Pixel hat das Display, 32×122 oder 256×122?>>>32×122 Pixel>>>> Dann brauchst du für jeden Pixel nur ein Bit also nur 122*4 Byte.>> Eben. Genau deswegen habe ich nachgefragt.
Boa ... was für nen dummi Fehler^^
Hier schonmal meine bisherigen Bemühungen für das Pollin LCD-12232.
Funktioniert soweit ganz schick ... aber ist eben auch die (finde ich)
unschöne/umständliche/langsame Variante ... naja ... vllt. probiert sich
ja jemand an diesem LCD und kann das als kleine Hilfe verwenden ...
Ich versuche mich gerade noch an die hier disskutierte Variante und
sollte ich diese irgendwann fertig stellen, poste ich sie hier :)
LG