Moin
Ich hatte mal wieder Zeit, um an meinem TWI (in C) weiter zu machen. Bisher kann ich Daten vom Master (atmega4zum Slave (atmega
übertragen.
Nun wollte ich hinzufügen, dass ich ganz einfach ohne Interrupt Daten vom Slave abholen kann (also dass der Slave dem Master daten zur verfügung stellen kann). Nachdem ich das Datenblatt studiert hatte, war ich nicht viel schlauer.
Verstehe ich den Ablauf richtig?
1. Slave-TWI wartet so lange, bis Adr angkommt und setzt dann TWINT auf 1
2. Der Master setzt das Bit 0 auf 1, und sendet so ein READ-Komando.
3. Der Slave gerät so in den sog. "ST"-Modus.
4. Sobald im Statusregister 0xA8 steht, kann ich einen Wert ins TWDR schreiben, der dann der master mit i2c_readNak(); auselsen kann
5. 0xC0 bestätigt übertragung und Nak
Soweit stimmen die Werte des Statusregisters im TWI-Slave auch. Beim Master kriege ich über den i2c_readNak(); Befehl jedoch immer nur 0xCD raus.
Hier mal mein Slave Programm:
Was mache ich denn falsch?Code:#include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include "uart.h" #define UART_BAUD_RATE 9600 void twi_slave_init(uint8_t slaveadr) { TWAR = slaveadr; TWCR |= (1<<TWEN) | (1<<TWEA); } int main(void) { uint8_t transfer; // Datentransfer Variable uint8_t status; // Statuscode Variable unsigned char buffer[10]; // Buffer für itoa uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); twi_slave_init(0xCC); // TWI Slave initialisieren & Adresse festloegen sei(); while(1) { while(!(TWCR & 0b10000000)); //solange warten, bis was ankommt status = TWSR; // Status abfragen.. uart_puts("\r 0x"); uart_puts(itoa(status, buffer, 16)); //Status ausgeben TWCR &=~ (1<<TWINT); //TWINT auf 0 setzten damit TWI wieder arbeitet TWCR |= (1<<TWEA); //TWEA auf 1 setzten um Ack zu senden if(TWSR == 0xA8) //Warten bis Slave Adr mit READ empfangen { TWDR = 0xAA; //Zu Übermittelnden Wert in TWDR schreiben } } }
Gruss Jey
Lesezeichen