Hallo zusammen, ich beschäftige mich gerade mit dem I2C-Bus und finde einfach nicht die Ursache, warum nach der START-BEDINGUNG nicht in die TWI-Interruptservice-Routine ( TWI-ISR ) gesprungen wird. Weder in Echt noch in der ATMEL-STUDIO Simulation. Ein ATmega8 ( Es soll mal ein ATmega8L oder 88 werden, wegen 3,3V Betriebsspannung ) wird mit einem 1,8432Mhz Quarz an 5V betrieben. Die Pullup-Widerstände ( 4k7 ) hängen jedoch schon an 3,3V. Im Programm ist die USART-Geschichte ( Debugroutine ) erstmal raus, auch andere Dinge sind erstmal auskommentiert. Die verschiedenen Dateien erlauben, ein für mich, komfortableres Arbeiten mit dem ATMEL-STUDIO 7, da ich nur die Reiter anklicken muss, um beispielsweise die Unterprogramme zu finden ( UP_Wii_Nunchuk.inc ) Wii_Nunchuk4.asm ist das " Hauptprogram " von dem aus alle weiteren eingebunden werden. Im Unterprogramm ( UP ) _twi_start wird die START-BEDINGUNG erzeugt und auf dem Oszi, sowie im Open Workbench Logic Analyser ist auch zu sehen, das diese tatsächlich erzeugt wird. An PortD5 ist ein Taster, um einmalig eine Aktion auszuführen. ( Ein-Tasterentprellroutine von Peter Danneger alias PeDa ). Im Simulator ist zunächst Continue ( F5 ) zu klicken. Wenn das Pausensymbol erscheint, dieses klicken, danach PIND5 klicken und wieder Continue bis erneut das Pausensymbol erscheint. Jetzt PIND5 wieder klicken ( löschen ) und wieder Continue und warten bis man zum Breakpoint bei rcall _twi_start gelangt. Ab nun mit Step Into ( F11 ) arbeiten. Mit dem Schreiben des Wertes für die START-BEDINGUNG in TWCR, sollte ja bereits das Bit TWINT dort gesetzt werden, was im Simulator allerdings nicht passiert. Somit ist eigentlich auch klar, das die TWI-ISR nicht angesprungen wird. Aber warum ? In der Appnote AN2480 bzw. AVR315 steht : As long as the TWINT Flag is set, the SCL line is held low. This allows the application software to complete its tasks before allowing the TWI transmission to continue. *The TWINT Flag is set:* *• After the TWI has transmitted a START/REPEATED START condition* • After the TWI has transmitted SLA+R/W • After the TWI has transmitted an address byte • After the TWI has lost arbitration • After the TWI has been addressed by own Slave address or general call • After the TWI has received a data byte • After a STOP or REPEATED START has been received while still addressed as a Slave • When a bus error has occurred due to an illegal START or STOP condition Leider weiß ich nicht wie ich ganz simpel das Projekt hier hochladen kann ( Wii_Nunchuk.atsln ) Da bin ich aber gespannt, ob jemand den Fehler findet. Bernd_Stein
:
Bearbeitet durch User
Ohne mich durch die Dateienflut durcharbeiten zu wollen, einfach die Frage: Wo wird TWEN gesetzt?
S. Landolt schrieb: > Frage: Wo wird TWEN gesetzt? > Die Dateienflut sieht schlimmer aus, als sie ist. Im Unterprogramm, dort wo die START-BEDINGUNG erzeugt wird. ( UP_Wii_Nunchuk.inc ) zu finden. Im Simulator sehe ich auch das dieses Bit gesetzt wurde. Ah, du bringst mich auf eine Idee. Sicherlich braucht die Hardware etwas Zeit um sich zu initialisieren oder so. Werde jetzt mal diese TWI-Peripherieeinheit vorher schon mal einschalten bzw. enablen, obwohl ich meine dies schon mal gemacht zu haben, aber in Beispielprogrammen gesehen habe, das dies auch erst geschieht, wenn eine TWI-Aktion erzeugt wird. Erstaunlich sehe gerade, das die OK-LED an ist, das ist schon mal ein sehr gutes Zeichen. Danke, wieder einen Schritt weiter. Leider ist in der Simu immer noch kein Sprung zur TWI-ISR. Es ist auch nicht zu sehen das TWINT in TWCR gesetzt ist, aber das die OK-LED an ist, sagt eigentlich das die TWI-ISR angesprungen wird. Bernd_Stein
:
Bearbeitet durch User
Hi
>ldi a,#twi_start
Wo ist das definiert? Das '#' kenne ich als Bestandteil von
Präprozessor-Direktiven. Wie der Assembler an anderen Stellen darauf
reagiert kann ich nicht sagen.
Bei meinen I2C-Routinen komme ich komplett ohne Interrupt aus.
MfG Spess
> Wo ist das definiert?
In Header_Wii_Nunchuk.h.
Ich kannte diese Verwendung von '#' auch nicht, scheint aber normal zu
sein. Ob es der Lesbarkeit zuträglich ist, sei dahin gestellt bzw. ist
wohl Geschmackssache. Letzteres ist auch, die ersten Schritte mit einer
grundlegenden Funktion über acht Dateien zu verteilen, einen guten Teil
der Befehle auszukommentieren und das dann noch mit dem Simulator zu
testen. Also mir persönlich ist das zu hoch - ich schreibe einen
Zehnzeiler mit Kontroll-LED und probiere es auf dem Steckbrett aus, ganz
simpel; von da aus kann ich dann weitermachen.
Ich habe die Dateien mal grob überflogen und keinen Fehler entdeckt. Ich stimme S.Landolt zu. Auch ich finde, dass die Dateien so zu unübersichtlich. Für das spätere Programm mag es so Ok sein, aber wir sind mit deiner Struktur nicht vertraut. Es ist ziemlich schwierig Fehler zu erkennen, die sich über mehrere Dateien verteilen. Reduziere dein Programm, so dass nur so viele Zeilen drin sind, wie unbedingt nötig, um das Problem vorzuführen. Und alles bitte in einer einzigen Datei. Dann können wir Dir besser helfen. Wahrscheinlich siehst du den Fehler dann sogar schon selbst.
:
Bearbeitet durch User
spess53 schrieb: > Bei meinen I2C-Routinen komme ich komplett ohne Interrupt aus. > Ja, das sehe ich oft, obwohl ATMEL selbst ja unter : " USING THE TWI " schreibt : " The AVR TWI is byte-oriented and interrupt based. " Egal, jeder so wie er will. Habe das Problem jetzt mal etwas einkreisen können. Und zwar hängt es irgendwie mit meiner Debugroutine ( USART-Transmitter ) zusammen. Habe dessen Interrupt durch auskommentieren gesperrt und dadurch geht die OK-LED schon mal an. In der Simu komme ich jedoch nie in die TWI-ISR, was aber sein muss, sonst wird die OK-LED nämlich nicht eingeschaltet. Habe jetzt mal das Program als ein Listing angehangen und hoffe das ihr damit besser klarkommt. Die *m8def.inc* jedoch nicht, damit das Listing nicht unnötig aufgebläht wird. Bernd_Stein
:
Bearbeitet durch User
Das Programm ist immer noch viel zu groß. Reduziere es noch weiter. Es sollte nur noch eine einzige TWI Transaktion drin sein, sonst keine weitere Schnittstelle.
Stefanus F. schrieb: > Das Programm ist immer noch viel zu groß. Reduziere es noch weiter. > OK, habe ich gemacht. Einmal alles in eine Datei ( Main_Test ) + die m8def.inc und einmal ein neues ATMEL-Studio7-Projekt angelegt. Dies als ZIP-File, damit wer es auch mag, meiner Meinung nach komfortabler mit den Reitern gearbeitet werden kann. Bernd_Stein
Mann, Mann ist das nervig. Die OK-LED geht in der Schaltung an, aber in der Simu vom ATMEL-Studio7, wird nicht in die TWI-ISR gesprungen. Aber es ist in der Realität so, sonst würde die OK-LED ja nicht angehen ( Kathode an PortD4 ). In der Simu ist das eigentlich auch richtig, das nicht zur TWI-ISR gesprungen wird, weil das TWINT-Flag ja nicht gesetzt wird ( siehe Screenshot ). Alles was ich jetzt gelesen habe, auch in englisch sagt aber, das nach ausgeführter TWI-Aktion das TWINT-Flag gesetzt wird. Im OLS ( dem Open Source Logic Analyser und auf dem Oszi ) sehe ich auch eindeutig, das die START-BEDINGUNG erzeugt wurde, was ja auch die OK-LED schlußendlich anzeigt. Gut ich weiß - Simulation ist nicht die Realität. Werde jetzt wieder einzelne Sachen einfügen, um genau feststellen zu können wo der Wurm drinn steckt. Es schien ja die Debugroutine ( USRAT-Transmit ) zu sein. Jetzt sehe erstmal zu, wieder die ProgrammLaufAnzeige ( PLA ) zu implementieren. PLA blinkt, OK-LED ist auch an, OLS zeigt die korrekte START-BEDINGUNG. So jetzt noch die Debugroutine oder sollte ich erstmal den aktuellen Programm status hochladen ? Ja, denke das ist besser, sonst wird es für euch wahrscheinlich ein zu großer Happen, wenn ich dann schreibe: " Jetzt ist vorbei mit OK-LED ON ". Bernd_Stein
:
Bearbeitet durch User
Bernd S. schrieb: > So jetzt noch die Debugroutine oder sollte ich erstmal den aktuellen > Programm status hochladen ? > Das ging irgendwie unter bearbeiten nicht, deshalb hier. Bernd_Stein
Da ist immer noch zu viel Code drin. Nimm den Timer und die Tastenentprellung raus. Wie gesagt soll einfach nur eine einzige TWI Transaktion im Code stehen, sonst nichts weiter. Vermutlich nerve ich Dich, aber genau so kreise ich Fehler ein, die sich gut versteckt haben. Immer weiter reduzieren, bis es plötzlich funktioniert oder auf so wenige Zeilen reduziert ist, dass ich sie fast auswendig aufsagen könnte.
Stefanus F. schrieb: > Da ist immer noch zu viel Code drin. Nimm den Timer und die > Tastenentprellung raus. > Die Tasterentprellung verstehste nich, hä ! Das war ein Scherz, aber ist wirklich heftig die zu verstehen. Ist Halt PeDa like genial, aber dafür tricky. Hannes Lux hatte auch immer so trickreiche Programme drauf, aber der kann leider Niemanden mehr direkt helfen. Jetzt versteh ich dich nicht. Das alles funktioniert ja, auch wenn anscheinend die Simu im ATMEL-Studio7 nicht richtig arbeitet. Den Taster brauch ich wirklich nur, um das Programm schrittweise testen zu können, aber hier steckt ja nicht das Problem. Außerdem bleibt der Timer-Overflow später bestehen, da die PLA-Funktion bleibt. Die Ursache steht eindeutig mit der Debug-Routine ( USART-Transmit ) im Zusammenhang, denn nun geht die OK-LED nicht mehr an. Wenn du die Version TWI_Interrupt_2.zip laufen lassen würdest, dann könntest du ebenfalls sehen, das die ( bei mir PD4 ) grüne OK-LED angeht und die ( bei mir PB4 ) rote PLA-LED munter weiterblinkt, wenn der Taster an PD5 betätigt wird. Die PLA-LED blinkt natürlich nach Betätigung des Taster weiter, ist ja eine ProgrammLaufAnzeige ;-). Ich denke euer Problem ist der 1,8432Mhz Quarz, aber mit dem kann ich fast wunderbar die 100kHz im I2C-Bus Normal Mode ( TWI-NM ) erreichen ( entweder 92kHz oder 102kHz )und für die RS232 ( USART ) gängige Baudraten. Hier 38400 Baud. Bernd_Stein
Es geht nicht darum, den Code zu verstehen. Es geht darum, alles was vom Problem ablenkt, zu entfernen, damit man sich auf das Problem konzentrieren kann. Außerdem geht es darum, mögliche Seiteneffekte zu eliminieren, um festzustellen, oder der TWI Code selbst die direkte Problemursache ist, oder nicht. > Das alles funktioniert ja, auch wenn anscheinend die > Simu im ATMEL-Studio7 nicht richtig arbeitet. Im Simulator muss es auch funktionieren. > Wenn du die Version TWI_Interrupt_2.zip laufen lassen würdest Ich habe gar kein Atmel Studio installiert. Mit meinen Beiträgen möchte ich Dir helfen, das Problem einzukreisen und es selbst zu beheben. > Ich denke euer Problem ist der 1,8432Mhz Quarz Was meinst du damit? Ich habe kein Problem mit deinem Quarz. Wenn du willst, kannst du deinen TWI Bus so langsam takten, wie du willst. Die allermeisten TWI Chips haben kein unteres Limit.
Hi Also im 4er Studio steht zum Simulator: >Das alles funktioniert ja, auch wenn >anscheinend die Simu im ATMEL-Studio7 nicht richtig arbeitet. Dann sieh halt mal in den 'Known Issues ' der Simulatorhilfe nach. Beim 4er Studio steht zum Simulator: Unsupported modules Simulation of TWI, USI and analog peripheral is not yet implemented. All instructions, interrupts and other peripherals are supported. See the Simulator Modules for more information MfG Spess
Jetzt mal unter uns, Stefanus - sehen Sie vielleicht in dem zuletzt vorgestellten zip-File irgendwo etwas mit "Debug-Routine ( USART-Transmit )"? Also ich finde nur zwei Versionen eines Hauptprogrammes, in einem davon auskommentierte Befehle, die irgendwie an USART erinnern.
Herr S. Landolt, legen Sie mir bitte nicht Worte in den Mund, die ich nicht geäußert habe. > Da ist immer noch zu viel Code drin. > Nimm den Timer und die Tastenentprellung raus. Da steht nichts mit USART.
:
Bearbeitet durch User
Missverständnis, Stefanus: ich dachte, Sie hätten hineingeschaut und vielleicht mehr gesehen als ich.
Stefanus F. schrieb: > Im Simulator muss es auch funktionieren. > Der Meinung bin ich auch und erst recht nachdem ich nachgeguggt habe was Spess geraten hat. https://www.microchip.com/webdoc/simulator/simulator.section.nft_gud_lc.html > > Was meinst du damit? Ich habe kein Problem mit deinem Quarz. > Na ich dachte, es würde wenigstens jemand mal das Programm ins A-Studio laden und diese bis jetzt ganz einfache Schaltung ( 2xLED, 1xTaster, 2xPullup 4k7, 1x100nF, 2x22pF, 1xQuarz ) auf einem Breadboard nachbauen, so wie ich es getan habe. Solange der Wii Nunchuk nicht dran ist, kann man ja alles mit 5V betreiben, obwohl ich schon gelesen habe, das er das auch überleben soll. Hauptproblem dachte ich, wäre dann der Quarz. Hauptproblem könnte jedoch sein, das kaum jemand sich für AVR8-Assembler interessiert und noch mit der RS232 arbeitet ohne einen USB-Wandler zu nutzten, denn dort ( USART-Transmitter ) liegt ja mein Problem. Im Simu sehe ich, das in die Interrupt-Vektortabelle sehr oft zu dem USART Data Register Empty Interrupt gesprungen wird. Diese Tabelle befindet sich in der IRQm8.inc. Ich hoffe halt darauf, das jemand so wie früher einmal mich... Beitrag "Re: AVR-ASM Knobelei : Bitmanipulation am LCD im 4-Bit Mode" Bernd_Stein
S. Landolt schrieb: > sehen Sie vielleicht in dem zuletzt > vorgestellten zip-File irgendwo etwas mit "Debug-Routine ( > USART-Transmit )"? > Nein, ich wollte erstmal eine Version hier hineinstellen, wo alles noch mit allen benötigten Routinen läuft. Dachte es wäre für euch und mich dann einfacher, sich auf den Programmteil zu konzentrieren, der die Probleme macht. @S. Landolt Verstehen Sie, warum das TWINT-Flag im TWCR nicht gesetzt wird ? Bernd_Stein
In meinem Zehnzeiler auf einem ATmega48PA wird TWINT gesetzt, aber das war eigentlich klar, denn so steht es ja auch im Datenblatt. Aber ich arbeite noch mit einem steinalten AVR-Studio und komme mit dem vorgestellten zip-File nicht zurecht, verstehe jetzt auch nicht, wo konkret das Problem liegt, beim TWINT, beim USART oder beim Simulanten - pardon, beim Simulator.
PS: Konkret: wo in dem 'TWI_Interrupt_2.zip' von 06:37 ist etwas zu "Debug-Routine ( USART-Transmit )" zu finden?
> das in die Interrupt-Vektortabelle sehr oft zu dem > USART Data Register Empty Interrupt gesprungen wird Ein Schuss ins Blaue: Ist dieser Interrupt freigegeben ohne dass etwas gesendet wird, so wird ständig diese ISR aufgerufen, d.h. das Hauptprogramm wird extrem zäh bzw. langsam.
PS: Vor allem: dieser Interrupt liegt vor dem TWI-Interrupt, hat also höhere Priorität und folglich würde Letzterer nie ausgeführt.
S. Landolt schrieb: > In meinem Zehnzeiler auf einem ATmega48PA wird TWINT gesetzt, aber das > war eigentlich klar, denn so steht es ja auch im Datenblatt. > Ich versteh nicht, das du dann nicht einfach diesen 10zeiler hier reinsetzt und ich ihn mal im Simu laufen lassen kann. > ... > PS: > Konkret: wo in dem 'TWI_Interrupt_2.zip' von 06:37 ist etwas zu > "Debug-Routine ( USART-Transmit )" zu finden? > ... Haben uns wahrscheinlich mit dem Schreiben überlappt. Lese : Beitrag "Re: AVR8ASM TWI Interrupt" > ... > Ein Schuss ins Blaue: Ist dieser Interrupt freigegeben ohne dass etwas > gesendet wird, so wird ständig diese ISR aufgerufen, d.h. das > Hauptprogramm wird extrem zäh bzw. langsam. > ... Da könnte was dran sein, werde ich näher untersuchen, da ich mich in vorherigen Versionen schon gewundert habe, das es mal langsam und mal schneller über die RS232 geht bzw. auf die Tasterbetätigung reagiert wird. Bernd_Stein
Bernd S. schrieb: > Im Simu sehe ich, das in die Interrupt-Vektortabelle sehr oft zu dem > USART Data Register Empty Interrupt gesprungen wird. Diese Tabelle > befindet sich in der IRQm8.inc. Da steht aber ein RETI drin. Alle Vektoren, wo Du ein RETI reinschreibst, dürfen niemals angesprungen werden !!! Never ever !!!
> Ich versteh nicht ... mal im Simu laufen lassen kann. Es würde ja nur bestätigt, was im Datenblatt steht. Und bevor ich ein (altes) AVR8-Datenblatt anzweifle, zweifle ich erst einmal ganz massiv am Simulator und danach eine ganze Weile an mir selbst. > Haben uns wahrscheinlich mit dem Schreiben überlappt... Aha - aber wo bzw. auf welcher Grundlage sollen wir nun einen Fehler finden?
> Alle Vektoren, wo Du ein RETI reinschreibst, dürfen niemals > angesprungen werden !!! > Never ever !!! ? Wenn z.B. der Interrupt lediglich dazu dient, den uC aus einem sleep aufzuwecken?
Peter D. schrieb: > Da steht aber ein RETI drin. > Alle Vektoren, wo Du ein RETI reinschreibst, dürfen niemals angesprungen > werden !!! > Never ever !!! > Ich dachte in diesem Fall schon, da in der ISR auch nicht mehr passiert. Bernd S. schrieb: > Ich versteh nicht, das du dann nicht einfach diesen 10zeiler hier > reinsetzt und ich ihn mal im Simu laufen lassen kann. > @S. Landolt Wieso hast du so geschickt versucht, dieser Sache aus dem Weg zu gehen ? S. Landolt schrieb: > Aha - aber wo bzw. auf welcher Grundlage sollen wir nun einen Fehler > finden? > Für alle nicht ATMEL-Studio7 Nutzer hatte ich hier die *Wii_Nunchuk_Komplett.asm* eingestellt. Beitrag "Re: AVR8ASM TWI Interrupt"
:
Bearbeitet durch User
> Für alle nicht ATMEL-Studio7 Nutzer hatte ich hier die > *Wii_Nunchuk_Komplett.asm* eingestellt. Jetzt gebe ich auf - dort ist doch (fast) alles USART-Relevante auskommentiert, bin ich denn blind?
Bernd S. schrieb: > Ich dachte in diesem Fall schon, da in der ISR auch nicht mehr passiert. In diesem Fall gerade nicht. Nur wenige Interrupts löschen ihr Pending-Flag automatisch, dieser nicht.
Auf vielfachen Wunsch (eines Einzelnen):
1 | .include "m48PAdef.inc" |
2 | |
3 | .org $0000 |
4 | rjmp main |
5 | |
6 | .org TWIaddr |
7 | cbi PORTD,2 |
8 | reti |
9 | |
10 | main: |
11 | sbi DDRD,2 ; LED gegen Vcc |
12 | sbi PORTD,2 |
13 | ldi r16,(1<<TWSTA)|(1<<TWEN)|(1<<TWIE) |
14 | sts TWCR,r16 |
15 | sei |
16 | main_loop: |
17 | rjmp main_loop |
Und nein, ich schreibe das nicht für einen ATmega8 um. Aber was fangen Sie jetzt damit an?
Peter D. schrieb: > In diesem Fall gerade nicht. Nur wenige Interrupts löschen ihr > Pending-Flag automatisch, dieser nicht. > Lese mich gerade wieder in die USART-Geschichte ein, mal sehen, ob ich das auch selbst irgendwann in den Unterlagen finde. S. Landolt schrieb: > Und nein, ich schreibe das nicht für einen ATmega8 um. > > Aber was fangen Sie jetzt damit an? > Na, ich beschäftige den ATMEL-Studio7 Simu damit ;-) Tja, auch hier kein Sprung zur TWI-ISR. Also ist für mich bestätigt, das der Simu einen Fehler hat. Danke. Bernd_Stein
:
Bearbeitet durch User
Nur am Rande: ein ATmega8 verlangt ein explizites Setzen des Stackpointers. Was aber erst beim Rücksprung aus der ISR wichtig würde.
... oder vielleicht doch schon beim Einsprung? Was macht der Simulator, wenn die Rücksprungadresse bei 0 abgelegt wird?
S. Landolt schrieb: > Nur am Rande: ein ATmega8 verlangt ein explizites Setzen des > Stackpointers. Was aber erst beim Rücksprung aus der ISR wichtig würde. > Hatte ich ehrlich gesagt gar nicht dran gedacht und dies nachgeholt, da vor dem Sprung zur ISR ja die Rücksprungadresse auf auf den Stack bzw. die SRAM-Adresse $0000 geschrieben wird und somit die ersten Programmzeilen überschrieben werden. Aber das brachte keine Änderung. Wie ich gerade gesehen habe, haben wir uns auf die Minute genau Überlappt ( 14:59 Uhr ). Im Simu wurde trotzdem PD4 richtig behandelt, weil dies ja vor dem Sprung zur ISR passiert bzw. es ja gar nicht zu einem Sprung dorthin kommt. Bernd_Stein
:
Bearbeitet durch User
Bernd S. schrieb: > Peter D. schrieb: >> In diesem Fall gerade nicht. Nur wenige Interrupts löschen ihr >> Pending-Flag automatisch, dieser nicht. >> > Lese mich gerade wieder in die USART-Geschichte ein, mal sehen, ob ich > das auch selbst irgendwann in den Unterlagen finde. > Habs gefunden, muss nur noch genau überlegen, was es bedeutet und vor allem in meinem Programm anrichtet : " The Data Register Empty (UDRE) Flag indicates whether the transmit buffer is ready to receive new data. This bit is set when the transmit buffer is empty, and cleared when the transmit buffer contains data to be transmitted that has not yet been moved into the Shift Register. For compatibility with future devices, always write this bit to zero when writing the UCSRA Register. " Was meinen die jetzt mit " write this bit to zero ... " ? Das übliche, dieses Bit durch "setzen" zu löschen, also beschreiben mit einer Eins oder wirklich dort eine Null hinschreiben ? Bernd_Stein
:
Bearbeitet durch User
UCSRA.UDRE lässt sich nicht explizit löschen, es gibt exakt den Zustand des transmit-buffers an; man kann nur UDR ständig füttern, oder muss eben diesen Interrupt abschalten. So steht es ja auch im Datenblatt, z.B. im Gegensatz zu TXC.
Zur Zeit sieht es so aus : Als Ursache wurde die USART-Transmit-Interrupt-Routine ausgemacht. Diese wird ständig angesprungen, da bei der Initialisierung UCRSA.UDRE gesetzt ist und nur durch beschreiben des UDR gelöscht werden kann. Jetziges Problem ist, das ich icht weiß warum die OK-LED nicht eingeschltet (Kathode an PD4 ) wird, weil der verdammte ATMEL-Studio7 Simulator nicht richtig arbeitet, denn er setzt TWCR.TWINT nicht. In Hterm sehe ich das die Rueckmeldung der TWI-Busschnittstelleneinheit bzw. TWSR bestaetigt, das die START-BEDINGUNG korrekt ausgefuehrt wurde ( $08 ). Dies konnte ich jedoch bereits am Oszi und am OLS ( Logic Analyser ) sehen. Allerdings taucht die Rueckmeldung 2x auf ( $08 ), was ich mir z.Zt. auch nicht erklaeren kann. Mir fehlt also eine Idee, wie ich es schaffen kann, über die RS232 (Debugroutine mittels USART-Transmit-Interrupt ), mir den korrekten Inhalt des TWSR anzeigen zu lassen. Im Anhang das Übliche. Main_Test_3.asm + m8def.inc für die Nicht ATMEL-Studio7 Nutzer, für all die Anderen TWI_Interrupt_3.zip IRQm8.inc ist aus versehen mit dabei. Bernd_Stein
:
Bearbeitet durch User
Ich sehe nicht, wo in Main_Test_3.asm TWINT zurückgesetzt wird. M.E. muss in der TWI-ISR, also irgendwo nach _TWIaddr: etwas in der Art stehen:
1 | in ia,TWCR |
2 | out TWCR,ia |
Peter D. schrieb: > Da steht aber ein RETI drin. So what? Ein einziges reti ist eine völlig legale ISR. Für sehr viele der Interrupts eines AVR8 ist nicht mehr nötig. Nämlich für all die, bei denen das Durchlaufen des Interrupt-Vectors das entsprechende IRQ-Flag automatisch löscht. Natürlich ist in den allermeisten Fällen so ein leere ISR nicht gerade sehr sinnvoll, das ist klar. Aber es kann Ausnahmen geben. Z.B. den Klassiker: die ISR existiert überhaupt nur, um einen Wakeup-Mechanismus zu komplettieren. In diesem Fall ist es völlig legitim, die ISR nur aus einem reti bestehen zu lassen (genauer: dafür sollte man dann sogar besser nur ein ret an selber Stelle verwenden). > Alle Vektoren, wo Du ein RETI reinschreibst, dürfen niemals angesprungen > werden !!! > Never ever !!! Bullshit. Das ist überhaupt kein Problem. Jedenfalls für alle Interrupts, die ihren IRQ automatisch löschen, wenn sie den Vector durchlaufen. Das ist eindeutig die deutliche Mehrheit der auf einem AVR8 verfügbaren Interrupts. Wie immer: man muß einfach nur wissen, was man da eigentlich tut. Primär also: das verschissene Datenblatt lesen, denn da steht sowas natürlich drin...
S. Landolt schrieb: > Ich sehe nicht, wo in Main_Test_3.asm TWINT zurückgesetzt wird. > Oh ha, danke. Muss natürlich gemacht werden. Heute jedoch nicht mehr, meine Konzentrationzeit ist nahe Null. c-hater schrieb: > Wie immer: man muß einfach nur wissen, was man da eigentlich tut. Primär > also: das verschissene Datenblatt lesen, denn da steht sowas natürlich > drin... > Das ist nur der erste Schritt. Und Datenblatt ist um einiges untertrieben ;-). Dabei ist zu hoffen, das dort kein Fehler ist. Das Hauptproblem bei den verschissenen Datenbüchern ist, das richtige Interpretieren bzw. verstehen des Inhalts. Genau wie bei meinem Programm, das du dir sicherlich nicht reingezogen hast, sonst hättest du ja was dazu geschrieben, wie es z.B. Landolt getan hat. Bernd_Stein
Mein Vorschlag mit dem in/out trifft es nicht, gar so einfach ist es nicht - mein Tag war etwas zu lang heute. Klar ist aber, dass die Mehrfachrückmeldung daher kommt, dass der Interruptrequest nie gelöscht wird.
Die TWI Schnittstelle kommt mir persönlich als eine der schwierigsten vor. Vor ein paar Jahren hatte ich mal einen I²C Master mit der USI Schnittstelle implementiert, die ist noch ekliger. Was mich irritiert: Warum wurde dein Interrupt nur zweimal aufgerufen? Da du TWINT nicht zurückgesetzt hast, hätte ich eine endlose Wiederholung erwartet.
Bernd S. schrieb: > Als Ursache wurde die USART-Transmit-Interrupt-Routine ausgemacht. Diese > wird ständig angesprungen, da bei der Initialisierung UCRSA.UDRE gesetzt > ist Warum zum Teufel setzt Du es dann? Als Programmierer sollte man sich defensives Programmieren angewöhnen, d.h. Fehler vermeidendes. Und dazu gehört eben, daß man nur die Interrupts freigibt, für die man auch einen Handler implementiert hat. Solche einfachen Regeln sollen Dir das Programmieren erleichtern und schränken Dich in keinster Weise ein. Klar ist nur RETI möglich, nur ist das nie wirklich nötig. Man kann einen Aufwachinterrupt auch nach dem Sleep disablen, bis dahin wird er ständig ausgeführt mit einem Main-Befehl im Wechsel. Sauberer ist daher, ihn im Handler zu disablen. Die minimale Flash-Einsparung durch den fehlenden Handler ist dagegen unerheblich.
c-hater schrieb: > Bullshit. Gerade für Assemblerprogrammierer sind sinnvolle Regeln überhaupt kein Bullshit. Man hat genug andere Fallstricke und muß sich nicht absichtlich noch weitere basteln. Warum also unnütz 8 CPU-Zyklen vergeuden?
Peter D. schrieb: > Warum zum Teufel setzt Du es dann? > Als Programmierer sollte man sich defensives Programmieren angewöhnen, > d.h. Fehler vermeidendes. Und dazu gehört eben, daß man nur die > Interrupts freigibt, für die man auch einen Handler implementiert hat. > Guten Morgen Peter, wenn ich geahnt hätte, das es mit UCRSA.UDRE solch Probleme geben würde, hätte ich es nicht verwendet. Ich will mit Interrupts arbeiten, dafür sind sie ja da. Ich wusste halt nicht, was ich in der ISR ( damit meinst du wohl den Handler ) hineinschreiben sollte, da... Ich kürz es jetzt mal ab, weil es gibt ja drei USART-Interruptquellen. Die Datenregister Leer-Unterbrechung, ist mir mittlerweile zu kompliziert in meinem Vorhaben umzusetzen und ist daher verworfen worden. Die Empfänger-Unterbrechung benötige ich nicht, da bleibt jetzt noch die Sendeschiebe-Unterbrechung, woran ich gerade arbeite ( UTXCaddr ). Bernd_Stein
Was lernen wir daraus? Bei "komischen" Problemen das Programm schrittweise reduzieren, bis notfalls nur noch die wenigen Zeilen Code übrig sind, die den Fehler auslösen. Dazu gehört auch das Entfernen nicht benutzter Funktionen, Libraries und Includes. Alleine schon die Existenz einer vollkommen unbenutzen Variable kann unter ungünstigen Umständen Fehlfunktionen auslösen.
Stefanus F. schrieb: > Was lernen wir daraus? > > Bei "komischen" Problemen das Programm schrittweise reduzieren, bis > notfalls nur noch die wenigen Zeilen Code übrig sind, die den Fehler > auslösen. > Grundsätzlich gebe ich dir Recht, jedoch in diesem Fall, hatte ich es ja getan, da ich die Debugroutine auskommentiert hatte ( direkt erstes Posting ). Da der Simu jedoch Fehlerhaft ist, hatte ich erstmal einen zweiten Fehler zu erkennen, den ich dann durch den TWI-10zeiler von Landolt dingfest machen konnte. Das UCRSA.UDRE nur durch schreiben in UDR gelöscht werden kann, machte mir jedoch solche Probleme in meiner Programmkonstellation, so dass ich es glücklicherweise verwerfen konnte und die UTXCaddr Interrupt dafür einsetzen kann. Bernd_Stein
Bernd S. schrieb: > Ich will mit Interrupts arbeiten, dafür > sind sie ja da. Nö, Interrupts verwendet man nicht, weil sie da sind, sondern nur, wenn man sie auch braucht. Und dabei gilt, erst den Handler schreiben und dann erst enablen! Enablen ohne Handler ergibt immer Seiteneffekte. Bernd S. schrieb: > Die Empfänger-Unterbrechung benötige ich nicht, da bleibt jetzt noch die > Sendeschiebe-Unterbrechung, woran ich gerade arbeite ( UTXCaddr ). In der Regel ist es genau umgekehrt. Der Empfang ist kritisch, es darf kein Byte verloren gehen, falls das Main mal länger beschäftigt ist. Das Senden ist unkritisch, dann wartet die Gegenstelle eben länger auf das nächste Byte.
> Grundsätzlich gebe ich dir Recht ... > Da der Simu jedoch Fehlerhaft ist Doppelfehler sind immer ätzend.
Peter D. schrieb: > Nö, Interrupts verwendet man nicht, weil sie da sind, sondern nur, wenn > man sie auch braucht. > Braucht man Interrupts ? Ich sehe zu oft, das in der AVR8-Assemblerprogrammierung das Polling benutzt wird. Ich als ASM-Programmierer sehe es als " Pflicht " an, jeden Interrupt zu nutzen, denn durch Polling mache ich ja gerade den hervorstechensten Vorteil der ASM-Programmierung zunichte. Nämlich seine unübertroffene Schnelligkeit bzw. sein schnelles Reagieren. In Bezug auf Sender und Empfänger hast zu sicherlich Recht. Nur in meinem Fall benötige ich lediglich den Sender. Hiermit schicke ich Debuginformationen an ein Terminalprogramm, da ja auf die ATMEL-Studio Simu kein Verlass ist ;-) Was genau sind Seiteneffekte ? Es wird vielfach erwähnt, aber das was ich gefunden habe erklärt jedoch nicht was damit genau gemeint ist. Hast du mal ein AVR8ASM-Codeschnipsel oder Sonstiges, wo man verstehen kann was das genau ist ? Bernd_Stein
Bernd S. schrieb: > Was genau sind Seiteneffekte ? Du hast sie doch gesehen. - nachfolgende Interrupts kommen nicht mehr ran. - Main wird massiv ausgebremst. - Interrupts mit automatischem Löschen, löschen dem Polling das Flag unter der Nase weg. Bernd S. schrieb: > hervorstechensten Vorteil der ASM-Programmierung zunichte. Nämlich seine > unübertroffene Schnelligkeit bzw. sein schnelles Reagieren. Ich habe das noch nie bemerkt, da bei meinen Applikationen die CPU nicht auf 100% ausgelastet ist. Dagegen den Vorteil von C, der erheblich schnelleren Programmerstellung, höheren Übersichtlichkeit, besseren Wartbarkeit, Erweiterbarkeit und geringeren Fehlerrate habe ich sehr deutlich bemerkt. Assembler hatte ich nur deshalb angefangen, da die ersten AT90S1200, ATtiny15 usw. sehr mageren Flash/RAM hatten und mit Hardwarestack auch nicht C-tauglich waren.
Peter D. schrieb: > Assembler hatte ich nur deshalb angefangen, da die ersten AT90S1200, > ATtiny15 usw. sehr mageren Flash/RAM hatten und mit Hardwarestack auch > nicht C-tauglich waren. > Seltsam, dabei hat ATMEL damals damit geworben auf C optimierte Controller entwickelt zu haben. So, zurück zu meinem Programm : Der Stand ist nun, das ich die UDRE-Interrupt Geschichte verworfen habe und statt dessen die USART Trasmit Complette ( UTXCaddr )Interrupt benutze. Die OK-LED ist immer noch nicht an, da sie höchstwahrscheinlich wieder rueck- gesetzt wird, denn es ist eindeutig zu sehen, das der richtige Status zurueck gemeldet wird. ($08 in Hterm ). Seltsam ist das die TWI-Interrupt öfters ausgeführt wird, obwohl die Taster- betaetigung quitiert wird. Bernd_Stein
Eine sinnvolle Motivation, ausgerechnet in Assembler zu programmieren: Man lernt Details des Prozessor direkter kennen, als durch die Abstraktion höherer Sprachen hindurch. Nicht jeder versucht sich an Assembler wegen der Performance.
Stefanus F. schrieb: > Man lernt Details des Prozessor direkter kennen, als durch die > Abstraktion höherer Sprachen hindurch. Man darf auch in C auf IO-Register direkt zugreifen und Interrupts programmieren. Es ist sogar einfacher, da man sich nicht immer wieder mit lästiger Kleinarbeit (push, pop, call, jmp, skip, ld, st, SREG sichern, Register und Variablen verwalten) aufhalten muß. Man kann aber auch eine fertige Lib benutzen.
Wie gestern abend noch nachgeschoben, funktioniert das in/out TWICR nicht, daran ändert auch Ihr dazwischengeschobenes 'ori ia,1<<TWINT' nichts, denn TWINT ist an dieser Stelle bereits gesetzt, sonst wäre die TWI-ISR nicht angesprungen worden. Mit dem Löschen von TWINT wird direkt die nächste Aktion ausgelöst ("Also note that clearing this flag starts the operation of the TWI"), und da TWSTA noch immer gesetzt ist, wird also wohl ein Restart ausgelöst, ad infinitum; lassen Sie mal in der TWI-ISR auch ein #rm_twi_restart (= $10) als gültig zu und schauen Sie, was passiert - ganz sicher bin ich mir nicht, bin kein I2C-Spezialist.
PS: Besser wäre es, während der Testphase sämtliche TWSR-Status-Codes ,"Rueckmeldungen" in Ihrer Nomenklatur, auf Hterm auszugeben (dabei dafür sorgen, dass die USART nicht 'überrollt' wird). Man sieht so schneller, was schief läuft.
S. Landolt schrieb: > (dabei > dafür sorgen, dass die USART nicht 'überrollt' wird). Das braucht man nicht, da I2C-Master nicht zeitkritisch ist. Es ist sogar besser, wenn die UART per Polling sendet, dann kann man die Ausgaben direkt im Interrupt machen.
Jetzt könnte Moby endlich beweisen was für ein ASM-Crack er ist! Aber stattdessen nicht mal ein Sabotagekommentar!
> Jetzt könnte Moby endlich beweisen was für ein ASM-Crack er ist!
Wo siehst du denn hier einen Beitrag von Moby?
S. Landolt schrieb: > Mit dem Löschen von TWINT wird direkt die nächste Aktion ausgelöst So ist es. Man muß erst die nächste Aktion vorbereiten und als letztes das TWINT setzen, um es zu löschen. In C habe ich dazu das TWCR in eine temp-Variable geschrieben, darin alle Aktionen gemacht und dann die Variable nach TWCR zurück geschrieben.
Stefanus F. schrieb: > Jetzt könnte Moby endlich beweisen was für ein ASM-Crack er ist! > > Wo siehst du denn hier einen Beitrag von Moby? Davon habe ich nichts geschrieben!
an Bernd Stein: Ihr derzeitiges Programm auf seine TWI-Grundstruktur eingedampft (nein, zehn Zeilen haben mir diesmal nicht gereicht), bringt bei mir die TWI-Status-Code-Folge (an SDA und SCL hängen nur die Pull-ups): $08 $48 $10 $48 $10 $48 $10 $48 ... also $08: A START condition has been transmitted $48: SLA+R has been transmitted; NOT ACK has been received $10: A repeated START condition has been transmitted $48: SLA+R has been transmitted; NOT ACK has been received ... ff Ist ja schön, dass ich etwas TWI lerne, aber eigentlich sollte ab jetzt jemand weiterhelfen, der etwas davon versteht - m.a.W., ich verabschiede mich ins Wochenende mit den besten Wünschen
Ist doch alles richtig. Solange kein I²C Slave antwortet, empfängt der µC kein ACK Signal.
Schon, aber zur Zeit lässt er nur $08 als gültig zu, folglich "Die OK-LED ist immer noch nicht an" und "die TWI-Interrupt öfters ausgeführt wird". Übrigens, Stefanus, dass Sie den einen Beitrag von mir zu Anfang derart in den falschen Hals bekamen, tut mir ausgesprochen leid; ich suchte nur Rat bei Ihnen, da ich Schwierigkeiten hatte, den Autor und seine Programmsammlung zu verstehen.
> Übrigens, Stefanus, dass Sie den einen Beitrag von > mir zu Anfang derart in den falschen Hals bekamen Hä? Ich habe Dir doch zugestimmt.
S. Landolt schrieb: > Ihr derzeitiges Programm auf seine TWI-Grundstruktur eingedampft (nein, > zehn Zeilen haben mir diesmal nicht gereicht), bringt bei mir die > TWI-Status-Code-Folge (an SDA und SCL hängen nur die Pull-ups): > > $08 $48 $10 $48 $10 $48 $10 $48 ... > also > $08: A START condition has been transmitted > $48: SLA+R has been transmitted; NOT ACK has been received > $10: A repeated START condition has been transmitted > $48: SLA+R has been transmitted; NOT ACK has been received > ... ff > Dies war sehr aufschlussreich, Danke. Somit hat meine Debugroutine natürlich ihren Sinn nicht richtig erfüllen können, da sie falsch plaziert wurde. Nachdem ich sie wie nachfolgend zu sehen, anders wo eingesetzt habe, konnte ich ebenfalls sehen, was "wirklich" passiert. Wirklich deshalb, weil ich sehe, das dies nicht so eine regelmäßige Sache ist, wie du beschreibst. Gut, dein Programm ist nicht mein Programm, deshalb kann es natürlich diese Regemäßigkeit bei dir geben. Wäre mal wieder schön, auf Grunde eines einzelnen, dein Programm sehen zu können ;-)
1 | _TWIaddr: |
2 | in s_sreg,SREG ;CPU-Statusregister sichern |
3 | |
4 | in ia,TWSR ;TWI-Statusregister lesen |
5 | andi ia,$F8 ;Nichtrelevante Bits ausmaskieren |
6 | |
7 | ;in ia,TWSR ;TWI Status Register lesen... |
8 | ;mov udr_char,ia ;...und an USART ( RS232 ) uebergeben... |
9 | out UDR,ia ;Zu sendenes Zeichen in UDR hineinschreiben |
10 | |
11 | cpi ia,#rm_twi_start ;Wurde die Startbedingung gesendet?... |
12 | brne _twi_error ;Nein => Fehlerbehandlung noetig |
13 | |
14 | cbi LED_PORT,led.ok ;...OK-LED einschalten |
15 | |
16 | rjmp _exit_twiaddr ;Interrupt Service Routine ( ISR ) verlassen |
17 | |
18 | _twi_error: |
19 | ;sbi LED_PORT,led.ok ;OK-LED ausschalten |
20 | |
21 | _exit_twiaddr: |
22 | cbr key_reg,1<<key.actuated;Tasterbetaetigung quitieren |
23 | |
24 | in ia,TWCR ;TWI-Kontroll Register lesen... |
25 | ori ia,1<<TWINT ;...und dort das TWI-Interrupt-Flag durch... |
26 | out TWCR,ia ;...beschreiben mit einer 1 loeschen. |
27 | |
28 | out SREG,s_sreg ;CPU-Statusregister wiederherstellen; |
29 | |
30 | reti ;Ruecksprung aus der Interrupt Service Routine |
>Stefanus F. schrieb: > Ist doch alles richtig. Solange kein I²C Slave antwortet, empfängt der > µC kein ACK Signal. > Nein, denn dann dürfte nicht einfach munter drauf weitergesendet werden. In dem Buch " I2C-Bus angewandt ", Kapitel Bytelevel der Datenübertragung, steht : "Kein Sender darf weitersenden, wenn er als Acknowledge-Bit eine 1 empfangen hat ( wird auch NACK = Not ACKnowledge bezeichnet )." Ob ATMEL das jetzt genau so implementiert hat,ist natürlich fraglich. S. Landolt schrieb: > Schon, aber zur Zeit lässt er nur $08 als gültig zu, folglich > "Die OK-LED ist immer noch nicht an" > und > "die TWI-Interrupt öfters ausgeführt wird". > Tja, daran habe ich noch zu knacken, da ich gar nicht weiß, warum gerade immer $FF gesendet wird. Blöderweise kann im Simu TWAR oder TWDR oder beide ( ich weiß es nicht mehr ) nicht geändert werden, obwohl sie R/W-Register sind. Auch wenn ich im Programm beiden ein General Call zuweise ( $00 ), wird munter immer $FF gesendet. Bernd_Stein
:
Bearbeitet durch User
Bernd S. schrieb: > "Kein Sender darf weitersenden, wenn er als Acknowledge-Bit eine 1 > empfangen hat ( wird auch NACK = Not ACKnowledge bezeichnet )." > > Ob ATMEL das jetzt genau so implementiert hat,ist natürlich fraglich. Nein, dein Verständnis der ganzen Sache ist fraglich. ACK oder NACK wird nachher in Software ausgewertet, damit hat ATMEL bzw. der verwendete uC nichts mehr zu tun. P.S. Eine 1 bedeutet auch das keine Devices sich an dieser Adrese am Bus befinden. Deswegen darf man mit neuer Adresse weiter versuchen. Bernd S. schrieb: >>Stefanus F. schrieb: >> Ist doch alles richtig. Solange kein I²C Slave antwortet, empfängt der >> µC kein ACK Signal. Insofern ist das richtig, unter anderem wird so auch festgestellt welche Adressen belegt sind.
:
Bearbeitet durch User
Marc V. schrieb: > ACK oder NACK wird nachher in Software ausgewertet, damit hat > ATMEL bzw. der verwendete uC nichts mehr zu tun. Das wird sehr wohl vom I2C-Controller ausgewertet. Nach einem NACK sind die einzigen erlaubten Aktion STOP oder repeat START. Alle anderen Aktionen sind undefiniert. Senden eines weiteren Datenbytes ist nicht erlaubt und wird vermutlich ein NOP bewirken.
Peter D. schrieb: > Marc V. schrieb: >> ACK oder NACK wird nachher in Software ausgewertet, damit hat >> ATMEL bzw. der verwendete uC nichts mehr zu tun. > > Das wird sehr wohl vom I2C-Controller ausgewertet. Nach einem NACK sind > die einzigen erlaubten Aktion STOP oder repeat START. Alle anderen > Aktionen sind undefiniert. Senden eines weiteren Datenbytes ist nicht > erlaubt und wird vermutlich ein NOP bewirken. LOL. Das stimmt bestimmt nicht.
Bernd S. schrieb: > "Kein Sender darf weitersenden, wenn er als Acknowledge-Bit eine 1 > empfangen hat ( wird auch NACK = Not ACKnowledge bezeichnet )." > > Ob ATMEL das jetzt genau so implementiert hat,ist natürlich fraglich. Nein, das ist kein bissel "fraglich". Die Atmel-TWI-Engine ist nämlich dafür schlicht nicht zuständig. Das ist allein die Entscheidung des Benutzers der TWI-Engine, also deiner Wenigkeit. Machst du es einfach nur richtig, wirst du auch diese Restriktion locker einhalten können... Mein Gott, I2C ist doch nicht so kompliziert. Wenn man das Protokoll wirklich verstanden hat, erschließt sich die Logik der Implementierung der AVR8-Hardware praktisch von selbst. @peda Es gibt auch kein generelles Problem bei der TWI-Hardware bezüglich des Multimaster-Modus, wie du behaupted hast (aber ja: es gab da ein Problem bei einigen wenigen Revisionen einiger weniger AVR8, heute aber nur noch von historischem Interesse...). Für den riesengroßen Rest gilt: Man muss es einfach nur korrekt umsetzen. Und ja, das geht auch problemlos in pure C, denn es gibt da keinerlei timing constraints, auf die man sich herausreden könnte! Man muss einfach nur das Protokoll verstanden haben und die Hardware. Und ja: es steht alles dazu nötige im DB. Wirklich! Man muss nur selber denken können, um auch das dem DB zu entnehmen, was nicht explizit da steht. Sprich: man braucht nicht mehr als ein gedankliches Modell, wie diese Hardware funktioniert und den festen Glauben, das Atmel gewollt hat, dass sie auch im Multimaster-Modus funktioniert, da dieser als Feature angepriesen wird... Und das tut sie tatsächlich, wenn man sie korrekt benutzt...
Marc V. schrieb: > Nein, dein Verständnis der ganzen Sache ist fraglich. > > ACK oder NACK wird nachher in Software ausgewertet, damit hat > ATMEL bzw. der verwendete uC nichts mehr zu tun. > > P.S. > Eine 1 bedeutet auch das keine Devices sich an dieser Adrese am Bus > befinden. Deswegen darf man mit neuer Adresse weiter versuchen. > Hallo Marc V., du konntest mir früher schon mal helfen, ich sezte auf dich ;-) Beitrag "Re: AVR8ASM TWI Interrupt" Mein Verständis ist mehr als fraglich, denn ich verstehe überhaupt nicht warum weiterhin $FF gesendet wird, wenn ich doch in der Initialisierung einen General Call in das TWDR und TWAR schreibe. Das dauernde Senden ( zumindest auf dem Bus ) konnte ich wieder mal durch verschieben dreier Codezeilen in der TWI-ISR ( _TWIaddr: ), welche das TWINT löschen, unterbinden. Bleibt also noch das Rätsel zu lösen, warum $FF gesendet wird und weiterhin die RS232 mit $48 zugeballert wird, obwohl das TWINT ja dann nicht mehr gelöscht wird. Warum wird dann dennoch weiterhin zu _TWIaddr: gesprugen ?
1 | _TWIaddr: |
2 | in s_sreg,SREG ;CPU-Statusregister sichern |
3 | |
4 | in ia,TWSR ;TWI-Statusregister lesen |
5 | andi ia,$F8 ;Nichtrelevante Bits ausmaskieren |
6 | |
7 | ;in ia,TWSR ;TWI Status Register lesen... |
8 | ;mov udr_char,ia ;...und an USART ( RS232 ) uebergeben... |
9 | out UDR,ia ;Zu sendenes Zeichen in UDR hineinschreiben |
10 | |
11 | cpi ia,#rm_twi_start ;Wurde die Startbedingung gesendet?... |
12 | brne _twi_error ;Nein => Fehlerbehandlung noetig |
13 | |
14 | cbi LED_PORT,led.ok ;...OK-LED einschalten |
15 | |
16 | in ia,TWCR ;TWI-Kontroll Register lesen... |
17 | ori ia,1<<TWINT ;...und dort das TWI-Interrupt-Flag durch... |
18 | out TWCR,ia ;...beschreiben mit einer 1 loeschen. |
19 | |
20 | rjmp _exit_twiaddr ;Interrupt Service Routine ( ISR ) verlassen |
21 | |
22 | _twi_error: |
23 | ;sbi LED_PORT,led.ok ;OK-LED ausschalten |
24 | |
25 | _exit_twiaddr: |
26 | cbr key_reg,1<<key.actuated;Tasterbetaetigung quitieren |
27 | |
28 | out SREG,s_sreg ;CPU-Statusregister wiederherstellen; |
29 | |
30 | reti ;Ruecksprung aus der Interrupt Service Routine |
Bernd_Stein
c-hater schrieb: > Man muss einfach nur das Protokoll verstanden haben und die Hardware. > Und ja: es steht alles dazu nötige im DB. Wirklich! Man muss nur selber > denken können, um auch das dem DB zu entnehmen, was nicht explizit da > steht. > Gut, dann werde ich ja von dir hier nichts mehr lesen, da ich es ja ohne deine Hilfe werde lösen können. Danke für diese hilfreiche Information, das dieses Forum hier absolut unnötig ist, wenn man das Datenbuch besitzt. Falls man dies besitzt und doch nicht zu Rande kommt, kann einem eh keiner helfen, denn das Problem kann man deiner Ansicht nach ja eh nur alleine lösen, wenn man klug genug ist. Nun, das bin ich nicht. Also erspare dir und vor allem mir meine kostbare Zeit unsere beider Beiträge zu lesen. Bernd_Stein
Peter D. schrieb: > Das wird sehr wohl vom I2C-Controller ausgewertet. Nach einem NACK sind > die einzigen erlaubten Aktion STOP oder repeat START. Alle anderen > Aktionen sind undefiniert. Senden eines weiteren Datenbytes ist nicht > erlaubt und wird vermutlich ein NOP bewirken. Nein. Siehe beiliegende Screenshots.
Bernd S. schrieb: > Warum wird dann dennoch weiterhin zu _TWIaddr: gesprugen ? Weiss ich nicht, werde später durch deinen Code durchgehen, aber das:
1 | ;***** Warum wird dies am Anfang gemacht ??? ***** |
2 | out UDR,ia ;Zu sendenes Zeichen in UDR hineinschreiben |
3 | ;***** Warum wird dies am Anfang gemacht ??? ***** |
4 | |
5 | cpi ia,#rm_twi_start ;Wurde die Startbedingung gesendet?... |
6 | |
7 | ;***** Wenn ia <> #rm_twi_start wird TWINT niemals gelöscht !!! *** |
8 | brne _twi_error ;Nein => Fehlerbehandlung noetig |
9 | ;***** Wenn ia <> #rm_twi_start wird TWINT niemals gelöscht !!! *** |
10 | ;***** Wenn TWINT nicht gelöscht wird, passiert WAS ? **** |
11 | ;***** GENAU - das, was dir passiert... ***** |
12 | |
13 | cbi LED_PORT,led.ok ;...OK-LED einschalten |
14 | in ia,TWCR ;TWI-Kontroll Register lesen... |
15 | ori ia,1<<TWINT ;...und dort das TWI-Interrupt-Flag durch... |
16 | out TWCR,ia ;...beschreiben mit einer 1 loeschen. |
17 | |
18 | rjmp _exit_twiaddr ;Interrupt Service Routine ( ISR ) verlassen |
19 | |
20 | _twi_error: |
:
Bearbeitet durch User
Bernd S. schrieb: > Gut, dann werde ich ja von dir hier nichts mehr lesen, da ich es ja ohne > deine Hilfe werde lösen können. Das könntest du tatsächlich... > Danke für diese hilfreiche Information, das dieses Forum hier absolut > unnötig ist, wenn man das Datenbuch besitzt. Nein, das ist es nicht. Auch Datenblätter können Fehler enthalten (dann ist es normal, Rat zu suchen) und sie können auch Sachverhalte nicht immer erschöpfend darstellen. Gerade wenn es um Protokolle geht. Da erwartet der Verfasser des DB nämlich schlicht Eigenleistung des Benutzers. Und das mit völligem Recht (dann ist es nicht normal, Rat zu suchen)! > Falls man dies besitzt und > doch nicht zu Rande kommt, kann einem eh keiner helfen, denn das > Problem > kann man deiner Ansicht nach ja eh nur alleine lösen, wenn man klug > genug ist. Jepp, wenn das DB und die zugehörige HW fehlerfrei ist, ist das tatsächlich so. Das mag dir nicht gefallen, ist aber nach den allgewaltigen Gesetzen der formalen Logik wirklich einfach so... Sprich: Meine Empfehlung für dich ist: lerne I2C (und zwar: bevor du es das erste Mal tatsächlich benutzt). Hättest du das getan, gäbe es diesen ganzen Thread mit an Sicherheit grenzender Wahrscheinlichkeit einfach nicht... Auch das eine Tatsache, die dir nicht schmecken wird, die aber nichtsdestotrotz unbeweifelbar WAHR ist...
c-hater schrieb: > (aber ja: es gab da ein Problem > bei einigen wenigen Revisionen einiger weniger AVR8, heute aber nur noch > von historischem Interesse...) Konkret war es der Atmega8, also nichts historisches. Die nötigen Würgarounds waren ziemlich heftig. Manueller Test, ob Bus frei ist, Überwachung des STOP, Überwachung ob SDA auf low klemmt, Timeout, Disable und Retry. Später gab es dann den ATmega88, aber da hab ich nicht nochmal Zeit gehabt, es zu testen. Wenn erstmal eine Firmware freigegeben ist, dann muß es schon einen triftigen Grund geben, neu zu programmieren und ne neue Revision in die Produktion zu geben. Nur der Verdacht, daß der ATmega88 den Bug nicht mehr haben könnte, reicht da nicht. Der Report von David Cook hat mir sehr geholfen: https://www.robotroom.com/Atmel-AVR-TWI-I2C-Multi-Master-Problem.html
c-hater schrieb: > Es gibt auch kein generelles Problem bei der TWI-Hardware bezüglich des > Multimaster-Modus, wie du behaupted hast David hat den ATMega168 and ATMega644 benutzt, ich den ATMega8, also ist das Problem sehr wohl generell.
:
Bearbeitet durch User
Marc V. schrieb: > Nein. > Siehe beiliegende Screenshots. Die zeigen exakt das, was ich gesagt habe. Auf Status 0x20, 0x30 darf nur ein STOP oder repeat START erfolgen. "can" hat in Datenblättern übersetzt eher die Bedeutung "darf". Was nicht im Datenblatt steht, hat implizit die Bedeutung "darf nicht". Es besteht also keine Freiheit, nicht im Datenblatt aufgeführte Sachen zu machen. Prinzipiell dürfte der Chip dabei sogar Schaden nehmen, ohne das Du den Chip reklamieren könntest. P.S.: Nehme alles zurück, es darf gesendet werden, warum auch immer. Aber kein Slave wird darauf reagieren, weil ja alle NACK gesendet haben.
:
Bearbeitet durch User
Peter D. schrieb: > c-hater schrieb: >> Es gibt auch kein generelles Problem bei der TWI-Hardware bezüglich des >> Multimaster-Modus, wie du behaupted hast > > David hat den ATMega168 and ATMega644 benutzt, ich den ATMega8, also ist > das Problem sehr wohl generell. Nun, ich sehe das nicht als Problem an. Multimaster-Modus bei TWI ist eher die Ausnahme, nicht die Regel, also sollte man auch entsprechende Security-checks einbauen. Es sollte selbstverständlich sein, dass man bei Multimaster-Modus nicht sofort loslegt, sondern einige Zeit vorher den Bus auf Idle prüft. Tut man nicht so, ist man selber schuld und nicht ATMEL - warum sollte die TWI-Hardware darauf achten ? Ist TWI-Bus frei ? Falls Nein, warte auf STOP oder Idle > 500us. Falls Ja, warte auf Idle > 500us sende los und nicht erst eine Tabelle mit 1000 Zuständen vorher analysieren. Wohlgemerkt, nur bei Multimaster-Modus...
:
Bearbeitet durch User
Peter D. schrieb: > P.S.: > Nehme alles zurück, es darf gesendet werden, warum auch immer. Sage ich doch. > Aber kein Slave wird darauf reagieren, weil ja alle NACK gesendet haben. Das wiederum ist nicht gesagt - wenn 2 uC miteinander komunizieren, kann das vielleicht anders vereinbart sein...
:
Bearbeitet durch User
Marc V. schrieb: > Es sollte selbstverständlich sein, dass man bei Multimaster-Modus nicht > sofort loslegt, sondern einige Zeit vorher den Bus auf Idle prüft. > Tut man nicht so, ist man selber schuld und nicht ATMEL - warum sollte > die TWI-Hardware darauf achten ? Nö, beim originalen Philips/NXP P80C552, P89C668 funktioniert es einwandfrei. Die halten die vorgeschriebene Pause von 4,7µs ein. Es ist explizit erlaubt STA und STO gleichzeitig zu setzen. Nur bei Atmel kracht es (AVR und 8051). Den Ärger mit Atmel hatte ich auch nur deswegen, weil der P89C668 abgekündigt wurde. Die Atmel warten zwar auch nach ihrem STOP die 4,7µs, aber wenn sie die Arbitration verlieren, warten sie nicht nochmal die 4,7µs. Sie senden ihr START dann 0µs nach dem STOP des anderen Masters.
:
Bearbeitet durch User
Peter D. schrieb: > Nö, beim originalen Philips/NXP P80C552, P89C668 funktioniert es > einwandfrei. Die halten die vorgeschriebenen Pause von 4,7µs ein. Es ist Ich halte es eher für ein Bonus - ist zwar schön, aber ich würde es bei Multimaster schon selber abwarten - bei I2C ist Geschwindigkeit bestimmt nicht der Grund zum Anwenden. Und wie gesagt, Multimaster bei I2C ist (für mich) eher die Ausnahme.
Marc V. schrieb: > Multimaster bei I2C ist (für mich) eher die Ausnahme. Ist schon recht praktisch, wenn jedes Modul antworten kann, sobald es bereit ist. Nach diesem Ärger mit den non-Philips I2C-µCs bin ich jetzt aber auf CAN umgestiegen. Das ist sogar einfacher zu programmieren.
Peter D. schrieb: > Nach diesem Ärger mit den non-Philips I2C-µCs bin ich jetzt aber auf CAN > umgestiegen. Das ist sogar einfacher zu programmieren. Genau. Ich bin auch umgestiegen, aber bei AVRs nur auf Hardware-Ebene - kein Bit Stuffing und ähnliches. Bei STM ist CAN eine ganz andere Geschichte, da ist alles nach Vorschrift aufgebaut und funktioniert absolut ohne Probleme.
Marc V. schrieb: > Bernd S. schrieb: >> Hier der aktuelle KOT ;-) > > Was ist jetzt, geht es ? > Natürlich nicht. Darauf hin habe ich mal das Löschen des TWCR.TWINT rausgenommen und somit wird SCL low natürlich "gestretched", also verlängert. Dies erwarte ich aber direkt nach der START-BEDINGUNG, da unter " Using the TWI " unter Punkt 1. steht : 1. Der erste Schritt bei einer TWI Übertragung ist das Senden einer START-BEDINGUNG. Dies wird gemacht, indem ein spezieller Wert in das TWCR geschrieben wird, der die TWI Hardware veanlasst, eine START-BEDINGUNG zu senden. Welcher Wert genommen werden muss, wird später beschrieben. *Wichtig ist, dass das TWINT Bit mit dem Schreiben des Wertes gesetzt wird.* Das Schreiben einer 1 in dass TWINT löscht dieses Flag. *Das TWI startet keine Operation, solange das TWINT im TWCR gesetzt ist.* Unmittelbar nachdem die Apllikation das TWINT gelöscht hat , wird das TWI mit dem Aussenden der START-BEDINGUNG beginnen. Die Übersetzung ist nicht von mir, ich denke jedoch, das diese Sinngemäß richtig ist, denn es ist eine Ausarbeitung der TU-Chemnitz. Das heißt für mich, da ich TWCR.TWINT nach der START-BEDINGUNG nicht mehr lösche, das die TWI Hardware keine neue Aktion ausführt. Warum wird dann verdammt noch mal dieses für mich unerklärliche $FF gesendet ? Ab dem 2ten Byte ist in Hterm TWCR zu sehen. $2D bedeutet das TWINT gelöscht ist !!!. Dafür kommt jedoch TWWC hinzu, was Write Collision bedeutet. Bit3 - TWWC: TWI Write Collision Flag Diese Bit wird gesetzt, wenn versucht wird in das TWI DATA Register (TWDR) zu schreiben, während das TWINT Flag Low ist. Das TWWC Flag wird gelöscht, wenn in das TWDR geschrieben wird, während TWINT High ist. Das es gesetzt wird ist klar, da ich TWDR & TWAR zu beginn lösche, weil ich sehen wollte, ob dieses gesendete $FF aus einem der beiden Register stammt, was bei TWDR passen könnte, weil es mit $FF intialsiert wird. Vermutlich ist es auch so und dieses TWCR.TWWC verhindert evtl. das mein Versuch TWDR zu ändern akzeptiert wird. Das 3te Byte und alle folgenden ($AD) zeigen jedoch, das TWCR.TWINT gesetzt ist. Warum verdammt noch mal ? In _TWIaddr: verhindere ich ja durch löschen des *key_reg.key_actuated* ,das erneut etwas in TWCR geschrieben werden kann und somit keine neue TWI Aktion ausgeführt wird und trotzdem wird TWCR.TWINT gesetzt. Was mache ich falsch bzw. verstehe ich aus dem Datenbuch ( DB ) falsch ? Bernd_Stein
Nachdem der Chip sich ja offenbar nicht konform zum DB verhält, bin ich einer Sache nachgegangen, die ich beim L-Typ ausgeschlossen, aber zum Glück noch im Hinterkopf hatte. Der Spuk hat hiermit ein Ende. Spess wird sicherlich ein Licht aufgehen. Kann man an den Beschriftungen des µC erkennen, welches DB bzw. DB-Revision hierfür zuständig ist ? Was kann man überhaupt aus den Beschriftungen erkennen im speziellen die auf der Rückseite ? Bitte nicht das es ein µC von ATMEL ist => Der ATmega8L ;-) Ich verlange schon mehr :-) Bernd_Stein
"1251" ist relevant bzgl Herstellungsdatum. Ansonsten ist die Beschriftung im ("complete") Datenblatt erklärt.
Hi >Nachdem der Chip sich ja offenbar nicht konform zum DB verhält, bin ich >einer Sache nachgegangen, die ich beim L-Typ ausgeschlossen, aber zum >Glück noch im Hinterkopf hatte. Nur gut, das du der erste auf der Welt bist, der das nach 18 Jahren festgestellt hat. Oder finde nur ich das merkwürdig? MfG Spess
STK500-Besitzer schrieb: > "1251" ist relevant bzgl Herstellungsdatum. > Ansonsten ist die Beschriftung im ("complete") Datenblatt erklärt. > Schön, dann zeig mir bitte den Link zu dem Datenbuch das passend zu dem Typ auf meinen Fotos ist. spess53 schrieb: > Nur gut, das du der erste auf der Welt bist, der das nach 18 Jahren > festgestellt hat. > > Oder finde nur ich das merkwürdig? > Es wird um sachdienliche Hinweise gebeten, um diese Datenleiche finden zu können. Aktenzeichen XY ;-) Bernd_Stein
:
Bearbeitet durch User
Lieber Bernd Stein, ohne Umschweife gerade heraus: Sie sind mit dieser Aufgabe überfordert. Es ist nicht nur mangelndes Datenblattstudium, wie c-hater schreibt, es ist mangelndes Verständnis, es fehlt an strukturiertem Vorgehen, es fehlt an Sorgfalt beim Lesen der Beiträge hier. Das muss man akzeptieren, oder um ein aktuelles Beispiel zu geben: nicht jeder kann zweiMeterfünfunddreißig überspringen. Eigentlich geht es mich ja nichts an, aber nachdem ich nun mal am Anfang dabei war, mögen Sie mir bitte dieses offene Wort nachsehen. Vielleicht kommen Sie sogar irgendwann zu einer Lösung, aber Ihre Frustrationsschwelle müsste schon ungewöhnlich hoch sein, um auf dem Weg dahin nicht jede Lust an der Sache zu verlieren, und das wäre doch schade.
S. Landolt schrieb: > Eigentlich geht es mich ja nichts an, aber nachdem ich nun mal am > Anfang dabei war, mögen Sie mir bitte dieses offene Wort nachsehen. > Vielleicht kommen Sie sogar irgendwann zu einer Lösung, aber Ihre > Frustrationsschwelle müsste schon ungewöhnlich hoch sein, um auf dem Weg > dahin nicht jede Lust an der Sache zu verlieren, und das wäre doch > schade. > Nein, ich nehme es dir nicht übel, da du eigentlich auch schon aufgeben wolltest und dennoch dabei geblieben bist. Wie ich schrieb, habe ich den Fehler gefunden, warum nach der START-BEDINGUNG noch $FF gesendet wurde, obwohl dies nicht sein dürfte. Ich dachte Spees würde dies hier wieder einfallen, denn genau das war der Fehler. Bei TWBR = 11, habe ich es optimistischerweise gelassen und nun ist alles gut. Werde mich wieder melden, wenn ich nicht alleine weiterkomme. Möchte jetzt nur noch nebenbei wissen, ob im DB zum Fotografiertem µC dieser Umstand beschrieben steht. Beitrag "Re: I2C/TWI TWBR > 10 warum?" Bernd_Stein
Dazu kann ich nichts sagen, ich finde im mir vorliegenden Datenblatt diese Sequenz nicht, lediglich im Abschnitt 'Datasheet Revision History' den ominösen Satz "... and using the TWI as Master with low TWBRR values are added into the datasheet." Allerdings gebe ich zu bedenken, dass gerade bei Interruptstrukturen längere Sendezeiten ganz unerwartete Folgen haben können, auch das Verschwinden von Fehlern.
S. Landolt schrieb: > Dazu kann ich nichts sagen, ich finde im mir vorliegenden Datenblatt > diese Sequenz nicht, lediglich im Abschnitt 'Datasheet Revision History' > den ominösen Satz "... and using the TWI as Master with low TWBRR values > are added into the datasheet." > Hätte es beinahe nicht gefunden, da das FireFox-Suchfenster bei so vielen Buchstaben, so tut, als ob der Text nicht vorhanden wäre. Hab jetzt mal unter dem wahrscheinlich ältesten DB geguckt ( 2486B-12/01 Preliminary ) finde dort leider auch nichts. > > Allerdings gebe ich zu bedenken, dass gerade bei Interruptstrukturen > längere Sendezeiten ganz unerwartete Folgen haben können, auch das > Verschwinden von Fehlern. > Tja, die meisten wollen es hier vielleicht nicht wahr haben, aber es ist eindeutig der Fehler, denn außer den Wert TWBR von 2 auf 11 zu verändern, habe ich nichts weiter getan. Die Gegenprobe ( wieder auf 2 bis 10 in 2er Schritten ), hat jedesmal den Fehler produziert. Bernd_Stein
:
Bearbeitet durch User
Hi >Nachdem der Chip sich ja offenbar nicht konform zum DB verhält, bin ich >einer Sache nachgegangen, die ich beim L-Typ ausgeschlossen, aber zum >Glück noch im Hinterkopf hatte. Ich kann mich dunkel daran erinnern, das in der Anfangszeit der AVRs das TWBR nicht kleiner als 10 sein sollte. AppNote AVR315 von 10/2005: TWBR should be 10 or higher if the TWI operates in Master mode. If TWBR is lower than 10, the Master may produce an incorrect output on SDA and SCL for the reminder of the byte. Seit wann dieser Satz aus der Appnote verschwunden ist entzieht sich meiner Kenntnis. Ebenso welche AVRs dies betrifft. Vielleich solltest du mal einen neuen (DateCode) testen. MfG Spess
Sehr spät, ich weiß, aber vielleicht doch noch von Nutzen: > AppNote AVR315 von 10/2005: > TWBR should be 10 or higher ... > Seit wann dieser Satz aus der Appnote verschwunden ist ... ... steht in der neuen, AN2480: "2564B 09/2007 Removed text about TWBR needs to be higher than 10" Also kann der vorliegende ATmega8L-8PU von Ende 2012 wohl kaum betroffen sein, trotz gegenteiligem Anschein > ... aber es ist eindeutig der Fehler
Hi
>"2564B 09/2007 Removed text about TWBR needs to be higher than 10"
Auf der ATMEL-CD von 11/2007 steht steht der Satz aber noch drin.
MfG Spess
Ich geb's auf, Spess - in der aktuellen AN2480, in deren Überschrift aber noch sehr wohl "AVR315" steht, findet sich direkt unter meinem Zitat "2564A 04/2006 Initial document release"; wie kam es dann zu Ihrer Version von 10/2005? Es scheint ein zumindest leichtes Chaos existiert zu haben.
Hi Nach meinen Dokementen: Rev. 2564B-AVR-09/04 Rev. 2564C-AVR-01/10 In AppNote 2564B steht der Satz mit den <10 drin, ab 2564C fehlt er. In den Datenblättern ist diese Einschränkung nie aufgetaucht. Also sind die Angaben "2564A 04/2006 Initial document release" "2564B 09/2007 Removed text about TWBR needs to be higher than 10" Unsinn. Ich habe noch eine ganze Reihe ATMEL-CDs. Danach ist die AVR315 zwischen 06/2004 und 10/2005, also vor der angebliche 'Initial document release', herausgekommen. 10/2005 habe ich schon die Rev.B. >Also kann der vorliegende ATmega8L-8PU von Ende 2012 wohl kaum betroffen >sein, trotz gegenteiligem Anschein Die Nachfolger des ATMega8, die ATMega48..168, sind um 2004 erschienen. Ab da an wird Atmel kaum noch solche kleinen Einschränkungen am Atmega8 beseitigt haben. Ich würde davon ausgehen, das du betroffen bist. MfG Spess
> In den Datenblättern ist diese Einschränkung nie aufgetaucht.
Siehe Anhang, aus dem Preliminary 2545B–AVR–01/04.
Übrigens bin nicht ich betroffen, sondern Bernd Stein, und bis der sich
wieder meldet, lasse ich die Sache ruhen; es war vielleicht ohnehin
nicht besonders sinnvoll von mir, sie nochmals hervorzuholen.
Hi
>Siehe Anhang, aus dem Preliminary 2545B–AVR–01/04.
Ok. Dann nehme ich das zurück.
MfG Spess
hi, nochmal was zum UDRE-Flag 1. immer wenn du über UART was senden willst solltest du prüfen ob es gesetzt ist, dann und nur dann ist UDR frei. 2. UDRIE benutzt man nur wenn man ohne Unterbrechung senden will. beim letzten zu sendendem Zeichen darf es nicht mehr gesetzt sein sonst springt er immer in diesen Int. Die Schnittstelle kann geschlossen oder manipuliert werden wenn TXCF gesetzt wurde(vorher löschen) UDRE sagt nur das das Datenregister frei ist, nicht das Senderegister. Solche Dinge sind aber durch ordentliches lesen des DB durchaus erkennbar. Viel Erfolg, Uwe
S. Landolt schrieb: >> In den Datenblättern ist diese Einschränkung nie aufgetaucht. > > Siehe Anhang, aus dem Preliminary 2545B–AVR–01/04. > > Übrigens bin nicht ich betroffen, sondern Bernd Stein, und bis der sich > wieder meldet, lasse ich die Sache ruhen... > Ganz schön komplizierte Sache für mich, zu erkennen, wie die Revisionsabfolge der Datenbücherüberarbeitungen ist. Zudem hatte ich mich auch noch zu Anfang mit der englischen Darstellung von Monat und Jahr vertan. In den neueren DB ist dies jetzt eindeutig. Wenn ich soweit richtig durchblicke, ist das Rev.2486Z-02/11 Datenbuch das passende zu meinem Ende Dezember 2012 produziertem µC. Uwe schrieb: > Solche Dinge sind aber durch ordentliches lesen des DB durchaus > erkennbar. > Ich hatte es schon mal erwähnt - "ordentliches" lesen reicht nicht aus, man muss es auch verstehen ;-) In der vergangenen Zeit habe ich versucht ein Programm auf diese Erkenntnis hin aufzubauen, scheitere aber daran, die richtige Adresse auszulesen. Beitrag "ATmega8: Das Buch Kapitel TWI ( Two Wire Serial Interface )" Bernd_Stein
Bernd S. schrieb: > Wenn ich soweit richtig durchblicke, ist das Rev.2486Z-02/11 Datenbuch > das passende zu meinem Ende Dezember 2012 produziertem µC. > Da ich keine Antwort erhalten habe, werte ich das mal als richtig. Jetzt wieder zu meinem Programm : Ich verstehe nicht, warum in Hterm der twi_schritt 14 ( $E0 ) angezeigt wird und der X-Zeiger die Adresse $0042 hat, obwohl dieser zu Beginn mit der Adresse (twi_status_nr_tab*2) initialisiert wird. Im Anhang der aktuelle Kot ;-) Bernd_Stein
Bisher sieben Downloads des Programms. Es ist wie verhext. Da ich mir auch andere AVR8ASM-Programme bezüglich der TWI-Interrupt-Geschichte anschaue, habe ich mir einen Trick abgeschaut, der schon mal dafür sorgte einen Fehler mit der Hilfe des Simulators zu finden, da ich hiermit endlich mal in die TWI-ISR springen konnte. Ich hatte diesen Befehl auskommentiert ( siehe Screenshot ) und dadurch wurde natürlich der X-Zeiger nicht in den Z-Zeiger kopiert. Aber nun passiert etwas in diesem Simulator, was ich mir wieder einmal absolut nicht erklären kann. Bevor der letzte Befehl in der TWI-ISR ( _TWIaddr: ) ausgeführt wird ( RETI ), springt der Simulator nach dem Wiederherstellen des CPU-Statusregisters in die Stelle des Codes, die im Anhang zu sehen ist ( Screenshot ...error_Sprungziel ). Versteht das Jemand ? Bernd_Stein
> Versteht das Jemand ?
Nein, von Verstehen kann meinerseits nicht die Rede sein. Nur eines
fällt mir auf: weshalb wird ZH:ZL in der TWI-ISR nicht gesichert?
Bernd_Stein schrieb: >> Versteht das Jemand ? >> S. Landolt schrieb: > Nein, von Verstehen kann meinerseits nicht die Rede sein. Nur eines > fällt mir auf: weshalb wird ZH:ZL in der TWI-ISR nicht gesichert? > Ich denke das kann man auch nicht verstehen. Es scheint ein kleiner Bug zu sein, denn dies passiert auch beim Verlassen eines Unterprogramms. Hier wird dann zum Semikolon unterhalb von *.include "UP.inc";Unterprogramme* gesprungen bevor der RET-Befehl ausgeführt wird. Ich dachte es wäre unnötig den Z-Zeiger zu sichern, da er in der Main immer neu geschrieben wird und ich ihn in der TWI-ISR praktisch im X-Zeiger sicher. Aber wie PeDa hier auch schrieb, sollte man sicher programmieren und es ist ja nicht auszuschließen, das bei Programmerweiterungen doch plötzlich ein IRQ angefordert wird, während in der Main z.B. gerade nur der Low-Teil vom Z-Zeiger geladen wird und dieser dann in der ISR überschrieben wird. Deshalb habe ich jetzt natürlich in der TWI-ISR den Stack zum kurzfristigen sichern des Z-Zeiger benutzt. Nun zur neuen Sache. Glaube zwar nicht, das mir hier jemand diesbezüglich helfen kann, dies ist im Moment auch nicht wichtig, da ja eindeutig zu sehen ist, das bisher alles richtig läuft. Aus meinen Unterlagen geht hervor, das der Wii Nunchuk mit der Bytefolge : $A4, $40, $00 Initialisiert werden soll. Dies habe ich auch hinbekommen, nur spinnt jetzt der Logik-Analyser ( OLS Open Workbensch Logic Sniffer ). Er decodiert nur zwei Bytes. Bernd_Stein
> Ich dachte es wäre unnötig den Z-Zeiger zu sichern, > da er in der Main immer neu geschrieben wird und > ich ihn in der TWI-ISR praktisch im X-Zeiger sicher. Sie scherzen! Was passiert, wenn innerhalb des main-Teils
1 | ldi zl, LOW(_twi_schritt_tab);Adresse der TWI-Schrittsprungtabelle.. |
2 | ldi zh,HIGH(_twi_schritt_tab);..im Z-Pointer speichern.. |
3 | add zl,twi_schritt ;..und der jeweiligen TWI-Aktion entsprechend.. |
4 | adc zh,null ;..die richtige Adresse bilden zu der.. |
5 | ijmp ;..gesprungen wird. |
der TWI-Interrupt auftritt?
Oh, Entschuldigung, da hatte ich nicht gründlich genug gelesen; an dieser Stelle ist der TWI-Interrupt ja gesperrt.
Bernd_Stein schrieb: >> Ich dachte es wäre unnötig den Z-Zeiger zu sichern, >> da er in der Main immer neu geschrieben wird und >> ich ihn in der TWI-ISR praktisch im X-Zeiger sicher. >> S. Landolt schrieb: > Sie scherzen! > Was passiert, wenn innerhalb des main-Teils
1 | > |
2 | > ldi zl,LOW(_twi_schritt_tab);Adresse der TWI-Schrittsprungtabelle.. |
3 | > ldi zh,HIGH(_twi_schritt_tab);..im Z-Pointer speichern.. |
4 | > add zl,twi_schritt ;..und der jeweiligen TWI-Aktion entsprechend.. |
5 | > adc zh,null ;..die richtige Adresse bilden zu der.. |
6 | > ijmp ;..gesprungen wird. |
7 | > |
> der TWI-Interrupt auftritt? > S. Landolt schrieb: > Oh, Entschuldigung, da hatte ich nicht gründlich genug gelesen; an > dieser Stelle ist der TWI-Interrupt ja gesperrt. > Ja, genau diese Passage meinte ich, wenn nämlich das Programm geändert wird, kann ja irgend ein IRQ zuschlagen und das führt dann zu unnötigen Fehlern, die man durch sicherers Programmieren ausschließen kann. Du hast also völlig Recht mit dem sichern des Z-Zeigers. Bernd_Stein
Hallo zusammen und frohes Neues, mittlerweile sind ja einige Monate vergangen und in letzter Zeit habe ich mich wieder mit diesem Wii-Nunchuk und der Interruptbasierten TWI-Programmierung dessen beschäftigt. Wegen dem Debug-Feature *" DebugWire "* bin ich auf den ATmega88PA umgestiegen, welcher mit mit einem 1,8432 MHz Quarz läuft und an 3,3V betrieben wird. Ich spreche den Nunchuk wie im Dokument des Anhangs an, wundere mich jedoch. 1. Sowohl ein weißer, wie ein schwarzer Nunchuk, lassen sich ansprechen, obwohl ich meine gelesen zu haben, das diese unterschiedliche TWI-Adressen haben. 2. Aus beiden kann ich nur $FF als Daten lesen, egal wie rum ich den Nunchuk hinlege. Es müsste sich eigentlich zumindest die X-Position ändern. Warum im Digramm zu DATA-READ nicht die Adresse $A5 angezeigt wird, weiß ich nicht, muss ein Designfehler vom OLS-Programm sein, denn in der Auflistung ( Pfeil ) wird es ja angezeigt. Was läuft hier falsch ? Bernd_Stein
Nachdem ich einige Beiträge gefunden habe, die auch das Problem haben, das nur $FF aus dem Wii Nunchuk gelesen werden kann, bin ich noch auf eine andere Dokumentation gestossen ( Siehe Anhang ). Diese erläutert kurz, wie ein schwarzer Nunchuk zu initialisieren ist. Bei mir reagieren wieder mal beide gleich (schwarz sowie weiß). Zusätzlich bekomme ich auch noch Spikes, die ich mir bisher noch nicht erklären kann. Erhalte immer die Werte $00, $A4, $20, $00, $00, $D0. Egal wie der Nunchuk liegt. Es ist zum Verzweifeln. Bernd_Stein
:
Bearbeitet durch User
Hier habe ich wieder eine etwas andere Erklärung, ich mache also eigentlich alles richtig : 1. Initialize the Nunchuk: START, 0x40, 0x00, STOP This sequence is the normal initialization sequence, which sets the encryption algorithm to default. Every byte which is read from the Nunchuk must then be decrypted with (x ^ 0x17) + 0x17. A better way is disabling encryption with this sequence: 2. Initialize the Nunchuk without encryption: START, 0xF0, 0x55, STOP START, 0xFB, 0x00, STOP This has the benefit that the actual data can be used without the decryption formula and it will work with Nunchuk-clones as well. 3. Read the device ident from extension register: START, 0xFA, STOP READ 6 byte The data is the ident, which I already mentioned, if the connected device is a Nunchuk or Classic controller and so on. 4. Read measurements from the device: START, 0x00, STOP READ 6 byte https://www.xarg.org/2016/12/using-a-wii-nunchuk-with-arduino/ Bernd_Stein
:
Bearbeitet durch User
Habe nun das Problem, das über die RS232 ein Datenbyte zu wenig angezeigt bzw. übermittelt wird. Finde die Ursache dafür jedoch nicht. Im OLS wird auf dem TWI-Bus folgendes *vor SLA+R* angezeigt : START; $A4; $F0; $55 STOP START; $A4; $FB, $00 STOP START; $A4; $00; STOP *SLA+R* ist im Screenshot zu sehen. Eingekreist ist die START-Bedingung. START; $A5; $7F; $80; $3F; $7D; $17; STOP Die ACK und den NOT-ACK habe ich bewust weggelassen, ist ja im Screeshot zu erkennen. Langsam wird mir klar, warum ich bisher nichts in AVR8ASM gefunden habe, was den TWI-Interrupt nutzt, sondern immer nur das Polling von TWCR.TWINT. Hier der wesentliche Programmausschnitt. Der _twi_status_check bzw. die TWI_Schritt überprüfung sind ausser Funktion.
1 | ; |
2 | ;TWI-Daten lesen |
3 | ; |
4 | _twi_data_ack: |
5 | ldi a,#cmd_twi_ack ;Acknowlegde-Puls.. |
6 | sts TWCR,a ;..generieren |
7 | |
8 | rjmp _twi_takten ;Den TWI-Ablauf weitertakten |
9 | ; |
10 | ;TWI Daten lesen und im SRAM speichern |
11 | ; |
12 | _twi_data_read: |
13 | ldi zh,HIGH(_twi_data_r) ;..SRAM-Basisadresse.. |
14 | ldi zl,LOW (_twi_data_r) ;..laden.. |
15 | add zl,twi_rxd ;..und Datenempfangszeiger.. |
16 | adc zh,null ;..hinzuaddieren |
17 | |
18 | lds twi_data,TWDR ;TWI-Datenbyte einlesen.. |
19 | st z,twi_data ;..und ins SRAM kopieren |
20 | |
21 | rcall _warte_udre ;TESTZWECKE #################################################################### |
22 | ld twi_data,z ;TESTZWECKE #################################################################### |
23 | sts UDR0,twi_data ;TESTZWECKE #################################################################### |
24 | |
25 | tst twi_rxd ;Daten empfangen fertig? |
26 | breq _twi_nack ;JA => springen |
27 | |
28 | dec twi_rxd ;Datenempfangszeiger einen weniger |
29 | |
30 | dec twi_ablauf_nr ;Acknowlegde-Puls erzeugen |
31 | |
32 | rjmp _idle ;Weiter im Programmlauf |
33 | _twi_nack: |
34 | ldi twi_rxd,#twi_rxd_anz ;Datenempfangszeiger erneut initialisieren |
35 | |
36 | ldi a,#cmd_twi_action ;TWI-Aktion ausfuehren und somit ein.. |
37 | sts TWCR,a ;..NOT Acknowlede erzeugen |
38 | |
39 | rjmp _twi_takten ;Den TWI-Ablauf weitertakten |
Bernd_Stein
Endlich einen entscheidenen Schritt weiter. Nach dem der Taster einmal betätigt wird, bekommt man die aus dem Wii Nunchuk gelesenen Daten über die RS232 angezeigt. Spalte 1 = X-Achse des Joysticks. Mittelwert = $7F, Links = $00, Rechts = $FF. Spalte 2 = Y-Achse des Joysticks. Mittelwert = $80, Zurück = $00, Vor = $FF. Spalte 3 = X-Achse vom Beschleunigungssensor. Mittelwert = $7F, neigen Links = $3B, neigen Rechts = $CD Spalte 4 = Y-Achse vom Beschleunigungssensor. Mittelwert = $7F, neigen Zurück = $3A, neigen Vor = $C9. Spalte 5 = Z-Achse vom Beschleunigungssensor. ?Wert = $C0. Spalte 6 = Die beiden unteren Bits der 3 Achsen des 10Bit -Beschleunigungssensors( jeweils Bit 1&0 ) und die Taster C & Z. Die RS232-Aufnahme zeigt die " Neutralstellungen ". Durch schütteln werden auch die maximal und minimal Werte des Beschleunigungssensors erreicht ( $FF & $00 in den Spalten 3,4 und 5. ) Blöde Sache für mich, da ich dachte es wäre ein Neigungssensor eingebaut. Außer dem Joystick und den beiden Tastern, kann ich den Beschleunigungssensor nur bedingt verwenden. Ach ja, der TWI-Status Check und dementsprechend auch die TWI-Fehlerroutinen sind zur Zeit inaktiv. Wie kann ich auf einfache Weise das komplette AS7-Projekt hier hochladen ? Bernd_Stein
:
Bearbeitet durch User
Habe jetzt mal den weißen Nunchuk angeschlossen und seine stabile Position zeigt folgende Werte. Stabil deshalb, da in diesem Bereich kleine Bewegungen nicht registriert werden, es also ein Totfenster gibt. Das ist beim schwarzen genau so. Leider ist diese Position bei dem weißen schon nach links geneigt, so das es für mich nicht die " Neutralstellung " einnimmt. Das brachte mich auf die Idee, die Kalibrationsbytes, die an der Speicheradresse $20 liegen sollen und 16 Bytes lang sein sollen, mal auszulesen. Der nächste Schritt soll dann das Verbiegen dieses Wertes für die X-Achse des Beschleunigungssensors sein, damit er bei $80 oder evtl. $7F auch seine " Neutralstellung " hat. Oder sollte ich gar einen anderen Wert nehmen und könnte damit vielleicht erreichen, das links geneigt $00 ergibt und rechts geneigt $FF ergibt ? Bernd_Stein
Mir fehlt es jetzt erstmal an Motivation mit dem Auslesen der 16 Kalibrationsbytes weiter zu machen, da mein Erfolg ja auch gleichzeitig einen derben Niederschlag nach sich zog, da ich ja durch blosses Bewegen des Nunchuk keine Werte von $00 bis $FF erreiche. Somit also einen nur sehr begrenzten Wertebereich bei diesen Bewegungen zur Verfügung habe. Denke nun auch, das durch ändern der Kalibrationswerte dies auch nicht erreicht werden kann. Die wenigen die dieser Thread nur noch oberflächlich interessiert, haben davon wohl auch keine Ahnung, was ich mit dem Ändern dieser 16 Bytes bewirken kann. Falls doch, dann ist es jedoch unwahrscheinlich, das diese auch noch durch das von mir geschriebene Programm durchsteigen und mir somit überhaupt richtig helfen können. Natürlich freue ich mich über jeden Tipp der mich weiterbringt. Ich werde jetzt also erstmal aufarbeiten, was so gelaufen ist. Meine Vorstellung der TWI war, das ich durch Schreiben einer 1, in das TWI-Controlregister ( TWCR ) an der Bitposition 7 ( TWINT ), erstmal direkt eine 1 im Simulator vorfinden würde, welche nach ein oder ein paar wenigen Systemtakten verschwinden würde und zu diesem Zeitpunkt z.B. die START-Bedingung auf den Bus erscheinen würde. Da kam schon die erste Überraschung, das das ATMEL-STUDIO 7 ( AS7 ) die TWI gar nicht simulieren kann. Dies zu erkennen dauerte schon eine ganze Weile, da ich mich ja total neu in den I2C-Bus eingearbeitet habe und somit noch nicht wirklich verstanden habe, wie im einzelnen genau die TWI im µC arbeitet. Dank S. Landolt seinem 10-Zeiler und Spess53, war dann klar das der Simulator hierfür nicht zu gebrauchen ist. Dann kam auch noch das Problem, das übrigens auch im Buch von Günter Schmitt " Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie " in der 4.Auflage auf der Seite 390 zum Bitratenfaktor ( TWBR ) beschrieben wird, das dieser Wert eben bei älteren ATmega-Controllern >10 sein muss. Was beim von mir jetzt verwendeten ATmega88PA nicht mehr der Fall ist. Zur Sicherheit habe ich jedoch jetzt mit TWBR = 2, eine SCL-Frequenz von 92kHz verwendet, da mit 102kHz ( TWBR = 1 ), die 100kHz des I2C-Busses um 2% überschritten würde. Hinzu kam eine gewisse Unsicherheit mit welcher Bytefolge nun der Wii Nunchuk zu intitialieren ist. Dank einer leider englischsprachigen Website war nun klar warum es zwei verschiedene Versionen gab. Mir ist die unverschlüsselte lieber. Dieser Seite habe ich es übrigens auch zu verdanken, das ich weiß, dass es diese 16-Kalibrationsbytes gibt und welche Bedeutung jedes einzelne Byte hat. 5. Read actual calibration data from the device https://www.xarg.org/2016/12/using-a-wii-nunchuk-with-arduino/ Leider gibt dieser, wohl deutschsprachige Kollege, keine eMail-Adresse bekannt, wo ich mal meinen Dank und sicherlich auch ein paar Fragen an ihn richten könnte. Das Logikanalyseprogramm ( OLS ) musse ich auch erst richtig bedienen lernen, damit ich mich nicht selbst damit verarschte. Ein auch sehr, sehr nerviges Problem, war die RS232-Kommunikation um den Programmablauf transparenter zu machen. Zudem hoffte ich hier eine detailierte Erklärung zu den einzelnen TWI-Schritten zu erhalten, da ich glaubte jemand der in AVR8ASM fitter ist als ich und auch noch die benötigte Intelligenz besitzt sich die einzelnen TWI-Schritte, mit der einfachen Schaltung, selbst zu erschließen und mir genau erklären könnte was, wann passiert. Ich brauche sogar die Pullup Widerstände nicht, da diese im Nunschuk vorhanden sind. Anstelle dessen gab es wie immer Unterstellungen, das das Datenbuch nicht sorgfältig gelesen wurde und/oder es an Intelligenz hierfür scheitert. Meine Nunchuks haben die Platine des hier linken abgebildeten Exemplars : https://ardugnome.blogspot.com/2018/03/arduino-and-original-wii-nunchuck-vs_29.html Leider ist es auch mit DebugWire im Einzelschritt nicht möglich zu erkennen, was genau vor und nach einem Befehl in sämtlichen TWI-Registern geschehen ist. Ich will trotzdem beschreiben, wie ich es vermute. Fangen wir mit der START-Bedingung an. Nach einem Reset ist das TWCR mit $00 initialisiert. Zur Erzeugung des Startsignals, muss in diesem Register das TWINT-Flag mit einer 1 gelöscht werden, TWSTA mit einer 1 gesetzt, mit TWEN =1, die TWI freigegeben und mit TWIE =1, der TWI-Interrupt. Hiernach läuft das Programm erstmal weiter. Wieviel Systemtakte genau kann ich nicht sagen. Auf jeden Fall guckt die TWI-Hardware unabhängig vom Programmverlauf nach, ob der Bus frei ist ( SCL & SDA = High ). Wenn dies der Fall ist erzeugt diese das Startsignal, schreibt nach erfolgreicher Aktion dessen ins TWSR den Wert $08 und setzt ein paar Takte später evtl. im Gleichen, das TWINT-Flag in TWCR. Nun wird im Programmablauf der gerade bearbeitete Befehl zu ende geführt und wie üblich bei einem IRQ, die Adresse des darauf folgenden Befehls auf dem Stack abgelegt. Hierauf lädt der PC die Adresse in der Interruptverktortabelle die zu diesem IRQ gehört. Der dort stehende Sprungbefehl springt nun zur TWI-ISR. Nun ist es beim TWI-Interrupt jedoch so, das das TWINT-Flag nicht automatisch durch den Einsprung in die ISR gelöscht wird. Ich nutzte diese Situation in meinem Programm und verhinderte den erneuten Einsprung in die ISR bzw. ein ständigen Einsprung in diese, dadurch das ich den TWI-Interrupt sperrte ( TWIE=0 ). Weil es leider nicht zu ermitteln war, nach wievielen Systemtakten TWINT durch schreiben einer 1 gelöscht wird und ich bereits nach wenigen Systemtakten schon wieder in der Main dieses Flag auf gesetzt bzw. 1 abfragte, war also nicht klar, ob diese 1 nun durch schreiben von TWCR.TWINT noch gesetzt war oder durch die TWI-Hardware geschah. Deshalb bin ich in dem jetzigen Programm den Weg gegangen, das in Main erst zum TWI-Ablauf gesprungen wird, wenn entweder der Taster betätigt wurde oder TWEN=1 & TWIE=0 ist. Durch die Kombination TWEN=1 & TWIE=0 ist also klar, das zur TWI-ISR gesprungen wurde und nun kann zur nächsten entsprechenden TWI-Aktion, die durch die erzeugte Programmadresse aus _twi_ablauf: + twi_ablauf_nr, vorgegeben wird, mit ijmp geprungen werden. Über die TWI-Ablaufnummer ( twi_ablauf_nr ) bestimme ich also welche TWI-Aktion ausgeführt werden soll. Das Auslesen der Nunchukdaten bereitete mir zwei Probleme. Das erste war, was übrigens im Programmbeispiel k4p19.asm im oben genannten Buch zu sehen ist, das nach erzeugen von SLA+R nicht direkt TWDR eingelesen werden darf. Vorher ist nämlich die TWI-Aktion " Enable Acknowlege " auszuführen !!!. Zwar nicht genau wie im Buch, denn dies erzeugt ein Not Acknowledge ( NACK ), aber mit dem zusätzlichem Setzen von TWEA ( TWI-Enable Acknowlegde ). Also TWCR.TWINT.TWEA.TWEN.TWIE. Zum Zweiten, das ich entweder ein Byte zu viel auf dem TWI-Bus eingelesen habe und die Anzahl bei der RS232-Übertragung stimmte oder die Anzahl auf dem TWI-Bus stimmte, aber in der RS232-Übertragung fehlte das letzte einzulesende Byte. Dies war ein Programmierfehler, den ich glücklicherweise selbst gefunden habe. Ein weiterer Umstand, der wohl im Datenbuch ( DB ) steht ist der, das nach der STOP-Bedingung gar nicht in die TWI-ISR bzw. das TWINT nicht mehr von der Hardware gesetzt wird. Wie hiernach der Inhalt von TWCR ist habe ich noch nicht überprüft. So - und jetzt speziell zum Wii Nunchuk. Mir ist nicht klar wie die Z-Achse zu gebrauchen ist und ob es machbar ist, nur durch neigen des Nunchuk, die oberen 8-Bit im Bereich $00 bis $FF nutzen zu können oder geht dies grundsätzlich nur durch beschleunigen ( schütteln ). Bernd_Stein
Hier noch eine Seite die sich ebenfalls mit der TWI und AVR8ASM beschäftigt, jedoch wie üblich TWINT mittels polling auswertet. http://www.grzesina.de/avr/i2c/i2c.html Und noch was - ein Beschleunigungssensor ist ein Neigungssensor ! https://www.youtube.com/watch?v=Y_RazJga5jw Bernd_Stein
:
Bearbeitet durch User
Hab mal wieder mit dem weißen Nunchuk herumexperimentiert. Auch schon die 16 Kalibrationsbytes ab Adresse $20 ausgelesen und das erste an Adresse $20 erfolgreich verändert. Zuerst mit $FB, später $FF. Was ich auslas scheint jedoch nicht zu stimmen, da alle 16 Bytes $00 waren. Selbst die beiden Letzten, die ja die Checksumme bilden, blieben $00, obwohl ich ja das erste Byte veränderte. Noch erstaunter war ich, da ich den Nunchuk in Neutralstellung befestigte und die 6 Positionsbytes auf einmal plausibel waren. Zumindest die ersten Male die ich mit OLS untersuchte. Mittels RS232 konnte ich jedoch feststellen, dass auf einmal die X,X und Z-Werte des Beschleunigungssensors ab dem 447ten Byte kippen, aber stabil bleiben. Interessant ist, das dies auf die Bytestelle genau ( 446 ) reproduzierbar ist. Hat hier jemals irgend wer diese 16 Kalibrationsbytes vom Wii Nunchuk ausgelesen und kann mir schreiben, welche Werte er dort stehen hat ? Bernd_Stein
:
Bearbeitet durch User
Bearbeiten geht leider nicht mehr, deshalb hier kurz eingeschoben : https://wiibrew.org/wiki/Wiimote/Extension_Controllers/Nunchuck Es scheint sich also zu bestätigen, das die minimalen und maximalen Werte des Beschleunigungssensors nur durch schütteln zu erreichen sind. Aber es hat ja auch noch niemand veröffentlicht, was man mit den 16 Kalibrationsbytes anstellen kann ;-) Bernd_Stein
:
Bearbeitet durch User
Bernd S. schrieb: > Aber es hat ja auch noch niemand veröffentlicht, was man mit den > 16 Kalibrationsbytes anstellen kann ;-) Das meinst auch nur Du: https://www.hackster.io/infusion/using-a-wii-nunchuk-with-arduino-597254
> Bernd S. schrieb: >> Aber es hat ja auch noch niemand veröffentlicht, was man mit den >> 16 Kalibrationsbytes anstellen kann ;-) > Dieter F. schrieb: > Das meinst auch nur Du: > > https://www.hackster.io/infusion/using-a-wii-nunchuk-with-arduino-597254 > Das hatte ich übrigens schon auf einer anderen Website gefunden und auch hier verlinkt, aber da steht doch nur die Bedeutung dieser 16 Bytes. Jemanden, des sich mal näher damit befasst hatte, habe ich noch nicht gefunden. Das was ich ausgelesen hatte, kommt mir sehr suspekt vor. https://www.xarg.org/2016/12/using-a-wii-nunchuk-with-arduino/ Und noch was - damit wäre mir besser geholfen : Bernd S. schrieb: > Hat hier jemals irgend wer diese 16 Kalibrationsbytes vom Wii Nunchuk > ausgelesen und kann mir schreiben, welche Werte er dort stehen hat ? > Bernd_Stein
:
Bearbeitet durch User
Auf dieser Seite konnte ich schon mal erfahren, das die Neutralstellungswerte anscheinend bei der Beschleunigung von 1G, was wohl der Erdanziehungskraft entspricht, angezeigt werden. Weichen etwas von meinen ab, aber das ist ja nicht so wichtig. Aber was ist dann 0G ? http://rts.lab.asu.edu/web_325/CSE325_Assignment_6_F10.pdf Bernd_Stein
:
Bearbeitet durch User
Habe beim weißen Nunchuk die Adressen $20 ( OG X-Achse Bit 9:2 ) mit den Werten $04 bis $84 in $04 Abständen beschrieben, aber dies hat keinerlei Einfluss auf den Wert in Neutralstellung der X-Achse ( Adresse $00 ). Diese bleibt bei $A8 stehen. Dies ebenfalls für die Adresse $24 ( 1G X-Achse Bit 9:2 ), jedoch nur bis zum Wert $60. Auch hier keine Änderung. Im Foto sind die ersten 16-Byte halt die Kalibrationsbytes und die letzten 6-Bytes die aktuellen Werte in der Neutralstellung. Das hierzu gehörige Programm als Zip-Datei und die Abarbeitung geschieht mittels drücken des Tasters. Mir ist auch nicht klar, ob die Adresse nun 3-Bytes hat oder nur 2-Bytes benötigt oder gar nur 1-Byte. Befinden sich jetzt z.B. die aktuellen 6-Positionsbytes ab Adresse $000000 oder $0000 und die 16-Kalibrationsbytes ab Adresse $000020 oder $0020 oder gar $200000 bzw. $2000 oder doch nur $00 & $20, also 1-Byte ? Antworten die hier im Thread, selbst nach Jahren noch auftauchen, interessieren mich trotzdem, auch wenn ich es jetzt dabei belasse und den eingeschränkten Wertebereich des Beschleunigungssensors beim Neigen in kauf nehme. Bernd_Stein
:
Bearbeitet durch User
Nur als Ergänzung. Hatte dies auch mal gefunden ( ATXmega32A4U ), aber als nicht lauffähiges Programm erachtet. https://www.mikrocontroller.net/attachment/156333/i2c.asm Bernd_Stein
Hier nun der Programmstand. Mit dem schwarzen Nunchuk kann durch links/rechts neigen ( X-Achse des Beschleunigungssensors. Spalte 3 bei Hterm ) am PWM-Pinn OC0B ( PD5 ) die PWM in gewissen Grenzen verändert werden. OC0A ist ein Rechteckgenerator mit 3,6kHz. Um das Ganze zu starten, ist es nötig den Taster an PD7 einmalig zu betätigen. Bernd_Stein
Da der Mode 7 ( Fast PWM ) nicht optimal für eine DC-Motoransteuerung ist, habe ich nun auf Mode 5 ( Phase Correct PWM ) umgeschwenkt. Falls etwas bei dem TWI-Ablauf falsch läuft, wird eine Error-LED an PB5 eingeschaltet und das Programm läuft in einer Endlosschleife. An PB4 blinkt die PLA-LED ( ProgrammLaufAnzeige ) mit ca. 1Hz. Es darf nicht vergessen werden, den Taster an PD7 zu betätigen, damit das Ganze läuft. Etwas länger drücken, das Entprellen ist noch nicht optimiert. Um den verringerten Aussteuerbereich des X-Achsenbeschleunigungssensors auf das maximal Mögliche zu erhöhen, wird dieser Rohwert mit 1,5 multipliziert ( 384/256 ). In Hterm ist bei " New Line at " CR+LF einstellen und alle 52 Spalten zu nutzen, da dann in der neuen Zeile der erste Wert, des skalierten X-Achsenwertes zu sehen ist, der an OC0B in der Timer/Counter0 Overflow-ISR ausgegeben wird ( _OVF0addr: ). Alle anderen zu sehenden Werte sind die aufaddierten X-Achsenwerte. Zur Zeit fliegt mir immer der L298N um die Ohren, deshalb erstmal Programmierpause ;-) Beitrag "Re: CRS Robotics A255 Roboterarm" Bernd_Stein
:
Bearbeitet durch User
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.