Forum: Mikrocontroller und Digitale Elektronik Soft I²C zum Beispiel auf ATtiny13


von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
vor einigen Tagen fragte hier jemand nach einer soften I²C 
Implementierung, ich glaube für den ATtiny13. Damals konnte ich kein 
Beispiel geben, aber jetzt habe ich eins, weil ich es gerade für eine 
Bastelei selber brauchte.

Der ATtiny13 hat weder ein TWI noch ein USI Interface,
deswegen kann man das Protokoll nur "zu Fuß" per Bit-Banging
implementieren. Der Quelltext ist trivial und daher sicher leicht auf
andere Mikrocontroller portierbar.

Viel Spaß damit

von spess53 (Gast)


Lesenswert?

Hi

>Der ATtiny13 hat weder ein TWI noch ein USI Interface,
>deswegen kann man das Protokoll nur "zu Fuß" per Bit-Banging
>implementieren. Der Quelltext ist trivial und daher sicher leicht auf
>andere Mikrocontroller portierbar.

Gibt es als AppNote von ATMEL seit 1997.

MfG Spess

von Jim Beam (Gast)


Lesenswert?

Stefanus,

Als Verständnis-Basis ganz brauchbar und auch hinreichend dokumentiert.
Zu einer kompletten Lösung fehlt aber noch einiges,

- Slaveseitiges Clockstretching handelst Du m.E. nicht/nicht optimal.
- Und komplett fehlt ein Exeption/ErrorHandling:
  Wenn hier der Slave abkackt, hängt auch der Master forever!

Prof. Lösungen machen masterseitig ein Timeout und versuchen zumindest, 
den Bus wieder freizutakten, teils mehrmals nach zugebilligter 
Erholungsphase. Falls das fehlschlägt gibt es zumindest ein 
ErrorHandling und der Master "überlebt".
Ich nehme aber an, dass Stefanus den Code eher als "Basis" verstanden 
haben will.

Persönlich setze ich solche BIOS-Dinge grundsätzlich in Assembler um, 
das steigert Performance/schrumpft Code um Faktoren! Von solchen 
elementaren BIOS-Aufgaben sollten Hochsprachen besser die Finger lassen.

@SPESS:
> Gibt es als AppNote von ATMEL seit 1997.
Ja, stimmt.
Die dortige Umsetzung ist aber nur akademisch/rudimentär, hat mit realer 
Anforderung fast-nix zu tun und taugt nicht für die Praxis.

Interessant wäre mal eine TAUGLICHE SLAVE-LÖSUNG für TINYs ohne USI, das 
ist nämlich ungleich herausfordender, wenn man einigermassen 
praxistauglich sein möchte.
In eben-dieser-Praxis sind TINYs auch eher als SLAVE zu vermuten, als 
als Master.

von spess53 (Gast)


Lesenswert?

Hi

>Ja, stimmt.
>Die dortige Umsetzung ist aber nur akademisch/rudimentär, hat mit realer
>Anforderung fast-nix zu tun und taugt nicht für die Praxis.

Blödsinn. Ist in Geräten unserer Firma schon mehrere 1000 mal verkauft 
wurden. Und das nennst du 'taugt nicht für die Praxis.'
Dann solltest du an mal deiner Praxis feilen.

Jim Beam ist ubrigens ein grauenhaftes Gesöff. Amis können keins Whiskey 
machen.

MfG Spess

von Jim Beam (Gast)


Lesenswert?

@SPESS:

1000x unprofessionell bleibt unprofessionell, wird durch Multiplikation 
nicht besser...
Mehr von dem Unsinn, den Du schriebst kommentiere ich nicht.

Aber wie Du selbst durchblicken lässt:
> Amis können keins Whiskey machen.

DEIN Problem scheint wirklich der Alkohol zu sein... ;-)

von Stefan F. (Gast)


Lesenswert?

Jim Beam schrieb:
> Ich nehme aber an, dass Stefanus den Code eher als "Basis" verstanden
> haben will.

Genau. Beim Errorhandling käme ja auch gleich die Frage auf, was denn im 
Fehlerfall passieren soll. Eine generische Lösung, die dann auch noch 
mit den minimalen Ressourcen des ATtiny13 angemessen sparsam umgeht, 
kann ich mir nicht vorstellen.

An das Clock-Stretching habe ich gar nicht gedacht. Danke für den 
Hinweis.

> Interessant wäre mal eine TAUGLICHE SLAVE-LÖSUNG für TINYs ohne USI,
> das ist nämlich ungleich herausfordender

