Bei der I²C-Kommunikation in meinem archie hatte ich ebenfalls Probleme. Zuerst mit dem Multi-Master-Konzept. Als die in sinnvoller Zeit nicht gelöst werden (konnten) hatte ich umgestellt auf Ein-Master-mehrere Slaves (Anm.: Topo ist veraltet). Der zentrale Master "pollt" bei Bedarf (auf Anforderung) Werte von den Slaves. Ansonsten bin ich zu I²C der übliche Anfänger/Noncompos.Zitat:
Eine Fehlerquelle .. blieb _eine_ Abfrage auf I2C stecken .. unerklärlich .. (es sei denn, eine der Librarys spuckt in diese Suppe) ..
Bei diesen Arbeiten hatte ich mal die I²C-Bibliothek von Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury durchgeforstet - und die I²C-Gebetbücher wie Philips Semiconductors: THE I 2C-BUS SPECIFICATION, VERSION 2.1, JANUARY 2000, document order number: 9398 393 40011 sowie die ATMEL APPLICATION NOTE Atmel-2565E-Using-the-TWI-Module-as-I2C-Slave_AVR311_Application Note-03/2016. Auffällig war dabei (siehe rot - evtl. scrollen):
Entsprechend der Philips-Bibel zum I²C wird hier vorschriftsgemäß gewartet bis eine Antwort kommt. Und wenn keine kommt hängt sich das Zeugs auf. Das Stretching ist aber sowieso nicht unkompliziert.Code:/*************************************************************************
* Title: I2C master library using hardware TWI interface
* Author: Peter Fleury <pfleury@gmx.ch> http://jump.to/fleury
* File: $Id: twimaster.c,v 1.3 2005/07/02 11:14:21 Peter Exp $
* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3
* Target: any AVR device with hardware TWI
..
**************************************************************************/
. . .
/*************************************************************************
Issues a start condition and sends address and transfer direction.
return 0 = device accessible, 1= failed to access device
*************************************************************************/
unsigned char i2c_start(unsigned char address)
{
uint8_t twst;
// send START condition
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
// wait until transmission completed
while(!(TWCR & (1<<TWINT)));
// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ( (twst != TW_START) && (twst != TW_REP_START)) return 1;
// send device address
TWDR = address;
TWCR = (1<<TWINT) | (1<<TWEN);
// wail until transmission completed and ACK/NACK has been received
while(!(TWCR & (1<<TWINT)));
// check value of TWI Status Register. Mask prescaler bits.
twst = TW_STATUS & 0xF8;
if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
return 0;
}/* i2c_start */
/*************************************************************************
Meine Änderung war nun ein Counter der ne Weile zum runterzählen braucht und alternativ zum NICHT eintrudelnden Signal die Routine beendet (teils mit Fehlerflag). Das löste einerseits die Häng-ihn-auf-Probleme, andererseits klappte es nicht immer mit ner alternativen Lösung. Egal - mittlerweile läufts, siehe Link auf das Topo oben. Allerdings habe ich mittlerweile meinen I²C-Bus über ein ca. 2 m langes, nicht abgeschirmtes Flachbandkabel im archie mit 800 kHz in Betrieb. Anm.: Hab leider kein aktuell geltendes Topo in meiner "Bilderbibliothek".Fazit: möglicherweise könntest Du Dein Problem durch ne vergleichbare Änderung lösen?Code:/* I2C clock in Hz */
#define SCL_CLOCK 800000L
// ... hier 800 kHz, TWBR = 4 (komma 5)