www.mikrocontroller.net

Forum: Codesammlung TWI / I2C einf. MASTER SLAVE Beispiel(Assembler) ATmega8

Autor: Bernhard Schulz (bernhard)
Datum: 12.10.2005 23:06
Dateianhang: MASTER_SLAVE_TWI_I2C.zip (360,5 KB, 3274 Downloads)

Ein einfaches Beispiel für einen TWI / I2C Master und Slave.

Es werden 2 Daten-Bytes an den Slave gesendet und anschließend zwei
Daten-Bytes vom Slave empfangen.

Es ist kein fertiges Projekt, aber es hilft hoffentlich,
die Grundmechanismen schneller zu erkennen.

z.B: - Initialisierung
     - Adressvergabe
     - Interrupt-Handling
     - mögliche Error-Routinen
     - TWSR / TWCR - Auswertung

Die LEDs vom MASTER zeigen den Zustand der Datenübertragung
(z.B. erfolgreicher START) an und
die LEDs vom SLAVE, welcher TWSR Zustand anliegt, wenn der
TWI-Interrupt aufgerufen wird.

Absichtlich habe ich alle Vorgänge stark durch Warteschleifen und eine
sehr niedrige SCL Frequenz gebremst, damit man besser nachvollziehen
kann, wann was und wo passiert.


Bernhard
Autor: Thorran Microlovic (kleineronkel)
Datum: 18.10.2005 20:38

Hallo,
finde ich echt ne super sache das du das mal online gestellt hast,
werde es sofort mal ausprobieren.

Eine Frage hätte ich jedoch noch mit was für einem programm hast du den
Plan gezeichnet?
Autor: Bernhard Schulz (bernhard)
Datum: 21.10.2005 12:22

@Thorran Microlovic

>finde ich echt ne super sache das du das mal online gestellt hast,

Danke, ich hoffe, dass dieses kleine Beispiel bei den Grundlagen etwas
weiter hilft.

>mit was für einem programm hast du den Plan gezeichnet?

mit sPLAN 4.0, ist ein sehr einfaches und leicht zu bedienendes
Programm mit vielen interessanten Spezialfunktionen.
Autor: Mareike (Gast)
Datum: 04.01.2006 15:28

Hey super !
Danke das du das Programm online gestellt hast.
Möchte das selbe Programm in C-realisieren ! Nun habe ich von Assembler
nicht so den Plan! Kann mir jemanden einen Tipp geben?
Autor: Uwe Ortmann (schwede)
Datum: 21.01.2006 15:56

Hallo..
ich bin begeistert - genau das habe ich schon lange gesucht.
Jetzt habe ich begonnen, das ganze für mein eigenes Programm
abzuändern, und bin da auf ein Problem gestossen.
Es gibt da 2 Sachen die ich nicht verstehe. Das ist die Abfrage des
TW_INT_FLAG. WANN und von WEM wird es gesetzt oder gelöscht?
Die andere Sache ist der Check des Status-Registers (TWSR) - dieses
Register hat sehr unterschiedliche Werte. Ich möchte gern wissen, wie
sich die einzelnen Werte zusammensetzen? Also der Wert im Register
addiert mit 0xF8 ergibt einmal 0x08 oder 0x18 oder 0x40 usw.
Könnte man das mal zum besseren Verständnis in einer Tabelle
darstellen?

Gruss Uwe
Autor: Bernhard Schulz (bernhard)
Datum: 22.01.2006 20:31

@Uwe Ortmann (Schwede)

>Das ist die Abfrage des TW_INT_FLAG.
>WANN und von WEM wird es gesetzt oder gelöscht?

Gesetzt wird es, ganz allgemein ausgedrückt, wenn ein Ereignis am TWI
registriert wird.
z.B.

-eine bestimmte Aktion (zB. Start) durchgeführt wurde
-wenn ein Slave von einem Master angesprochen wird
-ein Zeichen vom Master gesendet wurde
-ein "Error" auftrat


Gelöscht wird es, in dem es auf "1" gesetzt wird


>Die andere Sache ist der Check des Status-Registers (TWSR) - dieses
>Register hat sehr unterschiedliche Werte. Ich möchte gern wissen, wie
>sich die einzelnen Werte zusammensetzen? Also der Wert im Register
>addiert mit 0xF8 ergibt einmal 0x08 oder 0x18 oder 0x40 usw.

Der Wert des Registers wird nicht mit 0xF8 addiert, sondern die
untersten 3Bit auf 0 gesetzt (2xVorteiler und 1xReserviertes-Bit), sie
werden sozusagen ausgeblendet.

Die Werte und die Bedeutungen findest Du ab Seite 177 im Datenblatt.

