Hallo. Ich habe schon das ganze forum durchsucht, zich seiten, ob nun TWI oder I2C... etc... Ich finde jedoch keine seite die mir ordentlich erklärt wie der Slave richtig daten empfängt. Der Aufbau ist folgender. 1 ATMega 16 steht als Master und 2 ATMega 16 als Slave. Ich habe es bis jetzt soweit hin das beide Slaves bemerken wann Start und Stop vom master gesendet wird... jedoch über das direkte abfragen der Ports. In den Registern der Mega reihe nach der Atmel Doku bekomm ich nicht wirklich die angegebenen Daten raus, ich denke aber mal das diese im TWCR liegen müssten... diese ist aber wie TWSR nur beim initialisieren auf dem startvalue und ändert sich dann nicht mehr. Nachdem ich nun wusste wann das mit dem senden anfängt und endet habe ich mit TWDR die daten abgefragt.... nun das merkwürdige... mal bekomm ich da die richtigen daten an den slaves und mal nicht... was mache ich falsch? Ich dachte da jetzt an das Schieberegister, da ja, wie ich gelesen habe bit 7-0 gesendet wird. Nur kann ich ja im TWSR keine datenveränderung feststellen. Ich verzweifle hilfe! MFG
da ändern sich irgendwie auch keine Flags.... ist auch nur ein bei der initialisierung das startflag, danach ändert es sich einmal bei der initialisierung des Masters am bus.... danach passiert mit den flags ebenfalls nix.... merkwürdig
hast du schonmal ins Datenblatt der ATMEGAs geschaut, da ist das recht gut erklärt
Hi du schreibst aber schon bei jedem INT das TWI Kontroll Register neu? Matthias
@ Pascal.. also nach dem Datenblatt und dem Beispielcode versuche ich es ja.. aber irgendwie.... @Matthias Das muss ich neu schreiben?????!!!
na ich werde das gleich mal testen... dies ist aber nur beim Slave so oder auch beim Master?
Es geht... danke.... wow... nur an diesem neu schreiben lag es jetzt... Ich glaube ich werde mal bei gelegenheit nen Tutorial machen, da diese frage hier ja sehr oft gestellt wird. Herzlichen Dank nochmal an alle und schöne woche
Kannst Du Deinen Code posten? :o) Mich würde der sehr interessieren! ;o) Frohes neues Jahr Florian
hab hier das gleiche prob .. kommt mir vor, als würde der slave atmega ned auf seine adresse oder auf die general call adresse reagieren poste morgen mal meinen code.. vielleicht kann ja einer helfen
Hi schneebrunzer, Du liest in deinem Code aus PORT A die Adresse für deinen Slave ein: > in tmp,PINA Gesetzt den Fall es liegt 0b00001000 auf PORTA, ergibt das bis jetzt eine SLAVE Adresse von 0x08. Dann verschiebst du das Ergebnis nach rechts -> Ergibt 0b00000100 (0x04) Und jetzt setzt du das 2. Bit im Temp Register: > sbr tmp,1 Das Ergibt hier somit die Slave Adresse 0b00000110 (0x06) Was du wohl erreichen wolltest, war dass das TWI auch auf General Calls reagiert, dann solltest du aber "sbr tmp,0" schreiben. Die Bits sind von 0..7 nummeriert. Auch in deiner TWI Interrupt Routine stimmt was AFAIK nicht: Du bist im Interrupt und musst selber den TWINT löschen, daher kannst du unendlich warten, bis das TWINT sich löscht. Deine Routine würde eher ohne Interrupts funktionieren. Deaktiviere mal den TWI Interrupt und rufe die two_wire_rec einfach mal aus dem Hauptprogramm auf. Der TWI Interrupt wird bei jedem Event auf dem TWI Bus gefeuert, solange der Slave adressiert ist. In dem Interrupt musst du dann entscheiden, was für eine Aktion mit dem aktuellen TWSR geschehen soll (mindestens 4 verschiedene Aktionen). Um ein Byte über den TWI Interrupt zu empfangen, sollte der Interrupt 3mal abgearbeitet werden (SLA+W,DATA,STOP) und nach jeder kurzen Aktion verlassen werden, sonst bleibt dein AVR vermeintlich stehen, da er endlos wartet. Versuchs erstmal ohne Interrupt, indem du das TWINT Flag pollst (wie auch in deiner Routine.
thx für die antwort.. hab mir den slave einfach laut master nachgebaut und wusste dabei nicht, wann der interrupt ausgelöst wird.. hatte das dann mal mit nem ice kontrolliert und bemerkt, dass der einfach immer auslöst (da der master ja sendete).. das hat mich etwas verwirrt.. ich möchte den slave gerne mit interrupts realisieren.. hab das mal etwas umgebaut .. (das mit dem general call hab ich geändert.. danke.. hab mich da damals vertan) hab auch die taktrate mal auf 100k beschränkt ( dez 72 in TWBR) stimmt der ablauf dann so in etwa: 1) int wird ausgelöst wenn irgendwas auf der taktleitung passiert 2) ich muss status-register kontrollieren ob sich mein slave erkannt und ein ack senden (oder nein, ack sendet der atmega doch selbst oder?) 3) danach geh ich aus der int routine raus.. 4) nächst int.. ich check ob daten erhalten.. schick ack (bzw. atmega schickt) und ich geh aus int routine raus 5) ... nächste daten .. eventuell 6) ich wart auf stopp kondition .. und spring raus.. oder war das anders.. bin jetzt voll verwirrt.. thx für die hilfe
Hi Schneebrunzer, so stimmts, bis auf dass der Interrupt zum ersten mal ausgelöst wird, wenn das TWI seine Slave-Adresse erkannt hat und dann solange bis STOP oder Fehler erkannt wurde. Ein ACK brauchst du nicht zu senden, du musst nur dem TWI mitteilen, dass er beim nächsten Mal ein ACK sendet. Schau mal in den Dateianhang, dann wird das Prinzip klar. Eigentlich geht es auch einfacher nur, so kannst du jedoch später auch Multimastermode, Fehlerabfrage usw. implementieren und den etwas empfindlichen TWI Bus fehlerresistenter machen. Gruss, Harry XS.
uff damn voll vergessen ... danke für deine hilfe! funktioniert jetzt alles... mein peinliches aber wahrlich das hauptproblem: vergiss niemals die massen beider µCs zu verbinden :-p .. (jaja fragt mich ned warum ich das vergessen habe, hab anscheinend ne abneigung gegen massen..) danke nochmals & grüße
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.