Ich habe folgendes Problem:
Ich möchte zwei AVR Atmega 328P-Pu dazu bringen, miteinander mit I2C zu kommunizieren
Beim Slave ist die Antwort auf den Generalruf aktiviert (Adresse 0x00) und es funktioniert. Oder zumindest kann ich sehen, dass es die ISR (TWI_vect) auf dem Slave mit dem Code weiter unten eingibt.
Wenn Sie jedoch versuchen, den Salve mit seiner eigenen Adresse (0x02) anzurufen, antwortet er nicht. Alles andere bleibt gleich (Schaltung, Pull-up-Widerstände etc.)
Darüber hinaus führt der Versuch, den Bus mit Anrufen an alle möglichen Adressen bis zu 128 zu bombardieren, zu keiner Antwort vom Slave.
Ich bin mir sicher, dass es irgendwo ein dummer Fehler ist, aber mir geht die Idee aus, warum es so ist. Jede Hilfe willkommen.
Auf Meister
Die I2C-Kommunikation wird so initiiert
uint8_t i2c_start(uint8_t address)
{
// reset TWI control register
TWCR = 0;
// transmit START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
// wait for end of transmission
while( !(TWCR & (1<<TWINT)) );
// check if the start condition was successfully transmitted
if((TWSR & 0xF8) != TW_START){ return 1; }
// load slave address into data register
TWDR = address;
// start transmission of address
TWCR = (1<<TWINT) | (1<<TWEN);
// wait for end of transmission
while( !(TWCR & (1<<TWINT)) );
// check if the device has acknowledged the READ / WRITE mode
uint8_t twst = TW_STATUS & 0xF8;
if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 2;
return 0;
}
Im Hauptruf des Meisters wird so gesprochen
uint8_t address=1;
addr=address<<1;
i2c_start(addr|I2C_WRITE); // I2C_WRITE =0x00
Auf Sklave
void I2C_init(uint8_t address){
// load address into TWI address register
TWAR = (address << 1);
TWAR = (1<<TWGCE); //respond to general call ! WARNING
// set the TWCR to enable address matching and enable TWI, clear TWINT, enable TWI interrupt
TWCR=0x0; //WARNING
TWCR = (1<<TWIE) | (1<<TWEA) | (1<<TWINT) | (1<<TWEN);
}
So sieht die Hauptsache am Sklaven aus
I2C_init(slaveaddress);
sei();
LED_PORT_DDR |= _BV(LED_BIT);
for(;;){
wdt_reset();
if(debug==1) //Debug is set to 1 in the ISR(TWI_vect)
{
LED_PORT_OUTPUT |= _BV(LED_BIT); //set to 1 e.g
}
}
Sie setzen die Slave-Adresse auf 0x00 (7 Bit), wenn Sie den allgemeinen Anruf aktivieren. Verwenden Sie TWAR |= (1<<TWGCE);
stattdessen.
SoreDakeNoKoto
Stunden
Chris Stratton
SoreDakeNoKoto
Stunden
Benutzer198530