Ich habe mal eine wirklich dumme Frage und eigentlich sogar sehr
peinlich, aber da peinliches immer nur für das Jahr gilt in dem man
peinlich war und danach alles vergessen werde ichdas für den Rest des
Jahres verkraften.
Ich wollte mir Klimmzüge über struct ersparen und habe folgendes
Problem. Ich möchte bei einem AVR in einem Array zusaetzlich zu einem
String noch ein einzelnes unsigned char integriert haben und kann das
nicht mischen. Von daher suche ich einen praktikablen Weg.
Folgendes funktioniert logischerweise:
1
const uint8_t mnem[][10] PROGMEM =
2
{
3
{ 4,'m','v','i',' ','a',',','?',0 },
4
{ "cmpg a,?" },
5
{ "cdis"}
6
};
Nun möchte ich natürlich nicht einen String schön in Einzelchars
eingeben, sondern als String.
Wie kann man das (was nicht funktioniert) elegant lösen?
1
const uint8_t mnem2[][10] PROGMEM =
2
{
3
{ 4,"mvi a,?" },
4
{ "cmpg a,?" },
5
{ "cdis"}
6
};
Hier meckert der Compiler mit:
1
cp1_term.c:37:3: error: initializer element is not computable at load time
2
cp1_term.c:37:3: error: (near initialization for 'mnem2[0][1]')
;-) und sagt mir nicht, dass der Fehler in Zeile 42 liegt, er liegt in
Zeile 37
Einen guten Rutsch an alle
... wenn man ganz alleine zu Hause sitzt ... und noch nicht mal vor die
Haustüre darf, ist da eine schlechte Idee zu böllern. Im Übrigen böller
ich seit Jahrzehnten nicht mehr
https://godbolt.org/z/1W9K3v
\x leitet ein Hex-String-Literal ein, einzelne Strings können einfach
durch hintereinandersetzen verkettet werden.
Ansonsten nicht zu viel erwarten von der Trollarmee hier, schon gar
keine sinnvollen Antworten.
fragender schrieb:> const uint8_t mnem[][10] PROGMEM => {> { "\x04""mvi a,?" },> { "cmpg a,?" },> { "cdis"}> };> https://godbolt.org/z/1W9K3v>> \x leitet ein Hex-String-Literal ein, einzelne Strings können einfach> durch hintereinandersetzen verkettet werden.>> Ansonsten nicht zu viel erwarten von der Trollarmee hier, schon gar> keine sinnvollen Antworten.
boah, okay... vielen Dank (an den Kopf batsch). Das funktioniert. Haber
jetzt aber schon die Programmstruktur geändert dahingehend, dass ich die
Zahl mit in den String nehmen und beim Auslesen extrahiere.
Hmmm, ob ich noch einmal den Programmcode ändere ?
Ralph S. schrieb:> Ich wollte mir Klimmzüge über struct ersparen
Koste es, was es wolle.
Ralph S. schrieb:> Hmmm, ob ich noch einmal den Programmcode ändere ?
Zu es. Mit einem struct ist es sauber, kleiner, einfacher, wartbarer,
lesbarer.
Heute siehst Du die 10 Zeilen mehr beim Typ und merkst nicht, wie Du
Dich auf 30 oder mehr Zeilen verrenkst. Mit einem struct machen weitere
Änderungen auf einmal Spaß, weil es immer besser wird. Am Ende ist der
ganze Code nur halb so groß.
Veit D. schrieb:> Du legst ein 2 dimensionales Array an in dem Daten fehlen. Das muss> schief gehen. Deine Ausleseroutine macht bestimmt im RAM Nirwana weiter.
Das war ja mein Problem. Ein String ist ein "Array of Char" und die 4
sollte ein weiteres Char sein (kein Ascii-Zeichen). Ich wußte einfach
nicht mehr, dass das so geht:
{"\x04""Text"}
wie es
fragender schrieb:> const uint8_t mnem[][10] PROGMEM => {> { "\x04""mvi a,?" },> { "cmpg a,?" },> { "cdis"}> };
gezeigt hat.
Eine Struktur hatte ich anderst gemacht gehabt, die auch funktioniert
hat (und NICHT im Ram-Nirvarna gewütet hat).
Veit D. schrieb:> struct Struktur> {> byte pin;> char text[21];> };>> Struktur daten[] = {> {1, "mvi a,?"},> {2, "cmpg a,?"},> {3, '\0'},> {4, "cdis"},> };
Genau das was du da schreibst, wollte ich vermeiden, weil die Strings
hier auch RAM belegen, ich das aber im Flash haben wollte und deshalb
den Zusatz PROGMEM gebraucht hab. Mache ich das über die Struktur, wird
das auslesen über read_pgm_byte noch witziger.
Wie gesagt war das oben die Lösung. Im Übrigen mache ich das nicht mit
einem Arduino (verstehe ich nicht, warum man häufig annimmt, wenn ein
AVR im Spiel ist, dass das ein Arduino-Sketch wird).
Hier gings ums grundsätzliche und von probiere ich solche Dinge auf der
Console mit GCC (für PC) aus und nicht auf dem Controller. Wenn sie
dort funktionieren wirds an den Controller angepasst (bei STM32 brauche
ich in der Regel keine oder kaum Anpassung, bei AVR kommt immer das
"depperte" read_pgm ins Spiel).
Veit D. schrieb:> Ab dem neuen Jahr zeigste den kompletten Code!
den zeige ich in der Regel immer. Hier ging es aber ums Array an sich
(und das was die Lösung war hatte ich schon mal gewußt und schlicht
wieder vergessen gehabt).
Ralph S. schrieb:> Im Übrigen mache ich das nicht mit> einem Arduino (verstehe ich nicht, warum man häufig annimmt, wenn ein> AVR im Spiel ist, dass das ein Arduino-Sketch wird).
Deine Annahme ist falsch. Mir ist es egal in welcher Umgebung du
programmierst. Ich habe für mich den Code in der Arduino IDE getestet.
Geht meistens schneller und bequemer, gerade für solche Dinge. Versteife
dich nicht darauf wer was in welcher Umgebung programmiert und zeigt.
Der eigentliche Code ist entscheidend.
>> Ohne die Auswertung anzuzeigen (die ist für das Array auch ohne Belang,> im Flash ist jetzt vor dem eigentlichen String eben ein Byte abgelegt.
Da werden jeweils 2 Bytes abgelegt. Dein Byte und ein \0, das ist ja
auch nur ein normaler String.
Kuddel schrieb:> Da werden jeweils 2 Bytes abgelegt. Dein Byte und ein \0, das ist ja> auch nur ein normaler String.
Ich sehe da 7 Char, plus eine Null.
Völlig egal, ob man { "\x12""out p2"} oder { "\x12out p2"} schreibt.
Arduino Fanboy D. schrieb:
> Ich sehe da 7 Char, plus eine Null.>> Völlig egal, ob man { "\x12""out p2"} oder { "\x12out p2"} schreibt.
Absolut korrekt, und ich habe die Strings ja auch im Stile von "\x04mvi
a,?" dann abgelegt.
Es ging ja genau darum, vor dem eigentlichen String, ein einzelnes Byte
(in meinem Falle den Opcode einer Mnemonic) abzulegen. Das ein String
ein abschließendes 0-Byte hat ist klar.
Veit D. schrieb:> Ich habe für mich den Code in der Arduino IDE getestet.> Geht meistens schneller und bequemer, gerade für solche Dinge. Versteife> dich nicht darauf wer was in welcher Umgebung programmiert und zeigt.> Der eigentliche Code ist entscheidend.
;-) oki, dann hatte ich das falsch verstanden. Ich denke jeder hat seine
Umgebung, um etwas schnell auszuprobieren.
Ich stimme meinen Vorrednern zu!
Es ist falsch, einfach ein Byte vor den String zu dengeln, nur weil es
bequemer ist.
Ich will nicht bezweifeln, dass es funktioniert.
Aber: Es ist die falsche Denke.
Gewöhnst du dich an die falsche Denke, wirst du noch weit häufiger
solchen "Mist" konstruieren.
Ich prophezeie dir: Damit wirst du irgendwann auf die Nase fallen. Und
die Leute, welche deinen Code warten müssen werden sich bitterlich bei
dir beschweren.
Strukturen wurden nicht ohne Grund erfunden!
Eben um unterschiedliche Datentypen zusammenfassen zu können.
Ja, Auch dieses Beispiel nutzt Arduino Code, allerdings nur für die
Ausgabe.
Ich hoffe, dass es dich nicht überfordert, den Kern da raus zu
operieren.
----------
Code:
Arduino Fanboy D. schrieb:> struct Struktur> {> byte pin;> char text[21];> };>> const Struktur daten[] PROGMEM= {> {7, "ggcdis"},> {5, "mvi a,?"},> {9, "cmpg a,?"},> {113, '\0'},> {42, "cdis"},> {16, "ffcdis"},> {6, "ggcdis"},> };
das ist das, was ich ursprünglich gewollt hatte und weswegen auch immer
nicht gleich geklappt hatte. Aus dem Grund hatte ich das prakmatisch
machen wollen. Das hier ist natürlich die korrekte Art und Weise....
Nichts desto trotz werd ich mich mal für n paar Tage oder so aus dem
Forum zurückziehen, Urlaub ist eh rum (und seit gestern darf ich auch
wieder vor die Tür)