Forum: Mikrocontroller und Digitale Elektronik Arrey Zugriff mit Byte


von Daniel G. (daniel83)


Lesenswert?

Hallo ich habe ein Problemchen.

Ich möchte sowas machen.
Beispiel:
1
unsignedbyte i=0x06;
2
unsignedbyte[30] Arrey;
3
Arrey[i]=0x98;

Das geht auch Wunderbar, bis 15, danach nicht.

In C# geht folgendes
1
Arrey[(int)i]=0x98;

Das habe ich versucht, hat aber nicht gebracht was ich wollte. Das Byte 
i ist ein Byte und wird auch gebraucht als solches, muss ich mir jetzt 
eine Converrtierungsrutine schreiben, ist kein Problem, aber wenns ohne 
geht wäre das sehr schön.
Kennt jemand das Verhalten, also liegt das an dem Byte, oder hab ich 
irgendwo anders nen Bug und ich schiebe das nur auf das Byte?

Und Ja ich weiß, das mit dem woanders nen Bug ist eher die Frage nach 
geht das was ich beschreiben habe, also eher ausschluss Verfahren.

Gruß Daniel

von Karl H. (kbuchegg)


Lesenswert?

Du hast woanders einen Bug

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> unsignedbyte[30] Arrey;
> Das geht auch Wunderbar, bis 15, danach nicht.
Sicher? Arrays werden so deklariert:
unsignedbyte Arrey[30];

Zeig doch mal mehr vom Code, der Fehler steckt woanders...

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Das heißt "arrAy" (mit "e" tut es ja in den Augen weh).

von Daniel G. (daniel83)


Lesenswert?

Das heißt anders, und das Array ist auch richtig deklariert, besteht 
auch aus anderen Komponenten, hängt ne Struktur drin, war nur nen 
schnell zusammen getipptes Beispiel, ohne test, kann also durchaus sein, 
dass ich mich da vertippt hab.
Mir gings nur um das Byte als index, das geht also, Ok, dann such ich 
mal wo anders, ging nur darum, dass ich mir da jetzt nicht die Finger 
wund suche.

von Daniel G. (daniel83)


Lesenswert?

Der Zugriff sieht so aus:
1
pTsKeysSlave1[(int)ubKey].ubKeyDownCommand=ubCommand;

von Karl H. (kbuchegg)


Lesenswert?

Daniel G. schrieb:
> Der Zugriff sieht so aus:
>
1
pTsKeysSlave1[(int)ubKey].ubKeyDownCommand=ubCommand;


Ein Tip.
Vergiss deine ständige Casterei solange du nicht weißt was du tust.
Das Ziel muss sein: Sowenig Casts wie möglich. Jeder Cast ist ein 
potentieller Fehler, den du machst. Mit einem Cast hebelst du das 
Typsystem des Compilers aus! DU übernimmst dann die Verantwortung, dass 
alles korrekt ist, der Compiler akzeptiert dann jeden Scheiss.


Zu deinem Code.
Schön.
Und was soll uns das jetzt sagen?

Kannst du mir auch einen Tip geben? Mein Auto fährt nicht mehr 
richtig.Ich poste jetzt dann gleich mal ein Photo von einer der 
Schrauben. Wärst du so nett und siehst du dir das an, um mir dann zu 
sagen, was denn da falsch sein könnte?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Mir gings nur um das Byte als index, das geht also
Ja. Den Index kannst du problemlos bis ans Ende des Wertebereichs laufen 
lassen (short: 0..32767, unsigned short: 0..65535)

> pTsKeysSlave1[(int)ubKey].ubKeyDownCommand=ubCommand;
Hurra, eine Scheibe Salami... :-/

Interessant wäre z.B.
Welche Plattform (Controller, Compiler)?
Komplette Deklaration des Structs und des Arrays.
Am besten den ganzen betroffenen Sourcecode.
Dann kann dir evtl. geholfen werden.

von Daniel G. (daniel83)


Lesenswert?

