www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Arrey Zugriff mit Byte


Autor: Daniel G. (daniel83)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo ich habe ein Problemchen.

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

Das geht auch Wunderbar, bis 15, danach nicht.

In C# geht folgendes
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast woanders einen Bug

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Christian H. (netzwanze) Benutzerseite
Datum:

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

Autor: Daniel G. (daniel83)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Daniel G. (daniel83)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Zugriff sieht so aus:
pTsKeysSlave1[(int)ubKey].ubKeyDownCommand=ubCommand;

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel G. schrieb:
> Der Zugriff sieht so aus:
>
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?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Daniel G. (daniel83)
Datum:

Bewertung
0 lesenswert
nicht 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 ^^

Autor: Daniel G. (daniel83)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also:

System MSP430 F149
Compiler Chrossworks

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

Des Arrays
TS_KEYS pTsKeysSlave1[KEY_COUNT_ONE];

Zugriff abhängig von Empfangenen RS485 Protokollen

z.B. hier meine Initialisierung mit 0
pTsKeysMaster[ubKey].ubKeyDownCommand=0x00;
                        pTsKeysMaster[ubKey].ubKeyDownParameter=0x00;
                        pTsKeysMaster[ubKey].ubKeyUpCommand=0x00;
                        pTsKeysMaster[ubKey].ubKeyUpCommand=0x00;
                        pTsKeysMaster[ubKey].ulWindowUsed=0x00000000;
                        pTsKeysMaster[ubKey].ubToggleCommand=0x00;
                        pTsKeysMaster[ubKey].ubState=0x00;
                        pTsKeysMaster[ubKey].uwTimestamp=0x0000;
                        pTsKeysMaster[ubKey].ubUpDownFlags=0x00;
                        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.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

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

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

Autor: Daniel G. (daniel83)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: ... ... (docean) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Daniel G. (daniel83)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Daniel G. (daniel83)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

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

Also eingang[1]
void do_sth(unsigned char eingang[])    // bsp. 0xB6 0x1A 0x00 0x1D 0x00 + (XOR der 5 Bytes Vorher hier egal) zum lesen
                // 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.

Autor: Daniel G. (daniel83)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Möglicherweise ist der Fehler auch hier
(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

Autor: Daniel G. (daniel83)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Verdammt, der Komentar ist falsch an der stelle
// 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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Wie ernst sind deine Kommentare zu nehmen
Und was sagen sie aus?
     //Normalerweise Switch hier
      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?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel G. schrieb:
> Möglicherweise ist der Fehler auch hier
>
(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
( ulWindowUsed | (1UL << ubWindowToAdd) );


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

Autor: Daniel G. (daniel83)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel G. schrieb:
> Verdammt, der Komentar ist falsch an der stelle
>
// 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.

Autor: Daniel G. (daniel83)
Datum:

Bewertung
0 lesenswert
nicht 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
unsigned long ul1=1;
( ulWindowUsed | (ul1 << ubWindowToAdd) );
(nicht auf syntax getestet)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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
>
> unsigned long ul1=1;
> ( ulWindowUsed | (ul1 << ubWindowToAdd) );
> 
> (nicht auf syntax getestet)

Ich habs dir doch aufgeschrieben!

Autor: Daniel G. (daniel83)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Daniel G. (daniel83)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich habs dir doch aufgeschrieben!

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

:-)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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 )

Autor: Daniel G. (daniel83)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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 ;-)

Autor: Daniel G. (daniel83)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
erledigt ;-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.