Anmekung: Für viele Anwendungen empfielt es sich, wenn man nach einem
INT-Flag-Interrupt prüft, warum dieses INT-Flag gesetzt wurde.

Ich hoffe, ich habe Dir etwas weiter helfen können?

Demnächst werde ich hier ein sehr interessantes "RS232-TWI-Interface"

veröffentlichen, dort sind die einzelnen Funktionen detaillierter
angewendet worden.

Gruß

Bernhard
Autor: Bernhard Schulz (bernhard)
Datum: 22.01.2006 22:52

Autor: Uwe Ortmann (schwede)
Datum: 28.01.2006 18:50

Hallo...
erstmal Danke für die Tipps, haben mir sehr viel geholfen. Allerdings
machen mir noch 2 Sachen "Kopfschmerzen".
Ein kleines Problem:
Ich takte meinen mega8 mit 16MHz - das macht dann pro Zyklus 60 ns. Wie
baut man am besten eine Zählschleife auf, um eine Pause von 6 ms zu
bekommen?
Das grössere Problem:
Ich möchte einen externen Interrupt an Int0 auswerten (also ein
Unterprogramm starten). Ich bekomme das einfach nicht hin. Könnte ich
ein wenig Hilfe bekommen?

Gruss  Uwe
Autor: Bernhard Schulz (bernhard)
Datum: 30.01.2006 09:59

@UWE

>Wie baut man am besten eine Zählschleife auf, um eine Pause von 6 ms
>zu bekommen?

Du hast es schon richtig formuliert, mit einer Zählschleife,
bei 16MHz Takt vergehen 0.0625µs pro Takt, d.h.
Du müsstest den µC mit 96.000 Takten mit sich selbst beschäftigen, um
eine Pause von 6ms zu erzeugen.

Schau mal bitte nach unter:
http://www.mikrocontroller.net/forum/read-4-57760.html#


>Ich möchte einen externen Interrupt an Int0 auswerten (also ein
>Unterprogramm starten).

Vor langer Zeit habe ich hier mal einen kleinen Beitrag dazu
geschrieben:

http://www.mikrocontroller.net/forum/read-4-156657.html

Vielleicht hilft es Dir etwas weiter?

Bernhard
Autor: Uwe Ortmann (schwede)
Datum: 07.02.2006 18:23

Hallo...
nachträglich noch vielen Dank, hat mir weitergeholfen.

Bei einer Sache muss ich allerdings noch mal nachfragen, damit ich da
nichts falsch verstehe.
Im Programm ganz oben ist der Vorteiler für das TWI mit 0, 4, 16 und 64
angegeben. Ist die 64 der grösst mögliche Teilungsfaktor?
Denn wenn ich meinen Mega8 mit vollen 16MHz takte dann hätte ich auf
dem TWI noch 250 KHz - also deutlich zu viel. Da wäre es wohl besser
ich takte den Controller mit 1MHz. Da komme ich auf ca. 15KHz, was für
eine längere Busleitung von Vorteil ist.

Habe ich das so richtig verstanden?

Gruss Uwe
Autor: Bernhard Schulz (bernhard)
Datum: 07.02.2006 21:38
Dateianhang: BERECHNUNG_SCL_FREQUENZ.xls (27 KB, 367 Downloads)

@UWE

>Ist die 64 der grösst mögliche Teilungsfaktor?
>Da wäre es wohl besser ich takte den Controller mit 1MHz


Ja das ist er und zusätzlich kannst Du auch die Bitrate ändern, um die
SCL-Frequenz zu verändern,
aber sie sollte größer als 11 sein, da es ansonsten zu Problemen bei
der Busverbindung kommen kann.


Ich stell Euch mal eine Excel-Tabelle zur Verfügung, womit man die
SCL-Frequenz berechnen kann.

Bernhard
Autor: Ingo (Gast)
Datum: 14.02.2006 16:25

Hallo,

kämpfe gerade mit TWI und bin dan hierauf gestoßen.
Da ist mir was aufgefallen: Die Berechnung der TWI-Bitrate
funktioniert
laut Atmel-Datenblättern so:
                    CPU Clock frequency
  SCL frequency = ----------------------------

                    16 + 2(TWBR) x 4 ^ TWPS
In dem Excel-Sheet steht aber:
  =Fcpu/(16+(2*TWBR)*TWPS)
Also, wenn ich die Frequenz für zwei gleich hoch getaktete Controller
berechne wird das vielleicht gehen, aber bei verschiedenen Frequenzen?
Oder übersehe ich was ganz entscheidendes?
Autor: Bernhard Schulz (bernhard)
Datum: 22.03.2006 00:16
Dateianhang: BERECHNUNG_SCL_FREQUENZ.xls (26,5 KB, 382 Downloads)