Mit dem Code wollte ich nicht um Hilfe bitten, sondern lediglich zeigen, 
wie ich es gemacht habe, um mögliche Unklarheiten aus meinem leicht 
fehlerhaften Beispiel vom anfang aus zu räumen, dass mir damit niemeand 
helfen kann war mir klar.
Den Cast habe ich drin, weil ich wie ich beschreiben habe versucht hab, 
ob das verhalten besser wird wenn ich int caste, das war nicht der Fall.
Dank der Mithilfe weiß ich jetzt, dass ich Byte durch aus als IUndex 
verwenden kann, das ging aus meinem Schlauen Buch nämlich nicht hervor.
D.H. ich muss woanders suchen.
und euch jetzt mit mienem ganzen Code zu zu müllen und sagen, sucht mir 
mal meinen Fehler halte ich nicht für das richtige verhalten, d.H. ich 
werde mir jetzt mal die zugriffs rutinenn ansehen und selbst suchen.

Vielen Dank

P.S. zu deinem Auto, versuch mal die Schraube wieder da hin zu packen, 
wo du sie her hast, vieleicht gehts dann besser ^^

von Daniel G. (daniel83)


Lesenswert?

Also:

System MSP430 F149
Compiler Chrossworks

Deklaration:
1
typedef struct   {
2
                  ubyte ubKeyDownCommand;       // Command if Key is pressed
3
                  ubyte ubKeyDownParameter;      // Parameter if Key is pressed
4
                  ubyte ubKeyUpCommand;          // Command if Key is released
5
                  ubyte ubKeyUpParameter;          // Parameter if Key is released
6
                  ubyte ubToggleCommand;          // TRUE if Command is Toggle Command
7
                  ulong ulWindowUsed;                //  Bits are set if Window is used for this Key
8
                  ubyte ubState;                          //  Anything to do for this Key?
9
                  uword uwTimestamp;                 // Timestamp
10
                  ubyte ubUpDownFlags;              //  Do i need this
11
                  ubyte ubWindowsSend;             //  conter for how many Commands are send
12
                  } TS_KEYS;

Des Arrays
1
TS_KEYS pTsKeysSlave1[KEY_COUNT_ONE];

Zugriff abhängig von Empfangenen RS485 Protokollen

z.B. hier meine Initialisierung mit 0
1
pTsKeysMaster[ubKey].ubKeyDownCommand=0x00;
2
                        pTsKeysMaster[ubKey].ubKeyDownParameter=0x00;
3
                        pTsKeysMaster[ubKey].ubKeyUpCommand=0x00;
4
                        pTsKeysMaster[ubKey].ubKeyUpCommand=0x00;
5
                        pTsKeysMaster[ubKey].ulWindowUsed=0x00000000;
6
                        pTsKeysMaster[ubKey].ubToggleCommand=0x00;
7
                        pTsKeysMaster[ubKey].ubState=0x00;
8
                        pTsKeysMaster[ubKey].uwTimestamp=0x0000;
9
                        pTsKeysMaster[ubKey].ubUpDownFlags=0x00;
10
                        pTsKeysMaster[ubKey].ubWindowsSend=0x00;
diesmal ohne int Cast.


Die Ankommenden Protokolle habe ich natürlich geprüft.

ubKey ist ein Teil meines Protokolls.

Zum Test meinen Protokoll rutine habe ich einfach hin und zurück 
geschickt, das hat geklappt, jetzt habe ich Speicher Operationen, also 
zuweisungen ins Arrey dazwischen gebaut. diese Klappen auch bis index 
15, also 0x0F danach kommt Quatsch. Deshalb habe ich es erstmal auf die 
Bytes geschoben.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Deshalb habe ich es erstmal auf die Bytes geschoben.
Du hast nur 2kByte Speicher, das ist dir klar?

Das Alignment hier ist schlecht:
1
:
2
ubyte ubKeyDownCommand;       // Command if Key is pressed
3
ubyte ubKeyDownParameter;     // Parameter if Key is pressed
4
ubyte ubKeyUpCommand;         // Command if Key is released
5
ubyte ubKeyUpParameter;       // Parameter if Key is released
6
ubyte ubToggleCommand;        // TRUE if Command is Toggle Command
7
ulong ulWindowUsed;           //  Bits are set if Window is used for this Key
8
:
5 Chars, und dann ein Long bei einem 16-Bit-Prozessor. Wie verpackt dein 
Compiler das?

