PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : atmega8 TWI slave



JeyBee
05.06.2010, 19:22
Moin

Ich hatte mal wieder Zeit, um an meinem TWI (in C) weiter zu machen. Bisher kann ich Daten vom Master (atmega48) zum Slave (atmega8) ü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:



#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
}
}
}


Was mache ich denn falsch?
Gruss Jey