www.mikrocontroller.net

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


Autor: Bernhard S. (bernhard)
Datum:
Angehängte Dateien:

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:

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 S. (bernhard)
Datum:

@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:

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:

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 S. (bernhard)
Datum:

@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 S. (bernhard)
Datum:

Autor: Uwe Ortmann (schwede)
Datum:

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 S. (bernhard)
Datum:

@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:

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 S. (bernhard)
Datum:
Angehängte Dateien:

@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:

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 S. (bernhard)
Datum:
Angehängte Dateien:

@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 S. (bernhard)
Datum:

@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:

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 S. (bernhard)
Datum:

@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:
Angehängte Dateien:

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 S. (bernhard)
Datum:

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:

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 S. (bernhard)
Datum:

>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:

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:

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:

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:

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:

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

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

Gruss
Manni
Autor: Hendrik Brocke (kirvandax)
Datum:

Hallo.

Ich beschäftige mich erst seit ein paar Tagen mit Microcontrollern und
bin bei der Suche nach Hilfe zur TWI Schnittstelle in diesem Thread
fündig geworden. Erste Versuche haben mit dem (gering modifizierten)
Code auch schon geklappt (nur Daten senden an einen PCF8575 I/O
Extender).

Nun wollte ich den den Code etwas aufräumen und in handliche
Unterprogramme
zerlegen und bin dabei über zwei Stellen gestolpert.

1. Warum wird beim Senden der Stardbedingung für den Receiver Teil das
TWEA Bit gesetzt? Wenn ich das richtig verstanden habe wird dadurch doch
ein ACK ausgeführt, was an der stelle eigentlich gar nicht passieren
sollte. Die Startbedingung sollte doch bei MR und MT Teil identisch
sein, oder nicht?

2. Ich habe in den Beiträgen weiter oben etwas über multiple
Fehlermeldungen bei der Kommunikation gelesen.
Diesbezüglich hätte ich eine Vermutung.
Angenommen der Slave antwortet nicht, weil z.B. die Adresse falsch ist,
dann würde, weil kein ACK kommt der Errorhandler ausgeführt. Dieser
stoppt
und initialisiert das TWI neu. Springt dann aber wieder in die
abgebrochene Kommunikation zurück:

TWI_ERROR:
....

; TWI INITIALISIERUNG
   rcall TWI_INI
  rcall wait_1s
  sbi PORTD,0
ret   <<< Diesen Rücksprung meine ich

Als nächstes sollen Daten empfangen/gesendet werden , dabei fehlen Start
und SLA+R, also gibt es wieder eine Fehlermeldung. Solange bis der Code
mit dem STOP durch ist und wieder von vorne anfängt.

So zumindest verstehe ich den Code.

Kann das jemand bestätigen bzw. mir das TWEA Bit erklären?
Danke im Voraus.

MfG
 Hendrik
Autor: Name (Gast)
Datum:

>Kann das jemand bestätigen bzw. mir das TWEA Bit erklären?

Ich lese Quelltexte von dieser Website nie, weil sie sehr oft fehlerhaft
sind und totalen Schwachfug enthalten, aber den zweiten Wunsch kann ich
dir erfüllen:

TWEA sorgt dafür, dass beim nächsten TWINT eines Empfangs auch direkt
ein ACK gesendet wird, ergo ist es die "Empfangsbestätigung" über TWI.
Autor: Nop M. (gtf)
Datum:

Hallo Bernhard Schulz,
möchte mich bei dir für das einwandfreie Beispiel bedanken!!!

Ständig erhielt ich nach SLA+R  --  NACK($48), erst nachdem ich das
Programm vom Mega 16 zu Mega 8 portierte ist dieser Fehler verschwunden.
Etweder hat mein Mega 16 einen TWI- Bug oder alle M16 sind
verbuggt(keine Ahnung).
Dann konnte ich keine Daten auslesen erst mit deiner MR_LeseRoutine ist
es mir gelungen Daten aus’m DS1307 auszulesen, was für ein tolles Gefühl
:-)
Davor habe ich mich 3 Tage mit TWI rumgeplagt.