Allerdings. Darauf habe ich ehrlich gesagt keine Lust. Es ist ja nicht 
so, dass man unbedingt auf Teufel komm raus den kleinsten µC ohne die 
dafür vorgesehene Hardware verwenden muss.

> In eben-dieser-Praxis sind TINYs auch eher als SLAVE zu vermuten,
> als als Master.

Jawohl, aber dann bitte wenigstens einen mit USI.

von Peter D. (peda)


Lesenswert?

Jim Beam schrieb:
> Persönlich setze ich solche BIOS-Dinge grundsätzlich in Assembler um,
> das steigert Performance/schrumpft Code um Faktoren!

Es steigert nichts, da auch in Assembler die 100kHz abgewartet werden 
müssen.
Und der Code wird bestenfalls minimal kleiner (micro-optimisation).

Jim Beam schrieb:
> - Slaveseitiges Clockstretching handelst Du m.E. nicht/nicht optimal.

Braucht man aber nur, wenn der I2C-Slave ein MC ist. Bei dummen 
I2C-Slaves ist SCL nur ein Eingang (PCF8574, DS1307, MCP3425, 24C512 
usw.).

Hier noch ne I2C-Lib:
Beitrag "Re: I2C Eeprom AT24C512 Lib für Pagewrite in C"

von Michael U. (amiga)


Lesenswert?

Hallo,

Peter D. schrieb:
> Braucht man aber nur, wenn der I2C-Slave ein MC ist. Bei dummen
> I2C-Slaves ist SCL nur ein Eingang (PCF8574, DS1307, MCP3425, 24C512
> usw.).

die Grenze kann sehr fließend sein. Komplexe ICs, die per I2C 
gesteuert/programmiert werden, nutzen es durchaus. Das Datenblatt weißt 
normalerweise nicht darauf hin, weil es zum I2C-Standard gehört.
Vor vielen Jahren hat mich ein MP3-Decoder (MAS3507) damit zur 
Verzweiflung gebracht.

Gruß aus Berlin
Michael

von Peter D. (peda)


Lesenswert?

Michael U. schrieb:
> Das Datenblatt weißt
> normalerweise nicht darauf hin

Steht aber drin, Seite 34: I2CC SCL IN/OUT
Bei den oben genannten ICs fehlt beim SCL-Pin das "OUT".
Außerdem steht drin, daß der MAS3507 ein DSP mit ROM ist, also kein 
"dummes" Hardware-I2C.

Ist aber auch kein großer Akt, bei solchen Slaves ein Warten auf SCL_in 
= 1 zu ergänzen.
1
#define SSCL_in            PIN_B1
2
#define sscl_hi()       SSCL = 1; while (SSCL_in == 0);

: Bearbeitet durch User
von Apollo M. (Firma: @home) (majortom)


Lesenswert?

wenn ich so etwas sehe ... bäh, klippschule?!

... byte = (byte << 1) & 0xFF;


mt

hier mal zwei varianten für die "high performer" ...

void i2c_send(uint8_t data) { //send data bits and starts with msb
    for (uint8_t bit = 0; bit!=8; bit++) {
        if (data & (0x80>>bit)) SDA_HIGH;
        else SDA_LOW;

        I2C_DELAY;
        SCL_HIGH;
        I2C_DELAY;
        SCL_LOW;
    }
}

oder so ...

void i2c_send(uint8_t data) { //send data bits and starts with msb
    uint8_t bitChanges = data ^ (data>>1);
    for (uint8_t bit = 0x80; bit; bit >>= 1) {
        //toggling, if not avr DATA_PIN ^= 1;
        if (bitChanges & bit) PINB = 1<<DATA_PIN;

        I2C_DELAY;
        SCL_HIGH;
        I2C_DELAY;
        SCL_LOW;
    }
}

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Apollo M. schrieb:
> ... byte = (byte << 1) & 0xFF;

Den Teil "& 0xFF" kürzt der Compiler raus, der steht da nur, um Lint 
zufrieden zu stellen. Übrig bleibt eine Simple LSL Operation. Erzähle 
mir nicht, dass die unperformant sei.

Bist du ganz sicher, dass "(0x80>>bit)" schneller ist?

Ich finde deinen Ansatz auch nicht so gut. die Bits von 0 bis 7 zu 
zählen, aber tatsächlich die Bits 7 bis 0 zu senden. Das stiftet 
Verwirrung.

Außerdem Hand auf Herz: Kommt es bei I²C auf einzelne CPU Takte an?

von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

Stefanus F. schrieb:
> Übrig bleibt eine Simple LSL Operation

Ich habe jetzt mal ins Assembler Listing geschaut. Interessanterweise 
hater Compiler daraus "add r24, r24" gemacht. Aber egal, ist auch nur 
eine kurze Operation mit dem gleichen Ergebnis.

