Eine Fehlerquelle .. blieb _eine_ Abfrage auf
I2C stecken .. unerklärlich .. (es sei denn, eine der Librarys spuckt in diese Suppe) ..
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.
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):
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 */
/*************************************************************************
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.
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".
Code:
/* I2C clock in Hz */
#define SCL_CLOCK 800000L
// ... hier 800 kHz, TWBR = 4 (komma 5)
Fazit: möglicherweise könntest Du Dein Problem durch ne vergleichbare Änderung lösen?
Lesezeichen