von Daniel G. (daniel83)


Lesenswert?

Die 2 kByte speicher sind mir bewusst, ich brauche auch nicht viele 
Array Elemente, es sind "nur" 3x 20, das werden jeweils ca 240Bytes, 
also kein Problem, mein Compiler rechnet mir das ja aus, da liege ich 
mit 2 Arrays bei 854 benutzten Bytes, also noch massig Platz.
Was die 5 Bytes un den Long angeht, meckert mein Compiler nicht, 
möglicherweise legt er das selber um, man weiß es nicht, Kein Fehler, 
Keine Warnung. ansonsten wenn ich mich recht entsinne habe ich doch 
selbst wenn er es so macht zwischen drin  ungenutzten leeren Raum. Aber 
die Adressen sollte er sich selbst zusammen bauen. Meinst du dass das 
Problematisch ist, und ich möglicherweise deshalb einen "Offset" rein 
bekomme und nur den hinteren Teil des Longs verarbeite?

Darin lege ich übrigens informationen Bitweise ab um platz zu sparen, 
d.H. ist habe 30 Bits, die ich entsprechend setzte oder halt nicht.

Wenn das ganze läuft werden die Daten ohne hin inden Flash ausgelagert, 
da ich die eigentlich nur einemal schreiben muss. Dann ist der Ram 
wieder frei.

PS. Wie in einem Anderen Posting geschrieben, komme ich von der PC 
programmierung mit C#, da ist Speicherplatz kein Thema, meine C 
Kenntnisse frische ich gerade wieder auf.

von ... .. (docean) Benutzerseite


Lesenswert?

erstell mal ein kompilierbares Beispiel was genau den Fehler zeigt...

Damit hilfts du bei der Fehlersuche.

Am besten noch im allgemeinen C, also auch aufm AVR/PC erstellbar

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Meinst du dass das Problematisch ist, und ich ...
> nur den hinteren Teil des Longs verarbeite?
Nein, aber durch das Alignment auf gerade Adressen wird dein Struct um 2 
Byte größer, als du ausgerechnet hast.

Deine Rechnung:
14 Bytes pro Struct * 3*20 Elemente = 840 Bytes RAM für diese Structs.
Dazu dann
2* 3*20 = 120Bytes fürs Alignment
Das sind 960 Bytes.
Und dann braucht auch der Stack noch Platz, und die anderen Variablen...
Deshalb mein Verweis auf die Speichergröße.

> Dann ist der Ram wieder frei.
Der wird aber nicht dynamisch verwaltet...
Das müsstest du selber machen.

von Daniel G. (daniel83)


Angehängte Dateien:

Lesenswert?

So, hier ein zumindest bei Compilierbares Beispiel, es enthält 
eigentlich alle relevanten Funktion, eineige Wenige habe ich entfernt, 
da passiert aber nichts außer gültigkeits Prüfungen.
Die Funktion sollte identisch sein.
do_sth ist die Funktion wo etwas passiert.
Ich habe versucht alle selbst definierten Datentypen auf standart 
Datentypen um zu brechen.

von Daniel G. (daniel83)


Lesenswert?

>> Dann ist der Ram wieder frei.
>Der wird aber nicht dynamisch verwaltet...
>Das müsstest du selber machen.

ich würde hier direkt auf den Flash speicher schreiben, der RAM sieht 
die daten gar nicht wirklich, also muss ich auch nichts freigeben, 
ansonsten ist der Berech spätestens wieder frei, wenn di Funktion die 
sich solch eine Variable angelegt hat beendet ist.
Zuminedest hab ich das mla bei Gültigkeitsbereichen gelernt.

von Karl H. (kbuchegg)


Lesenswert?

