Hallo, hier meine Struktur des Programmes Main.c mit #include "Main.h" Projekt.c mit #include "Main.h" Main.h mit #include <avr/io.h> und der anderen notwendigen AVR- Dateien In der Main.h sind alle Makros, Funktionen, Prozeduren, Variablen usw. aufgelistet Ich kann in der *.h Datei ein Array definieren, nur eben keines mit konstanten Werten ausfüllen .... uint8_t TestArray[3]; // das geht uint8_t TestArray[] = {1,2,3} // das geht nicht in der *.h, logischerweise Also behelfe ich mir damit, eine Prozedur zu schreiben, die ein flüchtiges Array in ein globales Array schreibt, welches ich in der Main.h definiert habe ... void SchreibeArray(void) { uint8_t i, T_Array[] = {1,2,3}; for (i=0;i<3;i++) TestArray[i] = T_Array[i]; } Gibt es einen anderen Weg (enum o.a.)????? Ich habe große Tabellen zu verarbeiten und möchte nicht den SRAM überstrapazieren Danke ...
??? in main.c uint8_t T_Array[] = {1,2,3}; in main.h extern uint8_t T_Array[]; und schon kennt die ganze Welt (bzw. alle Dateien, die main.h inkludieren) dein T_Array. "uint8_t TestArray[] = {1,2,3} // das geht nicht in der *.h" Geht schon. Nur nicht mit mehreren Dateien, und natürlich mit Semikolon hinten dran. Oliver
Vielen Dank, vielleicht ist es auch nur noch ein kleiner Fehler, aber bei mir geht es leider so nicht Die Main.c erkennt natürlich das Array aber eine andere Datei (z.B. Init.c) eben nicht, trotz include Main.h am Anfang der Init.c und dem Hinweis extern in der Main.h ../Init.c:79: undefined reference to `T_Array' was könnte es sein? Wäre schön, wenn ich da weiter käme ... Wenn ich in dr main.h -- uint8_t TestArray[] = {1,2,3}; einschribe, dann kommt sofort --- GCC plug-in Error .... file not found Ich arbeite mit AVR Studio
Stell deinen Code mal komplett hier rein. Sonst wird das nichts. Die Glaskugeln sind gerade alle wieder in der monatlichen Wartung. Oliver
Ich habe mal schnell, nur das Problem betreffend, einen Test geschrieben --- es wäre wahnsinnig toll, wenn ich da weiter käme ... Danke
Also, so gehts leider nicht. Wenn du aus allen Modulen auf T_Array direkt zugreifen willst, dann muß das global deklariert sein, also ausserhalb von irgendeiner Funktion. Also etwa so: datei main.c ==================== #include <avr/io.h> uint8_t T_Array[] = {1,2,3}; int main() { ... } datei main.h ==================== extern uint8_t T_Array[]; datei projekt.c ==================== #include <avr/io.h> #include "main.h" void ZumProgrammPunkt(void) { T_Array[2] = 5; } Innerhalb von Funktionen deklarierte Variablen sind nur dort sichtbar. Dann musst du das Array als Parameter an andere Funktionen übergeben, etwa so: void ZumProgrammPunkt(uint8_t T_Array[]); int main() { uint8_t T_Array[] = {1,2,3}; ZumProgrammPunkt(T_Array); } Oliver
Hallo, setze einfach die Definition von "uint8_t TestArray2[] = {5,6,7,8};" vor dem "int main(void)". Als globale Variable definiert, funktionierts. Mit "extern" definierst Du nicht die Variable, sondern machst die Typ Definition für andere bekannt. In "main.c" vor "int main(void)" definierst Du erst die Variable und besetzt Sie mit Werten. Also: in Main.c #include "Main.h" uint8_t TestArray2[] = {5,6,7,8}; int main(void) { bla fasel } in Main.h extern uint8_t TestArray2[]; in Projekt.c #include "Main.h" void ZumProgrammPunkt(void) { TestArray2[3] = 5; }
Ich halts nicht aus -- das ist es --Heikos Variante funktioniert so wie ich es wollte, Olivers' auch, etwas verworrener vielleicht bei mehreren Dateien ---- danke Euch beiden !!! Ich habe vorher in Assembler programmiert ... Nur mal so aus Neugier ... wird jetzt sozusagen aus dem Programmfile (*.hex) das Array gelesen und quasi an eine feste Stelle im SRAM gespeichert? In Assembler kann ich ja direkt aus dem Programmspeicher lesen (lpm) - in C ist das schwierig (Programm stürzt ab) wenn ich #include <avr/pgmspace.h> nehme, aber wie ....
Also, ein "#include" sollte kein Programm abstürzen lassen. Der Compiler arbeitet Programmteile mit ein, die mehrere "init(x)" (ich glaube x = 0-9) beinhalten, in denen sogenannte vorarbeiten durchführt werden (definierte Variablen mit 0 vorbelegen und noch viele andere Dinge), dabei wird die Variable im Speicher (RAM) initialisiert und der Ram-Bereich ist reserviert, solange die Variable gültig ist, in diesem Fall während der gesamte Laufzeit (Globale extern). Bei den Vorarbeiten wird ebenfalls die Vorbelegung der Globalen Variable durchgeführt, wobei die Werte natürlich im Flash stehen, solange Sie ungleich 0 sind, glaube ich ?! Variablenwerte aus dem Flash zu laden, macht irgendwie wenig Sinn, kann aber mit dem von Dir angesprochenen realisiert werden. In solch einem Fall sind diese Variablen im Flash aber Konstante und der Compiler übernimmt diese Werte automatisch. Übrigens, in der Doku vom WinAVR ist eine gute Beschreibung, wie das Ganze funktioniert.
kommt drauf an wie du's benutzt, gib mal code zum beäugen. pumpkin
Also, sobald ich in meine Main.h #include <avr/pgmspace.h> einschreibe, stürzt bei Build (F7) das AVR-Studio Programm komplett ab, so dass ich sogar die Main.aps löschen muss, um wieder an die Dateien zu kommen ... Problem ist - ich möchte auf ca. 600 Byte - Konstanten zurückgreifen und da ist dann der SRAM schon mehr als halb voll. Als ich in Assembler programmiert habe, konnte ich die Konstanten im üppigen Programmspeicher lassen und habe sie direkt angesprochen, wenn ich sie brauchte. In C++ wird nun alles erst in den RAM geladen ....
Build succeeded with 0 Warnings... Welche Version vom AVR-Studio, welcher WinAVR, welches Betriebssystem? Oliver
Alles hornalt. Diese alten AVR-Studio-Versionen hatten einen Bug, der wohl den Parser festgeklemmt hat, der die Ausgaben von GCC analysiert. Wenn schon AVR Studio 4.12, dann build 498 (SP4 oder so). Oder gleich auf die aktuellen Versionen (AVR Studio 4.13 und WinAVR 2007xxxx) hochziehen.
@Jens-Erwin >Problem ist - ich möchte auf ca. 600 Byte - Konstanten zurückgreifen und >da ist dann der SRAM schon mehr als halb voll. >Als ich in Assembler programmiert habe, konnte ich die Konstanten im >üppigen Programmspeicher lassen und habe sie direkt angesprochen, wenn >ich sie brauchte. In C++ wird nun alles erst in den RAM geladen .... AFAIK kann man das in C(++) auf dem AVR nur "zu Fuss" machen, über die Funktionen pgm_read.. etc. Einfach ein (normales) konstantes Array definieren geht nicht, die landen trotzdem im RAM. Vielleicht kann man es über ein Macro hintricksen. Aber ich bin weiss Gott kein C-Profi. http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmspeicher_.28Flash.29 MfG Falk
Nix da. Selbstverständlich landet uint8_t myVar[3] PROGMEM = {1,2,3}; im Flash. Der Zugriff auf die einzelnen Werte erfogt dann über pgm_read() Oliver
@Oliver >Nix da. >Selbstverständlich landet >uint8_t myVar[3] PROGMEM = {1,2,3}; >im Flash. Der Zugriff auf die einzelnen Werte erfogt dann über >pgm_read() Sagte ich das nicht? MfG Falk
Die Frage ist doch die, ob alle 600 Byte im Flash landen und dort warten, oder nur die, die bearbeitet werden ... das ist ja auch in Assembler so. Ich hole also das Byte aus dem Programmflash und speichere es in ein Register oder in den SRAM, sende es z.B. und hole das nächste Byte aus dem Programmspeicher usw.
>> Die Frage ist doch die, ob alle 600 Byte im Flash landen und dort >> warten, oder nur die, die bearbeitet werden ... ??? die die du per attribut PROGMEM reinschiebst. wo liegt das problem?
@Jens-Erwin >Die Frage ist doch die, ob alle 600 Byte im Flash landen und dort >warten, oder nur die, die bearbeitet werden ... Es landen alle im FLASH und bleiben auch dort. Du kannst einzelne Werte dann mit pgm_read... lesen. >das ist ja auch in Assembler so. >Ich hole also das Byte aus dem Programmflash und speichere es in ein >Register oder in den SRAM, sende es z.B. und hole das nächste Byte aus >dem Programmspeicher usw. Genau das machst du auch in C, nur dass es eben leider (mit GCC) nicht direkt geht uint8_t const_array[5] PROGMEM = {1, 2, 3, 4, 5}; tmp = const_arry[3]; // geht nicht mit GCC sondern so gemacht werden muss tmp = read_pgm_byte(&const_array[3]); // GCC Methode MfG Falk
So jetzt ist alles klar ... danke Euch allen habe jetzt alle neue Software geladen .. und es geht !!!! also, ich habe beim Simulieren mal den Disassembler und den SRAM-Speicher beobachtet .. PROGMEM funktioniert wunderbar, die Daten werden NICHT im SRAM gespeichert, sondern nur dann, wenn man sie abruft ... also genau so wie ich es brauche -- entspricht absolut dem lpm Befehl in Assembler Damit kann man also wirklich größere Tabellen ablegen -- damit ist C++ für mich endgültig zum Durchbruch gegenüber Assembler gekommen (zeitkritische Sachen ausgenommen) .....
Prima. Mit dem "++" von "C++" hast du es zwar noch nicht so, aber das kann ja noch werden. Für Assembler-Freaks ist aber normales C sowieso viel besser geeignet. Oliver P.S. Schau dir mal das #define zu read_pgm_byte an. Welcher Befehl mag da wohl verwendet werden?
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.