Hallo, ich habe im Programm viele Variablen abgelegt. Diese werden im laufendem Programm gesetzt. Über UART möchte ich die Variablen auslesen. Ich möchte jeder Variable eine Nummer vorgeben, um dann über UART mit Angabe der Nummer, die Variablen auslesen. Praktisch sieht das so aus. Ich schicke über UART die Nummer an µC. Beim Empfang der Nummer, wird der Inhalt der entsprechenen Variable an den PC geschickt. Zur Zeit habe ich eine <switch case> Anweisung mit sehr viel Text. Ich möchte Speicherplatz sparen und die Variablen sofort über die Nummer ansprechen und auslesen. Wie kann man das machen? Gibt es so was wie eine Strukture oder ähnliches, damit ich dann einfach mit der Indexnummer die Variablen auslesen kann? Danke!
Hi! Ganz einfach! Ein Array anlegen: char Test[10] //10 char Variablen "hintereinander" Ansprechen tust du diese dann mit Test[0] //1. Variable Test[1] //2. Variable usw..
@ FrageMan (Gast) >Zur Zeit habe ich eine <switch case> Anweisung mit sehr viel Text. Ich >möchte Speicherplatz sparen und die Variablen sofort über die Nummer >ansprechen und auslesen. Wie kann man das machen? Das Zauberwort heisst Array. MFG Falk
Danke, das Problem ist aber, dass man bei Array nur einen Variablenamen hat, nähmlich den Arrayname. Und man kann sich schlecht merken, was für eine Variable sich unter der Nummer [x] verbirgt. Kann man das im Programmcode irgendwie besser gestalten? (ohne zu viel Speicherplatz zu verlieren)
> man kann sich schlecht merken, was für eine Variable sich unter > der Nummer [x] verbirgt. > Kann man das im Programmcode irgendwie besser gestalten? Du könntest die für den Arrayzugriff verwendeten Index-Werte als #defines oder als enum deklarieren:
1 | #define IDX_KIRSCHTORTE 0
|
2 | #define IDX_NAPFKUCHEN 1
|
3 | #define IDX_QUARKKEULCHEN 2
|
4 | #define IDX_BRATAPFEL 3
|
5 | |
6 | ...
|
7 | |
8 | Array[IDX_NAPFKUCHEN] = 4; |
Oder
1 | enum Indexwerte = |
2 | {
|
3 | idx_kirschtorte, |
4 | idx_napfkuchen, |
5 | idx_quarkkeulchen, |
6 | idx_bratapfel
|
7 | };
|
8 | |
9 | Array[idx_kirschtorte] = 9; |
Du kannst im Quellcode für die Nummern defines verwenden. Also z.B. #define TEMPERATUR 2 #define DRUCK 3 Dann kannst du im Programm übersichtlich mit variable[TEMPERATUR] drauf zugreifen. Ob du's so schreibst oder direkt variable[2] ändert an der Codegrösse nix.
oder eine Union verwenden: typedef union { uchar Buffer[10]; uchar Test1; uchar Test2; --- usw.. } TTest; TTest TX_Buffer; TTest RX_Buffer;
Zugriff dann über TX_Buffer.Buffer[0] ... ODER TX_Buffer.Test1;
1 | typedef union |
2 | {
|
3 | uchar Buffer[10]; |
4 | uchar Test1; |
5 | uchar Test2; |
6 | --- usw.. |
7 | } TTest; |
8 | |
9 | TTest TX_Buffer; |
10 | TTest RX_Buffer; |
Das geht schief, da Test1 und Test2 denselben Speicherbereich belegen. Richtig wäre es so:
1 | typedef union |
2 | {
|
3 | uchar Buffer[10]; |
4 | struct
|
5 | {
|
6 | uchar Test1; |
7 | uchar Test2; |
8 | --- usw.. |
9 | } TTest; |
10 | |
11 | TTest TX_Buffer; |
12 | TTest RX_Buffer; |
Wenn die in der union verwendete Struktur anonym bleibt, funktionieren die Zugriffe trotzdem so wie von tobi beschrieben.
@ Rufus: Ja, du hast Recht! War nur eine Idee von mir und zuwenig nachgedacht :-) Exakt also so: (Klammerfehler!)
1 | typedef union |
2 | {
|
3 | uchar Buffer[10]; |
4 | struct
|
5 | {
|
6 | uchar Test1; |
7 | uchar Test2; |
8 | --- usw.. |
9 | }
|
10 | } TTest; |
11 | |
12 | TTest TX_Buffer; |
13 | TTest RX_Buffer; |
Würd ich anders machen: 1. Variablen ganz normal im Programm anlegen 2. Über die Uart wird keine Nummer, sondern die Addresse der Variablen übergeben (sowie deren Länge) 3. Aus dem Mapfile weißt du welche Variable wo liegt 4. Im Programm wird dann einfach aus dem Speicher gelesen
Die Lösung von Gast halte ich für die Sinnvollste. So bleibt der Debugging-Code klein, und unabhängig von der Art der Variable (zB Strukturen, real, int, ..) Meines Wissens machen die Online-Debugger von SPS-Entwicklungsumgebungen das genauso, denn wenn man das falsche Projekt hat (also eine falsche Adresse ausließt) steht auch nur Müll in der Variable/Struktur.
"Die Lösung von Gast halte ich für die Sinnvollste" Natürlich! ;-) Hat auch den Vorteil, das absolut simpel zu implementieren ist.
Jap, man bildet die Variablen auf virtuelle Adressen ab. Ggf. kann man jeder virtuellen Adresse dann sogar noch eine Callback-Funktion zuordnen, welche bei Lese/Schreibzugriffen noch bestimmte Aktionen auslöst oder Bereichsprüfungen durchführt. struct mem_map_s { uint addr, void *p, uint len, }; mem_map_t memory_map [] = { /* virt. Adresse, Zeiger, Länge */ { ADDR_TAG, &day, 1}, { ADDR_MONAT, &month, 1}, { ADDR_JAHR, &year, 1}, { ADDR_STATUS, &state, 1}};
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.