Gesundes 2005 euch allen! Als erstes möchte ich mich entschuldigen, dass ich trotz der zahlreichen Postings zu diesem Thema hier so blöd fragen muss. Ich mochte mit einem MEGA32 einen PCF8574 (8-Bit IO-Expander) ansteuern. Der Bustakt ist 100kHz. Meine CPU wird mit 16MHz getaktet. Nach der wundervollen Formel (SCL = CPU/(16+2TWBR*4^TWPS)) sollte mein TWBR 72 betragen (bei TWPS = 0x00 also Prescaler von 1) doch das funzt net. Jetzt das skuriele: Rechlich Tests haben einen funktionstüchtigen Wert von 0 bis 15 für TWBR ergeben!!! Häää??? Bustakt von bis zu 1MHz??? Es spielt auch keine Rolle ob ich vom Quarz, vom STK500 oder vom internen RC Takten lasse. Es funktionieren immer Werte die weit von den Berechneten abweichen. Nun bitte ich euch meine Berechnung zu überprüfen. Danke!
CPU = 16000000 TWPS = 0 SCL = 1000000 ergibt TWBR von 72 Deine Berechnung mit TWPS=1 (also Prescaler 4) kann ich bestätigen. Hab ich getestet, ohne Erfolg. (Es funzen aber TWBRs von 0 bis 3 bei TWPS = 1)
"TWPS = Value of the prescaler bits in the TWI Status Register" Also kommen 1, 4, 16 und 64 laut Datenblatt in Frage. Oder sehe ich das falsch?
Legende der Formel auf Seite 173: "TWPS = Value of the prescaler !!!BITS!!! in the TWI Status Register" also 0 bis 3 (sind ja auch nur 2 Bit) Kommentat zur Tabelle auf Seite 177: "The value of TWPS1..0 is used in the equation" Soll heisen: Wenn in der Formel ...4^3 steht, ergibt sich ein Prescaler von 64
die Berechnung zu stimmen scheint, hier mal ne kurze Zusammenfassung meines Progs: Reset: interne Pullups an 72 nach TWBR 0 nach TWPS Main: Error-Led aus Adresse setzen zu sendende Byte setzen rcall SENDEN rjmp Main SENDEN: siehe Datenblatt Seite 180 (fast eins-zu-eins abgetipt) Error: STOP Error-LED an ergibt eine flackernde Error-Led. Ne Idee?
So, hier mal noch eine leicht vereinfachte Version meines Quelltextes, mit TWBR=0 und TWPS=0,die mehr oder weniger stabil lauft. Mit den berechnete Werten läufts net! Hab grad mal nen Mega16 probiert: Verhält sich ähnlich. Warum funzts bei allen andern, nur bei mir net? heul Bitte helft mir!
Hallo, in I2CInit: ldi r16,0 ;nach Formel: 72 bei TWSR = 0 oder 18 bei... out TWBR,r16 Du schreibst hier aber doch 0 in TWBR.
Ich hab vorgestern auch das erste mal meinen TWI angeschmissen bekommen.. hab mir die Routinen aussem Datablatt abgeschaut: twi_transmission: out TWDR, temp1 ldi temp1, (1<<TWINT)|(1<<TWEN) out TWCR, temp1 rjmp twi_wait twi_read: ldi temp1, (1<<TWINT)|(1<<TWEN) out twcr, temp1 rjmp twi_wait twi_start: ldi temp1, (1<<TWINT)|(1<<TWSTA)|(1<<TWEN) out TWCR, temp1 rjmp twi_wait twi_stop: ldi temp1, (1<<TWINT)|(1<<TWSTO)|(1<<TWEN) out TWCR, temp1 ret twi_wait: push temp2 ldi temp2, 0xFF twi_wait_2: dec temp2 breq twi_wait_3 in temp1, TWCR sbrs temp1, TWINT rjmp twi_wait_2 in temp1, TWDR pop temp2 ret twi_wait_3: ldi temp1, 99 pop temp2 ret Bei twi_wait kann man natürlich das mit temp2 rauslassen, ist aber deswegen, damit sich das Ding nicht aufhängt, wenn mal nen Sensor spinnt.. bei mir wird dann halt "99°C" angezeigt und das is dann OK. Geschmackssache. Aber Thorsten wird auch Recht haben ... Meine Init (@8Mhz): ; twi ldi temp1, 32 out twbr, temp1 Die Formel ist: CLK = Takt/(16+(2xTWBRx 4^TWPS)) Wenn TWPS = 0, dann ergibts sich für 4^TWPS = 1.. also vernachlässigbar. Außerdem sollte man mit TWBR nicht niedriger als 10 gehen.. dave
Wie ich das sehe, du willst, statt mehere Byte an eine Device, ein Byte an mehrere Device senden ? ldi Adr,0xXX rcall Senden wenn einer dovon nicht vorhanden ist, gibt's kein MT_SLA_ACK zurück ! Gruß Thany
Ich kann dem Thorsten nur zustimmen! Und auch deine Rechnung (Thany) ist meines Erachtens richtig. Nur funktioniert das nicht! Erst ein Wert zw 0 und 15 führt zu einer Datenübertragung (mehr oder weniger stabil). Und um einen einigermasen funktionstüchtigen Quellcode zu posten, hab ich die 0 ins TWBR geschrieben und als Kommentar die berechneten Werte. Die Frage ist halt, wo der Fehler liegt. (Hätte ich ein Oszi, würd ich einfach messen, hab ich aber nich) Ich habs übrigens auch schon in anderen Foren probiert, aber da bekam ich weder so schnell noch so sachliche Antworten. Großes Lob an euch!!! Ich bin optimistisch dass wir das Problem in kürze lösen. Bitte weiter so! Danke!
Die Rechnung stammt natürlich vom "Dave im Grab" nicht von Thany. Sorry. Thany hat aber auch recht, dass ich einen Wert an viele PCF8574s sende.
Also verwechsle bei meiner Rechnung: CLK = Takt/(16+(2xTWBRx 4^TWPS)) Wenn TWPS = 0, dann ergibts sich für 4^TWPS = 1.. also vernachlässigbar. nicht PS mit BR... Kannst ja mal umstellen: CLK = TWclk CLK = Takt/(16+(2xTWBR)) CLK * (16+(2xTWBR)) = Takt (16+(2xTWBR)) = Takt/CLK 2xTWBR = (Takt/CLK) - 16 TWBR = (Takt/Clk -16)/2 bei 8Mhz und 100khz : (80/1 - 16)/2 = 32 und 16Mhz und 100khz: (160/1 - 16)/2 = 72 Also stimmt doch alles.. So, was funktioniert jetzt nicht? Der Dave aussem Grab
Es fließen keine Daten wenn ich die (bewiesenermaßen) korekten Werte einprogramiere (TWBR=72 & TWPS=0). Erst wenn ich wesentlich kleiner Werte nehme "läuft" es . Was ich aber nicht verstehe! Denn eine kleineres TWBR ist eine größeres fSCL. Und ich glaube einfach nicht daran, dass ein Busstakt von 1MHz (TWBR=0 & TWBS=0) so gut funktionieren kann! @Dave: Du hast offensichtlich ein anderes Datenblatt als ich. Was ist das?
LOL.. ich arbeite auch die ganze Zeit nur mit dem M32 (von Atmel g) Was meinst du mit "Was ist das?" Ich kapier genau so wenig, warum er das bei dir nicht macht.. bei 8Mhz und Wert 32 klappts bei mir gut. Gib mal deinen Quelltext rüber. dave
Quelltext findest du oben: "TWI2.asm" Was ist das? ...für ein Datenblatt von dem du sprichst? Mir liegt das vom Mega32 Rev. G vor!
Achso.. ja das ganz normale M32, welches ich runtergeladen habe.. Wow.. ich hab A... Also bei mir sind die Routinen unter USING TWI Und das is drin: SCL frequency= CPU Clock frequency 16+2(TWBR)*4^TWPS Ich lade mir jetzt mal schnell das G... aber was da anders sein soll.. dave
Neue Erkenntnisse: Hab mal den Code von Dave nachvollzogen. Der 1. Unterschied ist die Warteschleife. Und der 2. Unterschied ist die völlige Ignoranz des Status-Registers. Ich hab also seinen Code meinem Code angepasst und siehe da: ES GEHT! Aber VIIIIEEEEL langsamer als meine Version. enttaüsch Ich hab dann alle Hebel in bewegung gesetzt und mir doch noch ein Oszi besorgt und die SCL gemessen. Nur Interessehalber die Ergebnisse mit MEINEM Proggi: TWBR SCL rech SCL mess Beschreibung 72 100000 100000 Nichts geht 12 400000 400000 alles Geht, kurz darauf FREEZ 10 444444 434782 2 von 8 PCFs gehen nicht 0 1000000 666666 alles geht (schnell) Zurück zur Sachlichkeit: Bei meinen Messungen hab ich gesehen, dass ein 5V Impuls doppelt so lang ist wie alle anderen. (Der wievielte Impuls das ist hab ich vergessen zu zählen). Bei Daves Prog trat das nicht auf. Ich wäre euch sehr verbunden wenn ihr trotz der recht guten Ergebnisse weiter meinen Code durchdenkt und mir meinen Fehler zeigen könntet. Mit Daves Code ist das Arbeiten (in meinem Fall) viel komplizierter, was ich vermeiden möchte. Danke trotzdem!
Also ich hab auch keinen Plan... die PCF machen ja nach Datasheet nur 100khz mit. Etwas ist da noch komisch: Quarz/Clock -16 = TWBR 16.000.000/666.666 = 24 24 - 16 = 8 Das hieße ja, dass TWBR in Realität 8 ist.. komisch komisch, vielleicht ziehen die PCFs auch einfach den Clock runter. Mein wait kannste auch einfach so ersetzten: wait: in r16,TWCR sbrs r16,TWINT rjmp wait ret Ich hab mir nur nicht die Mühe gemacht, meine Spezifizierung wieder rückgänig zu machen.. Setz das nochmal ein, dann bleibt der delay mit den 256 Takten weg. Hat niemand anders ne Ahnung? dave
Ich hab das 2xTWBR unterschlagen.. dann dürfte 4 rauskommen... Es is halt scho spät.. dave
Ich nehm auch an, dass die PCFs den Takt runterziehen. Die sind eigentlich nur für 100kHz. So richtig rechteckig sah der Takt auch nicht aus (bei 666 kHz) und unter dem Aspekt, dass schon im Datenblatt des Mega32 ein TWBR von >10 gefordert wird, glaube ich dass es reiner Zufall ist, dass das funktioniert. Ich wünsche mir einen ganz normalen I2C-Bus mit 100kHz (auch wenn er viieel langsamer ist) Deine wait-Schleife hatte ich von Anfang an so geändert (Hey, ich bin garnich so blöd wie ich aussehe. Aber ich seh verdammt blöd aus).
Stimmt ;) Unser Dirty-Harry sieht beschissen aus.. wie son Hund... Und du bist dir sicher, dass bei 100khz nichts anderes reingespielt hat? Vielleicht mal PS etwas höher setzten und dann in TWBR 18 reinhaun oder ähnlich. Also mein PCF (nur kurz zum Test-Zweck) hat schön bei 100khz mitgespielt. Isch nisch blicke dave
Juhu! ich habs! Also hier mal ne Fehlerbeschreibung. Mein Prog löst eine START aus. Dann wird gewartet bis die Hardware den START vollzogen hat. Dann wird im Statusregister geguckt, ob der START gelungen ist(TWSR = 0x08). Ist dies nicht der Fall, wird die Error-Funftion aufgerufen. Bei gelungenem START wird dann die Adresse und das Byte gesendet und die ganze Sache mit nem STOP abgeschlossen. Es wird aber diesmal nicht gewartet bis die Hardware mit dem STOP fertig ist!(Wozu auch?) Da in meinen Prog hinternanderweg gesendet wird (rcall Senden ... rcall Senden ...), wird die neue START-Kondition ausgelöst bevor überhaut ein handfestes STOP am Bus anliegt. Dies kommt dann einem REPEATED-START gleich und im Statusregister steht keine 0x08 sondern 0x10 (RESTART gelungen), was natürlich zu unrecht die Error-Funktion aufruft. Ein Aktzeptanz von TWSR=0x08 UND TWSR=0x10 nach dem START löst also mein Problem. Ich bedanke mich bei allen beteiligten!!! Ohne euch würde ich immernoch an meinem TWBR zweifeln und hätte bestimmt schon längst aufgegeben. Ihr seid die Größten! Also Danke nochmal ªpppµpµppppppppppµppª ªªª¿¿ðUsUx2222UZÆÆg@L¿ªªª ªp÷Ô2¾ ¾2/2/222222ZZ2@ ¾2Ô÷pª ¾2 ¿ ¾2/2/222222ZZ2@ ¿ 2¾ ¿Ô¯ ¾2/2/222222ZZ2@ ¯Ô¿ ¿Ô¯ ¾2/2/222222ZZ2@ ¯Ô¿ ¿Ô¾2/2/222222ZZ2@Ô¿ ª¿ ¾ ¾2Yx22222ZZ2@ ¾ ¿ª ¿ªª¿ ¿Ô2Yx2SZUÔL ¿ªª¿ ¿Ô22ZÔL ¾22Z@ ¾22Z@ ¾22Z@ ªªpp222SSggªª ª¾¾¾ÔÔÔÔÔÔÔÔÔððð𶶶ª
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.