Wie ernst sind deine Kommentare zu nehmen
1
void vSave(unsigned char ubReceiveCode, unsigned char ubKey, unsigned char ubCommand, unsigned char ubWindow, unsigned char ubUsed)
2.ter Parameter ist der ubKey

Aufruf
1
  vSave(eingang[0], eingang[1], eingang[2], eingang[3], eingang[4]);

Also eingang[1]
1
void do_sth(unsigned char eingang[])    // bsp. 0xB6 0x1A 0x00 0x1D 0x00 + (XOR der 5 Bytes Vorher hier egal) zum lesen
2
                // bsp. 0xBA 0x1a 0x67 0x1D 0x01 + (XOR der 5 Bytes Vorher hier egal) zum Speichern

wenn eingang[1] tatsächlich den Wert 0x1A hat (dezimal 26), dann bist du 
weit hinter dem Array.

von Daniel G. (daniel83)


Lesenswert?

Möglicherweise ist der Fehler auch hier
1
(ulWindowUsed|(1<<ubWindowToAdd));

das ist auch in dem Beispiel zu finden, aber hier nochmal schnell 
nachgefragt.

ich habe einen Long also 4Byte variable
ubWindowToAdd hat einen wert zwischen 1d und 30d also 0x01 bis 0x1E
ich möchte jetzt was einsprechende Bit kippen, also beu 0x09 also das 
9te bit in ulWindowUsed, laut meinem schlauen Buch geht das so. Nur 
halöt wieder mit int im Beispiel

von Daniel G. (daniel83)


Lesenswert?

Verdammt, der Komentar ist falsch an der stelle
1
// bsp. 0xB6 0x13 0x00 0x1D 0x00

fieser Fehler Teufel, hab die Kommentare eben schnell dazu gehackt um 
eine Hilfe bereitzustellen maximal ist natürlich 0x13 also 19 dezimal

edit: 0x13 ist natürlich 19d

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Karl heinz Buchegger schrieb:
> Wie ernst sind deine Kommentare zu nehmen
Und was sagen sie aus?
1
     //Normalerweise Switch hier
2
      pTsKeys=&pTsKeys;
Sieht irgendwie rekursiv aus...
Und zudem wird die globale Variable pTsKeys umgebogen :-o

> TS_KEYS_TEST pTsKeys[20];    //Create Array
Wie oft ist die header-Datei mit dieser Definition in andere C-Dateien 
eingebunden?

von Karl H. (kbuchegg)


Lesenswert?

Daniel G. schrieb:
> Möglicherweise ist der Fehler auch hier
>
1
(ulWindowUsed|(1<<ubWindowToAdd));
>
> das ist auch in dem Beispiel zu finden, aber hier nochmal schnell
> nachgefragt.
>
> ich habe einen Long also 4Byte variable
> ubWindowToAdd hat einen wert zwischen 1d und 30d also 0x01 bis 0x1E
> ich möchte jetzt was einsprechende Bit kippen, also beu 0x09 also das
> 9te bit in ulWindowUsed, laut meinem schlauen Buch geht das so.

Aber nur bis Bit 15
1
( ulWindowUsed | (1UL << ubWindowToAdd) );


Merke: In C ist jede Konstante bzw. alles was keinen Datentyp hat ein 
int (mit Ausnahme einer Gleitkommazahl, die ist double)

von Daniel G. (daniel83)


Lesenswert?

>> TS_KEYS_TEST pTsKeys[20];    //Create Array
>Wie oft ist die header-Datei mit dieser Definition in andere C-Dateien
>eingebunden?

Das ist ganz einfach, ich habe eine headerdatei, in der ich global diese 
deklaration mache, diese ist in (fast) allen anderen headerdateien 
eingebunden.

könnte das ein Problem sein, hab mal irgendwo gelesen, dass 
headerdateien, an der stelle wo sie gelinkt sind direkt eingebaut und 
ausgeführt werden, ich habe dadurch also etwa 12 Arrays, weil ich die 12 
mal gelinkt hab?

