So, die Masterdatei
Code:
#include <avr/io.h> // I/O Port definitions
#include <avr/interrupt.h> // Interrupt macros
#include <util/twi.h>
#define F_CPU 16000000UL //CPU Tackt
unsigned volatile char daten, error;
uint8_t adresse;
void twi_init(void);
int twi_senden(uint8_t adresse, char daten);
int main(void)
{
twi_init();
adresse = 0x40;
daten = 0x04;
while(1)
{
twi_senden(adresse, daten);
};
}
void twi_init(void)
{
DDRC &= !((1<<DD0) | (DD1));
PORTC = (1<<DD0) | (1<<DD1);
TWSR = 0x00; //Prescaler
TWBR = 12; //TWI 400khz
};
int twi_senden(uint8_t adresse, char daten)
{
uint8_t twst;
while(1)
{
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); //TWI aktivieren und Start condition auslösen
while(!(TWCR & (1<<TWINT))); //Warten auf Start condition
twst = TW_STATUS & 0xF8;
//if((TWSR & 0xF8) != 0x08);
if ((twst != TW_START) && (twst != TW_REP_START))continue;
TWDR = adresse & (0xFE); //Adresse mit Schreibbit(xxxxxxx0) in Register
TWCR = (1<<TWINT) | (1<<TWEN); //senden
//if((TWSR & 0xF8) != 0x18);
while(!(TWCR & (1<<TWINT))); //warten auf ACK oder NACK
twst = TW_STATUS & 0xF8;
if ((twst == TW_MT_SLA_NACK) || (twst == TW_MR_DATA_NACK))
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
while(TWCR & (1<<TWSTO));
continue;
}
TWDR = daten; //Byte in Datenregister laden
TWCR = (1<<TWINT) | (1<<TWEN); //senden
while (!(TWCR & (1<<TWINT))); //warten auf ACK oder NACK
//if ((TWSR & 0xF8) != 0x28);
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); //STOP Conditions auslösen
return 1;
}
};
Und hier die Slavedatei:
Code:
#include <avr/io.h> // I/O Port definitions
#include <avr/interrupt.h> // Interrupt macros
#include <util/twi.h>
#define F_CPU 16000000UL //CPU Tackt
#define timer 236
unsigned volatile char adresse, daten;
void twi_slave(void)
{
TWAR = 0x40;
TWCR &= ~(1<<TWSTA) | (1<<TWSTO);
TWCR = (1<<TWEA) | (1<<TWEN) | (1<<TWIE); //ack, TWI enable, Interupt
TWSR = 0;
};
ISR(TWI_vect)
{
switch(TW_STATUS)
{
case TW_SR_SLA_ACK:
//Wen ich hier den PORT1 Highschalte klappts.
TWCR = (1<<TWEN) | (1<<TWIE) | (1<<TWINT) | (1<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWWC);
break;
case TW_SR_DATA_ACK:
//Hier klappts leider nicht mehr, heisst das abfragen dieses Status schlägt fehl
PORTB |= (1<<PORTB1);
break;
}
/*daten = TWDR;
TWCR |= (1<<TWINT);
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
if (TW_STATUS == TW_SR_SLA_ACK)
{
daten = TWDR;
//if (daten == 0x04)
{PORTB |= (1<<PORTB1);}
else
{PORTB &= ~(1<<PORTB1);}
}*/
TWCR |= 0b10000000;
};
int main(void)
{
sei(); //Globale Interupts zulassen
twi_slave();
DDRB |= (1<<PORTB1) | (1<<PORTB2) | (1<<PORTB3); //B... AUSGANG
PORTB &= ~((1<<PORTB1) | (1<<PORTB2) | (1<<PORTB3)); //B.. Low
while(1)
{
}
}
So, ich habe den Status stück für Stück abgefragt. Und bei TW_STATUS_DATA_ACK
kriege ich keine Rückmeldung.
Also das heisst für mich das Ansprechen des Slaves funktioniert(TW_STATUS_SLA_ACK) und im weiteren Ablauf ist ein Fehler.
Nur habe ich keine Ahnung wo, noch nicht einmal ob Master oder Slave. Aber ich tendiere auf Master aufgrund der scheiternden Status abfrage im Slave.
Ich habe noch kein warten für das senden drin.
Würdest du das über delay machen oder einen Timer laufen lassen?
Lesezeichen