mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit USI von AtTiny26


Autor: Kai (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

Ich habe ein paar Probleme mit der USI des AtTiny26 und ich hoffe mir
kann jemand helfen.
Der AtTiny26 soll nachher als SPI<->I2C Wandler agieren (mit diversen
möglichkeiten den i2c bus zu konfigurieren) und ist nachher nur ein
kleiner Teil der gesammten Hardware.

Ich nutze hauptsächlich folgende Routinen:

Initialisierung:
  ;Initialisiert USI als SPI slave, MISO wird vorher schon
        ;richtig konfiguriert...
  ldi  temp, (1<<USIWM0)+(1<<USICS1)  ;+(1<<USIOIE)
  out  USICR, temp

SPI-Transfer Funktion (aus dem Datenblatt übernommen):
SpiXFer:  out  USIDR, SpiDat
SpiXFerNoWrite:  ldi  temp, (1<<USIOIF)
    out  USISR, temp
SpiXFerLoop:  sbis  USISR, USIOIF
    rjmp  SpiXFerLoop
    in  SpiDat, USIDR
    ret


Nun zu meinem Problem:
Über den SPI-Bus wird - um einen i2c write-transfer zu initiieren auf
den Bus ein paar bytes geschrieben, die in dem Ram zwischengepuffert
werden. Wenn die zu schreibenden i2c-daten alle übertragen werden, wird
ein i2c transfer durchgeführt. Wenn der i2c transfer beendet ist, rufe
ich die oben stehende Funktion SpiXFer auf und lasse damit eine
"0x00" ausgeben:

;...i2c transfer hier zuende...
ldi SpiDat, 0x00
rcall SpiXFer

Da der SPI-"Master" mitbekommen muss, wann der transfer beendet ist
polle ich momentan den SPI-Bus vom Master aus, ob der zurückgelesene
Wert=0x00 ist (der Master sendet dabei 0xff). Wenn der Wert 0x00 ist,
ist das ein Zeichen dafür, dass der i2c-transfer beendet ist.

Leider läuft an dieser stelle in 50% der Fälle die Bitsynchronisation
von Master und Slave durcheinander, das heisst der Master empfängt
werte wie:
0x0F
0xF0
Vermutlich kommt das dadurch, dass das USIDR-Register nicht
synchronisiert ist. Nur WIE warte ich auf den Zeitpunkt, dass ein Byte
zuvor komplett übertragen wurde?

Ich habe es mit folgender Funktion probiert. Damit klappt es aber auch
nicht:


SpiWait:  sbis  USISR, USIOIF
    rjmp  SpiWait

    ldi     SpiDat, 0x00
                rcall   SpiXFer

Hat jemand eine Idee, wie ich mein Problem lösen kann? Da das der erste
AVR mit USI ist, den ich benutze bin ich da momentan ziemlich ratlos.
Mit dem Overflow interrupt zu arbeiten ist leider nicht möglich, da das
Auslösen des Interrupts das Timing auf dem i2c Bus beeinflußt, was auf
keinen Fall geschehen darf, da er zu Tests von i2c slaves eingesetzt
wird (z.B. um seine maximale Clockrate zu ermitteln).

viele Grüße,

Kai

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.