>Und was sagen sie aus?
Dieser Komentar sagt aus, dass ich an dieser stelle die verschiedenen 
Arrays dem Pointer zuweise, damit ich das nachfolgende nur einaml 
Programmieren muss, da eine switchanweisung, wo ich nur auf verschiedene 
zuweisungen machen nicht wirklich aussage kräftig ist, habe ich sie hier 
raus gelöscht.

von Karl H. (kbuchegg)


Lesenswert?

Daniel G. schrieb:
> Verdammt, der Komentar ist falsch an der stelle
>
1
// bsp. 0xB6 0x13 0x00 0x1D 0x00
>
> fieser Fehler Teufel, hab die Kommentare eben schnell dazu gehackt um
> eine Hilfe bereitzustellen maximal ist natürlich 0x13 also 19 dezimal
>
> edit: 0x13 ist natürlich 19d

Trotzdem wäre ein Test mit Fehlerbehandlung sicherlich angebracht. Den 
kann man ja auch nur in der Debug-Version machen.

von Daniel G. (daniel83)


Lesenswert?

>Aber nur bis Bit 15

>Merke: In C ist jede Konstante bzw. alles was keinen Datentyp hat ein
>int (mit Ausnahme einer Gleitkommazahl, die ist double)

sprich ich muss sowas machen
1
unsigned long ul1=1;
2
( ulWindowUsed | (ul1 << ubWindowToAdd) );
(nicht auf syntax getestet)

von Karl H. (kbuchegg)


Lesenswert?

Daniel G. schrieb:
>>Aber nur bis Bit 15
>
>>Merke: In C ist jede Konstante bzw. alles was keinen Datentyp hat ein
>>int (mit Ausnahme einer Gleitkommazahl, die ist double)
>
> sprich ich muss sowas machen
>
1
> unsigned long ul1=1;
2
> ( ulWindowUsed | (ul1 << ubWindowToAdd) );
3
>
> (nicht auf syntax getestet)

Ich habs dir doch aufgeschrieben!

von Daniel G. (daniel83)


Lesenswert?

Die werte für eingang schicke ich mir selber per rs485, ich weiß also 
was da rein kommt. Diese kann ich auch ohne Probleme Überprüfen, ich 
habe schon Kilometer von Protokollen von hand durch gearbeitet.
Es kann also nichts größer als 19d kommen.

von Daniel G. (daniel83)


Lesenswert?

>Ich habs dir doch aufgeschrieben!

richtig, wollte nur nochmal nachhacken, damit wir beide das gleiche 
meinen.

von Karl H. (kbuchegg)


Lesenswert?

Daniel G. schrieb:
> Die werte für eingang schicke ich mir selber per rs485, ich weiß also
> was da rein kommt.

Berühmte letzte Worte:
Nein, da ist keine Spannung drauf.
Nein, der Träger kann nicht runterfallen.
Das hält bombenfest!
Nein, der Pointer kann nicht NULL sein.
Nein, das Byte kann keinen ungültigen Wert haben.

:-)

von Karl H. (kbuchegg)


Lesenswert?

Daniel G. schrieb:
>>Ich habs dir doch aufgeschrieben!
>
> richtig, wollte nur nochmal nachhacken, damit wir beide das gleiche
> meinen.

OK.
In dem Fall: nein, du MUSST es nicht so machen.
Es genügt völlig, wenn du die 1 als unsigned long definierst.

  ( 1UL << ubWindowToAdd )

von Daniel G. (daniel83)


Lesenswert?

>Es genügt völlig, wenn du die 1 als unsigned long definierst.

Korekt und das Problem löst es auch :-)

Vielen Dank für die Hilfe

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

>>> TS_KEYS_TEST pTsKeys[20];    //Create Array
>> Wie oft ist die header-Datei mit dieser Definition in andere C-Dateien
>> eingebunden?
> Das ist ganz einfach, ich habe eine headerdatei, in der ich global diese
> deklaration mache, diese ist in (fast) allen anderen headerdateien
> eingebunden.
Sieh dir das Thema Deklaration vs. Definition nochmal genauer an ;-)

von Daniel G. (daniel83)


Lesenswert?

erledigt ;-)

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
Noch kein Account? Hier anmelden.