@Ingo


>In dem Excel-Sheet steht aber:
>  =Fcpu/(16+(2*TWBR)*TWPS)
>Also, wenn ich die Frequenz für zwei gleich hoch getaktete Controller
>berechne wird das vielleicht gehen, aber bei verschiedenen
>Frequenzen? Oder übersehe ich was ganz entscheidendes?

Du hast Recht, hab's auch gerade gesehen.

In der euen Excel-Tabelle habe ich meinen Berechnungs-Fehler behoben.

Danke für den Hinweis.

Bernhard
Autor: Bernhard Schulz (bernhard)
Datum: 27.03.2006 13:56

@Mareike

>Möchte das selbe Programm in C-realisieren ! Nun habe ich von
>Assembler nicht so den Plan! Kann mir jemanden einen Tipp geben?

...wo drückt denn der Schuh ?
Autor: Läubi (Gast)
Datum: 01.04.2006 13:30

Hätte da eine Frage:

Aus der Slave.asm:
"TWSI_TW_SR_DATA_ACK:          ; x80  10000000 (die vorher adressierten
(SLA+W) Daten wurden empfangen;  ACK wurde zurückgesendet
  cbi PORTB,4
  in DATA, TWDR  ; DATA
  rjmp TWSI_w"

Ich will über TWI dem Slave einfach Daten zusenden.
Seh ich das recht das ich an obiger Stelle die Empfangenen Datennn
auswerten kann?
Also sagen wir mal ich sende vom Master 0xFA an den Slave, und an der
stelle wird dies empfangen?

Und kann ich dann einfach alle LED ausgaben Auskommentieren oder ist
noch mher nötig? Der Slave braucht auch nichts zurückzusenden, soll nur
Daten empfangen.
Autor: Bernhard Schulz (bernhard)
Datum: 02.04.2006 20:43

@Läubi

>Ich will über TWI dem Slave einfach Daten zusenden.
>Seh ich das recht das ich an obiger Stelle die Empfangenen Datennn
>auswerten kann?
>Also sagen wir mal ich sende vom Master 0xFA an den Slave, und an der
>stelle wird dies empfangen?

Ja das ist korrekt, das empfangene Byte vom Master liegt nun im
"DATA" zur weiteren Verarbeitung bereit


>Und kann ich dann einfach alle LED ausgaben Auskommentieren oder ist
>noch mher nötig? Der Slave braucht auch nichts zurückzusenden, soll
>nur Daten empfangen.


Die LEDs müssen nicht unbedingt sein, sie dienen nur dazu, zu zeigen,
welchen Wert gerade das "TWSR" - Register gehabt hat.

Bernhard
Autor: Martin (Gast)
Datum: 29.10.2006 20:28
Dateianhang: i2c.rar (4,9 KB, 396 Downloads)

Hallo!
Ich weiß dass ich einen ziemlich alten, aber nützlichen Beitrag hier
entstaube.
Ich habe dazu mal eine Frage:
Ich brauche für einen Aufbau den I2C Bus. Ich habe mir mal dieses
Beispiel heruntergeladen und ausprobiert. Es funktioniert, nur eben sehr
langsam (ist ja auch oben gesagt).
Also habe ich mir gedacht: Unnötige Wait-Befehele wegfallen lassen und
die Prescaler und Bitrate-Werte so einrichten, dass die Übertragung
recht schnell gehen müsste.
Anhand der LEDs in den I2C-Leitungen kann man erkennen, dass die
Datenübertragung recht schnell läuft (nur ganz kurzes aufblinken).
Dennoch ist nach der Übertragung noch eine recht lange Pause, ehe die
nächste Übertragung (neues Aufblinken) stattfindet. Hat jemand eine
Idee, woran das liegen könnte?

Vielen Dank schonmal für eure Hilfe!
Autor: Bernhard Schulz (bernhard)
Datum: 29.10.2006 20:34

Hallo Martin,


>Dennoch ist nach der Übertragung noch eine recht lange Pause

Ich vermute, dass noch irgendwo ein rcall wait_xxx sein unwesen treibt.

Entferne doch mal spaßenshalber komplett die wait Routinen ?

Gruß

Bernhard
Autor: Martin (Gast)
Datum: 29.10.2006 21:02

Gesagt...getan...und eine äußerst verblüffende Antwort:

Es gab in der Master-datei 2 wait-Zugriffe:
- der erste nach der Initialisierung, den hatte ich vorher da gelassen
weil der ja nur einmal durchlaufen wird und nicht stört.
- der zweite im Abschnitt "TWI_ERROR". Das verwundert mich sehr, weil
ich daraus schließe, dass nach jeder Übertraung anscheinend auch ein
Fehler auftritt. Darf das sein?
Ich meine es läuft jetzt schnell, also so wie gewünscht, aber es ist
doch irgendwie ein komisches Gefühl zu wissen dass da immer ein Fehler
drin ist. Oder ist das normal so?
Autor: Bernhard Schulz (bernhard)
Datum: 29.10.2006 21:08

>dass nach jeder Übertraung anscheinend auch ein Fehler auftritt. Darf das >sein ?

Nein, das darf natürlich nicht sein.

Also, Ursache suchen.

Vielleicht SCL-Takt zu hoch? Adresse falsch? usw...

Vielleicht gibts im Slave noch ein wait, so das das Antwort-Bit nicht
bereitgestellt wird?
Autor: Martin (Gast)
Datum: 29.10.2006 21:22

Hm da habe ich sicher was zu suchen, weil ich im Grunde genommen deine
möglichen Fehlerquellen ausschließen kann:
SCL-Takt: Habe mit Bitrate 255 und Prescaler 64 bis zu Bitrate 11 und
Prescaler 1 allerlei Tests gemacht, also bei 255/64 kann er ja nicht
mehr zu hoch sein^^.
Adresse kann nicht falsch sein, da der IC dann ja gar nicht angesprochen
würde. Anhand von LEDs erkennt man ja dass er angesprochen wird, nur
eben auch dass er wegen der langen Pause die Fehler-Routine aufruft.
Im Slave ist kein Wait mehr vorhanden.

Nunja ein Glück geht es ja schonmal jetzt sehr schnell - wofür ich sehr
dankbar bin - der Fehler wird sich wohl im Laufe der Zeit und mit einer
noch genaueren Vertiefung in den Bus hoffentlich finden.
Autor: Xine (Gast)
Datum: 17.06.2007 23:14

Hallo alle zusammen,

ich bin gerade auf der Suche nach I2C-Beiträgen auf diesen Artikel
gestoßen.

Oben ist dieses klasse Assembler-Programm gepostet. Leider habe ich von
Assembler fast gar keine Ahnung und beschäftige mich gerade mit C für
eine einfache Sende-Empfangs-Routine zwischen zwei AVR.

Das Ding läuft leider noch nicht und langsam gehen mir die Ideen aus.

1. Frage: Hat schon einmal jemand den i2c.h Header in CodeVisionAVR
benutzt? Nachdem mein selbst geschriebenes Programm Probleme macht,
dachte ich versuche ich den mal zu verwenden. Hat da jemand zufällig ein
kurzes Codebeispiel? Bei mir hakt es nämlich noch, der Slave versteht
aus irgendeinem Grund nicht, dass er angesprochen wird...

2. Frage: Existiert ein diesem Assembler-Programm ähnliches C-Programm?
Für eine C-Anfängerin wie mich wäre das nämlich echt hilfreich, da es
ewig dauert, bis man ein laufendes Programm gebastelt bekommt (mit
Datasheets, Atmel-Beispielen für andere Anwendungen, etc.)...

Danke und viele Grüße!!!

Xine.
Autor: TechInfo (Gast)
Datum: 18.06.2007 00:08

Hi Xine,

beschäftige mich auch grade mit TWI/I2C in C. Habe es mit der Procyon
avrlib zum Laufen bekommen (Tastatur und Display).

Schick mir doch mal genauere Angaben - welche Slaves willst du
ansteuern, wie ist dein Aufbau, etc.

Ich kann Dir dann meine Codebeispiele schicken.

seventh_son@gmx.de
Autor: Siem (Gast)
Datum: 03.12.2007 09:56

Ich suche im Forum seit Stunden nach so einem Beispiel in C ( =>negativ
:-( )
Hat jemand vielleicht das Beispiel hier in C übersetzt? Kann jemand
ähnliches Beispiel in C geben?

Gruß
Siem
Autor: Matt Matt (mtbmatt)
Datum: 29.12.2007 01:27

@siem: was suchst DU denn genau?
Autor: Manni (Gast)
Datum: 04.01.2008 22:04

@siem:
Ich habe heute sowas hier in Codesammlung gestellt.

Gruss
Manni

Antwort schreiben

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

Wichtige Regeln - erst lesen, dann posten!

  • Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
  • Aussagekräftigen Betreff wählen
  • Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
  • JPEG-Dateien (.jpg) nur für Fotos und Scans verwenden
  • Schaltpläne, Screenshots usw. als PNG oder GIF anhängen

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel





Hinweis: der Originalbeitrag ist mehr als 6 Monate alt.

webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net