Hallo!
Ich bin gerade am Debuggen eines Systems, das ich verkabeln sollte.
Es handelt sich dabei um einen Master (Atmega16) und 2 Slaves
(Atmega16), die über TWI verbunden sind. Kabellängen zwischen Master und
Slave: rund 4m.
Das ganze hat unter Laborbedingungen bereits funktioniert,
Datenaustausch hat geklappt. Nun wird das System heute an seinem
Bestimmungsort installiert, und der Master resettet sobald er Daten an
die Slaves senden will. Verkabelung habe ich nun schon zum 5. Mal
überprüft, die passt so.
Die Pullups sind am Master verbaut. Nur die kommen mir zu klein vor
(1kOhm) (habe ich nicht verbaut, sondern Kollege).
Nur ist das ganze nun schon ganz schön verbaut und es wäre mit großem
Aufwand verbunden diese Widerstände gegen größere zu tauschen. Deshalb
erst mal die Frage an euch:
Könnt Ihr euch vorstellen, dass der Prozessor abstürzt, sobald er zu
senden versucht, nur weil die Pullups zu klein gewählt sind? Vor allem:
Das ganze hat in der Werkstatt schon funktioniert. Nun wurde nur die
Verkabelung neu gemacht (Kabellängen in der Werkstatt: 1,5m ; jetzt:
4m).
Vielen Dank für die Mithilfe im Voraus!!
Debugger schrieb:> Könnt Ihr euch vorstellen, dass der Prozessor abstürzt, sobald er zu> senden versucht, nur weil die Pullups zu klein gewählt sind?
Naja, die 5 mA (bei Vcc = 5 V) lassen natürlich die Stromversorgung
etwas einbrechen, aber so dramatisch sollte das noch nicht sein.
Ich tippe eher auf Erdschleifenprobleme oder sowas.
Wie sieht denn die /RESET-Beschaltung aus?
Ich würde eher auf die geänderte Umgebung tippen. Die Schnittstelle ist
für diese Leitungslängen garnicht gedacht. Ich überbrücke damit zwar
auch bis zu 25m (bei 1,2K Ohm), aber mich stören hin und wieder
fehlerhafte übertragungen nicht. Wie äußert sich denn der Absturz. Wenn
die Schnittstelle hängt liegt es auch gerne an einer Leitung, die
dauerhaft 0-Potential hat.
Versorgungsspannung hab ich schon gemessen, die liegt konstant bei 4,9V.
Damit sollte der Controller noch klarkommen würd ich mal meinen.
Beschaltung von /Reset:
[code]
10kOhm
__
vcc o----|____|----------------------> /Reset vom Atmega
|
|
|
= 47pF
|
|
|
_ GND
47 pF ist recht dünn, da kann dir schon mal ein Impuls reinfeuern.
Empfohlen sind 10 nF, allerdings sollte man dann den Widerstand
nach Vcc noch mit einer Diode brücken, da /RESET intern keine
Schutzdiode nach Vcc hat. (Steht irgendwo in einer Appnote.)
Kannst du in die I²C-Leitungen (einschließlich Masse!) mal ein paar
"Angstwiderstände" reinsetzen? Vielleicht 22 Ω oder so auf jede
Seite. Das ist zwar noch keine echte Serienterminierung der
Leitung, könnte aber diese oder jene Störung ein wenig dämpfen.
Debugger schrieb:> Das Programm startet wieder von vorne (Initialisierungen etc.).
a) Watchdog schlägt zu, weil TWI-Bedingung nicht erfüllt ist /
Fehlerbehandlung ungenügend?
b) unerlaubte Sprungbedingung in die Wüste, aus gleichem Grund?
Kondensatoren werde ich vergrößern.
Diese Serien-Widerstände sollten sich einbauen lassen.
Mein Programm hat keinen Watchdog enabled. Kann mir auch nicht
vorstellen wo diese Sprungbedingung herkommen soll (Programm habe ich
überprüft).
Aktuelle TWI Frequenz: 100kHz. Könnte auch auf 10kHz zurückgehen. Bringt
das was?
Was sollte passieren, wenn ich die Kabel zu den Slaves abstecke und
versuche per TWI an die Slaves zu senden?
Grüße
Debugger schrieb:> Aktuelle TWI Frequenz: 100kHz. Könnte auch auf 10kHz zurückgehen. Bringt> das was?
Dann könntest du dir zumindest auch noch Serienwiderstände von
100 Ω in Daten- und Taktleitung problemlos leisten (damit ist die
Leitung recht gut abgeschlossen), möglicherweise sogar noch ein
paar Cs parallel.
> Was sollte passieren, wenn ich die Kabel zu den Slaves abstecke und> versuche per TWI an die Slaves zu senden?
Hängt von deiner Implementierung ab. Sie könnte beispielsweise in
einer Endlosschleife hängen und warten, bis der Slave sich meldet,
sie könnte auch mit einem Fehler aussteigen.
Vielleicht solltest Du doch mal den Code posten. Mit robustem Code ist
es auch bei Fehlern am Interface unmöglich, den Controller abstürzen zu
lassen. Es sei denn, Du hast wirklich ein physisches (sprich:
elektrisches) Problem, welches dem Controller einen Latch-Up verpasst.
Da er durch einen Reset (oder Sprung nach Adresse 0) rutscht, denke
ich erstmal nicht, dass es wirklich am Code liegt (es sei denn, er
hat Interrupts aktiviert und eine ISR vergessen, aber dann hätte der
Aufbau ja auch schon im Labor nicht funktioniert).
Jörg Wunsch schrieb:> Da er durch einen Reset (oder Sprung nach Adresse 0) rutscht, denke> ich erstmal nicht, dass es wirklich am Code liegt
Wenn die Fehlerbehandlung in der TWI-Routine nicht funktioniert, dann
vielleicht schon, da durch verrauschte Signale oder verschluckte
Start-Stop-Kennungen erwartete Bedingungen nicht eintreffen.
Jörg Wunsch schrieb:> es sei denn, er> hat Interrupts aktiviert und eine ISR vergessen, aber dann hätte der> Aufbau ja auch schon im Labor nicht funktioniert
Naja, ich hatte letzthin auch einige diffuse Probleme mit TWI, der
Logic-Analyzer hat dann für Klarheit gesorgt.
Knut Ballhause schrieb:> Jörg Wunsch schrieb:>> Da er durch einen Reset (oder Sprung nach Adresse 0) rutscht, denke>> ich erstmal nicht, dass es wirklich am Code liegt>> Wenn die Fehlerbehandlung in der TWI-Routine nicht funktioniert, dann> vielleicht schon, da durch verrauschte Signale oder verschluckte> Start-Stop-Kennungen erwartete Bedingungen nicht eintreffen.
Wie kommst du von da aber zu Adresse 0? Einen longjmp() an den
Anfang von main() wird man ja nicht programmieren. ;-)
Eher zu erwarten ist dann, dass sich der Code "aufhängt", weil er
auf eine Bedingung wartet, die unter den aktuellen Umständen nicht
eintrifft (beispielsweise eine Freigabe von SCL), und weil die
entsprechende Schleife keinen Abbruch-Zähler enthält.
Jörg Wunsch schrieb:> Wie kommst du von da aber zu Adresse 0
Über einen (unbeabsichtigten) Sprung in eine nichtprogrammierte
Flash-Adresse, über einen überlaufenden Pointer zum Beispiel. Trifft der
Programmcounter auf eine Adresse mit Ihnalt $FF, wird bis Adresse $0000
weitergezählt.
Knut Ballhause schrieb:>> Wie kommst du von da aber zu Adresse 0>> Über einen (unbeabsichtigten) Sprung in eine nichtprogrammierte> Flash-Adresse, über einen überlaufenden Pointer zum Beispiel. Trifft der> Programmcounter auf eine Adresse mit Ihnalt $FF, wird bis Adresse $0000> weitergezählt.
Davon ist bei C-Programmierung normalerweise nicht auszugehen, vor
solchen Fehlern bewahrt einen der Compiler recht zuverlässig.
Aber du hast natürlich Recht: der OP hat nirgends geschrieben, in
welcher Sprache er das programmiert hat.