Anbei die korrigierte Datei mit Clock-Stretching.

von spess53 (Gast)


Lesenswert?

Hi

>Interessanterweise
>hater Compiler daraus "add r24, r24" gemacht. Aber egal, ist auch nur
>eine kurze Operation mit dem gleichen Ergebnis.

lsl r24 und add r24,r24 haben den gleichen Assemblercode. Also ist 
beides richtig.

MfG Spess

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

Stefanus F. schrieb:
> Bist du ganz sicher, dass "(0x80>>bit)" schneller ist?
>
> Ich finde deinen Ansatz auch nicht so gut. die Bits von 0 bis 7 zu
> zählen, aber tatsächlich die Bits 7 bis 0 zu senden. Das stiftet
> Verwirrung.

die beste variante ist die nr.2, welche auch geeignet ist um eine 
schnelle sw spi variante zu bauen!
diese benutzt den avr toggle befehl, welcher dann auch für die clock 
benutzt werden sollte! nur wenn ein bit sich ändert wird toggling 
active, darum auch schneller!

 uint8_t bitChanges = data ^ (data>>1);
 for (uint8_t bit = 0x80; bit; bit >>= 1) {
    //toggling, if not avr DATA_PIN ^= 1;
    if (bitChanges & bit) PINB = 1<<DATA_PIN;

@verwirrung, das argument finde ich "gut" - näh lieber doch nicht, weil 
das kommt immer öfter, wenn mal der definierte sprachumfang von c auch 
benutzt wird.

mt

von Jim Beam (Gast)


Lesenswert?

Apollo M. schrieb:
> diese benutzt den avr toggle befehl, welcher dann auch für die clock
> benutzt werden sollte!

MOMENT MAL....

Du setzt doch NICHT ETWA bei H das Portbit auf AUSGANG-H??
Das enspricht absolut NICHT der I2C-Spec.!

Korrekt ist:
H = Port-ist-EINGANG mit Pullup
L = Port-ist-AUSGANG mit elektrisch L

Ansonsten kann es elektrische Kurzschlüsse auf dem Bus geben,
und es widerspricht komplett der I2C-Spezifikation.
Das wird ständig und gerne falsch gemacht.

von Apollo M. (Firma: @home) (majortom)


Lesenswert?

... ich liebe kurzschlüsse, am besten wenn's dann so richtig gut nach 
geschmorten riecht!

mein beispiel kommt von meiner sw spi ...

du hast recht mit dem hinweis zu i2c, daher sollte dann das dddrx reg 
zum toggling benutzt werden!

wichtig wäre hier zu erkennen, dass das toggling prinzip key ist!


mt

von Stefan F. (Gast)


Lesenswert?

Apollo M. schrieb:
> die beste variante ist die nr.2

Warum? Schneller ist hier vollkommen sinnlos, da die gesparte Zeit in 
einer längeren Warteschleife vernichtet werden muss.

Ich lege in erster Linie Wert auf gut lesbaren Code, da ich in einem 
Team arbeite und oft Sachen korrigieren muss, den Kollegen vorher 
entwickelt haben. Oft ist das so alter Code, dass sich niemand mehr 
daran erinnern kann und daher auch nicht erklären kann.

Performance-Optimierung steht in der Rangliste ganz unten, noch unter 
Keller-Aufräumen.

von Stefan F. (Gast)


Lesenswert?

> daher sollte dann das dddrx reg
> zum toggling benutzt werden!

Stimmt, eigentlich kann ich mir die Schreibzugriffe auf das PORTB 
Register sparen.

von Marcus H. (Firma: www.harerod.de) (lungfish) Benutzerseite


Lesenswert?

Jim Beam schrieb:
> Stefanus,
>
> Als Verständnis-Basis ganz brauchbar und auch hinreichend dokumentiert.
> Zu einer kompletten Lösung fehlt aber noch einiges,
>
> - Slaveseitiges Clockstretching handelst Du m.E. nicht/nicht optimal.
> - Und komplett fehlt ein Exeption/ErrorHandling:
>   Wenn hier der Slave abkackt, hängt auch der Master forever!
>
> Prof. Lösungen machen masterseitig ein Timeout und versuchen zumindest,
> den Bus wieder freizutakten, teils mehrmals nach zugebilligter
> Erholungsphase. Falls das fehlschlägt gibt es zumindest ein
> ErrorHandling und der Master "überlebt".
> Ich nehme aber an, dass Stefanus den Code eher als "Basis" verstanden
> haben will.

Für den Beitrag hast Du Dir einen großen Schluck Laphroaig verdient!
Speziell der Hinweis mit dem Freitakten ist wichtig, wenn es darum geht 
zuverlässige I2C-Lösungen zu bauen.


> Persönlich setze ich solche BIOS-Dinge grundsätzlich in Assembler um,
> das steigert Performance/schrumpft Code um Faktoren! Von solchen
> elementaren BIOS-Aufgaben sollten Hochsprachen besser die Finger lassen.

Auf einem Tiny13 macht Assembler nicht nur Spaß, sondern auch Sinn. Ist 
halt noch ein niedlich kleiner Mikrocontroller. Und so ein Bitbongo (tm) 
ist in Assembler auch nicht schlechter zu lesen als in C.
Für morgen Vormittag habe mir eine Portierung inkl. Sensoransteuerung 
für einen Soft-I2C in Maschinensprache auf einen ATtiny814 vorgenommen. 
Der Baustein kommt in einem Gerät als Hausmeister zum Einsatz. Die ganze 
Baugruppe nimmt im Sleep, mit laufendem WDT, unter Normalbedingungen 
gemessene <2µA auf.

von c-hater (Gast)


Lesenswert?

Stefanus F. schrieb:

> Warum? Schneller ist hier vollkommen sinnlos, da die gesparte Zeit in
> einer längeren Warteschleife vernichtet werden muss.

Das scheint nur so. Tatsächlich kann man gesparte Takte in in der 
Bitschieberei und Ausgabe dafür nutzen, das nächste Byte zu holen (als 
Transmitter) bzw. das vorige zu verarbeiten (als Receiver). Das 
verbessert insgesamt zumindest den Durchsatz oder erlaubt es überhaupt 
erst, bestimmte Timing Constraints einzuhalten.

Das gilt nicht nur für I2C, sondern ganz generell für alle Sachen die 
irgendwelche Bitserialierungen machen. Bekanntes Beispiel für sowas ist 
z.B. V-USB. Das würde ohne solche Techniken überhaupt nicht 
funktionieren können.

Der Trick ist dabei eben gerade, die "überflüssige" Zeit nicht in 
nutzlosen Warteoperationen zu vernichten, sondern sie sinnvoll zu 
nutzen.

> Ich lege in erster Linie Wert auf gut lesbaren Code

Wenn ich die Wahl habe zwischen schlecht lesbarem Code und gut lesbaren, 
aber komplett unbrauchbarem Code, dann fällt mir diese Wahl nicht 
schwer...

Aber OK, für einen I2C-Master spielt das alles wirklich nur eine 
untergeordnete Rolle. Wenn er richtig implementiert ist, wird auch 
langsamer Code immer funktionieren. Nur der erreichbare Durchsatz ist 
halt nicht so hoch, wie er sein könnte. Wenn er trotzdem genügt: ja dann 
würde ich natürlich auch den gut lesbaren Code bevorzugen. Schon 
deshalb, weil er auch viel einfacher zu schreiben ist...

von Stefan F. (Gast)


Lesenswert?

Marcus H. schrieb:
> Für morgen Vormittag habe mir eine Portierung inkl. Sensoransteuerung
> für einen Soft-I2C in Maschinensprache auf einen ATtiny814 vorgenommen.

Warum? Der hat doch ein richtiges TWI Interface sogar mit Filter für 
"noise and spike suppression" und konfigurierbaren Timeouts.

Mein obiger Code kann doch nur eine Notlösung mit provisorischem 
Charakter sein.

von Stefan F. (Gast)


Lesenswert?

c-hater schrieb:
> Wenn er trotzdem genügt: ja dann
> würde ich natürlich auch den gut lesbaren Code bevorzugen.

Na dann sind wir uns ja einig.

von Marcus H. (Firma: www.harerod.de) (lungfish) Benutzerseite


Lesenswert?

Stefanus F. schrieb:
> Marcus H. schrieb:
>> Für morgen Vormittag habe mir eine Portierung inkl. Sensoransteuerung
>> für einen Soft-I2C in Maschinensprache auf einen ATtiny814 vorgenommen.
>
> Warum? Der hat doch ein richtiges TWI Interface sogar mit Filter für
> "noise and spike suppression" und konfigurierbaren Timeouts.

Weil ich
- eine Menge Erfahrung mit undokumentierten Features in I2C Interfaces 
verschiedenster MCUs und Peripheriebausteine habe
- den ATtiny814 erstmals einsetze
- weil in dieser Anwendung ein Software-Automat, der auf zig Maschinen 
läuft, das geringste Risiko darstellt und am einfachsten zu 
dokumentieren ist
- weil meine Anwendungen nicht nur mal eben kurz auf dem Schreibtisch 
laufen sollen, sondern ohne Wartungsmöglichkeit für lange Zeit im Feld 
unterwegs sind


> Mein obiger Code kann doch nur eine Notlösung mit provisorischem
> Charakter sein.
Die Anfänger die sich auf Deinen Post verlassen wären sicher froh 
gewesen, Du hättest diese Einschätzung Deines Beispiels auch eingangs 
schon so geschrieben.

von Stefan F. (Gast)


Lesenswert?

Marcus H. schrieb:
> Die Anfänger die sich auf Deinen Post verlassen wären sicher froh
> gewesen, Du hättest diese Einschätzung Deines Beispiels auch eingangs
> schon so geschrieben.

Ja stimmt, darauf hätte ich hinweisen sollen.
Aber auf einem µC mit nur 32 Bytes RAM (+32 Register) kann man halt 
ohnehin keine Weltbewegenden Sachen machen. Ich habe den nur verwendet, 
weil ich meine Vorräte aufbrauchen will.

von W.S. (Gast)


Lesenswert?

Stefanus F. schrieb:
> aber jetzt habe ich eins, weil ich es gerade für eine
> Bastelei selber brauchte

Ist ja soweit OK, nur ein paar Bemerkungen meinerseits:
- i2c_start sollte bool sein und die while Zeile in i2c_start sollte 
durch eine kleine Verzögerung und dann ggf. return false ergeben.
- in i2c_stop sollte die while Zeile ganz raus. Es ist ja bereits alles 
erledigt.
- das unbegrenzte while in i2c_send ist auch nicht nett.
- das i2c_communicate mißfällt mir. Es ist mir zu überladen. Ich mache 
es lieber getrennt, das ist mMn handlicher:

void I2C_Init (void);
bool Do_I2C_Start (byte Adresse, bool obRead); // 7 bit
bool Do_I2C_Write (byte aByte);
byte Do_I2C_Read  (bool Acknowledge);
void Do_I2C_Stop  (void);

W.S.

von spess53 (Gast)


Lesenswert?

Hi

>Auf einem Tiny13 macht Assembler nicht nur Spaß, sondern auch Sinn. Ist
>halt noch ein niedlich kleiner Mikrocontroller. Und so ein Bitbongo (tm)
>ist in Assembler auch nicht schlechter zu lesen als in C.

Gibt es doch schon: AVR300: Software I2C™ Master Interface

MfG Spess

von W.S. (Gast)


Lesenswert?

Apollo M. schrieb:
> hier mal zwei varianten für die "high performer" ...
>
> void i2c_send(uint8_t data) { //send data bits and starts with msb
>     for (uint8_t bit = 0; bit!=8; bit++) {
>         if (data & (0x80>>bit)) SDA_HIGH;
>         else SDA_LOW;
>
>         I2C_DELAY;
>         SCL_HIGH;
>         I2C_DELAY;
>         SCL_LOW;
>     }
> }
>
> oder so ...

Das ist für dich high performer. aha.

Ähem.. guck mal:
1
byte I2C_dio (byte b)
2
{ byte c, e;
3
  c = 0x80;
4
  e = 0;
5
  while (c)
6
  { if (b & c) SDA_high(); else SDA_low();
7
    sdelay(sdavorscl);
8
    SCL_high();
9
    sdelay(sclhigh);
10
    c = c>>1;
11
    e = e<<1;
12
    if (SDA_State()) e |= 1;
13
    SCL_low();
14
    sdelay(sdahalte);
15
  }
16
  return e;
17
}

Das kann man sowohl für Read als auch für Write benutzen. Bei Read eben 
$FF senden. Allerdings schert es sich nicht um Verzögerungen vom Slave.

W.S.

von c-hater (Gast)


Lesenswert?

Stefanus F. schrieb:

> Aber auf einem µC mit nur 32 Bytes RAM (+32 Register) kann man halt
> ohnehin keine Weltbewegenden Sachen machen. Ich habe den nur verwendet,
> weil ich meine Vorräte aufbrauchen will.

Der Tiny13 hat allerdings 64Byte RAM (+32 Register)...

Ich gebe dir allerdings trotzdem insofern Recht, dass der Tiny13 ein 
wirklich ziemlich eingeschränkter Vertreter der AVR8-Familie ist. Ich 
bin zu meinem einzigen Exemplar vor ca. 10 Jahren gekommen, als er die 
paar Cent beigetragen hat, die ich noch brauchte, um bei einer 
Pollin-Bestellung einen Gutschein einlösen zu können.

In all den Jahren war er bei etlichen Projekten immer mal wieder in der 
Vorauswahl, ist dann aber immer wegen irgendwelcher störenden 
Beschränkungen rausgeflogen. So kommt es, dass ich dieses eine Exemplar 
dieser Supergurke immer noch rumliegen habe. Inzwischen bin ich auch 
nicht mehr sicher, dass ich überhaupt jemals eine passende Anwendung für 
das Teil finde. Für Anwendungen der in Frage kommenden Klassen ist immer 
der Tiny25 die bessere Wahl und der kostet ja praktisch dasselbe.

von Jim Beam (Gast)


Lesenswert?

Der Tiny13 hat aber ein besonderes Feature, was bisher nicht erwähnt 
wurde:
Nämlich der RC-Clock mit 9.6Mhz anstelle 8Mhz der anderen 8-Pinner.

Kann manchmal nützlich sein.

von c-hater (Gast)


Lesenswert?

Jim Beam schrieb:

> Der Tiny13 hat aber ein besonderes Feature, was bisher nicht erwähnt
> wurde:
> Nämlich der RC-Clock mit 9.6Mhz anstelle 8Mhz der anderen 8-Pinner.

Die anderen kannst du per OSCCAL auch völlig problemlos auf 9.6 
zwirbeln. Ist dann zwar, streng genommen, ausserhalb der jeweiligen 
Specs, aber mir ist noch kein Fall untergekommen, wo diese moderate 
"Übertaktung" (sowieso nur relevant für den Schreibzugriff auf Flash und 
EEPROM) irgendwie zu Problemen geführt hätte. Garantiert ist es aber 
herstellerseitig eben nicht. Das kann schon wichtig sein. Für 
Bastelprojekte allerdings nicht und auch nicht für kommerzielle 
Anwendungen, wo eben nicht in Flash oder EEPROM geschrieben wird.

von Jim Beam (Gast)


Lesenswert?

c-hater schrieb:
> Die anderen kannst du per OSCCAL auch völlig problemlos auf 9.6
> zwirbeln.

Interessant, käme mir sehr gelegen wenn das klappt.
Werde das auf jeden Fall mal pröben.

Habe mal irgendwann bei Atmel gelesen, dass man OSCCAL nur in kleinen 
Schritten ändern sollte, von 8->9.6 wäre dann aber schon ein Klopper 
nehme ich an. Sollte ich da am Progstart eine Schleife einbauen, oder 
wie hast Du das gemacht?

von Olaf (Gast)


Lesenswert?

> - weil meine Anwendungen nicht nur mal eben kurz auf dem Schreibtisch
> laufen sollen, sondern ohne Wartungsmöglichkeit für lange Zeit im Feld
> unterwegs sind

In dem Falle ist I2C grundsaetzlich nicht verwendbar. Es gibt naemlich 
durchaus ICs die sich so weghaengen das sie die Clockleitung auf Masse 
ziehen. Deshalb gibt es modernere I2C-ICs die einen Mindesttakt 
verlangen und sich resetten.

Olaf

von Alfred K. (Gast)


Lesenswert?

Jim Beam schrieb:
> Sollte ich da am Progstart eine Schleife einbauen, oder
> wie hast Du das gemacht?

Ganz einfach:
OSCCAL = 0xff;

Dann läuft das Teil mit ca. 14 - 15 MHz. Ein 20 MHz AVR wird damit auch 
nicht übertaktet.
Fertig.

von Marcus H. (Firma: www.harerod.de) (lungfish) Benutzerseite


Lesenswert?

Lieber Olaf (Gast):
seufz Ich finde solche pauschalen Ansagen immer recht schwierig. Im 
Endeffekt hast Du geschrieben, dass Du die Kompetenz des von Dir 
zitierten Schreibers anzweifelst. Gleichzeitig ist das Zitat aus dem 
Zusammenhang gerissen.
Für Dich sicherer wäre in diesem Fall eine Formulierung wie "I2C ist 
bekanntermaßen sehr störanfällig. Wie gehst Du mit diesem Problem um?"
Zumal der Schreiber bereits signalisiert hatte, dass ihm allerlei 
Probleme bekannt sind.


Also, schauen wir uns Deinen Post mal im Detail an:


Olaf schrieb:
>> - weil meine Anwendungen nicht nur mal eben kurz auf dem Schreibtisch
>> laufen sollen, sondern ohne Wartungsmöglichkeit für lange Zeit im Feld
>> unterwegs sind
>
> In dem Falle ist I2C grundsaetzlich nicht verwendbar. Es gibt naemlich
> durchaus ICs die sich so weghaengen das sie die Clockleitung auf Masse
> ziehen.

Es gibt Master und Slave Engines die sich so weghängen, dass sie nur mit 
einem Powercycle wieder zu beleben sind. Ein Grund, warum I2C ein von 
mir nicht sehr geschätztes Interface ist. Allerdings gibt es manchmal 
Sachzwänge, wenn z.B. ein Sensorhersteller nur dieses Interface zur 
Verfügung stellt.

>Deshalb gibt es modernere I2C-ICs die einen Mindesttakt
> verlangen und sich resetten.
>
> Olaf

Nach Deiner o.G. Aussage bin ich mir nicht sicher, was der Wert dieser 
Info ist? Sind diese I2C nun tauglich oder nicht?

Also was machen wir nun? Wir bekommen wir die Kuh vom Eis? Wie würdest 
Du mit diesen Problemen umgehen?

Ein kurze Liste an Vorschlägen, ohne Anspruch auf Vollständigkeit:
- die Slaves können vom Master freigeclockt werden
- wenn das nicht hilft kann der Master einen Powercycle der Slaves 
auslösen
- wenn ein Powercycle des Masters aufgrund einer hängenden I2C Engine 
nicht erwünscht ist, ist die Firmwareimplementation ein überschaubares 
Risiko
- es gibt Watchdog Konzepte nicht nur für MCUs sondern auch für 
Gesamtsysteme. Für ganz bestimmte Fälle kann man aber auch im 
Batteriemanagement einen Powercycle des Komplettsystems anstoßen

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Als erstes sollte man klären, ob diese ganzen Maßnahmen überhaupt 
angemessen sind.

In meinem konkreten Fall geht es um ein Kinderspielzeug (ein 
Eltern-Detektor vor der Zimmertüre). Der darf ruhig mal hängen bleiben.

von c-hater (Gast)


Lesenswert?

Alfred K. schrieb:

> Ganz einfach:
> OSCCAL = 0xff;

Wie Jim Beam schon festgestellt hat, empfiehlt Atmel, bei Änderungen von 
OSCCAL keine großen Sprünge zu machen. Sie sollten <= 2% bleiben. Also 
besser in einer Schleife vom Initialwert zum gewünschten Wert laufen 
lassen.

> Dann läuft das Teil mit ca. 14 - 15 MHz. Ein 20 MHz AVR wird damit auch
> nicht übertaktet.

Darum geht es auch garnicht. Worum es geht, sind Schreibvorgänge in 
Flash oder EEPROM. Das dafür nötige Timing wird bei den allermeisten 
AVR8 aus dem  RC-Oszillator abgeleitet, auch die Programmierspannung 
wird mit Ladungspumpen erzeugt, die durch diesen Oszillator getaktet 
werden.

DA sind also ggf. Probleme zu erwarten, nicht beim Betrieb der MCU. Die 
MCU macht erst Probleme, wenn der Takt für die Betriebsspannung zu hoch 
wird, bei 5V und RC-Oszillator als Taktquelle also nie, auch nicht wenn 
man OSCCAL auf Maximum setzt. Bei kleineren Betriebsspannungen sieht das 
naturgemäß anders aus, dann muss man natürlich auch diese Abhängigkeit 
bei Spielereien an OSCCAL berücksichtigen.

Das steht übrigens alles in den Datenblättern, man muss die einfach nur 
mal lesen...

von Marcus H. (Firma: www.harerod.de) (lungfish) Benutzerseite


Lesenswert?

Olaf schrieb:
...
> In dem Falle ist I2C grundsaetzlich nicht verwendbar. Es gibt naemlich
> durchaus ICs die sich so weghaengen das sie die Clockleitung auf Masse
> ziehen. Deshalb gibt es modernere I2C-ICs die einen Mindesttakt
> verlangen und sich resetten.

Weil ich das gestern bei meinem aktuellen Thema gesehen habe:
In die Richtung geht auch der Soft Reset bei den Sensirion SDP3x - 
Command 0x0006: Datenblatt "Soft Reset"
"This sequence resets the sensor with a separate reset block,
which is as much as possible detached from the rest of the
system on chip. Note that the I 2 C address is 0x00, which is the 
general call address, and that the command is 8 bit. The reset is 
implemented according to the I2C specification."

Einziger Haken ist die Situation in der ein Device dauerhaft eine 
Busleitung nach unten zieht - dann bekommt man den Bus auf diese Weise 
nicht mehr unter Kontrolle. Handelt es sich um SDA, dann probiert man zu 
Toggeln, bis SDA wieder auf High geht. Wenn es sich um ein "verlängertes 
Clock Stretching" handelt, braucht man einen Plan B.

von Marcus H. (Firma: www.harerod.de) (lungfish) Benutzerseite


Lesenswert?

Stefanus F. schrieb:
> Als erstes sollte man klären, ob diese ganzen Maßnahmen überhaupt
> angemessen sind.

Wichtig ist vor allem das Bewusstsein, dass der ganze Kram nicht 
unfehlbar ist. Nicht dass sich hier irgendwann einer vor lauter Frust 
hinter einen Zug wirft.

> In meinem konkreten Fall geht es um ein Kinderspielzeug (ein
> Eltern-Detektor vor der Zimmertüre). Der darf ruhig mal hängen bleiben.

Mmmh? Ich hatte Dich älter eingeschätzt. :D

von Alfred K. (Gast)


Lesenswert?

c-hater schrieb:
> Worum es geht, sind Schreibvorgänge in
> Flash oder EEPROM. Das dafür nötige Timing wird bei den allermeisten
> AVR8 aus dem  RC-Oszillator abgeleitet

Damit hast Du Recht und das muß berücksichtigt werden, wenn man 
schreibende EEPROM-Zugriffe braucht. Da das Timing eh sehr ungenau sein 
wird, kann man bei Bedarf OSCCAL auch vor und nach den Zugriffen 
umstellen.

c-hater schrieb:
> Das steht übrigens alles in den Datenblättern, man muss die einfach nur
> mal lesen...

Da steht aber auch, dass man während der Änderungen den Prozessor im 
Reset halten soll. Dazu hätte ich gerne ein Programmbeispiel.
Geht man zu den ATmega, dann gibt es keine Einschränkungen, die nur 2% 
Änderungen empfehlen. In der Praxis funktioniert auch direktes 
Beschreiben mit 0xFF problemlos.
Das zu den AVR Datenblättern.

Ich sehe jedenfalls keinen Grund, einen ATtiny13 nur wegen seiner 9,6 
MHz einem ATtiny25/45/85 zu bevorzugen.

von Stefan F. (Gast)


Lesenswert?

Marcus H. schrieb:
>> In meinem konkreten Fall geht es um ein Kinderspielzeug (ein
>> Eltern-Detektor vor der Zimmertüre). Der darf ruhig mal hängen bleiben.
> Mmmh? Ich hatte Dich älter eingeschätzt. :D

Ich bin der, der nicht rein darf.

von c-hater (Gast)


Lesenswert?

Alfred K. schrieb:

> Da das Timing eh sehr ungenau sein
> wird, kann man bei Bedarf OSCCAL auch vor und nach den Zugriffen
> umstellen.

Jepp.

> Da steht aber auch, dass man während der Änderungen den Prozessor im
> Reset halten soll.

Das bezieht sich auf einen extern eingespeisten Takt und genau den 
"verbotenen" Fall. Sprich: wenn man das macht, muss man das per externer 
Hardware lösen, eine Lösung per Programm ist dann natürlich nicht 
möglich.

Bezüglich des RC-Oszillators hilft eine Tatsache, die nicht dokumentiert 
ist, sich aber sehr leicht nachweisen läßt. Nämlich der Fakt, dass die 
Änderung von dessen Takt per OSCCAL einer Zeitkonstante unterliegt. Der 
erzeugte Takt folgt also nicht sprunghaft dem Wert in OSCCAL. Deswegen 
bleibt in den meisten Fällen auch eine größere Änderung von OSCCAL 
folgenlos. Wenn man sich die Sprungantwort anschaut, sieht man aber, 
dass bei wirklich extremen Änderungen die 2%-Latte sehr deutlich 
gerissen wird. Wenn man also clever ist, vermeidet man diese potentiell 
gefährliche Situation, zumal die "Kosten" dafür ja nun wirklich sehr 
überschaubar sind.

> Ich sehe jedenfalls keinen Grund, einen ATtiny13 nur wegen seiner 9,6
> MHz einem ATtiny25/45/85 zu bevorzugen.

Sag' ich ja. Die potentiellen Probleme lassen sich halt mit sehr wenig 
Aufwand zuverlässig umgehen, wenn sie denn in einer konkreten Anwendung 
überhaupt relevant sind.

von Marcus H. (Firma: www.harerod.de) (lungfish) Benutzerseite


Lesenswert?

Stefanus F. schrieb:
> Marcus H. schrieb:
>>> In meinem konkreten Fall geht es um ein Kinderspielzeug (ein
>>> Eltern-Detektor vor der Zimmertüre). Der darf ruhig mal hängen bleiben.
>> Mmmh? Ich hatte Dich älter eingeschätzt. :D
>
> Ich bin der, der nicht rein darf.

You made my day! :)
Das ist ja, wie wenn man bei der NSA "Verschlüsselungssoftware" kaufte.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.