terrorfreak
23.06.2010, 19:52
Hallo miteinander!
Wollte im Rahmen meiner Technikerarbeit über mehrere Atmega 16 Daten austauschen. Dafür ist einer als Master definiert und die anderen als Slave. Wollte erstmal ein Datenpaket an den Slave senden, der diese dann an PORTA anzeigt. Nur passiert leider nichts.^^ Ich hab mal die einzelnen Schritte durchnummeriert indem dann an diversen Ports dann durchnummeriert wird, wo der Controller gerade ist. Beim Master läuft alles schön nacheinander durch. Aber der Slave will leider nicht auf die Adressierung antworten. Wenn ich dem Slave die Adresse 0x02 gebe, muss ich ihn doch vom master mit 0x04 aufrufen, wegen dem read-write zum am Ende, oder? Ich hoffe ihr könnt mir dabei helfen! Hab schon hier und in anderen Foren viel durchgeschaut und bei mir im Programm eingefügt, aber leider klappt es immernoch nicht.
Hier mal der Master C-Code:
#define F_CPU 8000000UL
#include <avr/delay.h>
#include <avr/io.h>
void i2c_init(void)
{
TWSR = 0; // kein Vorteiler
TWBR = 32; // Da Quartz bei 8 MHz
}
void start_i2c()
{
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // Starte I2C
while (!(TWCR & (1<<TWINT))); // Warte, bis fertig
}
void stop_i2c()
{
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // Stoppe I2C
// Hier darf keine Warteabfrage hin, da I2C gestoppt ist.
}
void senden_i2c(char daten)
{
TWDR = daten; // Sende Daten
TWCR = (1<<TWINT) | (1<<TWEN);
while( !(TWCR & (1<<TWINT)) );
}
unsigned char i2c_empfangen(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
while(!(TWCR & (1<<TWINT)));
return TWDR;
}
void main (void)
{
DDRB=0xFF;
PORTB=0xFF;
i2c_init();
int daten2 = 0xAA;
while(1)
{
PORTB = 0x01;
// Sende 0xAA an Slave 1
start_i2c(); // Start I2C
_delay_ms(1000);
PORTB = 0x02;
senden_i2c(0x04); // Adressierung Slave 1
_delay_ms(1000);
PORTB = 0x03;
senden_i2c(daten2); // Daten übertragen
_delay_ms(1000);
stop_i2c();
PORTB = 0x04;
}
}
und hier der Slave C-Code:
#define F_CPU 8000000UL
#include <avr/delay.h>
#include <avr/io.h>
void i2c_init (uint8_t Address)
{
TWSR = 0; // kein Vorteiler
TWBR = 32; // Da Quartz bei 8 MHz
/*
** Set the TWI slave address
*/
TWAR = (Address << 1);
/*
** Activate TWI interface
*/
TWCR = (1<<TWEN)|(1<<TWEA);
}
unsigned char i2c_empfangen(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
while(!(TWCR & (1<<TWINT)));
return TWDR;
}
int daten = 0x00;
int main(void)
{
DDRA=0xFF;
PORTA=0xFF;
uint8_t status;
i2c_init(0x02);
while(1)
{
PORTA = 0x01;
while(!(TWCR & 0b10000000));
PORTA = 0x02;
TWCR &=~ (1<<TWINT); //TWINT auf 0 setzten damit TWI wieder arbeitet
PORTA = 0x03;
TWCR |= (1<<TWEA); //TWEA auf 1 setzten um Ack zu senden
PORTA = 0x04;
daten = i2c_empfangen();
PORTA = daten;
}
}
Wie gesagt, ich hoffe ihr könnt mir helfen, weil ich sonst ganz schön alt ausschaue demnächst. xD
Gruß Bastian
Wollte im Rahmen meiner Technikerarbeit über mehrere Atmega 16 Daten austauschen. Dafür ist einer als Master definiert und die anderen als Slave. Wollte erstmal ein Datenpaket an den Slave senden, der diese dann an PORTA anzeigt. Nur passiert leider nichts.^^ Ich hab mal die einzelnen Schritte durchnummeriert indem dann an diversen Ports dann durchnummeriert wird, wo der Controller gerade ist. Beim Master läuft alles schön nacheinander durch. Aber der Slave will leider nicht auf die Adressierung antworten. Wenn ich dem Slave die Adresse 0x02 gebe, muss ich ihn doch vom master mit 0x04 aufrufen, wegen dem read-write zum am Ende, oder? Ich hoffe ihr könnt mir dabei helfen! Hab schon hier und in anderen Foren viel durchgeschaut und bei mir im Programm eingefügt, aber leider klappt es immernoch nicht.
Hier mal der Master C-Code:
#define F_CPU 8000000UL
#include <avr/delay.h>
#include <avr/io.h>
void i2c_init(void)
{
TWSR = 0; // kein Vorteiler
TWBR = 32; // Da Quartz bei 8 MHz
}
void start_i2c()
{
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // Starte I2C
while (!(TWCR & (1<<TWINT))); // Warte, bis fertig
}
void stop_i2c()
{
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // Stoppe I2C
// Hier darf keine Warteabfrage hin, da I2C gestoppt ist.
}
void senden_i2c(char daten)
{
TWDR = daten; // Sende Daten
TWCR = (1<<TWINT) | (1<<TWEN);
while( !(TWCR & (1<<TWINT)) );
}
unsigned char i2c_empfangen(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
while(!(TWCR & (1<<TWINT)));
return TWDR;
}
void main (void)
{
DDRB=0xFF;
PORTB=0xFF;
i2c_init();
int daten2 = 0xAA;
while(1)
{
PORTB = 0x01;
// Sende 0xAA an Slave 1
start_i2c(); // Start I2C
_delay_ms(1000);
PORTB = 0x02;
senden_i2c(0x04); // Adressierung Slave 1
_delay_ms(1000);
PORTB = 0x03;
senden_i2c(daten2); // Daten übertragen
_delay_ms(1000);
stop_i2c();
PORTB = 0x04;
}
}
und hier der Slave C-Code:
#define F_CPU 8000000UL
#include <avr/delay.h>
#include <avr/io.h>
void i2c_init (uint8_t Address)
{
TWSR = 0; // kein Vorteiler
TWBR = 32; // Da Quartz bei 8 MHz
/*
** Set the TWI slave address
*/
TWAR = (Address << 1);
/*
** Activate TWI interface
*/
TWCR = (1<<TWEN)|(1<<TWEA);
}
unsigned char i2c_empfangen(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
while(!(TWCR & (1<<TWINT)));
return TWDR;
}
int daten = 0x00;
int main(void)
{
DDRA=0xFF;
PORTA=0xFF;
uint8_t status;
i2c_init(0x02);
while(1)
{
PORTA = 0x01;
while(!(TWCR & 0b10000000));
PORTA = 0x02;
TWCR &=~ (1<<TWINT); //TWINT auf 0 setzten damit TWI wieder arbeitet
PORTA = 0x03;
TWCR |= (1<<TWEA); //TWEA auf 1 setzten um Ack zu senden
PORTA = 0x04;
daten = i2c_empfangen();
PORTA = daten;
}
}
Wie gesagt, ich hoffe ihr könnt mir helfen, weil ich sonst ganz schön alt ausschaue demnächst. xD
Gruß Bastian