Guten Abend zusammen,
ich verzweifle aktuell an der Atmel AVR USI_TWI Library (siehe Anhang).
Eigentlich total simple, schreiben klappt auch super aber beim Lesen
komme ich nicht an die gelesenen Daten.
Hardwareseitig passt alles, die Daten liegen am Bus an... ich "finde"
sie nur nicht im Code.
Zum Lesen der Daten vom Bus brauche ich einen "Repeated Start", nachdem
es den nativ in der Library nicht gibt muss ich den wie folgt ausführen:
liefert mir lediglich ein 0x01 für TRUE. Ich muss irgendwie auf den
Pointer innerhalb der Library zugreifen. Alle Versuche dahingehend sind
bisher gescheitert :(
Wenn ich die Funktion mit einem Pointer aufrufe ...
1
uint8_tval=0x20;
2
ReadStatusRegister(&val,0xAA,2);
... habe ich in der Variable val irgendwas stehen (vermutlich die
Speicheradresse).
Könnt ihr mir hier helfen? Bitte?
USI_TWI_Start_Transceiver_With_Data(unsigned char *, unsigned char);
erwartet als ersten Parameter ein Array (=pointer) in passender Größe,
in das die empfangenen Daten geschrieben werden.
Also schau in dein C-Buch, was ein Array ist.
Oliver
Oliver S. schrieb:> USI_TWI_Start_Transceiver_With_Data(unsigned char *, unsigned char);> erwartet als ersten Parameter ein Array (=pointer) in passender Größe,> in das die empfangenen Daten geschrieben werden.>> Also schau in dein C-Buch, was ein Array ist.>> Oliver
Auch wenn Pointer häufig genutzt werden um auf Arrays zuzugreifen, haben
die nichts miteinander zu tun.
Ein Pointer ist sehr viel abstrakter und kann auf vollkommen beliebige
Daten verweisen.
Du solltest daher deinen eigenen Tipp beherzigen, und in ein C-Buch
schauen!
Harry L. schrieb:> Auch wenn Pointer häufig genutzt werden um auf Arrays zuzugreifen, haben> die nichts miteinander zu tun.>> Ein Pointer ist sehr viel abstrakter und kann auf vollkommen beliebige> Daten verweisen.
In C sind Array und Pointer gerade als Funktionsparameter, um die es
hier geht, aber sowas von eng verwandt, enger geht es gar nicht.
Oliver
Harry L. schrieb:> Ein Pointer ist sehr viel abstrakter und kann auf vollkommen beliebige> Daten verweisen.
Ein Pointer ist kann auf irgendwas zeigen (auch auf Funktionen oder auf
andere Pointer oder auf Register) und der, der den Pointer bekommt, muss
wissen, was er damit anzufangen hat.
Im speziellen Fall hier braucht es einfach die Anfangsadresse eines
Speicherblocks. Also enthalt im Fall hier der Pointer einfach genau
diese Adresse der ersten Speicherzelle des Arrays.
Harry L. schrieb:> Du solltest daher deinen eigenen Tipp beherzigen, und in ein C-Buch> schauen!
Es ist generell gut, in ein paar C-Bücher zu schauen, weil manche so
umständlich geschrieben sind, dass man sich fragt, ob der Autor selber
das auch richtig kapiert hat.
Borsty B. schrieb:> Wenn ich die Funktion mit einem Pointer aufrufe ...> uint8_t val = 0x20;> ReadStatusRegister(&val,0xAA,2);
Dieser Aufruf ist prinzipiell falsch, denn die Funktion ist so
definiert:
> uint8_t ReadStatusRegister(uint8_t reg, uint8_t dev, uint8_t readBytes)
Da darf keine Adresse übergeben werden. Das sollte aber der Compiler
schon anmäkeln...
Borsty B. schrieb:> Es hat mich allerdings auf den richtigen Weg gebracht, es funktioniert> nun :)
Nachdem dir von anderen geholfen wurde, wäre es ein richtig schöner
Abschluss deines Threads und wiederum eine Hilfe für andere, wenn du
allen verrätst, wie du das Problem letztlich gelöst hast...
Eventuell hilft es, alle Warnungen des Compilers einzuschalten. Vor
möglichen Fehler (wie Pointer mit Integer vertauscht) warnt er dann.
Außerdem empfehle ich die QT Creator IDE, die zeigt nämlich noch eine
ganze Reihe weitere mögliche Fehler schon beim Editieren an, und zwar
mehr als alle anderen mir bekannten IDEs.
http://stefanfrings.de/avr_ide/index.html#qtcreator
Die Daten werden also in das Data2 Array gelesen. Bisschen doof ist,
dass ich nun nicht flexibel sagen kann wie viele Bytes ich vom Bus lesen
möchte weil ich ja das Array schon fix definieren muss.
Aufgerufen wird die Funktion so:
Borsty B. schrieb:> Bisschen doof ist, dass ich nun nicht flexibel sagen kann wie viele> Bytes ich vom Bus lesen möchte weil ich ja das Array schon fix> definieren muss.
Wie viele Daten gelesen werden sollen, kannst du doch angeben. Wenn das
weniger sind, als das Datenarray gross ist, dann ist das halt so.
Oliver
Borsty B. schrieb:> static uint8_t data2[3];>> Die Daten werden also in das Data2 Array gelesen. Bisschen doof ist,> dass ich nun nicht flexibel sagen kann wie viele Bytes ich vom Bus lesen> möchte weil ich ja das Array schon fix definieren muss.>
Man kann einen Speicher auch zur Laufzeit allozieren mit malloc(), und
wenn man ihn nicht mehr braucht, dann mit free() freigeben. Das steht
oft auch in einem C-Buch.
Aber das ist wohl mehr Overhead, als ein statisches Feld, wo ein paar
Bytes nicht benutzt werden.
Denn mehr als 4 Lesebytes sind in der normalen I2C Wildbahn sehr selten.
Also nimmt man 8, und ist bis an sein Lebensende glücklich damit.
Hallo,
Lothar M. schrieb:> Es ist generell gut, in ein paar C-Bücher zu schauen, weil manche so> umständlich geschrieben sind, dass man sich fragt, ob der Autor selber> das auch richtig kapiert hat.
Eigentlich reicht ein einziges (K/R ). Da ist das Thema erschöpfend und
verständlich erklärt.
rhf