Moin moin!
Ich habe hier den Code von einem ATm16, der als Master ein Datenpaket (struct parameters_ctrl) über TWI von einem Slave abruft. Das Datenpaket ist in Master und Slave exakt gleich deklariert und im Slave auch initialisiert. Der Slave ist ein ATm8.
Das Problem ist, daß die Werte, die im Slave in die Struktur geschrieben wurden, nicht in der Struktur im Master ankommen. Die TWI-Kommunikation ist dabei wahrscheinlich nicht das Problem. Per printf-debugging habe ich festgestellt, daß die Funktion twi_request() mit return-Wert 0 beendet, also durchläuft wie geplant.
Ich vermute das Problem eher bei meinen Parameter-Übergaben, also die Referenzen auf die Struktur und das De-Referenzieren in der twi_request()-Funktion. Könnte sich das mal jemand anschauen?
Um den Compiler zu befriedigen, muß ich die Referenz auf die Struktur beim Aufruf aus main() auf "(unsigned char *)" casten. Da ich einfach nur die Struktur byteweise übertragen will, sollte das ok sein, weil die Datenbytes der Struktur im Speicher einfach hintereinander folgen. Richtig?
Wo ich mir nicht so sicher bin, ist diese Anweisung: *(buffer+i)=TWDR in twi_request(). Ist das die richtige Methode, um die Struktur byteweise vollzuschreiben?
Vielen Dank,
Nils
Code:
volatile struct {
unsigned char kp_pitch;
unsigned char tn_pitch;
unsigned char tv_pitch;
unsigned char kp_roll;
unsigned char tn_roll;
unsigned char tv_roll;
} parameters_ctrl;
volatile int twi_request(unsigned char adr, unsigned char *buffer, int buffersize) {
int i;
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTA); //generate start condition
while (!(TWCR & 0x80)) { }; //wait for TWINT set
if(TWSR!=0x08) { //0x08 == start condition sent
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); //release Bus
return 1; }
TWDR=(adr<<1)|0x01; //slave address and read-bit into TWDR
TWCR=(1<<TWINT)|(1<<TWEN); //address slave
while (!(TWCR & 0x80)) { }; //wait for TWINT set
if(TWSR!=0x40) { //0x40 == slave has acknowledged
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); //generate stop condition
return 2; }
for(i=0;i<buffersize;i++) {
if(i<buffersize-1) {
TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA); //request byte transfer from slave
while (!(TWCR & 0x80)) { }; //wait for TWINT set
if(TWSR!=0x50) { //0x50 == byte received,ack returned
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); //generate stop condition
return 3; }
}
else {
TWCR=(1<<TWINT)|(1<<TWEN); //request last lowbyte transfer from slave
while (!(TWCR & 0x80)) { }; //wait for TWINT set
if(TWSR!=0x58) { //0x58 == byte received,nack returned
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); //generate stop condition
return 4; }
}
*(buffer+i)=TWDR;
}
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); //generate stop condition
return 0;
}
In main() wird zyklisch der twi_request aufgerufen:
Code:
receive=twi_request(CTRL_B, (unsigned char *) ¶meters_ctrl, sizeof(parameters_ctrl));
Lesezeichen