Nochmals vielen Dank !

Mit freundlichen Grüßen
gtf
Autor: Flo S. (agemta)
Datum:
Angehängte Dateien:

hey.. ich plage mich jetzt schon fast eine Woche mit TWI rum. Ich hab
genau das Beispiel aufgebaut. 2 ATMega8 mit Leds am PORTB usw. Das
einzige was ich geändert habe ist, das ich vom Master aus nur 1 Bit
sende und der Slave es empfangen soll. Außerdem habe ich das ganze in C
gemacht. Trotzdem ist vom Aufbau alles gleich.
Mein Problem:
Adresse wird gesendet und Master erhält ACK.
Danach sendet er aber keine Daten sondern macht sofort Stop.
ich poste auch mal meine Programme.
Vllt findet jemand auf die schnelle ein Fehler?
Autor: Manni (Gast)
Datum:

Versuch's mal mit meinen Routinen, die bei mir seit langer Zeit absolut
stabil laufen.

[[Beitrag "AVR TWI Master und Slave Funtionen in C"]]

Gruss
Manni
Autor: Flo S. (agemta)
Datum:

Ich hab die Routinen ausprobiert. und siehe da.. es klappt! Frag  mich
aber trotzdem was mit meinen nicht stimmte?
Autor: Manni (Gast)
Datum:

Und schon wieder einen Baster zufrieden gestellt, ja das freut doch auch
mich :-)

Gruß
Manni
Autor: Obermayer Florian (Firma: tbd) (foikei)
Datum:

Hallo zusammen,

ich werd hier noch wahnsinnig. Ich kapier die Funktion des TWINT-Flags
einfach nicht, drum wollte ich mal vorsichtig nachfragen, ob mir einer
helfen kann (obwohl der Beitrag schon etwas älter ist).

In dem Beispiel von Bernhard S. heißt es in der MASTER.ASM unter
TWI-MASTER-RECEIVER:
TWI_MASTER_RECEIVER:
; LEDs aus                      
  ldi temp,255
  out PORTB,temp
; START                       
  ldi temp, (1<<TWINT | 1<<TWEA | 1<<TWSTA | 1<<TWEN )
  out TWCR, temp  
; warten, bis TWINT wieder = 1            
  rcall TWI_TWINT_wait
  cbi PORTB,0

LED's aus is noch ok, aber dann:
ins 'temp'-Register kommt bei TWINT ne "1" rein, und geb das ganze ins
TWCR aus. Und dann warte ich, bis TWINT wieder "1"??? Es wurde doch grad
ne 1 reingeschoben, also steht da auch gleich ne 1 drin, oder? Oder wird
das TWINT-Flag dann sofort auf 0 gezogen und kommt erst wieder auf 1,
wenn die Aktion fertig ist?

Wär echt nett, wenn mich einer auf den richtigen Weg leitet...
Danke euch!

mfg
Foikei

P.S.: wenn mein 30-Kanal-Temperatur-Logger fertig ist, stelle ich ihn
euch vor...wenn ich es denn schaffe, das TWI zu kapieren ;-)
Autor: MWS (Gast)
Datum:

Es gibt einige Flags bei den Atmels, die gelöscht werden, indem man sie
auf "1" setzt.

> Oder wird das TWINT-Flag dann sofort auf 0 gezogen und kommt erst wieder > auf
1, wenn die Aktion fertig ist?

Yep, durch Schreiben von 1 in TWINT wird es auf 0 gesetzt.
Autor: Axel Krüger (axel)
Datum:
Angehängte Dateien:

Habe mir vorgestern nen Layout nach dem Schaltplan gemacht)
Autor: Axel Krüger (axel)
Datum:
Angehängte Dateien:

...........................
Autor: Axel Krüger (axel)
Datum:
Angehängte Dateien:

Hmpf garnicht bemerkt, das die LEDs garnicht in der Reihenfolge sind -
aber ist wiegesagt auf die Schnelle geschehen..

Anbei der Assembler Code von Bernhard von der 1. Seite 1zu1 in C
uebersetzt.

gruss

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




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 erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net