Es ist doch egal wie lang es dauert so lange Du erreichst was Du vor hast.
Zum Befehl bzw. Parameter von I2CTWI_transmit3Bytes, er hat 4 Werte, erster ist die Zieladresse des I2C Gerätes. Betrachten wir das Ziel (RP6Base_I2CSlave.c) etwas genauer. Das was da übertragen wird ist schreibend eine Befehlssequenz die der Slave entschlüsseln muss und lesend ein Register.
Schaut man im Slave bei
// Command Registers - these can be written by the Master.
// The other registers (read registers) can NOT be written to. The only way to
// communicate with the Robot is via specific commands.
// Of course you can also add more registers if you like...
und
// Command processor:
// Commands:
nach, findet man das.
#define CMD_SETLEDS 3
Die 3 sagt also dem Slave das dies ein Befehl zum setzen von LEDs ist, da was anderes zu setzen macht nur Sinn wenn die restlichen Parameter passen. Siehe auch void task_commandProcessor(void). Der Wert counter sagt welche LEDs, vergleichbar mit setLEDs.
Übrigends ist das sehr unschön programmiert, besser und lesbarer wäre:
I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SETLEDS, counter);
Denn ändert man aus irgendwelchen Gründen den Define Wert, fliegt einem unnötiger Weise die halbe Software um die Ohren.
Liest man jedoch Werte aus (statt bisher schreibend vom Master aus gesehen), so muss man anders vorgehen. Dazu liest man Register aus, der Slave trägt die Werte dort ein. Welche Register, das sagen die Defines:
#define I2C_REG_ADC_ADC0_L 23
#define I2C_REG_ADC_ADC0_H 24
#define I2C_REG_ADC_ADC1_L 25
#define I2C_REG_ADC_ADC1_H 26
Grundsätzlich ist es nun so, das es einen bzw. 2 Zeiger gibt, der die Leseposition in den Registern anzeigt. Dieser wird pro gelesenem Byte erhöht. Beim schreiben ist es ebenso. Dieser Pointer wird normal durch den 2. Parameter in I2CTWI_transmit3Bytes gesetzt. 0 setzt also den Zeiger auf den Anfang, 5 würde ihn auf die 5 Stelle setzen so das als nächstes das 6.te byte gelesen wird. Das Verfahren entspricht auch grundsätzlich dem Lesen und Schreiben von eeproms nur das dort weit mehr Speicherzellen ansprechbar und adressierbar sind. Nachdem das gelesene low/high byte im Master wieder richtig zusammen gesetzt wurde, hat man einen Wert. Bekommt man keinen, hat man z.B. den Zeiger nicht richtig gesetzt, überlesen oder sonst was ist schief gegangen...
Ich hoffe das erklärt grob wie der Slave arbeitet bzw. was da wie und in welche Richtung übertragen wird. Durch entsprechende Änderungen kommst du auch an die Motorsteuerung. Dann noch eine Anmerkung, das I2C arbeitet mit diesen Libs nicht unbedingt stabil, es kann daher schon mal vorkommen das die ADCs keine Werte liefern, das muss aber nicht unbedingt ein Fehler in deinem Programm sein. Bevor man die Werte aus dem I2C nutzt, sollte man sie ggf. auf Plausibilität prüfen und nicht blind in Funktionen einspeisen. Das führt nur dazu, das man sich beim debuggen nen Wolf sucht.
Wenn Du verstehen willst wie Master und Slave zusammen arbeiten, wirst Du auch in beiden Programmteilen die Abläufe studieren müssen. Die emulierten Registersets sind der Schlüssel dazwischen. Müsste aber auch so aus dem Handbuch ersichtlich sein.
LG Rolf
Lesezeichen