MASTER sendet 1byte:
Code:
#include <avr/io.h>
#include <compat/twi.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#define master_adresse 0x01
void I2C_init(void);
void I2C_MASTER_TRANSCEIVE_ERROR(void);
void I2C_ERROR(void);
unsigned char transceive(unsigned char, unsigned char);
void main(void);
void I2C_init(void)
{
TWAR = (master_adresse<<1); //TWI-Addresse des Masters festlegen
TWSR &= 0b11111100; //Prescaler auf 1 setzen, Bit 1 und 0 auf 0
TWBR = 0xD; //Bitrate auf 12 setzen
sei(); //Interrupts global aktivieren
TWCR=(0<<TWINT)|(1<<TWEA)|(1<<TWEN);
}
void I2C_MASTER_TRANSCEIVE_ERROR(void)
{
PORTE=0x02;
I2C_ERROR();
}
void I2C_ERROR(void)
{
//STOP
TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
TWCR=(0<<TWEN);
//neu initialisieren
I2C_init();
}
unsigned char transceive(unsigned char slave_adresse,unsigned char transmit_data)
{
unsigned char received_data=0x00;
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); //START senden
while (!(TWCR & (1<<TWINT))); //warten bis TWINT gesetzt
if ((TWSR & 0xF8) != 0x08) {I2C_MASTER_TRANSCEIVE_ERROR();} //warten auf start
//Addresse des Slaves angeben
TWDR = (slave_adresse<<1);
TWCR = (1<<TWINT) | (1<<TWEN); //Addresse senden
while (!(TWCR & (1<<TWINT))); //warten bis TWINT gesetzt
if ((TWSR & 0xF8) != 0x18) {I2C_MASTER_TRANSCEIVE_ERROR();} //master transmit slave adresse ack
TWDR = transmit_data;
PORTE =transmit_data; //DATEN senden
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))); //warten bis TWINT gesetzt
if ((TWSR & 0xF8) != 0x28) {I2C_MASTER_TRANSCEIVE_ERROR();} //master transmit slave daten ack
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); //REPEATED START senden
while (!(TWCR & (1<<TWINT))); //warten bis TWINT gesetzt
if ((TWSR & 0xF8) != 0x10) {I2C_MASTER_TRANSCEIVE_ERROR();} //warten auf rep start
TWDR = (slave_adresse<<1) | 1;
//Addresse des Slaves angeben
TWCR = (1<<TWINT) | (1<<TWEN) | (0<<TWSTA) | (0<<TWSTO);
while (!(TWCR & (1<<TWINT))); //warten bis TWINT gesetzt
if ((TWSR & 0xF8) != 0x40) {I2C_MASTER_TRANSCEIVE_ERROR();}
TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))); //warten bis TWINT gesetzt
if ((TWSR & 0xF8) != 0x50) {I2C_MASTER_TRANSCEIVE_ERROR();}
TWCR = (1<<TWINT) | (0<<TWEA) | (1<<TWEN);
while (!(TWCR & (1<<TWINT))); //warten bis TWINT gesetzt
if ((TWSR & 0xF8) != 0x58) {I2C_MASTER_TRANSCEIVE_ERROR();}
received_data = TWDR;
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); //STOP
return received_data;
}
void main(void)
{
unsigned char slave_adresse,daten;
slave_adresse =0x02;
daten=0x01;
DDRB=0xFF;
DDRE=0xFF;
I2C_init();
_delay_loop_1(1);
PORTB=transceive(slave_adresse,daten);
_delay_loop_1(15);
}
slave emfängt byte und sendet 1byte zurück:
Code:
#include <avr/io.h>
#include <compat/twi.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#define slave_adresse 0x02
void init(void)
{
TWAR = (slave_adresse<<1);
TWCR = 0b11000101;
TWBR = 0xC;
TWSR &= 0b11111100;
sei();
TWCR |= 0b10000000;
}
SIGNAL (SIG_2WIRE_SERIAL)
{
switch(TWSR & 0b11111000)
{
case 0x80: PORTB=TWDR; //byte vom master an portb
break;
case 0xB8: //byte zum master
TWDR=0xF0;
PORTE=TWDR;
break;
// default: //TWSR=0xFF;
TWCR |= 0b10000000;
}
void main(void)
{
init();
DDRB=0xFF;
DDRE=0xFF;
for(;;);
}
bittschö nicht schön aber selten...
und nun viel spass beim testen
mfg
Lesezeichen