<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://www.mikrocontroller.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Maybee</id>
	<title>Mikrocontroller.net - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://www.mikrocontroller.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Maybee"/>
	<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/articles/Spezial:Beitr%C3%A4ge/Maybee"/>
	<updated>2026-04-11T09:16:12Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Operationsverst%C3%A4rker-Grundschaltungen&amp;diff=107513</id>
		<title>Operationsverstärker-Grundschaltungen</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Operationsverst%C3%A4rker-Grundschaltungen&amp;diff=107513"/>
		<updated>2025-05-18T17:22:08Z</updated>

		<summary type="html">&lt;p&gt;Maybee: /* Ein- und Ausgangsbereich */ Typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Idealisiertes Modell eines OPV==&lt;br /&gt;
&lt;br /&gt;
[[Bild:Opamp-symbol.png]]&lt;br /&gt;
&lt;br /&gt;
=== Anschlüsse ===&lt;br /&gt;
Ein Operationsverstärker hat zwei Eingänge (+) und (-) und einen Ausgang&lt;br /&gt;
(UA). Außerdem verfügt er über eine positive und eine negative&lt;br /&gt;
Spannungsversorgung (V+) und (V-).&lt;br /&gt;
&lt;br /&gt;
=== Spannungsversorgungen ===&lt;br /&gt;
Die Spannungsversorgungen sollen zunächst nicht interessieren. Sie&lt;br /&gt;
werden in Schaltungen oft nicht eingezeichnet. &lt;br /&gt;
In der Praxis ist es jedoch wichtig zu wissen, dass die Ausgangsspannung immer zwischen (V+) und (V-) liegt. Die Ausgangsspannung des OPV kommt schließlich  dadurch zustande, dass der Ausgang über einen Transistor mehr oder weniger hochohmig mit den beiden Versorgungsspannungen verbunden wird.&lt;br /&gt;
&lt;br /&gt;
Wenn man einen OPV also mit +5V versorgt, so kann der OPV im besten Fall am Ausgang +5V erzeugen. Man würde in diesem Fall von einem &amp;quot;Rail-to-Rail&amp;quot; Operationsverstärker sprechen.&lt;br /&gt;
Bei vielen Operationsverstärkern ist die maximal mögliche Ausgangsspannung geringer als die Versorgungsspannung. Ein mit +5V Spannungsversorgung beschalteter OPV kann dann beispielsweise nur +4V Ausgangsspannung erzeugen.&lt;br /&gt;
&lt;br /&gt;
=== Ausgang ===&lt;br /&gt;
Der Ausgang des OPV ist eine ideale Spannungsquelle. Das bedeutet, dass die&lt;br /&gt;
Ausgangsspannung unabhängig davon ist, was ausgangsseitig an den OPV&lt;br /&gt;
angeschlossen wird.&lt;br /&gt;
In der Praxis gilt dieses Modell häufig nur bei &amp;quot;sinnvollen Anwendungen&amp;quot;. So ist beispielsweise der Ausgangsstrom des OPV nach oben begrenzt (typischerweise im mA-Bereich), und manche OPV schwingen sehr leicht, wenn man sie kapazitiv belastet.&lt;br /&gt;
&lt;br /&gt;
=== Eingänge ===&lt;br /&gt;
Die Eingänge eines OPV sind hochohmig, d. h., es handelt sich nur um &amp;quot;Messfühler&amp;quot;, die keinen Strom führen.&lt;br /&gt;
Achtung: Die Eingangsschutzbeschaltung (Dioden von GND und gegen VCC) bei manchen OPVs kann jedoch dazu führen, dass Strom in den Eingang fliesst, wenn dessen Betriebsspannung z.B. abgeschaltet ist.&lt;br /&gt;
&lt;br /&gt;
=== Funktionsweise ===&lt;br /&gt;
Der OPV mißt zu jeder Zeit die Differenz &amp;lt;math&amp;gt;U_D = U(+) - U(-)&amp;lt;/math&amp;gt; der&lt;br /&gt;
Eingangsspannungen.&lt;br /&gt;
&lt;br /&gt;
Ist die Spannung an (+) größer als an (-), so erhöht der OPV die&lt;br /&gt;
Ausgangsspannung.&lt;br /&gt;
Ist die Spannung an (+) niedriger als an (-), so vermindert der OPV die&lt;br /&gt;
Ausgangsspannung.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis dieses Vorgangs wird häufig über die Gleichung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U_a = v \cdot U_D&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
beschrieben, wobei &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; eine sehr große Zahl (10^4...10^6) ist. &lt;br /&gt;
&lt;br /&gt;
Mit Hilfe der beschriebenen Funktionsweise lassen sich alle grundlegenden Schaltungen herleiten.&lt;br /&gt;
&lt;br /&gt;
=== Beispiel ===&lt;br /&gt;
&lt;br /&gt;
Betrachtet wird die invertierende Grundschaltung nach Abbildung a) im Abschnitt [[Operationsverstärker-Grundschaltungen#Verstärkergrundschaltungen|Verstärkergrundschaltungen]].&lt;br /&gt;
&lt;br /&gt;
[[Bild:Op-verstaerker-a.png]]&lt;br /&gt;
&lt;br /&gt;
Für die Pfeilrichtungen der Spannungen und Ströme gilt:&lt;br /&gt;
* &amp;lt;math&amp;gt;U_e&amp;lt;/math&amp;gt;: von oben nach unten&lt;br /&gt;
* &amp;lt;math&amp;gt;I_{R3}&amp;lt;/math&amp;gt;: von links nach rechts&lt;br /&gt;
&lt;br /&gt;
Die Spannung am (+)Eingang ist gleich Null. Die Spannung am (-)Eingang wird durch die Spannungsquelle &amp;lt;math&amp;gt;U_e&amp;lt;/math&amp;gt; und durch die im OPV befindliche und mit dem Ausgang verbundene Spannungsquelle des OPV manipuliert.&lt;br /&gt;
&lt;br /&gt;
* Ist die Spannung am (-)Eingang negativ, so erhöht der Operationsverstärker die Ausgangsspannung. Dadurch wird durch die Rückführung über den Widerstand auch die Spannung am (-)Eingang positiver. Und zwar so lange, bis die Spannung am (-)Eingang gleich groß ist, wie die Spannung am (+)Eingang, also U(-)=0V.&lt;br /&gt;
* Ist die Spannung am (-)Eingang positiv, so vermindert der Operationsverstärker die Ausgangsspannung. Dadurch wird durch die Rückführung über den Widerstand auch die Spannung am (-)Eingang negativer. Und zwar so lange, bis die Spannung am (-)Eingang gleich groß ist, wie die Spannung am (+)Eingang, also U(-)=0V.&lt;br /&gt;
&lt;br /&gt;
Der Operationsverstärker wird also die Spannungen an (+) und (-) angleichen. Das passiert immer dann, wenn der Ausgang mit dem (-)Eingang verbunden ist. Der Trick in dieser Schaltung besteht darin, dass von der Ausgangsspannung nur ein Teil wieder rückgeführt wird. Die Spannung U_e ist daher höher, als der Teil der benötigt wird, um die Spannungen an den Eingängen aneinander anzugleichen.&lt;br /&gt;
Man nennt das Prinzip &amp;quot;Gegenkopplung&amp;quot;. Auf diese Art und Weise funktionieren alle analogen OPV-Schaltungen.&lt;br /&gt;
&lt;br /&gt;
Da an (+) Massepotential anliegt, wird somit auch (-) daran angeglichen, und so liegt an &amp;lt;math&amp;gt;R_3&amp;lt;/math&amp;gt; die Spannung &amp;lt;math&amp;gt;U_e&amp;lt;/math&amp;gt; an. Daher gilt: &lt;br /&gt;
&amp;lt;math&amp;gt;I_{R3}=\frac{U_e}{R_3}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da der (-)Eingang hochohmig ist, fließt &amp;lt;math&amp;gt;I_{R3}&amp;lt;/math&amp;gt; über &amp;lt;math&amp;gt;R_4&amp;lt;/math&amp;gt; weiter zum OPV-Ausgang.&lt;br /&gt;
&lt;br /&gt;
Ua ist die Spannung vom Ausgang zur (virtuellen) Masse am (-)Eingang.&lt;br /&gt;
(--&amp;gt; Pfeil einzeichnen und klarmachen, daß es egal ist, ob der Pfeil vom&lt;br /&gt;
Ausgang zur Masse geht oder vom Ausgang &amp;quot;entgegen der Stromrichtung&amp;quot; zur&lt;br /&gt;
virtuellen Masse an (-)!)&lt;br /&gt;
&lt;br /&gt;
Mit Hilfe von &amp;lt;math&amp;gt;I_{R3}=\frac{U_e}{R_3}&amp;lt;/math&amp;gt; ergibt sich:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U_a = -R_4 \cdot I_{R3} = -{{R_4} \over {R_3}} \cdot U_e.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Energie für den Stromtransport über &amp;lt;math&amp;gt;R_4&amp;lt;/math&amp;gt; stammt vom OPV! Sobald die Ladungen ausgehend von der Spannungsquelle &amp;lt;math&amp;gt;U_e&amp;lt;/math&amp;gt; die virtuelle Masse an (-) erreicht haben, hat &amp;lt;math&amp;gt;U_e&amp;lt;/math&amp;gt; seine gesamte Energie abgegeben.&lt;br /&gt;
&lt;br /&gt;
== Reale OPVs / Kennwerte ==&lt;br /&gt;
Abweichend vom idealen OPV besitzen reale OPVs diverse Einschränkungen und Kennwerte, die sie für verschiedene Einsätze mehr oder weniger prädestinieren.&lt;br /&gt;
&lt;br /&gt;
=== Leerlaufverstärkung ===&lt;br /&gt;
Die Leerlaufverstärkung gibt an, wie stark sich das Ausgangssignal i.A. der Änderung eines Eingangsignals statisch ändert, bzw nach dem Einschwingen erreichen könnte, wenn es nicht durch die Betriebsgrenzen limitiert wäre.&lt;br /&gt;
&lt;br /&gt;
=== Verstärkungs-Bandbreiteprodukt ===&lt;br /&gt;
Das Verstärkungs-Bandbreiteprodukt gibt an, bei welcher Verstärkung welche Bandbreite erreicht werden kann. Durch Rückkopplung kann die Verstärkung eingestellt werden. Bei kleinerer Verstärkung ergibt sich somit eine höhere Bandbreite, wenn das Produkt aus beiden konstant ist. Die Bandbreite bei der Verstärkung eins heißt Transitfrequenz (englisch &amp;quot;Unity Gain Frequency&amp;quot;). Das Verstärkungs-Bandbreiteprodukt ist entscheidend für das Kleinsignalverhalten.&lt;br /&gt;
&lt;br /&gt;
=== Anstiegsgeschwindigkeit ===&lt;br /&gt;
Bestimmend für das Großsignalverhalten ist neben dem Verstärkungs-Bandbreiteprodukt die Anstiegsgeschwindigkeit (slew rate), da bei hohen Ausgangsamplituden die Ausgangskurve eventuell zu steil wird, um richtig wiedergegeben zu werden.&lt;br /&gt;
&lt;br /&gt;
=== Gleichtaktverstärkung ===&lt;br /&gt;
Infolge des inhomogenen Aufbaus der internen Verstärkerstufen werden die beiden Eingangssignale nicht exakt gleich verstärkt, was in einen Gleichanteil und einen Differenzanteil aufgeteilt werden kann. Die nicht erwünschte Gleichtaktverstärkung bzw. ihr Gegenstück, die Gleichtaktunterdrückung (engl. &#039;&#039;common mode rejection ratio, CMRR&#039;&#039;) ist dabei ein Maß für die Qualität des OPVs. Klassische (VFB) OPV haben immer ein mit der Frequenz fallendes (-20 dB/Dekade) CMRR.&lt;br /&gt;
&lt;br /&gt;
=== Ein- und Ausgangsbereich ===&lt;br /&gt;
Wie weiter oben schon angesprochen ist die Ausgangsspannung eines OPVs begrenzt von der Versorgungsspannung und dem internen Aufbau des OPVs. Standard-OPV erreichen meist einen Ausgangsbereich, der bis circa 1-2 V an Versorgungsspannungen heran reicht, während sogenannte Rail-to-Rail (R2R) OPV sehr nah (bei niedriger Last bis auf wenige mV) an die Versorgungsspannungen herankommt. Das ist jedoch mit Abstrichen verbunden, sodass es in der Regel besser ist R2R OPV nur wenn nötig zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Ähnliche Beschränkungen gibt es auch für die Eingänge eines OPVs, hier werden im Wesentlichen drei Arten unterschieden:&lt;br /&gt;
&lt;br /&gt;
* Klassisch: Eingangsspannung darf nur bis wenige Volt an die Versorgung herankommen.&lt;br /&gt;
* Ground-Sensing: Die Eingangsspannung darf bis zur negativen Versorgung heruntergehen, klassische Vertreter sind LM324/LM358.&lt;br /&gt;
* Rail-to-Rail Input/Output (RRIO): R2R OPV, wo sowohl Eingänge als auch Ausgänge bis an die Versorgungsspannungen reichen.&lt;br /&gt;
&lt;br /&gt;
Bei klassischen Operationsverstärkern ist zu beachten, dass manche ein Verhalten namens &#039;&#039;phase reversal&#039;&#039; (Phasenumkehr) zeigen, wenn die Eingangsspannung den zulässigen Bereich überschreitet. Bei der Phasenumkehr dreht sich die Phase in der Eingangsstufe des OPVs um 180° und Rückkopplung wird zur Mitkopplung. Ein bekannter Vertreter dieser Art ist die TL06x/TL07x/TL08x Familie von OPV.&lt;br /&gt;
&lt;br /&gt;
== Verstärkergrundschaltungen ==&lt;br /&gt;
=== Grundbeschaltung mit Berechnung ===&lt;br /&gt;
[[Bild:Op-verstaerker-a.png]] [[Bild:Op-verstaerker-b.png]]&lt;br /&gt;
&lt;br /&gt;
In a) und b) verwenden wir den OPV als Verstärker und nutzen hier die Möglichkeit der Gegenkopplung, um definierte Verstärkungen zu erhalten. Wir gehen wieder davon aus, dass der OPV ein ideales Bauteil ist und daher seine Leerlaufverstärkung unendlich ist. Ebenso betrachten wir den Eingangswiderstand als unendlich.&lt;br /&gt;
&lt;br /&gt;
In &#039;&#039;&#039;a)&#039;&#039;&#039; ist ein invertierender Verstärker mit einem OPV dargestellt. Durch die Widerstände R3 und R4 wird die Verstärkung bestimmt:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;V = \frac{U_a}{U_e} = -\frac{R_4}{R_3}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Verhältnis der beiden Widerstände bestimmt also die Verstärkung und somit die Ausgangsspannung:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;U_a = -\frac{R_4}{R_3} \cdot U_e &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oder auch&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;U_a = V \cdot U_e&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das negative Vorzeichen drückt aus, dass es sich um einen invertierenden Verstärker handelt.&lt;br /&gt;
&lt;br /&gt;
Beim nichtinvertierenden Verstärker &#039;&#039;&#039;b)&#039;&#039;&#039; finden wir auch eine Rückkopplung über R6 zum invertierenden Eingang des OPVs. Die Verstärkung wird durch das Gegenkopplungsnetzwerk R6 und R7 bestimmt. Hier ist:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;V = 1 + \frac{R_6}{R_7}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Verstärkung von 1 ist sinnvoll, wenn eingangsseitig eine Spannungsquelle mit hohem Innenwiderstand verwendet wird. Für &amp;lt;math&amp;gt;\frac{R_6}{R_7} \to 0&amp;lt;/math&amp;gt; heißt die Schaltung &amp;quot;Spannungsfolger&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Kleinere Werte als 1 lassen sich nicht realisieren. Die Ausgangsspannung errechnet sich also so:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;U_a = U_e \cdot \left (1 + \frac{R_6}{R_7}\right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beispiel: Eine Eingangsspannung von 0,5 V soll auf den Wert 5 V verstärkt werden, es ist also eine Verstärkung V von 10 benötigt. R7 ist mit 10 k&amp;amp;Omega; vorgegeben. Also ist das Verhältnis&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\frac{R_6}{R_7} = V - 1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei einem Wert von 10 k&amp;amp;Omega; für R7 errechnet sich R6 zu&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
R_6 = (V - 1) \cdot R_7&lt;br /&gt;
    = (10 - 1) \cdot 10\,\mathrm{k\Omega}&lt;br /&gt;
    = 90\,\mathrm{k\Omega}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Ausgangsspannung Ua wird also:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
U_a =   U_e \cdot \left (1 + \frac{R_6}{R_7}\right )&lt;br /&gt;
   = 0{,}5\,\mathrm{V} \cdot \left (1 + \frac{90\,\mathrm{k\Omega}}{10\,\mathrm{k\Omega}}\right)&lt;br /&gt;
   = 5\,\mathrm{V}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Nichtinvertierender Verstärker mit Offset ===&lt;br /&gt;
Eine Abwandlung des nichtinvertierenden Verstärkers erlaubt es, einen konstanten Offset vorzugeben. D.h. von der zu verstärkenden Eingangsspannung U(e) wird eine konstante Spannung U(o) abgezogen und die Differenz verstärkt. Auf der Ausgangsspannung U(a) findet sich die Offsetspannung U(o) allerdings wieder.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Op-verstaerker-offset.png]]&lt;br /&gt;
&lt;br /&gt;
Es gilt:&lt;br /&gt;
&lt;br /&gt;
Offsetspannung: &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
U_o =  U_V \cdot \frac{R_2}{R_1 + R_2}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
mit U(V) = Versorgungsspannung an R1&lt;br /&gt;
&lt;br /&gt;
Verstärkung:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
V = 1 + \frac{R_3}{\frac{R_1 \cdot R_2}{R_1 + R_2}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ausgangsspannung:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
U_a = (U_e - U_o) \cdot V + U_o&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Vorteil dieser Schaltung ist, daß nur die Differenz verstärkt wird. Damit kann eine größere Verstärkung gewählt werden. Zu berücksichtigen ist dabei, dass die Ausgangsspannung U(a) um die Offsetspannung U(o) verschoben ist.&lt;br /&gt;
&lt;br /&gt;
=== Spannungsfolger (Impedanzwandler) ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:Op-spannungsfolger1.png]]&lt;br /&gt;
&lt;br /&gt;
Eine Abart des nichtinvertierenden Verstärkers stellt der Spannungsfolger dar. Beim nichtinvertierenden Verstärker errechnet sich die Ausgangsspannung aus:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;U_a = U_e \cdot \left (1 + \frac{R_2}{R_1}\right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn wir R2 auf 0Ω (mit R1 &amp;gt; 0) oder R1 auf unendlich (mit R2 &amp;lt; ∞) ändern, erhalten wir daher:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;V = 1 + \frac{R_2}{R_1} = 1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Spannungsfolger hat also eine Verstärkung V von 1.&lt;br /&gt;
&lt;br /&gt;
Umgezeichnet sieht die Schaltung dann so aus: &lt;br /&gt;
&lt;br /&gt;
[[Bild:Op-spannungsfolger2.png]]&lt;br /&gt;
&lt;br /&gt;
Man erhält den klassischen Elektrometerverstärker. Der Zweck dieser Schaltung ist die sogenannte Impedanzwandlung. Man nutzt die Eigenschaft, dass ein idealer OP einen unendlichen Eingangswiderstand und einen Ausgangswiderstand von 0Ω hat. Zwar sieht das real natürlich anders aus - so liegt der Eingangswiderstand Re bei normalen OPs in der Größenordnung von 1MOhm bis &amp;lt;math&amp;gt;10^{15} \Omega&amp;lt;/math&amp;gt;, der Ausgangswiderstand Ra im Bereich 20Ω bis 1kOhm - trotzdem kann man mit einer solchen Schaltung aus einer relativ hochohmigen Spannungsquelle eine niederohmige, durch Folgeschaltungen belastbare Spannungsquelle machen.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Op-spannungsfolger3.png|left]]&lt;br /&gt;
&lt;br /&gt;
In dem nebenstehenden Beispiel ist eine einfache Möglichkeit zur Erzeugung einer Referenzspannung gezeigt: Es kommt eine normale Stabilisierungsschaltung mit einer Z-Diode (früher &amp;quot;Zenerdiode&amp;quot;) und einem Widerstand zur Anwendung, die aber nicht mehr die schlechten Eigenschaften der Standardbeschaltung hat. Trotz des steilen Durchbruchverhaltens einer Z-enerdiode hängt die genaue Spannung davon ab, welcher Strom durch sie fließt. Dieser Strom würde sich aber ändern, wenn ein Verbraucher die Zenerdiode direkt mit einem ungleichmäßigen Stromfluss belasten würde. Als Folge davon würde die Spannungslage der Zenerdiode je nach Verbraucherlast schwanken. Durch den Spannungsfolger wird das verhindert, weil dieser den vom Verbraucher gezogenen Strom bereitstellt und durch den Widerstand an der Z-Diode praktisch immer derselbe Strom fließt. Ein Einfluss ist nur noch durch die Versorgungsspannung gegeben, weil deren Änderung einen minimal geänderten Stromfluss in der Z-Diode auslöst, der bei großen Änderungen wieder Spannungsänderungen bewirkt. Bei Chips in denen sehr genaue Spannungen benötigt werden, kommen daher 2 verkettete Stufen dieser Art zum Einsatz. Die erste stabilisiert den Eingang, die zweite den Ausgang.  &lt;br /&gt;
&lt;br /&gt;
{{Clear}}&lt;br /&gt;
&lt;br /&gt;
[[Bild:Op-spannungsfolger4.png|left]]&lt;br /&gt;
&lt;br /&gt;
Eine weitere Anwendungsmöglichkeit wäre das hochohmige Auskoppeln einer Brückenspannung. Die Brückenschaltung selbst wird durch Folgeschaltungen nicht mehr belastet, alle anderen Eigenschaften bleiben erhalten.&lt;br /&gt;
&lt;br /&gt;
{{Clear}}&lt;br /&gt;
&lt;br /&gt;
=== Der Komparator ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:Op-komp-a.png]] [[Bild:Op-komp-b.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In der einfachsten Beschaltung des Operationsverstärkers erhält man einen Komparator. Es fällt auf, dass kein Gegenkopplungsnetzwerk vorhanden ist. Der OP arbeitet daher mit seiner vollen Leerlaufverstärkung Vo. Dies bedeutet, dass bereits eine kleine Eingangsspannung genügt, um den OP in die Begrenzung zu treiben. Das heißt, die Ausgangsspannung Ua wird annähernd die Betriebsspannung erreichen.&lt;br /&gt;
&lt;br /&gt;
Achtung: nicht jeder OP ist als Komparator verwendbar! Manche haben Schutzdioden zwischen invertierendem und nichtinvertierendem Eingang, die bei einem zu großen Spannungsunterschied das Signal kurzschließen. Ob das bei einem konkreten OP-Typ der Fall ist, findet man im Datenblatt: bei den absolute maximum ratings ist die &amp;quot;Differential Input Voltage&amp;quot; angegeben. Wenn dort nur 1 bis 2 Volt stehen, ist der OP nicht als Komparator einsetzbar.&lt;br /&gt;
Die sichere Alternative ist jedoch, einen speziellen Komparator-IC  zu verwenden. Diese sind im Grunde auch nur OPs, aber für den Komparator-Betrieb optimiert. &lt;br /&gt;
&lt;br /&gt;
Beim Komparator gibt es zwei Möglichkeiten der Beschaltung: die invertierende nach a) und die nichtinvertierende Beschaltung nach b). &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Berechnungsbeispiel für Schaltung b)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Angenommen die Leerlaufverstärkung Vo von 40000 und eine Eingangsspannung von 0,1 Volt. Die Betriebsspannungen Vcc und Vee legen wir auf +/- 24 V fest. Damit ergibt sich theoretisch für Ua:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;U_a =  V_0 \cdot U_e = 40000 \cdot 0{,}1\,\mathrm{V} = 4000\,\mathrm{V}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ist natürlich ein unrealistischer Wert, da Ua nicht höher sein kann als die Betriebsspannung. Also anders ausgedrückt: Bei welcher Spannung Ue erreicht der OP seine Aussteuerungsgrenze?&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;U_e = V_{cc} / V_0 = 24\,\mathrm{V} / 40000 = 0{,}6\,\mathrm{mV}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das bedeutet, dass eine Spannung von 0,6 mV ausreicht um den Komparator in die Begrenzung zu treiben.&lt;br /&gt;
&lt;br /&gt;
Das gleiche gilt auch für den invertierenden Komparator, allerdings wird hier der OP in die negative Begrenzung gebracht.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;-U_a = V_0 \cdot U_e&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese beiden einfachsten Komparatorschaltungen werden so nur sehr selten verwendet, weil sie keine Hysterese haben. D.h. es gibt nur eine Umschaltschwelle. Dadurch kann der Ausgang schwingen, wenn das Eingangssignal sehr nah an der Umschaltschwelle liegt, weil kleinste Störungen im Signal den Komparator mehrfach schalten lassen (dafür reichen wenige mV!). Ausserdem sind Operationsverstärker als Komparator relativ langsam, das liegt am inneren Aufbau. Echte Komparatoren sind deutlich schneller und sie haben auch kein Problem damit, wenn der Ausgang in die Sättigung geht. Darum beschaltet man einen OPV bzw. Komparator meistens mit Hysterese. Das nennt man dann einen [[Schmitt-Trigger]].&lt;br /&gt;
&lt;br /&gt;
=== Der Addierer (Summierverstärker) ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:Op-addierer.png]]&lt;br /&gt;
&lt;br /&gt;
Ein als invertierender Verstärker beschalteter OP lässt sich so beschalten, dass ein Summensignal aus den Eingangsspannungen gebildet wird. Um die Funktion deutlich zu machen, ist eine Betrachtung der einzelnen Ströme nötig.&lt;br /&gt;
&lt;br /&gt;
In einem invertierenden Verstärker wird sich die Ausgangsspannung immer so einstellen, dass der invertierende Eingang Massepotential hat. Die virtuelle Masse (VM) unterscheidet sich von einer &amp;quot;normalen&amp;quot; Masse dadurch, dass das Potential durch einen Regelungsvorgang zustande kommt. &lt;br /&gt;
An der virtuellen Masse (VM) gilt die Knotenpunktregel, wonach die Summe der zufließenden Ströme gleich der Summe der abfließenden Ströme ist.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;I_1 + I_2 = -I_3&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sofern &amp;lt;math&amp;gt;U_{e1}&amp;lt;/math&amp;gt; und &amp;lt;math&amp;gt;U_{e2}&amp;lt;/math&amp;gt; bekannt sind, lässt sich die Gleichung umformen in:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\frac{U_{e1}}{R_1} + \frac{U_{e2}}{R_2} = -\frac{U_a}{R_3}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nach Ua aufgelöst ergibt sich:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;-U_a = \left (U_{e1} \cdot \frac{R_3}{R_1}\right ) + \left (U_{e2} \cdot \frac{R_3}{R_2}\right ) + ... + \left (U_{en} \cdot \frac{R_3}{R_n}\right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Einen Sonderfall gibt es, wenn die Widerstände R1 und R2 gleich sind. Dann gilt&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;R_1 = R_2 = R_x&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
und damit&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;-U_a = \frac{R_3}{R_x} \cdot (U_{e1} + U_{e2})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Der Subtrahierer (Differenzverstärker) ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:Op-subtrahierer.png]]&lt;br /&gt;
&lt;br /&gt;
Ein Subtrahierer ist die Zusammenschaltung eines invertierenden und eines nichtinvertierenden Verstärkers. Schliessen wir Punkt Ue1 nach Masse kurz und steuern Ue2 an, arbeitet die Schaltung als nichtinvertierender Verstärker. Wird Ue2 nach Masse verbunden und Ue1 angesteuert, verhält sich die Schaltung als invertierender Verstärker (R7 vorerst nicht beachten).&lt;br /&gt;
&lt;br /&gt;
Für den 1. Fall (nichtinvertierender Verstärker) gilt:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;i&amp;gt;U&amp;lt;sub&amp;gt;a&amp;lt;/sub&amp;gt; = U&amp;lt;sub&amp;gt;e2&amp;lt;/sub&amp;gt; (1 + R&amp;lt;sub&amp;gt;6&amp;lt;/sub&amp;gt;\R&amp;lt;sub&amp;gt;4&amp;lt;/sub&amp;gt; )&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für den 2. Fall (invertierender Verstärker) gilt:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;i&amp;gt;U&amp;lt;sub&amp;gt;a&amp;lt;/sub&amp;gt; = -U&amp;lt;sub&amp;gt;e1&amp;lt;/sub&amp;gt; R&amp;lt;sub&amp;gt;6&amp;lt;/sub&amp;gt;\R&amp;lt;sub&amp;gt;4&amp;lt;/sub&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der dritte Fall ist die Ansteuerung beider Eingänge:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;i&amp;gt;U&amp;lt;sub&amp;gt;a&amp;lt;/sub&amp;gt; = -U&amp;lt;sub&amp;gt;e1&amp;lt;/sub&amp;gt;  R&amp;lt;sub&amp;gt;6&amp;lt;/sub&amp;gt;\R&amp;lt;sub&amp;gt;4&amp;lt;/sub&amp;gt; + U&amp;lt;sub&amp;gt;e2&amp;lt;/sub&amp;gt;  (1 + R&amp;lt;sub&amp;gt;6&amp;lt;/sub&amp;gt;\R&amp;lt;sub&amp;gt;4&amp;lt;/sub&amp;gt; )&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Schaltung ist gut für eine Erklärung, praktisch aber taugt sie nichts. Denn liegen an den Eingängen gleiche Spannungen an, ist die Ausgangsspannung nicht 0, wie eigentlich zu vermuten wäre. Deshalb ändern wir die Schaltung und fügen R7 ein. Jetzt stellt sich am Punkt + des OPs die Spannung&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;i&amp;gt;U&amp;lt;sub&amp;gt;e2+&amp;lt;/sub&amp;gt; = U&amp;lt;sub&amp;gt;e2&amp;lt;/sub&amp;gt; R&amp;lt;sub&amp;gt;7&amp;lt;/sub&amp;gt;\(R&amp;lt;sub&amp;gt;5&amp;lt;/sub&amp;gt; + R&amp;lt;sub&amp;gt;7&amp;lt;/sub&amp;gt;)&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ein. Wenn wir das berücksichtigen, erhalten wir endlich einen richtigen Subtrahierer:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;i&amp;gt;U&amp;lt;sub&amp;gt;a&amp;lt;/sub&amp;gt; = U&amp;lt;sub&amp;gt;e2&amp;lt;/sub&amp;gt;  (1 + R&amp;lt;sub&amp;gt;6&amp;lt;/sub&amp;gt;\R&amp;lt;sub&amp;gt;4&amp;lt;/sub&amp;gt; ) R&amp;lt;sub&amp;gt;7&amp;lt;/sub&amp;gt;\(R&amp;lt;sub&amp;gt;5&amp;lt;/sub&amp;gt; + R&amp;lt;sub&amp;gt;7&amp;lt;/sub&amp;gt;) - R&amp;lt;sub&amp;gt;6&amp;lt;/sub&amp;gt;\R&amp;lt;sub&amp;gt;4&amp;lt;/sub&amp;gt;  U&amp;lt;sub&amp;gt;e1&amp;lt;/sub&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dies gilt für alle Subtrahierer, obwohl es natürlich auch hier wieder zwei Sonderfälle gibt; nämlich a) wenn alle Gegenkopplungswiderstände gleich sind:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;i&amp;gt;R&amp;lt;sub&amp;gt;6&amp;lt;/sub&amp;gt; = R&amp;lt;sub&amp;gt;7&amp;lt;/sub&amp;gt; = R&amp;lt;sub&amp;gt;4&amp;lt;/sub&amp;gt; = R&amp;lt;sub&amp;gt;5&amp;lt;/sub&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
dann ist &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;i&amp;gt;U&amp;lt;sub&amp;gt;a&amp;lt;/sub&amp;gt; = U&amp;lt;sub&amp;gt;e2&amp;lt;/sub&amp;gt; - U&amp;lt;sub&amp;gt;e1&amp;lt;/sub&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oder b) wenn die Widerstandsverhältnisse gleich sind  :&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;i&amp;gt;R&amp;lt;sub&amp;gt;6&amp;lt;/sub&amp;gt;\R&amp;lt;sub&amp;gt;4&amp;lt;/sub&amp;gt; = R&amp;lt;sub&amp;gt;7&amp;lt;/sub&amp;gt;\R&amp;lt;sub&amp;gt;5&amp;lt;/sub&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann ergibt sich für Ua:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;i&amp;gt;U&amp;lt;sub&amp;gt;a&amp;lt;/sub&amp;gt; =  (U&amp;lt;sub&amp;gt;e2&amp;lt;/sub&amp;gt; R&amp;lt;sub&amp;gt;7&amp;lt;/sub&amp;gt;\R&amp;lt;sub&amp;gt;5&amp;lt;/sub&amp;gt; ) -  (U&amp;lt;sub&amp;gt;e1&amp;lt;/sub&amp;gt; R&amp;lt;sub&amp;gt;6&amp;lt;/sub&amp;gt;\R&amp;lt;sub&amp;gt;4&amp;lt;/sub&amp;gt; )&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oder noch einfacher:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;i&amp;gt;U&amp;lt;sub&amp;gt;a&amp;lt;/sub&amp;gt; = (U&amp;lt;sub&amp;gt;e2&amp;lt;/sub&amp;gt; -U&amp;lt;sub&amp;gt;e1&amp;lt;/sub&amp;gt;)  R&amp;lt;sub&amp;gt;6&amp;lt;/sub&amp;gt;\R&amp;lt;sub&amp;gt;4&amp;lt;/sub&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Addierer/Subtrahierer mit unterschiedlichen Faktoren ===&lt;br /&gt;
Legt man nicht den + sondern den - Eingang des Operationsverstärkers als Bezugspunkt zur Masse mit einem Widerstand fest, übernimmt der Vorwiderstand vom - Eingang, R4 die Aufgabe von R5.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Op-addsub.png]]&lt;br /&gt;
&lt;br /&gt;
Hier die Schaltung die addieren und subtrahieren kann, mit unterschiedlichen Faktoren.&lt;br /&gt;
Sie kann verwendet werden für Aufgaben wie: Gesucht ist eine Schaltung, die aus 0...2.56 V eine Spannung von -10V...10V macht. Für dieses Beispiel wird hier die Dimensionierung durchgeführt:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align: left&amp;quot; &lt;br /&gt;
|&amp;lt;math&amp;gt;U_{e1} = 5\,\mathrm{V}&amp;lt;/math&amp;gt;&lt;br /&gt;
|Einfach festgelegt, muss nur ein positiver Wert sein&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;R_6 = 200\,\mathrm{k\Omega}&amp;lt;/math&amp;gt;&lt;br /&gt;
|Einfach festgelegt, könnte auch 100k oder 500k sein&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;U_{e2i} = 0\,\mathrm{V},\, U_{ai} = -10\,\mathrm{V}&amp;lt;/math&amp;gt;&lt;br /&gt;
|gewählter momentaner &#039;&#039;Zustand 1&#039;&#039;, Ue2 = 0V ist günstig für Berechnung, Ua ist die dazupassende Ausgangsspannung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;U_{e2ii} = 2{,}56\,\mathrm{V},\, U_{aii} = 10\,\mathrm{V}&amp;lt;/math&amp;gt;&lt;br /&gt;
|gewählter beliebiger &#039;&#039;Zustand 2&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;U_m = U_{e2}&amp;lt;/math&amp;gt;&lt;br /&gt;
|Gleichgewicht am Eingang&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;I_a + I_b = I_c&amp;lt;/math&amp;gt;&lt;br /&gt;
|In den Eingang fließt &amp;quot;kein&amp;quot; Strom&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\frac{U_a-U_{e2}}{R_6} + \frac{U_{e1}-U_{e2}}{R_4} = \frac{U_{e2}}{R_c}&amp;lt;/math&amp;gt;&lt;br /&gt;
|Gleichung mit den Unbekannten R4 und Rc&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\frac{U_{ai}-U_{e2i}}{R_6} + \frac{U_{e1}-U_{e2i}}{R_4} = \frac{U_{e2i}}{R_c}&amp;lt;/math&amp;gt;&lt;br /&gt;
|Variablen für &#039;&#039;Zustand 1&#039;&#039; eingesetzt, bildet 1. Gleichung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;\frac{U_{aii}-U_{e2ii}}{R_6} + \frac{U_{e1}-U_{e2ii}}{R_4} = \frac{U_{e2ii}}{R_c}&amp;lt;/math&amp;gt;&lt;br /&gt;
|Variablen für &#039;&#039;Zustand 2&#039;&#039; eingesetzt, bildet 2. Gleichung&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;R_4=-\frac{R_6\cdot U_{e1}}{U_{ai}}&amp;lt;/math&amp;gt;&lt;br /&gt;
|2 Gleichungen mit 2 Unbekannten, Lösung durch Umformen der 1. Gleichung nach R4 und einsetzen von Ue2i=0 (freundlicherweise fällt die 2. Unbekannte dabei raus)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;R_4 = 100\,\mathrm{k\Omega}&amp;lt;/math&amp;gt;&lt;br /&gt;
|restliche Werte eingesetzt&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;R_c=\frac{R_6\cdot U_{e1}\cdot U_{e2ii}}{U_{aii}\cdot U_{e1}-U_{ai}\cdot (U_{e1}-U_{e2ii})-U_{e1}\cdot U_{e2ii}}&amp;lt;/math&amp;gt;&lt;br /&gt;
|Ergebnis für R4 in die 2. Gleichung einsetzen und Umformen nach Rc&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;math&amp;gt;R_c = 41{,}6\,\mathrm{k\Omega}&amp;lt;/math&amp;gt;&lt;br /&gt;
|Werte eingesetzt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Der Instrumenten-Verstärker ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:Instrument.png]]&lt;br /&gt;
&lt;br /&gt;
Ein Nachteil des Subtrahierers ist sein geringer Eingangswiderstand. Um den nahezu unendlichen Eingangswiderstand des verwendeten Operationsverstärkers zu erreichen, kann man einfach vor beide Eingänge je einen Impedanzwandler vorschalten.&lt;br /&gt;
Die hier beschriebene Schaltung ist um drei Widerstände erweitert und ermöglicht die Einstellung der Differenz-Verstärkung über nur einen Widerstand, nämlich R2.&lt;br /&gt;
&lt;br /&gt;
Am invertierenden Eingang von IC1A gilt (Knotenregel):&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\frac{U_{a1}-U_{e1}}{R_1}-\frac{U_{e1}-U_{e2}}{R_2}=0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Am invertierenden Eingang von IC1C gilt (Knotenregel):&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\frac{U_{a2}-U_{e2}}{R_1}+\frac{U_{e1}-U_{e2}}{R_2}=0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Subtrahiert man die beiden Gleichungen voneinander, erhält man:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;U_{a2}-U_{a1}=(U_{e2}-U_{e1})\cdot\left (1+\frac{2\cdot R_1}{R_2}\right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Letztere Differenz ist die Eingangsspannung eines normalen Subtrahierers mit der Verstärkung 1.&lt;br /&gt;
&lt;br /&gt;
Also ergibt sich als Ausgangsspannung:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;U_a=(U_{e2}-U_{e1}) \cdot \left (1+\frac{2\cdot R_1}{R_2}\right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Differenzverstärkung beträgt demnach:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;V=\left (1+\frac{2\cdot R_1}{R_2} \right )&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anwendung: Auswertung von Brückenschaltungen, wie Drucksensoren oder Dehnungsmessstreifen, die durch den Eingangswiderstand der Messschaltung nicht belastet werden dürfen.&amp;lt;br&amp;gt;&lt;br /&gt;
Instrumenten-Verstärker kann man auch fertig kaufen. Im INA102 ist die komplette Schaltung integriert. Für R2 sind 3 verschiedene Werte eingebaut, die bei passender Verschaltung eine Verstärkung von 1, 10, 100 oder 1000 ermöglichen.&lt;br /&gt;
&lt;br /&gt;
Da die Gleichtaktunterdrückung hauptsächlich von der Übereinstimmung der Widerstände abhängt, sind für viele Standardanwendungen, insbesondere solche mit niedriger erforderlicher Bandbreite, integrierte Instrumentenverstärker zu bevorzugen.&lt;br /&gt;
&lt;br /&gt;
=== Der Potentialdifferenzverstärker ===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Potentialdifferenzverstärker.png|400px]]&lt;br /&gt;
&lt;br /&gt;
Der Potentialdifferenzverstärker ist eine OPV-Schaltung zum gewichteten Addieren und Subtrahieren beliebiger Spannungen.&lt;br /&gt;
&lt;br /&gt;
Falls die Bedingung &lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\sum\frac{R_{0}}{R_{i}}=\sum\frac{R_{0}^{&#039;}}{R_{i}^{&#039;}}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
erfüllt ist, vereinfacht sich der Term für die Ausgangsspannung zu folgendem Term:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
U_{a}=\sum\frac{R_{0}^{&#039;}}{R_{i}^{&#039;}}U_{i}^{&#039;}-\sum\frac{R_{0}}{R_{i}}U_{i}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenschaltungen ==&lt;br /&gt;
&lt;br /&gt;
=== Der Integrator ===&lt;br /&gt;
&lt;br /&gt;
Der Integrator wird verwendet, um die Integration eines Signales vorzunehmen. Sein Verhalten entspricht im wesentlichem der mathematischen Integration.&lt;br /&gt;
&lt;br /&gt;
=== Der Differentiator ===&lt;br /&gt;
&lt;br /&gt;
Der Differentiator wird verwendet, um die Differentiation (Ableitung) eines Signales vorzunehmen. Er funktioniert ähnlich wie ein Hochpass. Die Ausgangsspannung ist proportional zur Änderung der Eingangsspannung. Die Dimensionierung für eine stabile Funktion ist nicht ganz einfach, dadurch wird diese Schaltung selten verwendet.&lt;br /&gt;
&lt;br /&gt;
=== Der Logarithmierer ===&lt;br /&gt;
&lt;br /&gt;
Logarithmierer werden mit der Kennlinie einer Diode konstruiert, die einen eingeprägten Strom in eine Spannung übersetzt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Potenzieren ===&lt;br /&gt;
&lt;br /&gt;
= Spannungsversorgung und Beschaltung =&lt;br /&gt;
&lt;br /&gt;
== Betrieb mit einfacher Versorgungsspannung ==&lt;br /&gt;
&lt;br /&gt;
Häufig möchte man eine Wechselspannung wie z.B. ein Audiosignal, das auch negative Spannungen enthält, mit einem Opamp verstärken, hat aber nur eine einfache, in Bezug zu Masse positive Versorgungsspannung zur Verfügung. Dafür bieten sich folgende Schaltungen an, die in der Literatur leider häufig vernachlässigt werden.&lt;br /&gt;
&lt;br /&gt;
Durch die Kondensatoren können die Operationsverstärker in geeigneten Arbeitspunkten betrieben werden, obwohl die Eingangs- und Ausgangsspannungen echte Wechselspannungen sind. Nachteil ist die Hochpasswirkung der Kondensatoren in Verbindung mit den verwendeten Widerständen. Die Grenzfrequenz der Hochpässe muss tief genung gewählt werden, um den gewünschten Frequenzbereich verstärken zu können. Zur Verstärkung von Gleichspannungen (z.B. aus Temperatursensoren) sind diese Schaltungen nicht geeignet. &lt;br /&gt;
&lt;br /&gt;
=== Nichtinvertierender Verstärker ===&lt;br /&gt;
&lt;br /&gt;
[[Bild: Ss_opamp1.png]]&lt;br /&gt;
&lt;br /&gt;
Der positive Eingang wird mit einem Spannungsteiler (R3 und R5) auf die halbe Betriebsspannung gelegt. Dieser Spannung wird dann die zu verstärkende Eingangswechselspannung überlagert. Mit den Kondensatoren am Eingang (C1) und Ausgang (C2) wird der Gleichspannungsanteil abgekoppelt.&lt;br /&gt;
&lt;br /&gt;
Die Verstärkung hat in diesem Beispiel für Wechselspannung den Wert 11 (Formel wie oben), für Gleichspannung aber den Wert 1, da C4 für Gleichspannung einen unendlichen Widerstand darstellt. C3 sollte dorthin führen, wo das Eingangssignal seinen Bezugspunkt hat, also die Abschirmung der Cinch-Buchse, während R5 dorthin führt, von wo der Operationsverstärker seine negative Versorgungsspannung bekommt, falls das nicht die gleichen Potentiale, hier GND, sein sollten.&lt;br /&gt;
&lt;br /&gt;
=== Invertierender Verstärker ===&lt;br /&gt;
&lt;br /&gt;
Das Prinzip funktioniert analog auch für die invertierende Beschaltung:&lt;br /&gt;
&lt;br /&gt;
[[Bild: Ss_opamp2.png]]&lt;br /&gt;
&lt;br /&gt;
== Betrieb mit negativer Hilfsspannung ==&lt;br /&gt;
&lt;br /&gt;
Alternativ lässt sich auch eine negative Hilfsspannung erzeugen. Damit bekommt der Operationsverstärker seine &amp;quot;Plus-Minus&amp;quot;-Versorgung, und er kann Wechselspannungen um das Ground-Potential herum problemlos verstärken.&lt;br /&gt;
&lt;br /&gt;
Die negative Hilfsspannung erzeugt man zweckmässigerweise mit einer Ladungspumpe. Dazu bieten sich zwei Möglichkeiten an:&lt;br /&gt;
&lt;br /&gt;
* einen speziellen IC nach der Art eines ICL 7660&lt;br /&gt;
* eine Rechteckspannung auf einen Spannungsverdoppler geben. Dieser besteht aus 2 Dioden und 2 Kondensatoren. Die Konfiguration sollte natürlich so sein, dass eine negative Hilfsspannung erzeugt wird. Schaltbeispiele gibt&#039;s im Netz. Als Rechteckspannung kann ein unbenutzter PWM-Ausgang dienen, der mit 50% Tastverhältnis läuft.&lt;br /&gt;
&lt;br /&gt;
Ein Ripple auf der negativen Hilfsspannung wird von modernen Operationsverstärkern wirkungsvoll unterdrückt. Die PSRR (power supply rejection ratio) weist oft Werte um 120 dB auf (bei 120 Hz, darüber fällt sie meist mit 20 dB/Dekade).&lt;br /&gt;
&lt;br /&gt;
Siehe auch http://de.wikipedia.org/wiki/Ladungspumpe#Negative_Ausgangsspannungen&lt;br /&gt;
&lt;br /&gt;
= Kaufempfehlung =&lt;br /&gt;
LM358 2 OPs in einem Gehäuse oder &lt;br /&gt;
LM324 4 OPs in einem Gehäuse&lt;br /&gt;
&lt;br /&gt;
MCP6001/6004 CMOS OPs mit Rail to Rail Input und Output, tiefem Stromverbrauch, und geringer Versorgungsspannung&lt;br /&gt;
&lt;br /&gt;
Preis jeweils ca. 0,30€ aus Deutschland oder ca. 2 bis 4 cent aus China (AliExpress, ebay, …).&lt;br /&gt;
&lt;br /&gt;
Siehe auch [[Standardbauelemente#Operationsverst.C3.A4rker|Standardbauelemente - Operationsverstärker]].&lt;br /&gt;
&lt;br /&gt;
Wer Audio OpAmps sucht - tangentsoft.net hat mal welche unter die Lupe genommen: [http://www.tangentsoft.net/audio/opamps.html Notes on Audio OpAmps]&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
* [[Schmitt-Trigger]]&lt;br /&gt;
* [[Aktiver RC-Bandpass]]&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/396747#4567112 Forumsbeitrag]: Pegelanpassung 0 bis 3V auf -15 bis +20V&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/466046?goto=5686087#5686087 Forumsbeitrag]: Strommessung an der Versorgungsspannung, Fehlerbetrachtung und verbesserte Schaltung&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/510652?goto=6542833#6542656 Forumsbeitrag]: &amp;quot;bouncing ball&amp;quot; Schaltung gesucht&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/512469#6575560 Forumsbeitrag]: Maximum von zwei 4-20mA Eingängen auf einen 4-20mA Ausgang bilden&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/514936#new Forumsbeitrag]: 1500V Linearverstärker&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/519089#6704061 Forumsbeitrag]: Suche OpAmp RRIO bis 36V out&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/524737?goto=6822386#6820279 Forumsbeitrag]: Sinusgenerator mit HV-Endstufe gesucht&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/532820?goto=6981066#6980991 Forumsbeitrag]: Differenzverstärker für hohe Eingangsspannungen&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/158333?goto=2439071#2439071 Forumsbeitrag]: Audioverstärker mit +/-120V Ausgangsspannung&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/555507?goto=7434148#7434148 Forumsbeitrag]: High Voltage Amplifier&lt;br /&gt;
&lt;br /&gt;
= Weblinks =&lt;br /&gt;
*[http://www.ti.com/ww/en/bobpease/assets/AN-31.pdf AN-31] - National Semiconductor Application Note 31 mit vielen weiteren OP-Schaltungen&lt;br /&gt;
*[https://e2echina.ti.com/cfs-file/__key/telligent-evolution-components-attachments/00-52-01-00-00-04-59-46/OP-amp-for-everyone.pdf Op Amps for Everyone], sehr umfangreiches Dokument zu OPV und deren Anwendung, englisch &amp;lt;!-- ursprünglicher Link ist tot: http://www-s.ti.com/sc/psheets/slod006b/slod006b.pdf, ebenso http://www.foxcomputer.se/Op%20Amps%20For%20Everyone%20SLOD006B.pdf --&amp;gt;&lt;br /&gt;
* [http://www.elektronik-kompendium.de/sites/bau/0209092.htm Operationsverstärker im ElKo]&lt;br /&gt;
*[http://www.inf.fu-berlin.de/lehre/WS00/peg/folien/Peg_v7a.pdf OP Teil 1], [http://www.inf.fu-berlin.de/lehre/WS00/peg/folien/Peg_v7b.pdf OP Teil 2] - OP-Schaltungen (deutsch)&lt;br /&gt;
* [http://www.roboternetz.de/wissen/index.php/Operationsverst%C3%A4rker RN-Wissen Operationsverstärker]&lt;br /&gt;
* [http://www.national.com/AU/design/0,4706,268_0_,00.html Online Seminar] von National Semiconductor&lt;br /&gt;
* [http://www.franzis.de/elo-das-magazin/grundlagen-und-ausbildung/operationsverstaerker/der-operationsverstaerker ELO-Online-Magazin, Franzis-Verlag], [http://www.franzis.de/online-shop/elektronik/lernpakete-elektronik/lernpaket-elektronik-mit-ics Lernpaket Elektronik mit ICs] &amp;quot;Elektronische Experimente mit integriertem Schaltkreis&amp;quot;, Kasten mit Steckbrett/Bauelementen (ca. 40EUR), &lt;br /&gt;
* [https://web.archive.org/web/20130828131053/http://elektronikwissen.net/opamp/9-opamp-wissen.html OpAmp Praxis], Praktikertipps + schwingende Operationsverstärker in den Griff bekommen &amp;lt;!-- ursprünglicher Link ist tot --&amp;gt;&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Frequency_multiplier Frequenzvervielfacher]&lt;br /&gt;
* [https://sound-au.com/appnotes/an001.htm Präzisionsgleichrichter], engl.&lt;br /&gt;
* [https://play.google.com/store/apps/details?id=com.wdcreative.elektropro ElektroEasy-App], Berechnung von OPVs&lt;br /&gt;
* [http://www.elektronikinfo.de/strom/operationsverstaerker.htm Grundlagen Operationsverstärker]&lt;br /&gt;
* [http://www.elektronikinfo.de/strom/op_rauschen.htm Rauschverhalten von OpAmps]&lt;br /&gt;
* [https://www.edn.com/class-ab-inverting-amp-uses-two-floating-amplifier-cells/ Class AB inverting amp uses two floating-amplifier cells], HV-Verstärker mit +/-500V Ausgangsspannung&lt;br /&gt;
* [https://www.youtube.com/watch?v=qNeOWJz2oUw#t=21m11s A deeper insight into Differential Amplifiers with high common mode voltage], Youtube-Video&lt;br /&gt;
* [http://www.rinck-electronics.de/ Rinck Electronics GmbH], Messtechnik - Stromversorgung - Anzeigen - Handbedienebenen&lt;br /&gt;
* [https://www.youtube.com/watch?v=1voyXXpq-k0#t=27m TSP #246] - High-Voltage Amplification, Signal Generation, Power Supply Design Tutorial &amp;amp; Experiments&lt;br /&gt;
* [https://tlk-energy.de/blog/pid-regler-einstellen PID Regler einstellen]&lt;br /&gt;
* [https://www.youtube.com/playlist?list=PLMKxBlyAyypxuaI7pbfRkSryvTDef_Y1S The Bob Pease Show], Youtube Playlist&lt;br /&gt;
* [https://www.youtube.com/watch?v=qC7hrYJVvD8 Was macht ein PID-Regler?] Youtube Video (engl.)&lt;br /&gt;
&lt;br /&gt;
[[Category:Grundlagen]]&lt;br /&gt;
[[Category:Bauteile]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Entprellung&amp;diff=94343</id>
		<title>Entprellung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Entprellung&amp;diff=94343"/>
		<updated>2016-11-13T15:53:59Z</updated>

		<summary type="html">&lt;p&gt;Maybee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Problembeschreibung ==&lt;br /&gt;
Mechanische stromführende Komponenten wie [[Schalter]] und [[Taster]] neigen beim Ein- und Ausschalten zum sogenannten &#039;&#039;&#039;Prellen&#039;&#039;&#039;, d.h sie schalten schnell mehrfach aus und ein, was durch mechanische Vibrationen des Schaltkontaktes verursacht wird, sofern sie nicht mit aufwändigen mechanischen Maßnahmen dagegen geschützt sind. Besonders die [[Drehgeber]] sind aufgrund der Raststellungen und der Bewegung des Bedieners dafür empfindlich. Auch optoelektronische Bauelemente und chemische Kontaktschalter, sowie Flüssigkeitsschalter haben das Problem.&lt;br /&gt;
&lt;br /&gt;
Vereinfacht dargestellt, sieht eine von einem prellenden Schalter oder Taster geschaltete Spannung wie folgt aus:&lt;br /&gt;
[[Bild:Entprellen.png]]&lt;br /&gt;
&lt;br /&gt;
Es existieren also mehrere kurze Einschaltimpulse, welche bei Tastern als Mehrfachbefehl und bei Drehgebern als falsche Winkelbewegung interpretiert werden kann. Bei Schaltern wiederum, kommt es in der elektronischen Baugruppe zu mehreren Resets und Einschaltvorgängen, die unnötig Strom ziehen oder im schlechtesten Fall die Schaltung stressen oder beschädigen können. Wichtige Schalter und solche, die hohe Ströme führen sollen, werden dazu mit geeigneten Maßnahmen wie Redundanz, Stufenschaltkonzepten oder bei Gas- und Flüssigkeitschaltern durch elektrochemische Maßnahmen abgesichert. Bei einfachen Schaltern spart man sich dies jedoch.&lt;br /&gt;
&lt;br /&gt;
Da es bei diesen einfachen, ungeschützten Schaltern keine sichere Möglichkeit gibt, diese Effekte zu vermeiden, muss das falsche Signal durch die Elektronik sinnvoll ausgewertet werden. Dafür gibt es verschiedene Ansätze:&lt;br /&gt;
&lt;br /&gt;
== Hardwareentprellung ==&lt;br /&gt;
&lt;br /&gt;
===Prellfreie Schalter===&lt;br /&gt;
&lt;br /&gt;
Wie bereits angedeutet, hält die elektromechanische Industrie für Spezialanwendungen verschiedene Sonderkonstruktionen bereit, die saubere Schaltzustände nach Aussen generieren, indem sie entweder eine mechanische Dämpfung in Form eines selbsthemmenden Federmechanismus oder eine integrierte elektronische Signalverzögerung benutzen. Solche Systeme sind jedoch teuer und werden meist nur im Leistungsbereich eingesetzt. Zudem sind sie nicht 100% sicher und fallen alterungsbedingt aus. Wo immer es geht, werden daher weitere Maßnahmen getroffen, ein Prellen zu unterdrücken.&lt;br /&gt;
&lt;br /&gt;
===Wechselschalter===&lt;br /&gt;
&lt;br /&gt;
Für die Entprellung von Wechselschaltern (engl. Double Throw Switch) kann ein klassisches RS-[[Flipflop]] genutzt werden. Bei dieser Variante werden neben zwei NAND-Gattern nur noch zwei Pull-Up Widerstände benötigt.&lt;br /&gt;
&lt;br /&gt;
[[Bild:NAND_debouncer.png|thumb|left|350px|&#039;&#039;&#039;Taster entprellen mit NAND-RS-Flipflop&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der gezeigten Schalterstellung liegt an der Position /S der Pegel 0 an. Damit ist das Flipflop gesetzt und der Ausgang auf dem Pegel 1. Schließt der Schalter zwischen den Kontakten 2 und 3, liegt an der Postion /R der Pegel 0 an. Dies bedeutet, dass der Ausgang des Flipflops auf den Pegel 0 geht. Sobald der Schalter von einem zum anderen Kontakt wechselt, beginnt er in der Regel zu prellen. Während des Prellens wechselt der Schalter zwischen den beiden Zuständen &amp;quot;Schalter berührt Kontakt&amp;quot; und &amp;quot;Schalter ist frei in der Luft&amp;quot;. Der Ausgang des Flipflops bleibt in dieser Prellzeit aber stabil, da der Schalter während des Prellens nie den gegenüberliegenden Kontakt berührt und das RS-Flipflop seinen Zustand allein halten kann. Die Prellzeit ist stark vom Schaltertyp abhängig und liegt zwischen 0,1 und 10ms. Die Dimensionierung der Widerstände ist relativ unkritisch. Als Richtwert können hier 100kOhm verwendet werden.&lt;br /&gt;
&lt;br /&gt;
====Wechselschalter ohne Flip-Flop====&lt;br /&gt;
&lt;br /&gt;
Wenn man mal gerade kein Flip-Flop zur Hand hat, kann man sich auch mit dieser Schaltung behelfen.&lt;br /&gt;
&lt;br /&gt;
[[Bild:WechselEntprellC.PNG|thumb|left|350px|&#039;&#039;&#039;Wechsler entprellen mit Kondensator&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zur Funktionsweise:&lt;br /&gt;
Beim Umschalten wird der Kondensator immer sofort umgeladen.&lt;br /&gt;
Während der Kontakt prellt, befindet er sich in der Luft und hat keinerlei Verbindung. Während dieser Zeit übernimmt der Kondensator das halten des Pegels.&lt;br /&gt;
&lt;br /&gt;
Dimensionierung:&lt;br /&gt;
Ist der entprellte Taster an ein IC Angeschlossen, ist der &#039;&#039;Input Leakage Current&#039;&#039; der ausschlaggebende Strom. Falls weitere Ströme fließen sind diese mit zu berücksichtigen. Bei einem Mikrocontroller von Atmel sind 1µA typisch.&lt;br /&gt;
Es gilt:&lt;br /&gt;
:&amp;lt;math&amp;gt;\frac{dU}{dt} = \frac{I}{C}&amp;lt;/math&amp;gt;&lt;br /&gt;
Da eine Prellung ca. 10ms dauert und die Spannung in dieser Zeit beispielsweise um maximal 0,5V fallen soll kommt man auf folgende Kapazität:&lt;br /&gt;
:&amp;lt;math&amp;gt; C = \frac{I \cdot dt}{dU} = \frac{1\mu A \cdot 10ms}{0,5V} = 20nF &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um Stromspitzen zu verringern kann ein Widerstand mit eingefügt werden. Eine Zeitkonstante von 1µs bis 1ms scheint sinnvoll. Also 500 Ohm bis 500kOhm sind nutzbar, wobei bei niedrigem Widerstand die Stromspitzen höher sind, und bei 500kOhm der Pinstrom störend wird.&lt;br /&gt;
&lt;br /&gt;
===Einfacher Taster===&lt;br /&gt;
&lt;br /&gt;
Auch wenn das RS-Flipflop sehr effektiv ist, wird diese Variante der Entprellung nur selten angewendet. Grund dafür ist, dass in Schaltungen häufiger einfache Taster eingesetzt werden. Diese sind oft kleiner und preisgünstiger. Um einfache Taster (engl. Single Throw Switch) zu entprellen, kann ein einfacher RC-Tiefpass eingesetzt werden. Hierbei wird ein Kondensator über einen Widerstand je nach Schalterstellung auf- oder entladen. Das RC-Glied bildet einen Tiefpass, sodass die Spannung über den Kondensator nicht von einen Pegel auf den anderen springen kann.&lt;br /&gt;
&lt;br /&gt;
[[Bild:RC_debouncer.png|thumb|left|300px|Taster entprellen mit RC-Entpreller]]&lt;br /&gt;
&lt;br /&gt;
[[Datei:Entprellen1a.png|thumb|350px| Entstehender Spannungsverlauf]]&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
Wenn der Schalter geöffnet ist, lädt sich der Kondensator langsam über die beiden Widerstände R&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; und R&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; auf V&amp;lt;sub&amp;gt;cc&amp;lt;/sub&amp;gt; auf. Beim Erreichen der Umschaltschwelle springt der Ausgang auf den Pegel 0. Wird der Schalter geschlossen, entlädt sich der Kondensator langsam über den Widerstand R&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;. Demnach ändert sich der Ausgang des Inverters auf den Pegel 1. Während der Taster prellt, kann sich die Spannung über dem Kondensator nicht sprunghaft ändern, da das Auf- und Entladen eher langsam über die Widerstände erfolgt. Außerdem sind die Schaltschwellen für den Übergang LOW-&amp;gt;HIGH und HIGH-&amp;gt;LOW stark verschieden (Hysterese, siehe Artikel [[Schmitt-Trigger]]). Bei richtiger Dimensionierung der Bauelemente wird somit der Ausgang des Inverters prellfrei.&lt;br /&gt;
&lt;br /&gt;
Zu beachten ist, dass der Inverter &#039;&#039;&#039;unbedingt&#039;&#039;&#039; einer mit [[Schmitt-Trigger]]-Eingängen sein muss, weil bei Standard-Logikeingängen im Bereich von üblicherweise 0,8V - 2,0V der Ausgang nicht definiert ist. Als Inverter kann zum Beispiel der 74HC14 oder der CD40106 (pinkompatibel) eingesetzt werden. Alternativ kann auch ein CD4093 eingesetzt werden. Bei dem CD4093 handelt es sich um NAND-Gatter mit Schmitt-Trigger-Eingängen. Um aus einem NAND-Gatter einen Inverter zu machen, müssen einfach nur die beiden Eingänge verbunden werden oder ein Eingang fest auf HIGH gelegt werden.&lt;br /&gt;
&lt;br /&gt;
Für eine geeignete Dimensionierung muss man etwas mit den Standardformeln für einen Kondensator jonglieren. Die Spannung über den Kondensator beim Entladen berechnet sich nach:&lt;br /&gt;
:&amp;lt;math&amp;gt;U_C(t) = U_0 \cdot e^{\frac{-t}{R_2 C_1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit der Ausgang des Inverters stabil ist, muss die Spannung über den Kondensator und damit die Spannung am Eingang des Inverters über der Spannung bleiben, bei welcher der Inverter umschaltet. Diese Schwellwertspannung ist genau die zeitabhängige Spannung über den Kondensator.&lt;br /&gt;
:&amp;lt;math&amp;gt;U_C(t)\!\ = U_{th}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Durch Umstellen der Formel ergibt sich nun:&lt;br /&gt;
:&amp;lt;math&amp;gt;R_2=\frac{-t}{C_1 \cdot ln\left(\frac{U_{th}}{U_0} \right)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Taster prellt üblicherweise etwa 10ms. Zur Sicherheit kann bei der Berechnung des Widerstandes eine Prellzeit von 20ms angenommen werden. U_0 ist die Betriebsspannung also Vcc. Die Schwellwertspannung muss aus dem Datenblatt des eingesetzten Schmitt-Triggers abgelesen werden. Beim 74HC14 beträgt der gesuchte Wert 2,0V. Nimmt man für den Kondensator 1µF und beträgt die  Betriebsspannung 5V, ergibt sich für den Widerstand ein Wert von etwa 22kOhm.&lt;br /&gt;
&lt;br /&gt;
Wird der Schalter geöffnet, lädt sich der Kondensator nach folgender Formel auf:&lt;br /&gt;
:&amp;lt;math&amp;gt;U_C(t) = U_0 \cdot \left( 1-e^{\frac{-t}{(R_1+R_2)\cdot C_1}} \right)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit U_th=U_C ergibt das Umstellen nach (R_1+R_2):&lt;br /&gt;
:&amp;lt;math&amp;gt;R_1+R_2 = \frac{-t}{C_1 \cdot ln\left(1-\frac{U_{th}}{U_0} \right)} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für die Schwellspannung lässt sich aus dem Datenblatt ein Wert von 2,3V ablesen. Mit diesem Wert und den Annahmen von oben ergibt sich für R_1+R_2 ein Wert von 32kOhm. Somit ergibt sich für R_1 ein Wert von etwa 10kOhm.&lt;br /&gt;
&lt;br /&gt;
Anmerkung: Beim 74LS14 von Hitachi z.&amp;amp;nbsp;B. sind die oberen und unteren Schaltschwellwerte unterschiedlich. Es muss darauf geachtet werden, dass U_{th} beim Entladen die untere Schwelle und U_{th} beim Laden die obere Schwelle einnimmt.&lt;br /&gt;
&lt;br /&gt;
== Softwareentprellung ==&lt;br /&gt;
&lt;br /&gt;
In den Zeiten der elektronischen Auswertung von Tastern und Schaltern ist das softwaretechnische Entprellen oft billiger, als die Benutzung eines teuren Schalters. Daher werden heute z.B. auch Computertastaturen nicht mehr mit prellarmen Tasten oder Entprellkondensatoren ausgestattet.&lt;br /&gt;
&lt;br /&gt;
Bei Verwendung des in den meisten Geräten ohnehin vorhandenen Mikrocontrollers z.B., kann man sich die zusätzliche Hardware sparen, da die Entprellung in Software praktisch genauso gut funktioniert. Dabei ist nur zu beachten, dass zusätzliche Rechenleistung und je nach Umsetzung auch einige Hardwareressourcen (z.B. Timer) benötigt werden. Dafür hat man aber den Vorteil, kurze Pulse, die offensichtlich keine Tastenbetätigung sein können sondern z. B. durch Einstreuungen hervorgerufen werden, einfach ausfiltern zu können.&lt;br /&gt;
&lt;br /&gt;
=== Flankenerkennung ===&lt;br /&gt;
Bei einem Taster gibt es insgesamt 4 theoretische Zustände:&lt;br /&gt;
&lt;br /&gt;
* 1. war nicht gedrückt und ist nicht gedrückt&lt;br /&gt;
* 2. war nicht gedrückt und ist gedrückt (steigende Flanke)&lt;br /&gt;
* 3. war gedrückt und ist immer noch gedrückt&lt;br /&gt;
* 4. war gedrückt und ist nicht mehr gedrückt (fallende Flanke)&lt;br /&gt;
&lt;br /&gt;
Diese einzelnen Zustände lassen sich jetzt bequem abfragen/durchlaufen. Die Entprellung geschieht dabei durch die ganze Laufzeit des Programms. Die Taster werden hierbei als Active-Low angeschlossen, um die internen Pull-Ups zu nutzen.&lt;br /&gt;
&lt;br /&gt;
Diese Routine gibt für den Zustand &amp;quot;steigende Flanke&amp;quot; den Wert &amp;quot;1&amp;quot; zurück, sonst &amp;quot;0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define TASTERPORT PINC&lt;br /&gt;
#define TASTERBIT PINC1&lt;br /&gt;
&lt;br /&gt;
char taster(void)&lt;br /&gt;
{&lt;br /&gt;
    static unsigned char zustand;&lt;br /&gt;
    char rw = 0;&lt;br /&gt;
&lt;br /&gt;
    if(zustand == 0 &amp;amp;&amp;amp; !(TASTERPORT &amp;amp; (1&amp;lt;&amp;lt;TASTERBIT)))   //Taster wird gedrueckt (steigende Flanke)&lt;br /&gt;
    {&lt;br /&gt;
        zustand = 1;&lt;br /&gt;
        rw = 1;&lt;br /&gt;
    }&lt;br /&gt;
    else if (zustand == 1 &amp;amp;&amp;amp; !(TASTERPORT &amp;amp; (1&amp;lt;&amp;lt;TASTERBIT)))   //Taster wird gehalten&lt;br /&gt;
    {&lt;br /&gt;
         zustand = 2;&lt;br /&gt;
         rw = 0;&lt;br /&gt;
    }&lt;br /&gt;
    else if (zustand == 2 &amp;amp;&amp;amp; (TASTERPORT &amp;amp; (1&amp;lt;&amp;lt;TASTERBIT)))   //Taster wird losgelassen (fallende Flanke)&lt;br /&gt;
    {&lt;br /&gt;
        zustand = 3;&lt;br /&gt;
        rw = 0;&lt;br /&gt;
    }&lt;br /&gt;
    else if (zustand == 3 &amp;amp;&amp;amp; (TASTERPORT &amp;amp; (1&amp;lt;&amp;lt;TASTERBIT)))   //Taster losgelassen&lt;br /&gt;
    {&lt;br /&gt;
        zustand = 0;&lt;br /&gt;
        rw = 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return rw;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Erweiterung, damit beliebig lange das Halten einer Taste erkannt wird kann man ganz einfach so implementieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    // zustand kann entweder zum ersten mal als gehalten detektiert werden oder aber jedes weitere mal&lt;br /&gt;
    else if (((zustand == 1) || (zustand == 2)) &amp;amp;&amp;amp; !(TASTERPORT &amp;amp; (1&amp;lt;&amp;lt;TASTERBIT)))   //Taster wird gehalten&lt;br /&gt;
    {&lt;br /&gt;
         zustand = 2;&lt;br /&gt;
         rw = 0;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Warteschleifen-Verfahren ===&lt;br /&gt;
&lt;br /&gt;
Soll nun mit einem Mikrocontroller gezählt werden, wie oft ein Kontakt oder ein Relais geschaltet wird, muss das Prellen des Kontaktes exakt berücksichtigt - und von einem gewollten Mehrfachschalten abgegrenzt werden, da sonst  möglicherweise Fehlimpulse gezählt- oder andererseits echte Schaltvorgänge übersprungen werden. Dies muss beim Schreiben des Programms hinsichtlich des Abtastens des Kontaktes unbedingt Rechnung getragen werden.&lt;br /&gt;
&lt;br /&gt;
Beim folgenden einfachen Beispiel für eine Entprellung ist zu beachten, dass der AVR im Falle eines Tastendrucks 200ms wartet, also brach liegt. Bei zeitkritischen Anwendungen sollte man ein anderes Verfahren nutzen (z.&amp;amp;nbsp;B. Abfrage der Tastenzustände in einer Timer-Interrupt-Service-Routine).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;inttypes.h&amp;gt;&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
#warning &amp;quot;F_CPU war noch nicht definiert, wird nun mit 3686400 definiert&amp;quot;&lt;br /&gt;
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz  */&lt;br /&gt;
#endif&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;     /* bei alter avr-libc: #include &amp;lt;avr/delay.h&amp;gt; */      &lt;br /&gt;
&lt;br /&gt;
/* Einfache Funktion zum Entprellen eines Tasters */&lt;br /&gt;
inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)&lt;br /&gt;
{&lt;br /&gt;
    if ( !(*port &amp;amp; (1 &amp;lt;&amp;lt; pin)) )&lt;br /&gt;
    {&lt;br /&gt;
        /* Pin wurde auf Masse gezogen, 100ms warten   */&lt;br /&gt;
        _delay_ms(50);   // Maximalwert des Parameters an _delay_ms &lt;br /&gt;
        _delay_ms(50);   // beachten, vgl. Dokumentation der avr-libc&lt;br /&gt;
        if ( *port &amp;amp; (1 &amp;lt;&amp;lt; pin) )&lt;br /&gt;
        {&lt;br /&gt;
            /* Anwender Zeit zum Loslassen des Tasters geben */&lt;br /&gt;
            _delay_ms(50);&lt;br /&gt;
            _delay_ms(50); &lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    DDRB &amp;amp;= ~( 1 &amp;lt;&amp;lt; PB0 );        /* PIN PB0 auf Eingang Taster)  */&lt;br /&gt;
    PORTB |= ( 1 &amp;lt;&amp;lt; PB0 );        /* Pullup-Widerstand aktivieren */&lt;br /&gt;
    ...&lt;br /&gt;
    if (debounce(&amp;amp;PINB, PB0))&lt;br /&gt;
    {&lt;br /&gt;
        /* Falls Taster an PIN PB0 gedrueckt     */&lt;br /&gt;
        /* LED an Port PD7 an- bzw. ausschalten: */&lt;br /&gt;
        PORTD = PORTD ^ ( 1 &amp;lt;&amp;lt; PD7 );&lt;br /&gt;
    }&lt;br /&gt;
    ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die obige Routine hat leider mehrere Nachteile:&lt;br /&gt;
* sie detektiert nur das Loslassen (unergonomisch)&lt;br /&gt;
* sie verzögert die Mainloop immer um 100ms bei gedrückter Taste&lt;br /&gt;
* sie verliert Tastendrücke, je mehr die Mainloop zu tun hat.&lt;br /&gt;
&lt;br /&gt;
Eine ähnlich einfach zu benutzende Routine, aber ohne all diese Nachteile findet sich im Forenthread&lt;br /&gt;
[http://www.mikrocontroller.net/topic/164194#new Entprellung für Anfänger]&lt;br /&gt;
&lt;br /&gt;
Der &#039;&#039;DEBOUNCE&#039;&#039; Befehl in dem BASIC-Dialekt BASCOM für AVR ist ebenfalls nach dem Warteschleifen-Verfahren programmiert. Die Wartezeit beträgt standardmäßig 25 ms, kann aber vom Anwender überschrieben werden. Vgl.  [http://avrhelp.mcselec.com/bascom-avr.html?DEBOUNCE BASCOM Online-Manual zu DEBOUNCE].&lt;br /&gt;
&lt;br /&gt;
Eine C-Implementierung für eine Tastenabfrage mit Warteschleife ist im Artikel [[AVR-GCC-Tutorial#IO-Register_als_Parameter_und_Variablen|AVR-GCC-Tutorial: IO-Register als Parameter und Variablen]] angeben.&lt;br /&gt;
&lt;br /&gt;
Der Nachteil dieses Verfahrens ist, dass der Controller durch die Warteschleife blockiert wird. Günstiger ist die Implementierung mit einem Timer-Interrupt.&lt;br /&gt;
&lt;br /&gt;
==== Warteschleifenvariante mit Maske und Pointer (nach Christian Riggenbach) ====&lt;br /&gt;
&lt;br /&gt;
Hier eine weitere Funktion, um Taster zu entprellen: Durch den zusätzlichen Code kann eine Entprellzeit von durchschnittlich 1-3ms (mindestens 8*150µs = 1ms) erreicht werden. Grundsätzlich prüft die Funktion den Pegel der Pins auf einem bestimmten Port. Wenn die/der Pegel 8 Mal konstant war, wird die Schleife verlassen. Diese Funktion kann sehr gut eingesetzt werden, um in einer Endlosschleife Taster anzufragen, da sie, wie erwähnt, eine kurze Wartezeit hat.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void entprellung( volatile uint8_t *port, uint8_t maske ) {&lt;br /&gt;
  uint8_t   port_puffer;&lt;br /&gt;
  uint8_t   entprellungs_puffer;&lt;br /&gt;
&lt;br /&gt;
  for( entprellungs_puffer=0 ; entprellungs_puffer!=0xff ; ) {&lt;br /&gt;
    entprellungs_puffer&amp;lt;&amp;lt;=1;&lt;br /&gt;
    port_puffer = *port;&lt;br /&gt;
    _delay_us(150);&lt;br /&gt;
    if( (*port &amp;amp; maske) == (port_puffer &amp;amp; maske) )&lt;br /&gt;
      entprellungs_puffer |= 0x01;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Funktion wird wie folgt aufgerufen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
  // Bugfix 20100414&lt;br /&gt;
  // http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_port_pass&lt;br /&gt;
  entprellung( &amp;amp;PINB, (1&amp;lt;&amp;lt;PINB2) ); // ggf. Prellen abwarten &lt;br /&gt;
  if( PINB &amp;amp; (1&amp;lt;&amp;lt;PINB2) )           // dann stabilen Wert einlesen&lt;br /&gt;
  {&lt;br /&gt;
    // mach was&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    // mach was anderes&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Als Maske kann ein beliebiger Wert übergeben werden. Sie verhindert, dass nichtverwendete Taster die Entprellzeit negativ beeinflussen.&lt;br /&gt;
&lt;br /&gt;
==== Debounce-Makro von Peter Dannegger ====&lt;br /&gt;
&lt;br /&gt;
Peter Dannegger hat in [http://www.mikrocontroller.net/topic/164194#1566921 &amp;quot;Entprellen für Anfänger&amp;quot;] folgende vereinfachtes Entprellverfahren beschrieben. Das Makro arbeitet in der Originalversion mit &#039;&#039;active low&#039;&#039; geschalteten Tastern, kann aber einfach für  &#039;&#039;active high&#039;&#039; geschaltete Taster angepasst werden ([[Pollin Funk-AVR-Evaluationsboard#Tasty Reloaded|Tasty Reloaded]]). &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************************************************************/&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/*                      Not so powerful Debouncing Example              */&lt;br /&gt;
/*                      No Interrupt needed                             */&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/*              Author: Peter Dannegger                                 */&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/************************************************************************/&lt;br /&gt;
// Target: ATtiny13&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#define F_CPU 9.6e6&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define debounce( port, pin )                                         \&lt;br /&gt;
({                                                                    \&lt;br /&gt;
  static uint8_t flag = 0;     /* new variable on every macro usage */  \&lt;br /&gt;
  uint8_t i = 0;                                                      \&lt;br /&gt;
                                                                      \&lt;br /&gt;
  if( flag ){                  /* check for key release: */           \&lt;br /&gt;
    for(;;){                   /* loop ... */                         \&lt;br /&gt;
      if( !(port &amp;amp; 1&amp;lt;&amp;lt;pin) ){  /* ... until key pressed or ... */     \&lt;br /&gt;
        i = 0;                 /* 0 = bounce */                       \&lt;br /&gt;
        break;                                                        \&lt;br /&gt;
      }                                                               \&lt;br /&gt;
      _delay_us( 98 );         /* * 256 = 25ms */                     \&lt;br /&gt;
      if( --i == 0 ){          /* ... until key &amp;gt;25ms released */     \&lt;br /&gt;
        flag = 0;              /* clear press flag */                 \&lt;br /&gt;
        i = 0;                 /* 0 = key release debounced */        \&lt;br /&gt;
        break;                                                        \&lt;br /&gt;
      }                                                               \&lt;br /&gt;
    }                                                                 \&lt;br /&gt;
  }else{                       /* else check for key press: */        \&lt;br /&gt;
    for(;;){                   /* loop ... */                         \&lt;br /&gt;
      if( (port &amp;amp; 1&amp;lt;&amp;lt;pin) ){   /* ... until key released or ... */    \&lt;br /&gt;
        i = 0;                 /* 0 = bounce */                       \&lt;br /&gt;
        break;                                                        \&lt;br /&gt;
      }                                                               \&lt;br /&gt;
      _delay_us( 98 );         /* * 256 = 25ms */                     \&lt;br /&gt;
      if( --i == 0 ){          /* ... until key &amp;gt;25ms pressed */      \&lt;br /&gt;
        flag = 1;              /* set press flag */                   \&lt;br /&gt;
        i = 1;                 /* 1 = key press debounced */          \&lt;br /&gt;
        break;                                                        \&lt;br /&gt;
      }                                                               \&lt;br /&gt;
    }                                                                 \&lt;br /&gt;
  }                                                                   \&lt;br /&gt;
  i;                           /* return value of Macro */            \&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
   Testapplication&lt;br /&gt;
 */&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  DDRB  &amp;amp;= ~(1&amp;lt;&amp;lt;PB0);&lt;br /&gt;
  PORTB |=   1&amp;lt;&amp;lt;PB0;&lt;br /&gt;
  DDRB  |=   1&amp;lt;&amp;lt;PB2;&lt;br /&gt;
  DDRB  &amp;amp;= ~(1&amp;lt;&amp;lt;PB1);&lt;br /&gt;
  PORTB |=   1&amp;lt;&amp;lt;PB1;&lt;br /&gt;
  DDRB  |=   1&amp;lt;&amp;lt;PB3;&lt;br /&gt;
  for(;;){&lt;br /&gt;
    if( debounce( PINB, PB1 ) )&lt;br /&gt;
      PORTB ^= 1&amp;lt;&amp;lt;PB2;&lt;br /&gt;
    if( debounce( PINB, PB0 ) )&lt;br /&gt;
      PORTB ^= 1&amp;lt;&amp;lt;PB3;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn das Makro für die gleiche Taste (Pin) an mehreren Stellen aufgerufen werden soll, muss eine Funktion angelegt werden, damit beide Aufrufe an die gleiche Zustandsvariable &#039;&#039;flag&#039;&#039; auswerten [http://www.mikrocontroller.net/topic/195914#1918727]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Hilfsfunktion&lt;br /&gt;
uint8_t debounce_C1( void )&lt;br /&gt;
{&lt;br /&gt;
  return debounce(PINC, PC1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Beispielanwendung&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  DDRB  |=   1&amp;lt;&amp;lt;PB2;&lt;br /&gt;
  DDRB  |=   1&amp;lt;&amp;lt;PB3;&lt;br /&gt;
  DDRC  &amp;amp;= ~(1&amp;lt;&amp;lt;PC1);&lt;br /&gt;
  PORTC |=   1&amp;lt;&amp;lt;PC1; // Pullup für Taster&lt;br /&gt;
&lt;br /&gt;
  for(;;){&lt;br /&gt;
    if( debounce_C1() )  // nicht: debounce(PINC, PC1)&lt;br /&gt;
      PORTB ^= 1&amp;lt;&amp;lt;PB2;&lt;br /&gt;
    if( debounce_C1() )  // nicht: debounce(PINC, PC1)&lt;br /&gt;
      PORTB ^= 1&amp;lt;&amp;lt;PB3;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Timer-Verfahren (nach Peter Dannegger) ===&lt;br /&gt;
&lt;br /&gt;
==== Grundroutine (AVR Assembler) ====&lt;br /&gt;
&lt;br /&gt;
Siehe dazu: [http://www.mikrocontroller.net/forum/read-4-20435.html#new Forum] &lt;br /&gt;
&lt;br /&gt;
Vorteile&lt;br /&gt;
* besonders kurzer Code&lt;br /&gt;
* schnell&lt;br /&gt;
&lt;br /&gt;
Außerdem können 8 Tasten (aktiv low) gleichzeitig bearbeitet werden, es dürfen also&lt;br /&gt;
alle exakt zur selben Zeit gedrückt werden. Andere Routinen können z.&amp;amp;nbsp;B. nur eine Taste verarbeiten, d.h. die zuerst oder zuletzt gedrückte gewinnt, oder es kommt Unsinn heraus.&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Einlese- und Entprellroutine ist nur 8 Instruktionen&lt;br /&gt;
kurz. Der entprellte Tastenzustand ist im Register &#039;&#039;key_state&#039;&#039;. Mit nur 2 weiteren Instruktionen wird dann der Wechsel von &#039;&#039;Taste offen&#039;&#039; zu&lt;br /&gt;
&#039;&#039;Taste gedrückt&#039;&#039; erkannt und im Register &#039;&#039;key_press&#039;&#039; abgelegt. Im Beispielcode werden dann damit 8 LEDs ein- und ausgeschaltet. Jede Taste entspricht einem Bit in den Registern, d.h. die Verarbeitung erfolgt bitweise mit logischen Operationen. Zum Verständnis empfiehlt es sich daher, die Logikgleichungen mit Gattern für ein Bit = eine Taste aufzumalen. Die Register kann man sich als Flipflops denken, die mit der Entprellzeit als Takt arbeiten. D.h. man kann das auch so z.&amp;amp;nbsp;B. in einem GAL22V10 realisieren.&lt;br /&gt;
&lt;br /&gt;
Als Kommentar sind neben den einzelnen Instruktionen alle 8 möglichen&lt;br /&gt;
Kombinationen der 3 Signale dargestellt.&lt;br /&gt;
&lt;br /&gt;
Beispielcode für AVR (Assembler):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
.nolist&lt;br /&gt;
.include &amp;quot;c:\avr\inc\1200def.inc&amp;quot;&lt;br /&gt;
.list&lt;br /&gt;
.def  save_sreg         = r0&lt;br /&gt;
.def  iwr0              = r1&lt;br /&gt;
.def  iwr1              = r2&lt;br /&gt;
&lt;br /&gt;
.def  key_old           = r3&lt;br /&gt;
.def  key_state         = r4&lt;br /&gt;
.def  key_press         = r5&lt;br /&gt;
&lt;br /&gt;
.def  leds              = r16&lt;br /&gt;
.def  wr0               = r17&lt;br /&gt;
&lt;br /&gt;
.equ  key_port          = pind&lt;br /&gt;
.equ  led_port          = portb&lt;br /&gt;
&lt;br /&gt;
      rjmp   init&lt;br /&gt;
.org OVF0addr		;timer interrupt 24ms&lt;br /&gt;
      in     save_sreg, SREG&lt;br /&gt;
get8key:                               ;/old      state     iwr1      iwr0&lt;br /&gt;
      mov    iwr0, key_old             ;00110011  10101010            00110011&lt;br /&gt;
      in     key_old, key_port         ;11110000&lt;br /&gt;
      eor    iwr0, key_old             ;                              11000011&lt;br /&gt;
      com    key_old                   ;00001111&lt;br /&gt;
      mov    iwr1, key_state           ;                    10101010&lt;br /&gt;
      or     key_state, iwr0           ;          11101011&lt;br /&gt;
      and    iwr0, key_old             ;                              00000011&lt;br /&gt;
      eor    key_state, iwr0           ;          11101000&lt;br /&gt;
      and    iwr1, iwr0                ;                    00000010&lt;br /&gt;
      or     key_press, iwr1           ;store key press detect&lt;br /&gt;
;&lt;br /&gt;
;			insert other timer functions here&lt;br /&gt;
;&lt;br /&gt;
      out    SREG, save_sreg&lt;br /&gt;
      reti&lt;br /&gt;
;-------------------------------------------------------------------------&lt;br /&gt;
init:&lt;br /&gt;
      ldi    wr0, 0xFF&lt;br /&gt;
      out    ddrb, wr0&lt;br /&gt;
      ldi    wr0, 1&amp;lt;&amp;lt;CS02 | 1&amp;lt;&amp;lt;CS00    ;divide by 1024 * 256&lt;br /&gt;
      out    TCCR0, wr0&lt;br /&gt;
      ldi    wr0, 1&amp;lt;&amp;lt;TOIE0             ;enable timer interrupt&lt;br /&gt;
      out    TIMSK, wr0&lt;br /&gt;
&lt;br /&gt;
      clr    key_old&lt;br /&gt;
      clr    key_state&lt;br /&gt;
      clr    key_press&lt;br /&gt;
      ldi    leds, 0xFF&lt;br /&gt;
main: cli&lt;br /&gt;
      eor    leds, key_press           ;toggle LEDs&lt;br /&gt;
      clr    key_press                 ;clear, if key press action done&lt;br /&gt;
      sei&lt;br /&gt;
      out    led_port, leds&lt;br /&gt;
      rjmp   main&lt;br /&gt;
;-------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Komfortroutine (C für AVR) ====&lt;br /&gt;
&lt;br /&gt;
Siehe dazu: [http://www.mikrocontroller.net/forum/read-4-310276.html Forum]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Anmerkung&#039;&#039;&#039; Wenn statt active-low (Ruhezustand High) active-high (Ruhezustand Low) verwendet wird muss eine Zeile geändert werden siehe:&lt;br /&gt;
[http://www.mikrocontroller.net/forum/read-4-310276.html gesamter Beitrag im Forum], &lt;br /&gt;
[http://www.mikrocontroller.net/topic/48465#606555 Stelle 1 im Beitrag], ([http://www.mikrocontroller.net/topic/48465#2306398 Stelle 2 im Beitrag] muss *nicht* geändert werden, da hier die Polarität gar keinen Einfluß hat).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Anmerkung 2&#039;&#039;&#039; Zur Initialisierung siehe [http://www.mikrocontroller.net/topic/48465#3572793 Forum]&lt;br /&gt;
&lt;br /&gt;
Funktionsprinzip wie oben plus zusätzliche Features:  &lt;br /&gt;
* Kann Tasten sparen durch unterschiedliche Aktionen bei kurzem oder langem Drücken&lt;br /&gt;
* Wiederholfunktion, z.&amp;amp;nbsp;B. für die Eingabe von Werten&lt;br /&gt;
&lt;br /&gt;
Das Programm ist für avr-gcc/avr-libc geschrieben, kann aber mit ein paar Anpassungen auch mit anderen Compilern und Mikrocontrollern verwendet werden. Eine Portierung für den AT91SAM7 findet man [http://www.google.com/codesearch?q=show:ac2viP-2E2Y:pzkOO5QRsoc:RPICuprYy-A&amp;amp;sa=N&amp;amp;cd=1&amp;amp;ct=rc&amp;amp;cs_p=svn://mikrocontroller.net/mp3dec/trunk&amp;amp;cs_f=keys.c#a0 hier] (aus dem Projekt [[ARM MP3/AAC Player]]).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/************************************************************************/&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/*                      Debouncing 8 Keys                               */&lt;br /&gt;
/*                      Sampling 4 Times                                */&lt;br /&gt;
/*                      With Repeat Function                            */&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/*              Author: Peter Dannegger                                 */&lt;br /&gt;
/*                      danni@specs.de                                  */&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/************************************************************************/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
#define F_CPU           1000000                   // processor clock frequency&lt;br /&gt;
#warning kein F_CPU definiert&lt;br /&gt;
#endif&lt;br /&gt;
 &lt;br /&gt;
#define KEY_DDR         DDRB&lt;br /&gt;
#define KEY_PORT        PORTB&lt;br /&gt;
#define KEY_PIN         PINB&lt;br /&gt;
#define KEY0            0&lt;br /&gt;
#define KEY1            1&lt;br /&gt;
#define KEY2            2&lt;br /&gt;
#define ALL_KEYS        (1&amp;lt;&amp;lt;KEY0 | 1&amp;lt;&amp;lt;KEY1 | 1&amp;lt;&amp;lt;KEY2)&lt;br /&gt;
 &lt;br /&gt;
#define REPEAT_MASK     (1&amp;lt;&amp;lt;KEY1 | 1&amp;lt;&amp;lt;KEY2)       // repeat: key1, key2&lt;br /&gt;
#define REPEAT_START    50                        // after 500ms&lt;br /&gt;
#define REPEAT_NEXT     20                        // every 200ms&lt;br /&gt;
&lt;br /&gt;
#define LED_DDR         DDRA&lt;br /&gt;
#define LED_PORT        PORTA&lt;br /&gt;
#define LED0            0&lt;br /&gt;
#define LED1            1&lt;br /&gt;
#define LED2            2&lt;br /&gt;
 &lt;br /&gt;
volatile uint8_t key_state;                                // debounced and inverted key state:&lt;br /&gt;
                                                  // bit = 1: key pressed&lt;br /&gt;
volatile uint8_t key_press;                                // key press detect&lt;br /&gt;
 &lt;br /&gt;
volatile uint8_t key_rpt;                                  // key long press and repeat&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
ISR( TIMER0_OVF_vect )                            // every 10ms&lt;br /&gt;
{&lt;br /&gt;
  static uint8_t ct0 = 0xFF, ct1 = 0xFF, rpt;&lt;br /&gt;
  uint8_t i;&lt;br /&gt;
 &lt;br /&gt;
  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms&lt;br /&gt;
 &lt;br /&gt;
  i = key_state ^ ~KEY_PIN;                       // key changed ?&lt;br /&gt;
  ct0 = ~( ct0 &amp;amp; i );                             // reset or count ct0&lt;br /&gt;
  ct1 = ct0 ^ (ct1 &amp;amp; i);                          // reset or count ct1&lt;br /&gt;
  i &amp;amp;= ct0 &amp;amp; ct1;                                 // count until roll over ?&lt;br /&gt;
  key_state ^= i;                                 // then toggle debounced state&lt;br /&gt;
  key_press |= key_state &amp;amp; i;                     // 0-&amp;gt;1: key press detect&lt;br /&gt;
 &lt;br /&gt;
  if( (key_state &amp;amp; REPEAT_MASK) == 0 )            // check repeat function&lt;br /&gt;
     rpt = REPEAT_START;                          // start delay&lt;br /&gt;
  if( --rpt == 0 ){&lt;br /&gt;
    rpt = REPEAT_NEXT;                            // repeat delay&lt;br /&gt;
    key_rpt |= key_state &amp;amp; REPEAT_MASK;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
///////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
// check if a key has been pressed. Each pressed key is reported&lt;br /&gt;
// only once&lt;br /&gt;
//&lt;br /&gt;
uint8_t get_key_press( uint8_t key_mask )&lt;br /&gt;
{&lt;br /&gt;
  cli();                                          // read and clear atomic !&lt;br /&gt;
  key_mask &amp;amp;= key_press;                          // read key(s)&lt;br /&gt;
  key_press ^= key_mask;                          // clear key(s)&lt;br /&gt;
  sei();&lt;br /&gt;
  return key_mask;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
///////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
// check if a key has been pressed long enough such that the&lt;br /&gt;
// key repeat functionality kicks in. After a small setup delay&lt;br /&gt;
// the key is reported being pressed in subsequent calls&lt;br /&gt;
// to this function. This simulates the user repeatedly&lt;br /&gt;
// pressing and releasing the key.&lt;br /&gt;
//&lt;br /&gt;
uint8_t get_key_rpt( uint8_t key_mask )&lt;br /&gt;
{&lt;br /&gt;
  cli();                                          // read and clear atomic !&lt;br /&gt;
  key_mask &amp;amp;= key_rpt;                            // read key(s)&lt;br /&gt;
  key_rpt ^= key_mask;                            // clear key(s)&lt;br /&gt;
  sei();&lt;br /&gt;
  return key_mask;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
// check if a key is pressed right now&lt;br /&gt;
//&lt;br /&gt;
uint8_t get_key_state( uint8_t key_mask )&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  key_mask &amp;amp;= key_state;&lt;br /&gt;
  return key_mask;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
uint8_t get_key_short( uint8_t key_mask )&lt;br /&gt;
{&lt;br /&gt;
  cli();                                          // read key state and key press atomic !&lt;br /&gt;
  return get_key_press( ~key_state &amp;amp; key_mask );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
///////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
uint8_t get_key_long( uint8_t key_mask )&lt;br /&gt;
{&lt;br /&gt;
  return get_key_press( get_key_rpt( key_mask ));&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main( void )&lt;br /&gt;
{&lt;br /&gt;
  LED_PORT = 0xFF;&lt;br /&gt;
  LED_DDR = 0xFF;                     &lt;br /&gt;
&lt;br /&gt;
  // Configure debouncing routines&lt;br /&gt;
  KEY_DDR &amp;amp;= ~ALL_KEYS;                // configure key port for input&lt;br /&gt;
  KEY_PORT |= ALL_KEYS;                // and turn on pull up resistors&lt;br /&gt;
&lt;br /&gt;
  TCCR0 = (1&amp;lt;&amp;lt;CS02)|(1&amp;lt;&amp;lt;CS00);         // divide by 1024&lt;br /&gt;
  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms&lt;br /&gt;
  TIMSK |= 1&amp;lt;&amp;lt;TOIE0;                   // enable timer interrupt&lt;br /&gt;
&lt;br /&gt;
  sei();&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    if( get_key_short( 1&amp;lt;&amp;lt;KEY1 ))&lt;br /&gt;
      LED_PORT ^= 1&amp;lt;&amp;lt;LED1;&lt;br /&gt;
 &lt;br /&gt;
    if( get_key_long( 1&amp;lt;&amp;lt;KEY1 ))&lt;br /&gt;
      LED_PORT ^= 1&amp;lt;&amp;lt;LED2;&lt;br /&gt;
 &lt;br /&gt;
    // single press and repeat&lt;br /&gt;
 &lt;br /&gt;
    if( get_key_press( 1&amp;lt;&amp;lt;KEY2 ) || get_key_rpt( 1&amp;lt;&amp;lt;KEY2 )){&lt;br /&gt;
      uint8_t i = LED_PORT;&lt;br /&gt;
 &lt;br /&gt;
      i = (i &amp;amp; 0x07) | ((i &amp;lt;&amp;lt; 1) &amp;amp; 0xF0);&lt;br /&gt;
      if( i &amp;lt; 0xF0 )&lt;br /&gt;
        i |= 0x08;&lt;br /&gt;
      LED_PORT = i;      &lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das single-press-und-repeat-Beispiel geht nicht in jeder Beschaltung; folgendes Beispiel sollte universeller sein (einzelne LED an/aus):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// single press and repeat&lt;br /&gt;
if( get_key_press( 1&amp;lt;&amp;lt;KEY2 ) || get_key_rpt( 1&amp;lt;&amp;lt;KEY2 ))&lt;br /&gt;
    LED_PORT ^=0x08;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Neuere Variante, die einer Taste folgende Funktionen erlaubt:&lt;br /&gt;
https://www.mikrocontroller.net/topic/48465?goto=1753367#1753367&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
- get_key_press()&lt;br /&gt;
- get_key_rpt()&lt;br /&gt;
- get_key_press() mit get_key_rpt()&lt;br /&gt;
- get_key_short() mit get_key_long()&lt;br /&gt;
- get_key_short() mit get_key_long_r() und get_key_rpt_l()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Erweiterung für die Erkennung von zwei gleichzeitig gedrückten Tasten:&lt;br /&gt;
https://www.mikrocontroller.net/topic/48465?goto=1753367#1753367&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
- get_key_common()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Funktionsweise =====&lt;br /&gt;
Der Code basiert auf 8 parallelen vertikalen Zählern, die über die Variablen ct0 und ct1 aufgebaut werden&lt;br /&gt;
&lt;br /&gt;
[[Bild:VertCount.png|framed|center|&#039;&#039;&#039;8 vertikale Zähler in 2 8-Bit Variablen&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
wobei jeweils ein Bit in ct0 mit dem gleichwertigen Bit in ct1 zusammengenommen einen 2-Bit-Zähler bildet.&lt;br /&gt;
Der Code der sich um die 8 Zähler kümmert, ist so geschrieben, daß er alle 8 Zähler gemeinsam parallel behandelt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
  i = key_state ^ ~KEY_PIN;                       // key changed ?&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
i enthält an dieser Stelle für jede Taste, die sich im Vergleich mit dem vorhergehenden entprellten Zustand (keystate) verändert hat, ein 1 Bit.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
  ct0 = ~( ct0 &amp;amp; i );                             // reset or count ct0&lt;br /&gt;
  ct1 = ct0 ^ (ct1 &amp;amp; i);                          // reset or count ct1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese beiden Anweisungen erniedrigen den 2-Bit Zähler ct0/ct1 für jedes Bit um 1, welches in i gesetzt ist. Liegt an der entsprechenden Stelle in i ein 0 Bit vor (keine Änderung des Zustands), so wird der Zähler ct0/ct1 für dieses Bit auf 1 gesetzt.&lt;br /&gt;
Der Grundzustand des Zählers ist als ct0 == 1 und ct1 == 1 (Wert 3). Der Zähler zählt daher mit jedem ISR Aufruf, bei dem die Taste im Vergleich zu keystate als verändert erkannt wurde&lt;br /&gt;
&lt;br /&gt;
   ct1   ct0&lt;br /&gt;
     1    1   // 3&lt;br /&gt;
     1    0   // 2&lt;br /&gt;
     0    1   // 1&lt;br /&gt;
     0    0   // 0&lt;br /&gt;
     1    1   // 3&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
  i &amp;amp;= ct0 &amp;amp; ct1;                                 // count until roll over ?&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
in i bleibt nur dort ein 1-Bit erhalten, wo sowohl in ct1 als auch in ct0 ein 1 Bit vorgefunden wird, der betreffende Zähler also bis 3 zählen konnte. Durch die zusätzliche Verundung mit i wird der Fall abgefangen, dass ein konstanter Zählerwert von 3 in i ein 1 Bit hinterlässt. Im Endergebnis bedeutet dass, dass nur ein Zählerwechsel von 0 auf 3 zu einem 1 Bit an der betreffenden Stelle in i führt, aber auch nur dann, wenn in i an dieser Bitposition ebenfalls ein 1 Bit war (welches wiederrum deswegen auf 1 war, weil an diesem Eingabeport eine Veränderung zum letzten bekannten entprellten Zustand festgestellt wurde). Alles zusammengenommen heißt das, dass ein Tastendruck dann erkannt wird, wenn die Taste 4 mal hintereinander in einem anderen Zustand vorgefunden wurde als dem zuletzt bekannten entprellten Tastenzustand.&lt;br /&gt;
&lt;br /&gt;
An dieser Stelle ist i daher ein Vektor von 8 Bits, von denen jedes einzelne der Bits darüber Auskunft gibt, ob die entsprechende Taste mehrmals hintereinander im selben Zustand angetroffen wurde, der nicht mit dem zuletzt bekannten Tastenzustand übereinstimmt. Ist das der Fall, dann wird eine entsprechende Veränderung des Tastenzustands in key_state registriert&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
  key_state ^= i;                                 // then toggle debounced state&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
und wenn sich in key_state das entsprechende Bit von 0 auf 1 verändert hat, wird dieses Ereignis als &#039;Taste wurde niedergedrückt&#039; gewertet.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
  key_press |= key_state &amp;amp; i;                     // 0-&amp;gt;1: key press detect&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit ist der Tasteneingang entprellt. Und zwar sowohl beim Drücken einer Taste als auch beim Loslassen (damit Tastenpreller beim Loslassen nicht mit dem Niederdrücken einer Taste verwechselt werden). Der weitere Code beschäftigt sich dann nur noch damit, diesen entprellten Tastenzustand weiter zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Der Codeteil sieht durch die Verwendung der vielen bitweisen Operationen relativ komplex aus. Behält man aber im Hinterkopf, dass einige der bitweisen wie ein &#039;paralles If&#039; gleichzeitig auf allen 8 Bits eingesetzt werden, dann vereinfacht sich vieles. Ein&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    key_press |= key_state &amp;amp; i;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
ist nichts anderes als ein&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    // teste ob Bit 0 sowohl in key_state als auch in i gesetzt ist&lt;br /&gt;
    // und setze Bit 0 in key_press, wenn das der Fall ist&lt;br /&gt;
    if( ( key_state &amp;amp; ( 1 &amp;lt;&amp;lt; 0 ) ) &amp;amp;&amp;amp;&lt;br /&gt;
        ( i &amp;amp; ( 1 &amp;lt;&amp;lt; 0 ) )&lt;br /&gt;
       key_press |= ( 1 &amp;lt;&amp;lt; 0 );&lt;br /&gt;
&lt;br /&gt;
    // Bit 1&lt;br /&gt;
    if( ( key_state &amp;amp; ( 1 &amp;lt;&amp;lt; 1 ) ) &amp;amp;&amp;amp;&lt;br /&gt;
        ( i &amp;amp; ( 1 &amp;lt;&amp;lt; 1 ) )&lt;br /&gt;
       key_press |= ( 1 &amp;lt;&amp;lt; 1 );&lt;br /&gt;
&lt;br /&gt;
    // Bit 2&lt;br /&gt;
    if( ( key_state &amp;amp; ( 1 &amp;lt;&amp;lt; 2 ) ) &amp;amp;&amp;amp;&lt;br /&gt;
        ( i &amp;amp; ( 1 &amp;lt;&amp;lt; 2 ) )&lt;br /&gt;
       key_press |= ( 1 &amp;lt;&amp;lt; 2 );&lt;br /&gt;
&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
nur als wesentlich kompaktere Operation ausgeführt und für alle 8 Bits gleichzeitig.&lt;br /&gt;
Die Kürze und Effizienz dieser paar Codezeilen ergibt sich aus dem Umstand, dass jedes Bit in den Variablen für eine Taste steht und alle 8 (maximal möglichen) Tasten gleichzeitig die Operationen durchlaufen.&lt;br /&gt;
&lt;br /&gt;
Funktionsweisen der verschienden Modi anhand von Zeitstrahlen erklärt:&lt;br /&gt;
https://www.mikrocontroller.net/topic/48465?goto=1753367#1844458&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Walkthrough&amp;quot; der verschiedenen Zuständer der Einzelnen Variablen anhand eines Tastendrucks (avrfreaks.net)&lt;br /&gt;
http://www.avrfreaks.net/comment/726676#comment-726676&lt;br /&gt;
&lt;br /&gt;
===== Reduziert auf lediglich 1 Taste =====&lt;br /&gt;
Diskussionen im Forum zeigen immer wieder, dass viele eine Abneigung gegen diesen Code haben, weil er ihnen sehr kompliziert vorkommt.&lt;br /&gt;
&lt;br /&gt;
Der Code ist nicht leicht zu analysieren und er zieht alle Register dessen, was möglich ist, um sowohl Laufzeit als auch Speicherverbrauch einzusparen. Oft hört man auch das Argument: Ich benötige ja nur eine Entprellung für 1 Taste, gibt es da nichts Einfacheres?&lt;br /&gt;
&lt;br /&gt;
Hier ist die &#039;Langform&#039; des Codes, so wie man das für lediglich 1 Taste schreiben würde, wenn man exakt dasselbe Entprellverfahren einsetzen würde. Man sieht: Da ist keine Hexerei dabei: In key_state wird der letzte bekannte entprellte Zustand der Taste gehalten. Der Pin-Eingang wird mit diesem Zustand verglichen und wenn sich die beiden unterscheiden, dann wird ein Zähler heruntergezählt. Produziert dieses herunterzählen einen Unterlauf des Zählers, dann gilt die Taste als entprellt und wenn dann auch noch die Taste gerade gedrückt ist, dann wird dieses in key_press entsprechend vermerkt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t key_state;&lt;br /&gt;
uint8_t key_counter;&lt;br /&gt;
volatile uint8_t key_press;&lt;br /&gt;
&lt;br /&gt;
ISR( ... Overflow ... )&lt;br /&gt;
{&lt;br /&gt;
  uint8_t input = KEY_PIN &amp;amp; ( 1 &amp;lt;&amp;lt; KEY0 );&lt;br /&gt;
&lt;br /&gt;
  if( input != key_state ) {&lt;br /&gt;
    key_counter--;&lt;br /&gt;
    if( key_counter == 0xFF ) {&lt;br /&gt;
      key_counter = 3;&lt;br /&gt;
      key_state = input;&lt;br /&gt;
      if( input )&lt;br /&gt;
        key_press = TRUE;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
    key_counter = 3;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint8_t get_key_press()&lt;br /&gt;
{&lt;br /&gt;
  uint8_t result;&lt;br /&gt;
&lt;br /&gt;
  cli();&lt;br /&gt;
  result = key_press;&lt;br /&gt;
  key_press = FALSE;&lt;br /&gt;
  sei();&lt;br /&gt;
&lt;br /&gt;
  return result;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der vollständige Entprellcode, wie weiter oben gelistet, besticht jetzt aber darin, dass er compiliert kleiner ist als diese anschaulichere Variante für lediglich 1 Taste. Und das bei gleichzeitig erhöhter Funktionalität. Denn zb. ein Autorepeat ist in diesem Code noch gar nicht eingebaut. Und spätestens wenn man dann eine 2.te Taste entprellen möchte, dann ist auch der SRAM-Speicherverbrauch dieser Langform höher als der des Originals für 8 Tasten. Daraus folgt: Selbst für lediglich 1 Taste ist die Originalroutine die bessere Wahl.&lt;br /&gt;
&lt;br /&gt;
Und wegen der Komplexität mal eine Frage: Sind Sie selbst in der Lage eine entsprechend effiziente sqrt() Funktion zu schreiben, wie die, die sie in der Standard-C-Bibliothek vorfinden? Nein? Dann dürften Sie eigentlich Ihrer Argumentation nach die Bibliotheksfunktion sqrt() nicht verwenden, sondern müssten sich statt dessen selbst eine Wurzel-Funktion schreiben.&lt;br /&gt;
&lt;br /&gt;
=== Selbstsättigendes Filter (nach Jürgen Schuhmacher) ===&lt;br /&gt;
Durch die Nutzung der diskreten Signalanalyse in Software kann die Funktionalität einer einfachen Entprellung mit einem Widerstand, einem Kondensator und einem Schmitttrigger wie in Hardware nachgebildet werden, indem ein abstraktes IIR-Filter benutzt wird, der eine Kondensatorladekurve emuliert. Mit der Vorschrift Y(t) = k Y(t-1) + Input wird ein einfaches Filter erzeugt, dass dem Eingangswert träge folgt. Bei Überschreiten eines bestimmten Wertes erfolgt mit einer einfachen Abfrage das Schalten des Ausgangssignals.&lt;br /&gt;
&lt;br /&gt;
Für Assembler und VHDL bei FPGAs eignet sich aufgrund der leicht zu implementierenden binären Operationen folgende Darstellung mit einer Auflösung des Filterwertspeichers von nur 8 bit: Wert_Neu = Wert_Alt - Wert_Alt/16 + 16*(Taste = True). Der Filterwert bildet dann den gedämpften Verlauf des Eingangs (flankenverschliffen) ab und kann Prellen bis nahe an den Grenzbereich zum schnellen Tasten unterdrücken. Der Ausgangswert ist dann einfach das höchstwertige Bit des Filterwertes.&lt;br /&gt;
&lt;br /&gt;
[[Datei:Entprellung mit IIR-Filter.gif]]&lt;br /&gt;
&lt;br /&gt;
Dazu muss das Signal des Tasters idealerweise um den Faktor 10-20 schneller abgetastet werden, als die höchste gewünschte Tippgeschwindigkeit vorgibt. Noch schneller abzutasten ist möglich, führt aber zu mehr Bedarf an Bits beim Filter. Die Schmittriggerfunktion kann dadurch gebildet werden, dass eine 1 am Ausgang bei z.B. Überschreiten einer 55% Grenze und eine 0 bei Unterschreitung der 45%-Grenze ausgeben wird. Im Zwischenbereich wird der alte Wert gehalten. Die realen Grenzen dieser [[Hysterese]] müssen an die Applikation angepasst werden, da zu enge Grenzen sonst zu empfindlich gegenüber Störungen wären.&lt;br /&gt;
&lt;br /&gt;
=== Einfaches Mittelwertfilter (nach Lothar Miller) ===&lt;br /&gt;
Für digitale Schaltungen oder PLDs empfiehlt sich ein FIR-Filter mit aneinandergereihten FlipFlops. Man schiebt das Eingangssignal in eine FlipFlop-Kette und schaltet oberhalb der Mitte um:&lt;br /&gt;
&lt;br /&gt;
SignalInput -&amp;gt; FF1 -&amp;gt; FF2 -&amp;gt; FF3 -&amp;gt; FF4 -&amp;gt; FF5 -&amp;gt; FF6 -&amp;gt; FF7 -&amp;gt; FF8&lt;br /&gt;
&lt;br /&gt;
Wenn alle FFs = 1 (Summe der FFs=8) dann SignalOutput = 1&amp;lt;br /&amp;gt;&lt;br /&gt;
Wenn alle FFs = 0 (Summe der FFs=0) dann SignalOutput = 0&lt;br /&gt;
&lt;br /&gt;
Dieses Verfahren kann sehr einfach in Logik abgebildet werden, weil für die Berechnung des Ausgangs nur ein NOR bz. ein AND Gatter nötig ist.&lt;br /&gt;
&lt;br /&gt;
Das reale Signal muss dazu aber genügend langsam abgetastet werden, sodaß die Filterperiode die Prelldauer übersteigt, um zu verhindern, daß nicht inmitten einer passiven Phase eines Prellvorgangs ein 8fach 1 gesehen wird. Damit wird die Interetation vergleichsweise langsam.&lt;br /&gt;
&lt;br /&gt;
== Gegenüberstellung der Verfahren ==&lt;br /&gt;
* HW - &amp;quot;entprellte Schalter&amp;quot;: Sehr teuer, grosse Bauform, verschleissbelastet, geringe Haltbarkeit&lt;br /&gt;
* HW - &amp;quot;Umschalter&amp;quot; : benötigt aufwändigeren Schalter, benötigt Elektronik&lt;br /&gt;
* HW - &amp;quot;Umschalter ohne FF&amp;quot; : benötigt aufwändigeren Schalter und kleinen Kondensator&lt;br /&gt;
* HW - &amp;quot;Kondensatorentprellung&amp;quot; : benötigt etwas mehr Platz, kommt mit schlechten Schaltern zurecht&lt;br /&gt;
&lt;br /&gt;
* SW - Flankenverfahren:&lt;br /&gt;
* SW - Warteschleife: Durch die Warteschleifen eine nicht zu vernachlässigende Verzögerung im Code. Speziell wenn mehrere Tasten zu überwachen sind, nicht unproblematisch&lt;br /&gt;
* SW - Timer: Universalfunktionalität, die durch geringen Speicherverbrauch, geringen Rechenzeitverbrauch und gute Funktion besticht. Der &#039;Verbrauch&#039; eines Timers sieht auf den ersten Blick schlimmer aus, als er ist, denn in den meisten Programmen hat man sowieso einen Basistimer für die Zeitsteuerung des Programms im Einsatz, der für die Tastenentprellung mitbenutzt werden kann.&lt;br /&gt;
* SW - Filter: sehr geringer Platzbedarf in FPGAs, relativ gute Wirkung&lt;br /&gt;
* SW - Filter 2: sehr geringer Platzbedarf, gute Wirkung&lt;br /&gt;
&lt;br /&gt;
== Links zum Thema ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.edn.com/design/analog/4324067/Contact-debouncing-algorithm-emulates-Schmitt-trigger Contact-debouncing algorithm (Artikel)],  [http://www.edn.com/Pdf/ViewPdf?contentItemId=4324067 als PDF]&lt;br /&gt;
* [[AVR-Tutorial: Tasten]]&lt;br /&gt;
* [[AVR-GCC-Tutorial#.28Tasten-.29Entprellung|AVR-GCC-Tutorial Tastenentprellung]]&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-4-20435.html Beitrag im Forum, AVR Assembler]&lt;br /&gt;
* [http://www.ganssle.com/debouncing.pdf A guide to debouncing (engl.), praktische Erläuterungen zum Entprellen in Soft- und Hardware]&lt;br /&gt;
* [http://www.pololu.com/docs/0J16/all Understanding Destructive LC Voltage Spikes]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR]]&lt;br /&gt;
[[Kategorie:Signalverarbeitung]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=WordClock_mit_WS2812&amp;diff=91463</id>
		<title>WordClock mit WS2812</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=WordClock_mit_WS2812&amp;diff=91463"/>
		<updated>2016-01-24T21:35:13Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieser Artikel ist der Nachfolger der beiden Projekte [[Word_Clock]] und [[WordClock24h]]. Diese Projekte werden hier zusammengefasst und mit ein- und derselben Hard- und Software realisiert. Es ist damit der Bau einer 12-Stunden WordClock und einer minutengenauen 24-Stunden WordClock möglich.&lt;br /&gt;
&lt;br /&gt;
Um die beiden Varianten zu unterscheiden, wird die 12-Stunden-Variante im folgenden &#039;&#039;&#039;WordClock12h&#039;&#039;&#039; und die 24-Stunden-Variante &#039;&#039;&#039;WordClock24h&#039;&#039;&#039; genannt.&lt;br /&gt;
&lt;br /&gt;
Zugehöriger Thread im Forum: https://www.mikrocontroller.net/topic/385955&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WordClock12h:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Datei:wordclock-frontplatte-v2.png| |WordClock12h]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WordClock24h:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Datei:WordClock24h-Frontplatte-800x800.png|400px|WordClock24h]]&lt;br /&gt;
&lt;br /&gt;
= Software =&lt;br /&gt;
&lt;br /&gt;
Die Software ist sowohl auf dem STM32F401RE oder STM32F411RE [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Board]] als auch auf einem [[WordClock_mit_WS2812#STM32F103C8T6_Mini-Development_Board|STM32F103-Mini-Development-Board]] lauffähig.&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
&lt;br /&gt;
Die Software wird ständig weiterentwickelt. Folgende Punkte wurden bereits umgesetzt:&lt;br /&gt;
&lt;br /&gt;
* Lauffähig auf STM32F401 [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo]], STM32F411 [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo]] und [[WordClock_mit_WS2812#STM32F103C8T6_Mini-Development_Board|STM32F103-Mini-Development-Board]]&lt;br /&gt;
* Anbindung IR-Fernbedienung mittels [[IRMP]]&lt;br /&gt;
* [[WordClock_mit_WS2812#MCURSES-Monitor|Monitoring]]/Benutzeroberfläche mittels [[MCURSES]]&lt;br /&gt;
* Einstellen des Anzeigemodus (&amp;quot;Sprache&amp;quot;) und der Farbe per IR-Fernbedienung&lt;br /&gt;
* Anbindung von LED-Stripes des Typs [[WordClock_mit_WS2812#WS2812|WS2812]] und [[WordClock_mit_WS2812#WS2812|WS2812B]]&lt;br /&gt;
* Sanftes Überblenden der Uhrzeiten auf den LEDs&lt;br /&gt;
* Wählbare Animationen bei Uhrzeitwechsel&lt;br /&gt;
* Automatische Helligkeitsregelung mittels [[WordClock_mit_WS2812#LDR|LDR]] (optional)&lt;br /&gt;
* Anbindung einer externen DS3231-[[WordClock_mit_WS2812#RTC_und_EEPROM|RTC]]&lt;br /&gt;
* Anbindung eines externen I2C-[[WordClock_mit_WS2812#RTC_und_EEPROM|EEPROM]]&lt;br /&gt;
* Optionale Anbindung eines [[WordClock_mit_WS2812#DCF77|DCF77]]-Moduls&lt;br /&gt;
* Optionale Anbindung eines [[WordClock_mit_WS2812#ESP8266|ESP8266]]-WLAN-Moduls&lt;br /&gt;
* Holen der Uhrzeit per TIME- oder NTP-Protokoll aus dem Internet&lt;br /&gt;
* Optionale Temperaturmessung und -Anzeige mit [[WordClock_mit_WS2812#Temperatur-Sensor|DS18xxx-Sensor]]&lt;br /&gt;
* Fernsteuerung per [[WordClock_mit_WS2812#Android_App|Android App]]&lt;br /&gt;
* Ambilight&lt;br /&gt;
&lt;br /&gt;
=== Geplante Features ===&lt;br /&gt;
&lt;br /&gt;
Die nächsten geplanten Punkte sind:&lt;br /&gt;
&lt;br /&gt;
* Konfiguration der Nachtzeit(en)&lt;br /&gt;
* Farbprogramme (Wählen der Farbe, optional automatisches Wechseln)&lt;br /&gt;
* Spiele wie TRON und TETRIS&lt;br /&gt;
&lt;br /&gt;
=== Download ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;EM::Blocks-Projekt, Version 1.6.3 vom 24.01.2016:&#039;&#039;&#039; [http://www.mikrocontroller.net/svnbrowser/wordclock24h/?view=tar Tarball]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SVN hier auf mikrocontroller.net:&#039;&#039;&#039; svn://mikrocontroller.net/wordclock24h/&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Repo-Browser&#039;&#039;&#039;: [http://www.mikrocontroller.net/svnbrowser/wordclock24h/ WordClock24h im SVN]&lt;br /&gt;
&lt;br /&gt;
Hex-Dateien, wenn man - ohne zu compilieren - direkt flashen will:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WC12h&#039;&#039;&#039; Version 1.6.3 Nucleo401-Board: [[Datei:Wc12h-nucleo401.hex]]&lt;br /&gt;
* &#039;&#039;&#039;WC12h&#039;&#039;&#039; Version 1.6.3 Nucleo411-Board: [[Datei:Wc12h-nucleo411.hex]]&lt;br /&gt;
* &#039;&#039;&#039;WC12h&#039;&#039;&#039; Version 1.6.3 STM32F103-Board: [[Datei:Wc12h-STM32F103.hex]]&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;WC24h&#039;&#039;&#039; Version 1.6.3 Nucleo401-Board: [[Datei:Wc24h-nucleo401.hex]]&lt;br /&gt;
* &#039;&#039;&#039;WC24h&#039;&#039;&#039; Version 1.6.3 Nucleo411-Board: [[Datei:Wc24h-nucleo411.hex]]&lt;br /&gt;
* &#039;&#039;&#039;WC24h&#039;&#039;&#039; Version 1.6.3 STM32F103-Board: [[Datei:Wc24h-STM32F103.hex]]&lt;br /&gt;
&lt;br /&gt;
* [[WordClock_mit_WS2812#Android_App|Android App]] 1.5: [[Datei:WC24h.apk]]&lt;br /&gt;
&lt;br /&gt;
Wie man diese APK unter Android installiert, kann man hier nachlesen:&lt;br /&gt;
&lt;br /&gt;
http://www.pcwelt.de/ratgeber/Android-Smartphones-Apps-ausserhalb-des-Android-Market-installieren-1929591.html&lt;br /&gt;
&lt;br /&gt;
Am einfachsten erlaubt man die Installation von Apps &amp;quot;aus unbekannten Quellen&amp;quot; und klickt anschließend direkt auf dem Android-Gerät auf den [[WordClock_mit_WS2812#Download|Download]]-Link. Dann kann man das Programm direkt nach dem Download installieren.&lt;br /&gt;
&lt;br /&gt;
=== Software für Windows ===&lt;br /&gt;
&lt;br /&gt;
* EM::Blocks IDE, siehe http://www.emblocks.org/, &#039;&#039;&#039;nur notwendig, wenn man selber die Sources übersetzen möchte!&#039;&#039;&#039;&lt;br /&gt;
* ST-Link/V2 Software zum Flashen, siehe: http://www.st.com/web/catalog/tools/FM146/CL1984/SC724/SS1677/PF251168&lt;br /&gt;
* STM32 Virtual COM Port Driver: http://www.st.com/web/en/catalog/tools/PF257938&lt;br /&gt;
* PuTTY (http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html) oder andere Terminal-Emulation&lt;br /&gt;
&lt;br /&gt;
=== WordClock-Quellcode selbst übersetzen ===&lt;br /&gt;
&lt;br /&gt;
Dieser Vorgang ist nur notwendig, wenn man an den Quellen etwas ändern möchte. Im Normalfall braucht man lediglich eine der oben im [[WordClock_mit_WS2812#Download|Download]]-Kapitel angegebenen Hex-Dateien auszuwählen und diese auf den Prozessor flashen.&lt;br /&gt;
&lt;br /&gt;
Wenn man an dem Programm etwas ändern oder erweitern möchte, dann startet man die zuvor installierte EM::Blocks-IDE. Aus dem SVN lädt man sich den Tarball (Link siehe Kapitel [[WordClock_mit_WS2812#Download|Download]]) und entpackt diesen unter C:\EmBlocksProjects.&lt;br /&gt;
&lt;br /&gt;
Nach dem Entpacken findet man dann im Unterverzeichnis wclock24h die Projekt-Datei &#039;&#039;&#039;wclock24h.ebp&#039;&#039;&#039;, um den Quellcode für ein [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Board]] zu compilieren. In der EM::Blocks-Ide kann man nun mit &#039;&#039;&#039;File -&amp;gt; Open&#039;&#039;&#039; die Projekt-Datei laden.&lt;br /&gt;
&lt;br /&gt;
Möchte man jedoch den Quellcode für das [[WordClock_mit_WS2812#STM32F103C8T6_Mini-Development_Board|STM32F103-Mini-Board]] übersetzen, dann lädt man die Projektdatei &#039;&#039;&#039;wclock24h-F103.ebp&#039;&#039;&#039; aus dem Unterverzeichnis &#039;&#039;&#039;wclock24h-F103&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Anschließend wählt man in der oberen Zeile in der Mitte das Ziel aus, wofür man den Quellcode übersetzen möchte.&lt;br /&gt;
&lt;br /&gt;
Beim [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo]]-Projekt werden folgende Alternativen angeboten:&lt;br /&gt;
&lt;br /&gt;
WC24h:&lt;br /&gt;
&lt;br /&gt;
* WC24h-Nucleo401-Debug&lt;br /&gt;
* WC24h-Nucleo401-Release&lt;br /&gt;
&lt;br /&gt;
* WC24h-Nucleo411-Debug&lt;br /&gt;
* WC24h-Nucleo411-Release&lt;br /&gt;
&lt;br /&gt;
WC12h:&lt;br /&gt;
&lt;br /&gt;
* WC12h-Nucleo401-Debug&lt;br /&gt;
* WC12h-Nucleo401-Release&lt;br /&gt;
&lt;br /&gt;
* WC12h-Nucleo411-Debug&lt;br /&gt;
* WC12h-Nucleo411-Release&lt;br /&gt;
&lt;br /&gt;
In der F103-Projektdatei können folgende Varianten ausgewählt werden:&lt;br /&gt;
&lt;br /&gt;
WC24h:&lt;br /&gt;
&lt;br /&gt;
* WC24h-STM32F103-Debug&lt;br /&gt;
* WC24h-STM32F103-Release&lt;br /&gt;
&lt;br /&gt;
WC12h:&lt;br /&gt;
&lt;br /&gt;
* WC12h-STM32F103-Debug&lt;br /&gt;
* WC12h-STM32F103-Release&lt;br /&gt;
&lt;br /&gt;
Die Debug-Varianten sind lediglich für die Bugsuche im Programm vonnöten. Es empfiehlt sich daher im Normalfall, die entsprechende Release-Variante auszuwählen.&lt;br /&gt;
&lt;br /&gt;
Nach der Auswahl kann man dann unter &#039;&#039;&#039;Build -&amp;gt; Rebuild all target files&#039;&#039;&#039; den Übersetzungsvorgang starten. Danach findet man im Unterverzeichnis bin\\Release die dazugehörige Hex-Datei mit dem ST-Link-Programm dann auf dem Ziel geflasht werden kann. Das wars!&lt;br /&gt;
&lt;br /&gt;
= Hardware =&lt;br /&gt;
&lt;br /&gt;
== STM32F103C8T6 Mini-Development Board ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:STM32F103C8T6.png|miniatur|STM32F103C8T6 Mini-Development Board]]&lt;br /&gt;
[[Datei:WordClock24h-an-STM32F103-C8T6.png|mini|STM32F103C8T6 an STM32F103 Mini-Development Board]]&lt;br /&gt;
&lt;br /&gt;
Dies ist ein kleines, platzsparendes Board mit ausreichendem 32Bit-Mikrocontroller. Der STM32F103C8T6 hat 64 KB Flash und 20KB RAM. Bei ebay ist er für kleines Geld (unter 4 EUR) zu haben: Einfach dort nach &amp;quot;STM32F103C8T6&amp;quot; suchen. Die Anbieter sind meist in China. Aber es gibt auch Anbieter aus Deutschland, wo das bestellte Board dann auch schon nach 2 Tagen im Briefkasten steckt. Meist sind die deutschen Anbieter aber etwas teurer.&lt;br /&gt;
&lt;br /&gt;
Während die [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Boards]] bereits den &amp;quot;Programmer&amp;quot; ST-Link-V2 zum Programmieren des Flashs on-Board haben, ist dies hier nicht der Fall. Hier muss ein separates ST-Link-V2 zum einmaligen Programmieren verwendet werden. Hat man schon ein [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Board]] zuhause, kann der darauf befindliche ST-Link verwendet werden. Oder man beschafft sich einen eigenen Programmer. Bei eBay erhält man sie bereits im einstelligen Euro-Bereich, wenn man nach &amp;quot;ST-Link V2&amp;quot; sucht.&lt;br /&gt;
&lt;br /&gt;
Der Vorteil dieses Boards gegenüber dem Nucleo ist der geringe Platzbedarf. Es müssen lediglich ein paar Verbindungen zu den weiter unten erläuterten Modulen wie [[WordClock_mit_WS2812#RTC_und_EEPROM|EEPROM und RTC]] sowie [[WordClock_mit_WS2812#ESP8266|ESP8266]] ESP01 gezogen werden.&lt;br /&gt;
&lt;br /&gt;
Rechts ist die Anschluss-Skizze der WordClock an das [[WordClock_mit_WS2812#STM32F103C8T6_Mini-Development_Board|STM32F103-Mini-Development-Board]] zu sehen.&lt;br /&gt;
&lt;br /&gt;
== STM32F401RE Nucleo und STM32F411RE Nucleo ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:WC24h-Nucleo-Oberseite.jpg|miniatur|Nucleo: Zusätzliche Drahtbrücken R35 + R37 + 8MHz Quarz]]&lt;br /&gt;
[[Datei:WC24h-Nucleo-Unterseite.jpg|miniatur|Nucleo: Zu entfernende Lötbrücken + anzulötende 22pf Kondensatoren]]&lt;br /&gt;
[[Datei:WC24h-Nucleo-Shield.jpg|miniatur|Prototyp-Shield für das Nucleo-Board mit TSOP, ESP8266 und 3,3V Spannungsregler, später noch Anschluss für DCF77/EEPROM/RTC]]&lt;br /&gt;
&lt;br /&gt;
Es kann sowohl das 401er als auch das 411er [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Board]] verwendet werden. Beide werden identisch genutzt.&lt;br /&gt;
&lt;br /&gt;
Damit das Board später für den Einbau nur noch (incl. Shield) 2cm hoch ist, sollte man die überstehenden Enden der Steckerleisten auf der &#039;&#039;&#039;Unterseite&#039;&#039;&#039; mit einer Kneifzange kürzen. Die beiden Jumper auf der Unterseite (beim ST-Link-Device-Teil) können dabei auf die Oberseite gesteckt werden.&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei verschiedene Revisionen von den Nucleo-Boards:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;MB1136 C01&amp;quot;: Der STM32F4x1 läuft nur mit dem ungenauen internen Oszillator&lt;br /&gt;
* &amp;quot;MB1136 C02&amp;quot;: Der STM32F4x1 erhält seinen 8MHz Takt vom ST-Link-Devices&lt;br /&gt;
&lt;br /&gt;
Damit auch das Board mit der Revision &amp;quot;MB1136 C01&amp;quot; zuverlässig im HSE-Modus mit 84MHz läuft, sind folgende Hardware-Änderungen notwendig:&lt;br /&gt;
&lt;br /&gt;
* Lötbrücken SB54 und SB55 entfernen (mit Lötkolben erhitzen und wegschnippen)&lt;br /&gt;
* Lötbrücken SB16 und SB50 entfernen (dito)&lt;br /&gt;
* R35 und R37 jeweils mit einem Stück Draht oder 0R-Widerstand bestücken&lt;br /&gt;
* Quarz X3 (8 MHz) einlöten&lt;br /&gt;
* C33 und C34 mit jeweils 22pF bestücken.&lt;br /&gt;
&lt;br /&gt;
C33 und C34 können auch normale THT-Bauteile sein, wenn man die Drähte vorher kürzt. Ich habe sie auf der Unterseite direkt an den Quarz-Anschlüssen angebracht, siehe Foto rechts. Es geht aber auch auf der Oberseite direkt an den dafür vorgesehenen Lötstellen - dann aber vorzugsweise mit 0603 SMD-Kondensatoren.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Man sollte auf jeden Fall erst die beiden Drahtbrücken R35 &amp;amp; R37 einlöten, bevor man den Quarz bestückt. Dann hat man wesentlich mehr Platz für den Lötkolben ;-)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es emfiehlt sich jedoch, diese Änderungen auch mit dem Board der Revision &amp;quot;MB1136 C02&amp;quot; durchzuführen, da wir später für die endgültige Uhr den ST-Link-Teil der Platine absägen werden. Dafür ist extra eine Bruchstelle vorgesehen. Nur so ist das Board dann schmal genug, damit es hinter den 7,5cm schmalen Rand der Frontplatte passt.&lt;br /&gt;
&lt;br /&gt;
Nicht wundern: Je nach Revision des Boards sind einige der oben genannten Lötbrücken erst gar nicht bestückt. Dann braucht da auch nichts entfernt zu werden. Das hier beschriebene stellt also den gewünschten Endzustand dar.&lt;br /&gt;
&lt;br /&gt;
Diese Arbeit ist in ca. 10 Minuten erledigt. Besondere SMD-Lötkenntnisse benötigt man dafür nicht.&lt;br /&gt;
&lt;br /&gt;
== Anschluss TSOP31238 ==&lt;br /&gt;
&lt;br /&gt;
Anschlüsse am [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Board]]:&lt;br /&gt;
&lt;br /&gt;
   TSOP-Pin1 an GND, TSOP-Pin2 an 3,3 oder 5V, TSOP-Pin3 an PC10&lt;br /&gt;
&lt;br /&gt;
Anschlüsse am [[WordClock_mit_WS2812#STM32F103C8T6_Mini-Development_Board|STM32F103-Mini-Development-Board]]:&lt;br /&gt;
&lt;br /&gt;
   TSOP-Pin1 an GND, TSOP-Pin2 an 3,3V oder 5V, TSOP-Pin3 an PB3&lt;br /&gt;
&lt;br /&gt;
== Anschluss WS2812 ==&lt;br /&gt;
&lt;br /&gt;
Bei der WordClock24h wird eine 16x18-Matrix verwendet, bei der WordClock12h eine 10x11-Matrix.&lt;br /&gt;
&lt;br /&gt;
Die [[WordClock_mit_WS2812#WS2812|WS2812]]-LEDs werden dabei folgendermaßen verdrahtet:&lt;br /&gt;
&lt;br /&gt;
==== Anschluss WS2812-Streifen für WordClock12h ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NEU&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
Hier wird eine Spezialanferigung von WS2812-Stripes eingesetzt - nämlich mit einem Rastermaß von 28,1mm. Damit ist die WordClock12h von den Maßen her kompatibel zum bisherigen [[Word_Clock]]-Projekt. Das hat den Vorteil, dass bisherige Frontplatten und Zwischenböden weiterverwendet werden können.&lt;br /&gt;
&lt;br /&gt;
Auch bei der Wordclock12h steht jeder zweite Streifen &amp;quot;auf dem Kopf&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
          M4                                   +-------+        M1&lt;br /&gt;
           O---------+              µC --------| R220  |--------O&lt;br /&gt;
           |         |                         +-------+        |&lt;br /&gt;
           |         |                                          |&lt;br /&gt;
           |         1  2  3  4  ...              11            |&lt;br /&gt;
           |         O--O--O--O--O--O--O--O--O--O--O--+         |&lt;br /&gt;
           |                                          |         |&lt;br /&gt;
           |        22                            12  |         |&lt;br /&gt;
           |         O--O--O--O--O--O--O--O--O--O--O--+         |&lt;br /&gt;
           |         |                                          |&lt;br /&gt;
           |         |                                          |&lt;br /&gt;
           |         O--O--O--O--O--O--O--O--O--O--O--          |&lt;br /&gt;
           |       23 24 ....                                   |&lt;br /&gt;
           |                                                    |&lt;br /&gt;
           |                                                    |&lt;br /&gt;
           O----------------------------------------------------O&lt;br /&gt;
          M3                                                    M2&lt;br /&gt;
&lt;br /&gt;
Dabei sind M1-M4 die 4 Minutenpunkte in den Ecken. Es wird keine Status-LED wie in der WordClock24 verwendet. Tatsächlich werden hier dafür die Minutenpunkte zur zusätzlichen Statusausgabe mitbenutzt.&lt;br /&gt;
&lt;br /&gt;
Weitere 100 LEDs hinter der Buchstabenkette werden als Ambilight unterstützt. Diese müssen einfach hinter der LED für den letzten Buchstaben in der Kette angeschlossen werden. Die Anzahl ist variabel, maximal 100 Ambilight-LEDs sind möglich.&lt;br /&gt;
&lt;br /&gt;
==== Anschluss WS2812-Streifen für WordClock24h ====&lt;br /&gt;
&lt;br /&gt;
Verwendet werden Standard-WS2812-Stripes mit &#039;&#039;&#039;60 LEDs pro Meter&#039;&#039;&#039;. Dabei steht jeder zweite Streifen &amp;quot;auf dem Kopf&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
               +-------------------------------------------------------+&lt;br /&gt;
               |                                                       |&lt;br /&gt;
               1  2  3  4  ...                              18         |&lt;br /&gt;
               O--O--O--O--O--O--O--O--O--O--O--O--O--O--O--O--+       |&lt;br /&gt;
                                                               |       |&lt;br /&gt;
               36                                       20  19 |       |&lt;br /&gt;
               O--O--O--O--O--O--O--O--O--O--O--O--O--O--O--O--+       |&lt;br /&gt;
               |                                                       |&lt;br /&gt;
               |                                                       |&lt;br /&gt;
               O--O--O--O--O--O--O--O--O--O--O--O--O--O--O--O--        |&lt;br /&gt;
              37 38 ....                                               |&lt;br /&gt;
                                                                       |&lt;br /&gt;
                                                                       |&lt;br /&gt;
            +-------+             Status-LED                           |&lt;br /&gt;
  µC -------| R220  |------------------O-------------------------------+&lt;br /&gt;
            +-------+&lt;br /&gt;
&lt;br /&gt;
Auch hier können bis zu 100 Ambilight LEDs hinter der LED für den letzten Buchstaben in der Kette angeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Anschlüsse am [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Board]]:&lt;br /&gt;
&lt;br /&gt;
* Stripe +5V an externe Stromversorgung +5V&lt;br /&gt;
* Stripe DI über einen Serienwiderstand von 220 Ohm an PC6&lt;br /&gt;
* Stripe GND an externe Stromversorgung GND und(!) an GND des Boards&lt;br /&gt;
&lt;br /&gt;
Anschlüsse am [[WordClock_mit_WS2812#STM32F103C8T6_Mini-Development_Board|STM32F103-Mini-Development-Board]]:&lt;br /&gt;
&lt;br /&gt;
* Stripe +5V an externe Stromversorgung +5V&lt;br /&gt;
* Stripe DI über einen Serienwiderstand von 220 Ohm an PA8&lt;br /&gt;
* Stripe GND an externe Stromversorgung GND und(!) an GND des Boards&lt;br /&gt;
&lt;br /&gt;
== Anschluss Temperatur-Sensor ==&lt;br /&gt;
&lt;br /&gt;
Optional: [[WordClock_mit_WS2812#Temperatur-Sensor|DS18xxx]] als Temperatur-Sensor&lt;br /&gt;
&lt;br /&gt;
Es werden unterstützt:&lt;br /&gt;
&lt;br /&gt;
* DS1820&lt;br /&gt;
* DS18S20&lt;br /&gt;
* DS1822&lt;br /&gt;
* DS18B20&lt;br /&gt;
&lt;br /&gt;
Anschlüsse am [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Board]]:&lt;br /&gt;
&lt;br /&gt;
* DS18xx-GND (Pin 1) an GND&lt;br /&gt;
* DS18xx-DQ  (Pin 2) an PD2 und über Pullup 4,7k an DS18xx-VDD&lt;br /&gt;
* DS18xx-VDD (Pin 3) an Board-interne oder externe 3,3V&lt;br /&gt;
&lt;br /&gt;
Anschlüsse am STM32F103 [[WordClock_mit_WS2812#STM32F103C8T6_Mini-Development_Board|STM32F103-Mini-Development-Board]]:&lt;br /&gt;
&lt;br /&gt;
* DS18xx-GND (Pin 1) an GND&lt;br /&gt;
* DS18xx-DQ  (Pin 2) an PB5 und über Pullup 4,7k an DS18xx-VDD&lt;br /&gt;
* DS18xx-VDD (Pin 3) an Board-interne oder externe 3,3V&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ist kein DS18xx Temperatur-Sensor angeschlossen, wird die Temperatur über die RTC (DS3231) ermittelt.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Anschluss LDR ==&lt;br /&gt;
&lt;br /&gt;
Optional: [[WordClock_mit_WS2812#LDR|LDR]] zur Messung der Umgebungshelligkeit&lt;br /&gt;
&lt;br /&gt;
Schaltung: &lt;br /&gt;
&lt;br /&gt;
            AGND -----+&lt;br /&gt;
                      |&lt;br /&gt;
                      R = 1K&lt;br /&gt;
                      |&lt;br /&gt;
            µC  ------+&lt;br /&gt;
                      |&lt;br /&gt;
                     LDR (Reichelt: &amp;quot;LDR 07&amp;quot;)&lt;br /&gt;
                      |&lt;br /&gt;
            3,3V -----+&lt;br /&gt;
&lt;br /&gt;
Anschluss am [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Board]]: PC4&lt;br /&gt;
Anschluss am STM32F103 Board: PA5&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Wird kein [[WordClock_mit_WS2812#LDR|LDR]] benutzt, muss der µC-Eingang per 10k-Pullup auf 3,3V gelegt werden!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Anschluss DCF77 ==&lt;br /&gt;
&lt;br /&gt;
Optional: [[WordClock_mit_WS2812#DCF77|DCF77]] Modul&lt;br /&gt;
&lt;br /&gt;
Anschlüsse am [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Board]]:&lt;br /&gt;
&lt;br /&gt;
* DCF77 GND an GND&lt;br /&gt;
* DCF77 V+  an 3,3V&lt;br /&gt;
* DCF77 Out an PC11&lt;br /&gt;
&lt;br /&gt;
Anschlüsse am STM32F103 [[WordClock_mit_WS2812#STM32F103C8T6_Mini-Development_Board|STM32F103-Mini-Development-Board]]:&lt;br /&gt;
&lt;br /&gt;
* DCF77 GND an GND&lt;br /&gt;
* DCF77 V+  an 3,3V&lt;br /&gt;
* DCF77 Out an PB4&lt;br /&gt;
&lt;br /&gt;
Getestet wurde die Software mit dem Reichelt-[[WordClock_mit_WS2812#DCF77|DCF77]]-Modul, das aber lediglich ein befriedigendes Empfangsverhalten hat.&lt;br /&gt;
&lt;br /&gt;
Wird ein [[WordClock_mit_WS2812#DCF77|DCF77]]-Modul benutzt, welches einen Open-Collector-Ausgang verwendet, muss an PC11 noch ein 100k Pullup (zu 3,3V) angeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Wird KEIN DCF-Modul verwendet, sollte der µC-Eingang per 100k Pullup auf 3,3V gelegt werden!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Anschluss ESP8266 ==&lt;br /&gt;
&lt;br /&gt;
Optional: [[WordClock_mit_WS2812#ESP8266|ESP8266]] ESP-01: WLAN Modul&lt;br /&gt;
&lt;br /&gt;
[[Datei:WC24h-ESP8266-ESP-01.png|miniatur|Anschlussbelegung ESP8266 ESP-01 - Bauteilseite!]]&lt;br /&gt;
&lt;br /&gt;
Anschlüsse [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Board]]:&lt;br /&gt;
&lt;br /&gt;
* ESP8266 GND an GND&lt;br /&gt;
* ESP8266 VCC   an &#039;&#039;&#039;externe&#039;&#039;&#039; 3,3V (Vorsicht: Modul zieht bis zu 200mA!)&lt;br /&gt;
* ESP8266 CH_PD an PA6&lt;br /&gt;
* ESP8266 RST   an PA7&lt;br /&gt;
* ESP8266 TXD   an USART6 RX (PA12)&lt;br /&gt;
* ESP8266 RXD   an USART6 TX (PA11)&lt;br /&gt;
&lt;br /&gt;
Anschlüsse [[WordClock_mit_WS2812#STM32F103C8T6_Mini-Development_Board|STM32F103-Mini-Development-Board]]:&lt;br /&gt;
&lt;br /&gt;
* ESP8266 GND an GND&lt;br /&gt;
* ESP8266 VCC   an &#039;&#039;&#039;externe&#039;&#039;&#039; 3,3V (Vorsicht: Modul zieht bis zu 200mA!)&lt;br /&gt;
* ESP8266 CH_PD an PA1&lt;br /&gt;
* ESP8266 RST   an PA0&lt;br /&gt;
* ESP8266 TXD   an USART2 RX (PA3)&lt;br /&gt;
* ESP8266 RXD   an USART2 TX (PA2)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Wird KEIN [[WordClock_mit_WS2812#ESP8266|ESP8266]]-Modul verwendet, ist nichts weiter zu beachten, da die Erkennung automatisch erfolgt.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Anschluss RTC und EEPROM ==&lt;br /&gt;
&lt;br /&gt;
I2C-Modul mit DS3231 als RTC und EEPROM&lt;br /&gt;
&lt;br /&gt;
[[Datei:WC24h-DS3231-EEPROM.png|miniatur|DS3231 RTC + EEPROM]]&lt;br /&gt;
&lt;br /&gt;
Dieses Modul (siehe auch Foto rechts) findet man bei eBay oder Amazon ab ca. 2 EUR, wenn man als Suchbegriff &amp;quot;DS3231 EEPROM&amp;quot; eingibt. Es wird als Echtzeituhrt und für die Speicherung der Konfigurationsparameter verwendet. Ist kein DS18xx als Temperatursensor angeschlossen, wird die RTC auch zur Temperaturmessung genutzt.&lt;br /&gt;
&lt;br /&gt;
Anschlüsse [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Board]]:&lt;br /&gt;
&lt;br /&gt;
* I2C GND an GND&lt;br /&gt;
* I2C VCC an Board-interne oder externe 3,3V&lt;br /&gt;
* I2C SCL an PA8&lt;br /&gt;
* I2C SDA an PC9&lt;br /&gt;
&lt;br /&gt;
Anschlüsse [[WordClock_mit_WS2812#STM32F103C8T6_Mini-Development_Board|STM32F103-Mini-Development-Board]]:&lt;br /&gt;
&lt;br /&gt;
* I2C GND an GND&lt;br /&gt;
* I2C VCC an Board-interne oder externe 3,3V&lt;br /&gt;
* I2C SCL an PB6&lt;br /&gt;
* I2C SDA an PB7&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NEU: AB Version 1.0 werden auch [[WordClock_mit_WS2812#RTC_und_EEPROM|RTC/EEPROM]]-Module mit DS1307 erkannt.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Da die Module aus China teilweise auch ohne bestückte Batterien gesendet werden, sollte man sich&lt;br /&gt;
genau überlegen, ob man die Batterie CR2032 oder den Akku LiR2032 einbaut.&lt;br /&gt;
      &lt;br /&gt;
Sind sowohl die Diode 1N4148 als auch der Widerstand neben dem [[WordClock_mit_WS2812#RTC_und_EEPROM|RTC]]-IC bestückt, dann kann man auch den Akku (relativ teuren) LiR2032 einsetzen. In diesem Fall muss das Modul aber mit +5V statt 3,3V betreiben, damit der Akku überhaupt geladen wird. Sonst ist er aufgrund der Selbstendladung irgendwann leer.&lt;br /&gt;
&lt;br /&gt;
Sinnvollerweise sollte man das Modul eher mit einer CR2032 Batterie betreiben. Dann sollte man aber sicherheitshalber die Diode oder den Widerstand (neben der Diode) auf dem Modul entfernen (falls vorhanden, siehe Bild), damit keine Ladung (und Überhitzung) der Batterie passiert. Das ist zwar eigentlich erst ab einer Betriebsspannung von ca. 3,7V möglich, aber sicher ist sicher. Im Normalfall reicht eine CR2032 Batterie für 5-10 Jahre.&lt;br /&gt;
&lt;br /&gt;
Es ist wenig ratsam, ein [[WordClock_mit_WS2812#DCF77|DCF77]]- und das [[WordClock_mit_WS2812#ESP8266|ESP8266]]-Modul gleichzeitig einzusetzen, da das [[WordClock_mit_WS2812#ESP8266|ESP8266]]-WLAN-Modul den [[WordClock_mit_WS2812#DCF77|DCF77]]-Empfänger stören kann. Im Zweifel sollte man sich für eine der beiden Möglichkeiten entscheiden.&lt;br /&gt;
&lt;br /&gt;
== Anschlusstabelle ==&lt;br /&gt;
&lt;br /&gt;
{| {{Tabelle}}&lt;br /&gt;
|+ &#039;&#039;&#039;Anschlüsse&#039;&#039;&#039;&lt;br /&gt;
|-  style=&amp;quot;background-color:#eeeeee&amp;quot;&lt;br /&gt;
! Device || [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Board]] || [[WordClock_mit_WS2812#STM32F103C8T6_Mini-Development_Board|STM32F103-Mini-Development-Board]]&lt;br /&gt;
|-&lt;br /&gt;
| [[WordClock_mit_WS2812#TSOP31238|TSOP31238]] ([[IRMP]]) || GPIO:   PC10               || GPIO:   PB3&lt;br /&gt;
|- &lt;br /&gt;
| [[WordClock_mit_WS2812#DCF77|DCF77]]                    || GPIO:   PC11               || GPIO:   PB4&lt;br /&gt;
|- &lt;br /&gt;
| [[WordClock_mit_WS2812#Temperatur-Sensor|DS18xxx]]      || GPIO:   PD2                || GPIO:   PB5&lt;br /&gt;
|- &lt;br /&gt;
| [[WordClock_mit_WS2812#LDR|LDR]]                        || GPIO:   PC4                || GPIO:   PA5&lt;br /&gt;
|- &lt;br /&gt;
| [[MCURSES]] terminal (USB)                              || USART2: TX=PA2  RX=PA3     || USART1: TX=PA9  RX=PA10&lt;br /&gt;
|- &lt;br /&gt;
| [[WordClock_mit_WS2812#ESP8266|ESP8266]]                || USART6: TX=PA11 RX=PA12    || USART2: TX=PA2  RX=PA3&lt;br /&gt;
|- &lt;br /&gt;
| [[WordClock_mit_WS2812#ESP8266|ESP8266]]                || GPIO:   RST=PA7 CH_PD=PA6  || GPIO:   RST=PA0 CH_PD=PA1&lt;br /&gt;
|- &lt;br /&gt;
| [[WordClock_mit_WS2812#ESP8266|ESP8266]] Debug (opt)    || USART1: TX=PA9 RX=PA10     || USART3: TX=PB10 RX=PB11&lt;br /&gt;
|- &lt;br /&gt;
| [[WordClock_mit_WS2812#RTC_und_EEPROM|RTC / EEPROM]]    || I2C3:   SCL=PA8 SDA=PC9    || I2C1:   SCL=PB6 SDA=PB7&lt;br /&gt;
|- &lt;br /&gt;
| [[WordClock_mit_WS2812#WS2812|WS2812]]                  || DMA1:   PC6                || DMA1:   PA8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Start =&lt;br /&gt;
&lt;br /&gt;
Dieses Kapitel beschreibt den Download der Software auf das verwendete Board und die erstmalige Prüfung und Konfiguration.&lt;br /&gt;
&lt;br /&gt;
Geflasht wird mit dem ST-Link-Programm, siehe oben.&lt;br /&gt;
&lt;br /&gt;
Zur Überprüfung sämtlicher Funktionen und zur Konfiguration dienst der [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]]. Dazu benötigt man ein Terminal-Emulationsprogramm (wie zum Beispiel PuTTY) und ein Mini-USB-Kabel für das [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Board]].&lt;br /&gt;
&lt;br /&gt;
Laut http://www.mikrocontroller.net/topic/356203#3979181 sollte man dabei die &amp;quot;blauen&amp;quot; USB3.0-Buchsen möglichst meiden.&lt;br /&gt;
&lt;br /&gt;
== Ablauf ==&lt;br /&gt;
&lt;br /&gt;
* [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Board]] und PC mit Mini-USB-Kabel verbinden (zum Flashen, Debuggen und als COM-Schnittstelle)&lt;br /&gt;
* Wenn man die EM::Blocks-IDE einsetzt: Nach [[WordClock_mit_WS2812#WordClock-Quellcode_selbst_.C3.BCbersetzen|Anleitung: WordClock-Quellcode selbst übersetzen]] vorgehen&lt;br /&gt;
* Die entsprechende Hex-Datei (aus dem Ordner wclock24h\bin\Release oder direkt hier herunterladen) flashen&lt;br /&gt;
* PuTTY starten&lt;br /&gt;
* PuTTY einstellen: Auswahl &amp;quot;Serial&amp;quot;, Serial Line: COM11 (kann abweichen, s.u.), Speed: 115200&lt;br /&gt;
* Einen Session-Namen eingeben, z.B. &amp;quot;Nucleo&amp;quot;&lt;br /&gt;
* Auf SAVE klicken, dann kann man die Session später wieder auswählen&lt;br /&gt;
* Open anklicken&lt;br /&gt;
* RESET-Button am [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Board]] drücken&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Wichtig für [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Board]]:&#039;&#039;&#039;: Die COM-Schnittstelle ist immer aktiv, egal, ob das Programm gerade läuft oder nicht. Wird PuTTY erst nach dem Programmstart gestartet, sieht man im Terminal nur die Änderungen, also im allgemeinen nur die Uhrzeit. Mit der ENTER-Taste sollte man dann einen kompletten Bildschirm-Refresh erzwingen. Alternativ drückt man auf dem Board einfach den Reset-Knopf, um die komplette Ausgabe im [[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]] nachzuvollziehen.&lt;br /&gt;
&lt;br /&gt;
Sollte man Probleme mit dem Finden der richtigen COM-Schnittstelle haben, hilft der Geräte-Manager aus der Systemsteuerung weiter.&lt;br /&gt;
&lt;br /&gt;
== [[MCURSES]]-Monitor ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:Wclock24-in-putty.png|miniatur|WordClock24h in PuTTY]]&lt;br /&gt;
&lt;br /&gt;
Der [[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]] dient zur Überprüfung sämtlicher Funktionen und der Konfiguration des WLAN-Moduls.&lt;br /&gt;
&lt;br /&gt;
Dafür ist es sinnvoll, noch den Zeichensatz auf ISO8858-1 umzustellen. das geht folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
  Change Settings -&amp;gt; Window -&amp;gt; Translation -&amp;gt; ISO-8859-1:1998 (Latin-1, West Europe)&lt;br /&gt;
  Anschließend zurück über &amp;quot;Session&amp;quot; oben links und: &amp;quot;Save&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dann klappts auch mit den Sonderzeichen.&lt;br /&gt;
&lt;br /&gt;
Möchte man lieber schwarz auf weiß statt weiß auf schwarz, kann man das folgendermaßen umstellen:&lt;br /&gt;
&lt;br /&gt;
   Change Settings -&amp;gt; Window -&amp;gt; Colours:&lt;br /&gt;
&lt;br /&gt;
      Default Foreground: 2 2 2&lt;br /&gt;
      Default Bold Foreground: 0 0 0&lt;br /&gt;
      Default Background: 245 245 245&lt;br /&gt;
      Default Bold Background: 255 255 255&lt;br /&gt;
      Cursor Text: 0 0 0&lt;br /&gt;
      Cursor Color: 255 0 0&lt;br /&gt;
      (Rest kann man so lassen)&lt;br /&gt;
&lt;br /&gt;
Anschließend zurück über &amp;quot;Session&amp;quot; oben links und: &amp;quot;Save&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dann sollte das Ergebnis so aussehen wie rechts im Bild.&lt;br /&gt;
&lt;br /&gt;
{| {{Tabelle}}&lt;br /&gt;
|+ &#039;&#039;&#039;Tasten im [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]]&#039;&#039;&#039;&lt;br /&gt;
|-  style=&amp;quot;background-color:#eeeeee&amp;quot;&lt;br /&gt;
! Taste || Funktion&lt;br /&gt;
|-&lt;br /&gt;
| d/D   ||  Anzeigemodus +/-&lt;br /&gt;
|- &lt;br /&gt;
| a/A   ||  Animation +/-&lt;br /&gt;
|- &lt;br /&gt;
| h/H   ||  Stunden +/-&lt;br /&gt;
|- &lt;br /&gt;
| m/M   ||  Minuten +/-&lt;br /&gt;
|- &lt;br /&gt;
| r/R   ||  Helligkeit Rot +/-&lt;br /&gt;
|- &lt;br /&gt;
| g/G   ||  Helligkeit Grün +/-&lt;br /&gt;
|- &lt;br /&gt;
| b/B   ||  Helligkeit Blau +/-&lt;br /&gt;
|- &lt;br /&gt;
| w/W   ||  Grundhelligkeit +/- (&#039;&#039;&#039;NEU!&#039;&#039;&#039;)&lt;br /&gt;
|- &lt;br /&gt;
| q     ||  Automatische Helligkeitsregelung ein/aus (&#039;&#039;&#039;NEU!&#039;&#039;&#039;)&lt;br /&gt;
|- &lt;br /&gt;
| n     ||  Zeit von einem Timeserver holen&lt;br /&gt;
|- &lt;br /&gt;
| t     ||  Temperatur-Anzeige für 5 Sekunden (&#039;&#039;&#039;NEU!&#039;&#039;&#039;)&lt;br /&gt;
|- &lt;br /&gt;
| T     ||  LED-Testprogramm (&#039;&#039;&#039;NEU!&#039;&#039;&#039;)&lt;br /&gt;
|- &lt;br /&gt;
| i     ||  IR-Anlernroutine&lt;br /&gt;
|- &lt;br /&gt;
| c     ||  Konfiguration (WLAN, Timeserver und [[WordClock_mit_WS2812#LDR|LDR]])&lt;br /&gt;
|- &lt;br /&gt;
| o     ||  Okay, Save. Damit werden die Einstellungen im [[WordClock_mit_WS2812#RTC_und_EEPROM|EEPROM]] gespeichert.&lt;br /&gt;
|- &lt;br /&gt;
| e     ||  [[WordClock_mit_WS2812#RTC_und_EEPROM|EEPROM]]-Hexdump zur Kontrolle des Inhalts&lt;br /&gt;
|- &lt;br /&gt;
| p     ||  Power On/Off. Hiermit kann man die Anzeige ein- und ausschalten.&lt;br /&gt;
|- &lt;br /&gt;
| l     ||  Logout. Die Ausgabe über das Terminal wird eingestellt, bis zur nächsten ENTER-Taste&lt;br /&gt;
|- &lt;br /&gt;
| ENTER || Login. Der komplette Bildschirm-Inhalt wird dabei neu geschrieben&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Die Uhrzeit wird jede Sekunde in Real Time hochgezählt. Desweiteren erscheinen Infos über empfangene Uhrzeiten per [[WordClock_mit_WS2812#RTC_und_EEPROM|RTC]], [[WordClock_mit_WS2812#DCF77|DCF77]] und [[WordClock_mit_WS2812#ESP8266|ESP8266]]. Ebenso lassen sich die Farben der LEDs und der Anzeigemodus einstellen. Außerdem unterstützt der [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]] beim Anlernen einer IR-Fernbedienung.&lt;br /&gt;
&lt;br /&gt;
== Konfiguration des WLAN-Moduls ==&lt;br /&gt;
&lt;br /&gt;
=== Access-Point ===&lt;br /&gt;
&lt;br /&gt;
2 Sekunden nach dem Start wird von der STM32-Software getestet, ob ein [[WordClock_mit_WS2812#ESP8266|ESP8266]]-WLAN-Modul angeschlossen ist. Wird das Modul gefunden, erscheint im [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]] die Meldung &#039;&#039;&#039;&amp;quot;ESP8266 up&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
25 Sekunden nach dem Start wird davon ausgegangen, dass das [[WordClock_mit_WS2812#ESP8266|ESP8266]]-WLAN-Modul mittlerweile eine Verbindung zu einem Access-Point (&amp;quot;AP&amp;quot;) hat. Wenn dies der Fall ist, wird im [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]] die Meldung &#039;&#039;&#039;&amp;quot;ESP8266 online&amp;quot;&#039;&#039;&#039; ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Sobald die Up-Meldung ausgegeben wurde, kann man die Access-Point-Einstellungen für das (optionale) WLAN-Modul folgendermaßen konfigurieren:&lt;br /&gt;
&lt;br /&gt;
* Taste &#039;c&#039; (klein!) drücken&lt;br /&gt;
&lt;br /&gt;
Nach Eingabe von &amp;quot;1&amp;quot; für &amp;quot;Configure Network Module ESP8266&amp;quot; erscheint dann folgenes Menü:&lt;br /&gt;
&lt;br /&gt;
  1. Configure access to AP&lt;br /&gt;
  2. Configure time server&lt;br /&gt;
  3. Configure time zone&lt;br /&gt;
  0. Exit&lt;br /&gt;
&lt;br /&gt;
* Taste 1 drücken&lt;br /&gt;
* SSID eingeben (oder durch leere Eingabe per ENTER abbrechen)&lt;br /&gt;
* Key eingeben (oder durch leere Eingabe per ENTER abbrechen)&lt;br /&gt;
&lt;br /&gt;
Es wird jetzt für eine gewisse Zeit versucht, eine Verbindung mit dem AP aufzunehmen. Hat das Modul nach ca. 30 Sekunden immer noch keine stabile Verbindung, sollte man das Modul einmal komplett vom Strom trennen. Die Einstellungen sind aber im [[WordClock_mit_WS2812#ESP8266|ESP8266]]-Modul gespeichert und sollten nach dem Wiedereinschalten der Spannung automatisch funktionieren. &#039;&#039;&#039;Eine erneute Konfiguration ist also in der Regel nicht mehr erforderlich.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Timeserver ===&lt;br /&gt;
&lt;br /&gt;
Den Timeserver konfiguriert man folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
* Taste &#039;c&#039; (klein!), danach &#039;1&#039; drücken&lt;br /&gt;
&lt;br /&gt;
Es erscheint dann folgendes Menü:&lt;br /&gt;
&lt;br /&gt;
  1. Configure access to AP&lt;br /&gt;
  2. Configure time server&lt;br /&gt;
  3. Configure time zone&lt;br /&gt;
  0. Exit&lt;br /&gt;
&lt;br /&gt;
* Taste 2 drücken&lt;br /&gt;
* IP-Adress des neuen Timeservers eingeben oder ausgegebene IP-Adresse wiederholen (leere Eingabe bricht ab)&lt;br /&gt;
&lt;br /&gt;
Der Timeserver muss ein RFC 868 konformer Timeserver oder NTP-Server sein. Voreingestellt ist ntp3.ptb.de (192.53.103.103). Dieser kann sowohl über TIME (RFC 868) oder NTP angesprochen werden. Da dieser Server oft ausgelastet ist, kann man auch auf time.nist.gov (216.229.0.179) ausweichen. Als Zeitzone ist standardmäßig GMT+1 gesetzt.&lt;br /&gt;
&lt;br /&gt;
Eine Liste von Timeservern, welche RFC 868 genügen, findet man u.a. hier: http://tf.nist.gov/tf-cgi/servers.cgi&lt;br /&gt;
&lt;br /&gt;
Nach der Eingabe der IP-Adresse des Timeservers wird zunächst geprüft, ob der Timeserver das NTP-Protokoll beherrscht und ob die Firmware des [[WordClock_mit_WS2812#ESP8266|ESP8266]] eine dafür nötige UDP-Verbindung aufnehmen kann. Wenn nicht, wird von NTP auf TIME (TCP) gewechselt.&lt;br /&gt;
&lt;br /&gt;
Die aktuelle Uhrzeit wird einmal pro Stunde vom Timeserver geholt, nämlich immer um xx:10:17 Uhr. Im [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]] kann man aber auch jederzeit die Taste &#039;n&#039; drücken, um ad hoc die Zeit zu holen. Das funktioniert auch mit einer angelernten IR-Fernbedienung.&lt;br /&gt;
&lt;br /&gt;
=== Zeitzone ===&lt;br /&gt;
&lt;br /&gt;
Die Einstellung der Zeitzone geht folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
* Taste &#039;c&#039; (klein!) gefolgt von &#039;1&#039; drücken&lt;br /&gt;
&lt;br /&gt;
Es erscheint dann wieder das bekannte Menü:&lt;br /&gt;
&lt;br /&gt;
  1. Configure access to AP&lt;br /&gt;
  2. Configure time server&lt;br /&gt;
  3. Configure time zone&lt;br /&gt;
  0. Exit&lt;br /&gt;
&lt;br /&gt;
* Taste 3 drücken&lt;br /&gt;
* Zeitzone eingeben, z.B. &#039;&#039;&#039;+1&#039;&#039;&#039; für GMT&#039;&#039;&#039;+1&#039;&#039;&#039; - also für unsere mitteleuropäische Zeit.&lt;br /&gt;
&lt;br /&gt;
== Konfiguration des LDR (Umgebungslicht-Messer) ==&lt;br /&gt;
&lt;br /&gt;
Die automatische Helligkeitsregelung muss explizit konfiguriert werden.&lt;br /&gt;
&lt;br /&gt;
* Im [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]] Taste &#039;c&#039; (klein!) drücken&lt;br /&gt;
&lt;br /&gt;
Es erscheint dann ein Menü:&lt;br /&gt;
&lt;br /&gt;
  1. Configure Network Module ESP8266&lt;br /&gt;
  2. Configure LDR&lt;br /&gt;
  0. Exit&lt;br /&gt;
&lt;br /&gt;
* Taste 2 drücken&lt;br /&gt;
&lt;br /&gt;
Dann kann man den [[WordClock_mit_WS2812#LDR|LDR]] ein- oder ausschalten:&lt;br /&gt;
&lt;br /&gt;
  Current configuration: LDR connected&lt;br /&gt;
&lt;br /&gt;
  1. LDR connected&lt;br /&gt;
  2. LDR not connected&lt;br /&gt;
  0. Exit&lt;br /&gt;
&lt;br /&gt;
Mit &#039;1&#039; wird der [[WordClock_mit_WS2812#LDR|LDR]] aktiviert, mit 2 wird er deaktiviert. Die Einstellung wird im [[WordClock_mit_WS2812#RTC_und_EEPROM|EEPROM]] gespeichert.&lt;br /&gt;
&lt;br /&gt;
Geplant ist hier später noch eine Kalibrierung, d.h. Anpassung an die Gegebenheiten der Umgebung.&lt;br /&gt;
&lt;br /&gt;
== IR-Fernbedienung ==&lt;br /&gt;
&lt;br /&gt;
In den ersten 3 Sekunden leuchtet die Status-LED mit der Farbe weiß, um zu signalisieren, dass nun eine IR-Fernbedienung angelernt werden kann. Wird währenddessen irgendein gültiger IR-Code empfangen, wechselt die Status-LED für eine Sekunde auf rot (FB-Knopf loslassen!) und es wird in die Anlernroutine gesprungen. Wird kein IR-Signal empfangen, startet das Programm wie gewohnt.&lt;br /&gt;
&lt;br /&gt;
Die Anlernroutine kann man auch mit dem blauen User-Button auf dem [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Board]] aktivieren. Desweiteren ist dies auch mit der Taste &#039;i&#039; möglich, wenn man den [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]] nutzt. Dort wird man dann aufgefordert, folgende FB-Tasten zu drücken:&lt;br /&gt;
&lt;br /&gt;
{| {{Tabelle}}&lt;br /&gt;
|+ &#039;&#039;&#039;Tasten für IR-Fernbedienung&#039;&#039;&#039;&lt;br /&gt;
|-  style=&amp;quot;background-color:#eeeeee&amp;quot;&lt;br /&gt;
! Taste || Funktion || LED || Buchstabe&lt;br /&gt;
|-&lt;br /&gt;
| Power || Anzeige ein/aus                           || LED1  || style=&amp;quot;text-align:center&amp;quot;| E&lt;br /&gt;
|- &lt;br /&gt;
| OK    || Speichern der Einstellungen               || LED2  || style=&amp;quot;text-align:center&amp;quot;| S&lt;br /&gt;
|- &lt;br /&gt;
| MODE- || Anzeigemodus erniedrigen                  || LED3  || style=&amp;quot;text-align:center&amp;quot;| A&lt;br /&gt;
|- &lt;br /&gt;
| MODE+ || Anzeigemodus erhöhen                      || LED4  || style=&amp;quot;text-align:center&amp;quot;| I&lt;br /&gt;
|- &lt;br /&gt;
| ANIM- || Animation erniedrigen                     || LED5  || style=&amp;quot;text-align:center&amp;quot;| S&lt;br /&gt;
|- &lt;br /&gt;
| ANIM+ || Animation erhöhen                         || LED6  || style=&amp;quot;text-align:center&amp;quot;| T&lt;br /&gt;
|- &lt;br /&gt;
| HOUR- || Stunde erniedrigen                        || LED7  || style=&amp;quot;text-align:center&amp;quot;| O&lt;br /&gt;
|- &lt;br /&gt;
| HOUR+ || Stunde erhöhen                            || LED8  || style=&amp;quot;text-align:center&amp;quot;| V&lt;br /&gt;
|- &lt;br /&gt;
| MIN-  || Minute erniedrigen                        || LED9  || style=&amp;quot;text-align:center&amp;quot;| I&lt;br /&gt;
|- &lt;br /&gt;
| MIN+  || Minute erhöhen                            || LED10 || style=&amp;quot;text-align:center&amp;quot;| E&lt;br /&gt;
|- &lt;br /&gt;
| RED-  || Helligkeit der Farbe Rot erniedrigen      || LED11 || style=&amp;quot;text-align:center&amp;quot;| R&lt;br /&gt;
|- &lt;br /&gt;
| RED+  || Helligkeit der Farbe Rot erhöhen          || LED12 || style=&amp;quot;text-align:center&amp;quot;| T&lt;br /&gt;
|- &lt;br /&gt;
| GREEN- || Helligkeit der Farbe Grün erniedrigen    || LED13 || style=&amp;quot;text-align:center&amp;quot;| E&lt;br /&gt;
|- &lt;br /&gt;
| GREEN+ || Helligkeit der Farbe Grün erhöhen        || LED14 || style=&amp;quot;text-align:center&amp;quot;| L&lt;br /&gt;
|- &lt;br /&gt;
| BLUE-  || Helligkeit der Farbe Blau erniedrigen    || LED15 || style=&amp;quot;text-align:center&amp;quot;| E&lt;br /&gt;
|- &lt;br /&gt;
| BLUE+  || Helligkeit der Farbe Blau erhöhen        || LED16 || style=&amp;quot;text-align:center&amp;quot;| I&lt;br /&gt;
|- &lt;br /&gt;
| BRIGHT-  || Grundhelligkeit erniedrigen            || LED17 || style=&amp;quot;text-align:center&amp;quot;| N&lt;br /&gt;
|- &lt;br /&gt;
| BRIGHT+  || Grundhelligkeit erhöhen                || LED18 || style=&amp;quot;text-align:center&amp;quot;| S&lt;br /&gt;
|- &lt;br /&gt;
| AUTO+  || Automatische Helligkeitsregelung ein/aus || LED19 || style=&amp;quot;text-align:center&amp;quot;| D (2. Zeile)&lt;br /&gt;
|- &lt;br /&gt;
| TEMP   || Anzeige der Temperatur für 5 Sekunden    || LED20 || style=&amp;quot;text-align:center&amp;quot;| R (2. Zeile)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Dabei leuchtet die oben angegebene LED hinter dem jeweiligen Buchstaben auf dem Display in der obersten Zeile (&#039;&#039;&#039;ES#IST#VIERTELEINS&#039;&#039;&#039;), damit der Anlernvorgang auch ohne [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]] vorgenommen werden kann. Sind die FB-Tasten angelernt, kann man die Uhrzeit, den Anzeigemodus und auch die Farben mittels IR-Fernbedienung einstellen.&lt;br /&gt;
&lt;br /&gt;
Es sind nur die gebräuchlichsten IR-Protokolle aktiviert, nämlich:&lt;br /&gt;
&lt;br /&gt;
* SIRCS (Sony)&lt;br /&gt;
* NEC (Viele Hersteller, sehr verbreitet)&lt;br /&gt;
* SAMSUNG&lt;br /&gt;
* MATSUSHITA&lt;br /&gt;
* KASEIKYO&lt;br /&gt;
&lt;br /&gt;
[[IRMP]] &amp;quot;versteht&amp;quot; jedoch bis zu 40 Protokolle. Braucht man weitere - wie RC5 oder RC6 - kann man sie in irmp/irmp-config.h freischalten. Bei Problemen empfiehlt sich die Lektüre des [[IRMP]]-Artikels.&lt;br /&gt;
&lt;br /&gt;
== Android App ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:Wc24h-Android.png|miniatur|WC24h Android App]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Für die STM32-Software-Version 1.5.0 muss die [[WordClock_mit_WS2812#Android_App|Android App]] mindestens die Version 1.4 oder höher haben!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ist ein [[WordClock_mit_WS2812#ESP8266|ESP8266]]-Modul angeschlossen und korrekt konfiguriert, kann die Uhr ab Software-Version 1.0 per [[WordClock_mit_WS2812#Android_App|Android App]] ferngesteuert werden.&lt;br /&gt;
&lt;br /&gt;
Momentan können folgende Einstellungen vorgenommen werden:&lt;br /&gt;
&lt;br /&gt;
* Ein-/Ausschalten der Uhr&lt;br /&gt;
* Einstellen der Farben&lt;br /&gt;
* Manuelle Einstellung einer Grundhelligkeit (&#039;&#039;&#039;Neu&#039;&#039;&#039;)&lt;br /&gt;
* Automatische Helligkeitsregelung per [[WordClock_mit_WS2812#LDR|LDR]] ein/aus  (&#039;&#039;&#039;Neu&#039;&#039;&#039;)&lt;br /&gt;
* Einstellung des Anzeigemodus&lt;br /&gt;
* Einstellung der Animation (Überblenden, Rollen, Explosion etc.)&lt;br /&gt;
&lt;br /&gt;
Weitere Features werden folgen.&lt;br /&gt;
&lt;br /&gt;
Bevor man mit der App Daten senden kann, muss man die IP-Adresse, die das [[WordClock_mit_WS2812#ESP8266|ESP8266]]-Modul bekommen hat, in der App einstellen. Dies geht über den Menü-Eintrag &amp;quot;Server&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
= Mechanik =&lt;br /&gt;
&lt;br /&gt;
== Anbringung der WS2812-Streifen ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:Wclock24h-WS2812-auf-Alu-Platte.jpg|miniatur|16 WS2812-Streifen auf Alu-Platte]]&lt;br /&gt;
[[Datei:Wclock24h-16-pol-Wanne.png|miniatur|16pol Wanne zum Verbinden des Netzteils und der Streifen]]&lt;br /&gt;
[[Datei:Wclock24h-Spannungsvergung-Streifen.jpg|miniatur|Anschluss der Streifen an die Spannungsversorgung]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WordClock24h:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Am besten verwendet man eine Alu-Platte mit den Maßen 310mmx310mm und 1mm Stärke. Darauf lassen sich nicht nur einfach die WS2812-LED-Streifen aufkleben, auch dient die Alu-Platte der Wärmeabfuhr. Die Alu-Platte kann man sich von einem der eBay-Händler für ca. 3,50 Euro zurechtschneiden lassen.&lt;br /&gt;
&lt;br /&gt;
Den LED-Streifen schneidet man 16 Streifen à 18 LEDs. Bevor man sie auf die LED-Platte klebt, sollte man senkrecht je einen Tesa-Streifen links und rechts auf die Alu-Platte kleben, da sich gezeigt hat, dass die Schnittkanten der Streifen gern einen Kurzschluss mit der Alu-Platte bilden.&lt;br /&gt;
&lt;br /&gt;
Die LED-Streifen werden dann im Zieharmonika-Verfahren aufgeklebt. Dabei steht jeder 2. Streifen auf dem Kopf. Das hat den Vorteil, dass die Verbindungen zwischen den Streifen möglichst kurz sind. Auf der rechten Seite verbindet man dann die Anschlüsse +5V mit +5V, GND mit GND und DO mit DI - siehe Bild. Man verbindet also den ersten mit dem zweiten Streifen, den dritten mit dem vierten Streifen usw.&lt;br /&gt;
&lt;br /&gt;
Auf der linken Seite verbindet man lediglich DO mit DI, also den zweiten Streifen mit dem dritten, den vierten mit dem fünften usw. An den verbleibenden Lötpunkten +5V und GND lötet man an jedem *zweiten* Streifen (1, 3, 5 usw.) die Spannungsversorgung  an. Praktisch ist die Verwendung eines 16-poligen Flachbandkabels, welches man auf einen Flachbandkabel-Stecker aufquetscht. Pin 1 und 2 gehen dann an 5V/GND des ersten Streifens, 3 und 4 an 5V/GND des dritten Streifens usw.&lt;br /&gt;
&lt;br /&gt;
Dann kann man mittels 16-poligem Wannenstecker, den man auf eine Lochrasterplatine lötet, die Spannungsversorgung einfach verpolungssicher anstecken. Unter der Lochrasterplatine werden die geradzahligen Pins und die ungeraden Pins je mit einem Kupferdraht verbunden. Mit einer 2-poligen Schraubklemme auf der Lochrasterplatine kann dann das Netzteil angeschlossen werden - siehe Bild rechts.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WordClock12h:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
(In Arbeit)&lt;br /&gt;
&lt;br /&gt;
== Zwischenplatten ==&lt;br /&gt;
&lt;br /&gt;
(in Arbeit)&lt;br /&gt;
&lt;br /&gt;
== Frontplatten ==&lt;br /&gt;
&lt;br /&gt;
(in Arbeit)&lt;br /&gt;
&lt;br /&gt;
= Sammelbestellungen =&lt;br /&gt;
&lt;br /&gt;
== WC12h Sammelbestellung LED Stripes ==&lt;br /&gt;
&lt;br /&gt;
Hier wird eine Spezialanfertigung mit einem Rastermaß von 28,1mm eingesetzt.&lt;br /&gt;
&lt;br /&gt;
(Kapitel noch in Arbeit)&lt;br /&gt;
&lt;br /&gt;
== WC12h Sammelbestellung Zwischenböden ==&lt;br /&gt;
&lt;br /&gt;
(Kapitel noch in Arbeit)&lt;br /&gt;
&lt;br /&gt;
== WC12h Sammelbestellung Frontplatten ==&lt;br /&gt;
&lt;br /&gt;
(Kapitel noch in Arbeit)&lt;br /&gt;
&lt;br /&gt;
== WC24h Sammelbestellung LED Stripes ==&lt;br /&gt;
&lt;br /&gt;
(Kapitel noch in Arbeit)&lt;br /&gt;
&lt;br /&gt;
== WC24h Sammelbestellung Zwischenböden ==&lt;br /&gt;
&lt;br /&gt;
(Kapitel noch in Arbeit)&lt;br /&gt;
&lt;br /&gt;
== WC24h Sammelbestellung Frontplatten ==&lt;br /&gt;
&lt;br /&gt;
(Kapitel noch in Arbeit)&lt;br /&gt;
&lt;br /&gt;
= Anhang =&lt;br /&gt;
&lt;br /&gt;
=== Historie der Software-Versionen ===&lt;br /&gt;
&lt;br /&gt;
Version 1.6.3:&lt;br /&gt;
&lt;br /&gt;
* WordClock12h: Anzeige der Temperatur durch Laufschrift&lt;br /&gt;
* Neue Anschlusspins für TSOP und DS18xxx am STM32F103&lt;br /&gt;
* Optimierung des WS2812-DMA-Transfers für STM32F103&lt;br /&gt;
* Temperaturmessung mit DS3231, wenn kein DS18xx angeschlossen&lt;br /&gt;
* Umstrukturierung der C-Sources&lt;br /&gt;
&lt;br /&gt;
Version 1.6.2:&lt;br /&gt;
&lt;br /&gt;
* Problem beim Verbindungsaufbau Andoid App -&amp;gt; WordClock behoben&lt;br /&gt;
&lt;br /&gt;
Version 1.6.1:&lt;br /&gt;
&lt;br /&gt;
* Zusätzliche Unterstützung der &amp;quot;klassischen&amp;quot; WordClock12h mit 10x11 LEDs&lt;br /&gt;
* Anpassung der [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]]-Oberfläche an WordClock12h-Variante&lt;br /&gt;
* Portierung auf STM32F103 abgeschlossen (IDE-Projekt folgt mit 1.6.2)&lt;br /&gt;
* Zusätzliche Unterstützung von neueren [[WordClock_mit_WS2812#ESP8266|ESP8266]]-Firmware-Versionen 1.0.1, 1.4.0 und 1.5.0.&lt;br /&gt;
* Optionales [[WordClock_mit_WS2812#ESP8266|ESP8266]]-Debugging auf zusätzlichem USART - nur für Entwickler&lt;br /&gt;
&lt;br /&gt;
Version 1.6.0:&lt;br /&gt;
&lt;br /&gt;
* Neben dem TIME-Protokoll (TCP) wird nun auch NTP (UDP) unterstützt - für ESP-Firmware-Versionen ab 0018000902.&lt;br /&gt;
&lt;br /&gt;
Version 1.5.9:&lt;br /&gt;
&lt;br /&gt;
* Unterstützung der neueren ESP Versionen 0020000903 und AT 0.21.0.0&lt;br /&gt;
* Vergrößerung der UART-FIFOs&lt;br /&gt;
* Verallgemeinerung der UART-Funktionen zwecks besserer Konfiguration&lt;br /&gt;
* Überarbeitung der [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]]-Oberfläche&lt;br /&gt;
&lt;br /&gt;
Version 1.5.8:&lt;br /&gt;
&lt;br /&gt;
* Bugfix: Fehler in 1.5.7 (Falsche Behandlung des DMA-Buffers) wurde behoben&lt;br /&gt;
* Neu: Bis zu 100 weitere LEDs hinter der Buchstabenkette werden als Ambilight angesteuert&lt;br /&gt;
&lt;br /&gt;
Version 1.5.7:&lt;br /&gt;
&lt;br /&gt;
* Bug in uart-Code für STM32F103 beseitigt - irrelevant für Nucleo STM324xx&lt;br /&gt;
* Timing für WS2812B angepasst, es werden nun WS2812 und WS2812B unterstützt&lt;br /&gt;
* Anzahl der möglichen [[WordClock_mit_WS2812#WS2812|WS2812]]-LEDs ist nun variabel gehalten. Das ist Voraussetzung für das demnächst verfügbare Ambilight.&lt;br /&gt;
&lt;br /&gt;
Version 1.5.6:&lt;br /&gt;
&lt;br /&gt;
* Unterstützung von [[WordClock_mit_WS2812#ESP8266|ESP8266]] mit neuerer Firmware, welche \r\n statt \r erwartet&lt;br /&gt;
* Unterstützung von verschiedenen Baudraten des [[WordClock_mit_WS2812#ESP8266|ESP8266]]-Moduls&lt;br /&gt;
* Automatische Umschaltung von 9600Bd auf 115200Bd beim [[WordClock_mit_WS2812#ESP8266|ESP8266]]&lt;br /&gt;
&lt;br /&gt;
Version 1.5.5:&lt;br /&gt;
&lt;br /&gt;
* Optimierungen im LED-Display-Code&lt;br /&gt;
* Diverse Anpassungen an STM32F103&lt;br /&gt;
&lt;br /&gt;
Version 1.5.4:&lt;br /&gt;
&lt;br /&gt;
* Automatische IR-Anlernroutine in den ersten 3 Sekunden ab Programmstart&lt;br /&gt;
* Kleiner Bugfix bei den möglichen Helligkeitsstufen (Dimmer)&lt;br /&gt;
&lt;br /&gt;
Version 1.5.2:&lt;br /&gt;
&lt;br /&gt;
* Anzeige der Firmware-Version des [[WordClock_mit_WS2812#ESP8266|ESP8266]]-Moduls im [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]]&lt;br /&gt;
* Korrektur in den Worttabellen für die Wörter ACHT und VIER in der zehnten Reihe&lt;br /&gt;
&lt;br /&gt;
Version 1.5.1:&lt;br /&gt;
&lt;br /&gt;
* Manuelle Helligkeitsregelung per [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]] / IR-Fernbedienung / [[WordClock_mit_WS2812#Android_App|Android App]] eingebaut&lt;br /&gt;
* Automatische Helligkeitsregelung per [[WordClock_mit_WS2812#LDR|LDR]] nun über [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]] / IR-Fernbedienung / [[WordClock_mit_WS2812#Android_App|Android App]] ein-/ausschaltbar&lt;br /&gt;
&lt;br /&gt;
Version 1.4.2:&lt;br /&gt;
&lt;br /&gt;
* Die geladenen aus dem [[WordClock_mit_WS2812#RTC_und_EEPROM|EEPROM]] RGB-Werte wurden nach dem Boot nicht mehr sofort übernommen. Ist korrigiert.&lt;br /&gt;
&lt;br /&gt;
Version 1.4.1:&lt;br /&gt;
&lt;br /&gt;
* Initialisierung des ADC korrigiert&lt;br /&gt;
* Automatische Helligkeitsregelung dunkelt nicht mehr so stark ab.&lt;br /&gt;
&lt;br /&gt;
Version 1.4.0:&lt;br /&gt;
&lt;br /&gt;
* Automatische Helligkeitsregelung mittels [[WordClock_mit_WS2812#LDR|LDR]]&lt;br /&gt;
* Helligkeitsstufen von 32 auf 64 erhöht&lt;br /&gt;
* LED-Testprogramm eingebaut (Taste &#039;T&#039; im [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]])&lt;br /&gt;
* Anzeige des [[WordClock_mit_WS2812#Temperatur-Sensor|DS18xxx]]-Typs im [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]])&lt;br /&gt;
* Unterstützung für Status-LED &#039;&#039;&#039;(beachte geändertes LED-Anschluss-Schema!)&#039;&#039;&#039;&lt;br /&gt;
* [[WordClock_mit_WS2812#Android_App|Android App]] an 64 Helligkeitsstufen angepasst&lt;br /&gt;
&lt;br /&gt;
Version 1.3.1:&lt;br /&gt;
&lt;br /&gt;
* Sporaisches Hangup-Problem nach Auslesen der Temperatur behoben&lt;br /&gt;
* Fehler bei der Erkennung des Family-Codes für [[WordClock_mit_WS2812#Temperatur-Sensor|DS18xxx]] beseitigt&lt;br /&gt;
* Optimierung des Zeitverhaltens beim Zugriff auf OneWire-Bus&lt;br /&gt;
* Optimierung des [[WordClock_mit_WS2812#WS2812|WS2812]]-Codes&lt;br /&gt;
&lt;br /&gt;
Version 1.3.0:&lt;br /&gt;
&lt;br /&gt;
* Unterstützung von [[WordClock_mit_WS2812#Temperatur-Sensor|DS18xxx]]-Temperatursensoren&lt;br /&gt;
* Temperatur-Anzeige innerhalb +10°C und 39,5°C&lt;br /&gt;
* Korrektur Sommerzeitumstellung&lt;br /&gt;
* Keine Unterstützung mehr von STM32F4-Discovery&lt;br /&gt;
&lt;br /&gt;
Version 1.2.0:&lt;br /&gt;
&lt;br /&gt;
* IRMP-Konfigurationsfehler behoben&lt;br /&gt;
&lt;br /&gt;
Version 1.1.0:&lt;br /&gt;
&lt;br /&gt;
* Animationen hinzugefügt&lt;br /&gt;
* Neue Tabellen für Uhrzeit und Temperatur&lt;br /&gt;
&lt;br /&gt;
Version 1.0.0:&lt;br /&gt;
&lt;br /&gt;
* Test auf verschiedene Adressen des I2C-[[WordClock_mit_WS2812#RTC_und_EEPROM|EEPROMs]]&lt;br /&gt;
* [[WordClock_mit_WS2812#RTC_und_EEPROM|EEPROM]]-Speicherplatzverbrauch minimiert&lt;br /&gt;
* [[WordClock_mit_WS2812#RTC_und_EEPROM|RTC]] DS3231-Routinen auf DS1307 verallgemeinert&lt;br /&gt;
* Network Listener (UDP) zum Fernsteuern der Uhr über WLAN&lt;br /&gt;
* [[WordClock_mit_WS2812#Android_App|Android App]] zum Fernsteuern der Uhr (Ein/Aus, Farben, Anzeigemodus)&lt;br /&gt;
&lt;br /&gt;
Version 0.9.1:&lt;br /&gt;
&lt;br /&gt;
* [[WordClock_mit_WS2812#RTC_und_EEPROM|EEPROM]]-Hexdump im [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]] eingebaut&lt;br /&gt;
* Zusätzliche Waitstates beim Beschreiben des [[WordClock_mit_WS2812#RTC_und_EEPROM|EEPROMs]]&lt;br /&gt;
&lt;br /&gt;
Version 0.9:&lt;br /&gt;
&lt;br /&gt;
* Zusätzlicher Anschluss von RST und CH_PD des [[WordClock_mit_WS2812#ESP8266|ESP8266]]-Moduls&lt;br /&gt;
* Verbesserung der [[WordClock_mit_WS2812#ESP8266|ESP8266]]-Konfiguration dank Hardware-Reset&lt;br /&gt;
* Nutzung des Stromsparmodus im [[WordClock_mit_WS2812#ESP8266|ESP8266]], wenn die Anzeige abgeschaltet wird&lt;br /&gt;
* Konfiguration der Zeitzone über [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]]&lt;br /&gt;
* Test und Überarbeitung der [[WordClock_mit_WS2812#RTC_und_EEPROM|EEPROM]] und [[WordClock_mit_WS2812#RTC_und_EEPROM|RTC]]-Funktionen&lt;br /&gt;
* Synchronisation der [[WordClock_mit_WS2812#RTC_und_EEPROM|RTC]]-Zeit mit dem µC-Timer&lt;br /&gt;
* Speichern folgender Daten im [[WordClock_mit_WS2812#RTC_und_EEPROM|EEPROM]]:&lt;br /&gt;
&lt;br /&gt;
     EEPROM-Version&lt;br /&gt;
     IRMP-Daten einer angelernten IR-Fernbedienung&lt;br /&gt;
     Aktuell eingestellte Farben und Anzeigemodus&lt;br /&gt;
     IP-Adresse des Timeservers&lt;br /&gt;
     Zeitzone&lt;br /&gt;
&lt;br /&gt;
Version 0.8:&lt;br /&gt;
&lt;br /&gt;
* Neue IR-Fernbedienungs-Tasten POWER und OK&lt;br /&gt;
* Einbau einer konfigurierbaren &amp;quot;Nachtzeit&amp;quot;, in der sich die Uhr selbstständig abschaltet&lt;br /&gt;
* Konfiguration des Timeservers über [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]]&lt;br /&gt;
* Speichern/Laden sämtlicher Konfigurations-Daten in externem EEPROM&lt;br /&gt;
* Initialisierung des [[WordClock_mit_WS2812#ESP8266|ESP8266]] verbessert (warten, bis nach PowerOn eine WLAN-Verbindung besteht)&lt;br /&gt;
* Aufteilung der Anzeige-Logik und des [[MCURSES]]-[[WordClock_mit_WS2812#MCURSES-Monitor|Monitor]]s auf dsp.c und monitor.c&lt;br /&gt;
* Aufteilung der [[WordClock_mit_WS2812#ESP8266|ESP8266]]-Routinen auf esp8266.c (low-level) und timeserver.c (high-level)&lt;br /&gt;
* Diverse Optimierungen - u.a. durch Einsatz von uint_fast8_t&lt;br /&gt;
* Diverse Bugfixes&lt;br /&gt;
&lt;br /&gt;
Version 0.7.1:&lt;br /&gt;
&lt;br /&gt;
* Portierung der Software auf STM32F411RE [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Board]]&lt;br /&gt;
&lt;br /&gt;
Version 0.7:&lt;br /&gt;
&lt;br /&gt;
* Portierung der Software auf STM32F401RE [[WordClock_mit_WS2812#STM32F401RE_Nucleo_und_STM32F411RE_Nucleo|Nucleo-Board]]&lt;br /&gt;
* uart2.c generalisiert auf uart.c (verschiedene UARTs möglich)&lt;br /&gt;
* Bugfix im UART-Ringbuffer-Code (Interrupt-Sperre)&lt;br /&gt;
* Anzeige der Online-Devices ([[WordClock_mit_WS2812#ESP8266|ESP8266]], [[WordClock_mit_WS2812#DCF77|DCF77]], EEPROM, [[WordClock_mit_WS2812#RTC_und_EEPROM|RTC]]) im Terminal&lt;br /&gt;
* Verschiedene Optimierungen&lt;br /&gt;
&lt;br /&gt;
Version 0.6:&lt;br /&gt;
&lt;br /&gt;
* Konfiguration des WLAN-Moduls (SSID &amp;amp; Key) nun über Terminal statt fest im Code verdrahtet.&lt;br /&gt;
* Einstellung der Zeitzone möglich. Standard ist GMT+1, also mitteleuropäische Zeit.&lt;br /&gt;
* [[WordClock_mit_WS2812#DCF77|DCF77]]- und [[WordClock_mit_WS2812#ESP8266|ESP8266]]-Modul-Aktivierung automatisch - keine Einstellung mehr im Code notwendig.&lt;br /&gt;
* I2C-Lib hinzugefügt (noch ungetestet und daher noch nicht verwendet).&lt;br /&gt;
* I2C-[[WordClock_mit_WS2812#RTC_und_EEPROM|EEPROM]]-Modul hinzugefügt (noch ungetestet und daher noch nicht verwendet).&lt;br /&gt;
* I2C-[[WordClock_mit_WS2812#RTC_und_EEPROM|RTC]]-Modul (DS3231) hinzugefügt (noch ungetestet und daher noch nicht verwendet).&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR-GCC-Codeoptimierung&amp;diff=90757</id>
		<title>AVR-GCC-Codeoptimierung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR-GCC-Codeoptimierung&amp;diff=90757"/>
		<updated>2015-12-21T05:13:01Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Änderung 90492 von Mfgkw (Diskussion) rückgängig gemacht. Der Wert 59.1 ist schon richtig.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Entstanden aus diesem [http://www.mikrocontroller.net/topic/66690 Thread] sollen hier ein paar Hinweise/Erfahrungen gegeben werden, um den Quellcode in Punkto Größe und Geschwindigkeit zu optimieren. &#039;&#039;En detail&#039;&#039; ist das Thema komplex, da es stark von der Codeoptimierung des Compilers abhängt. Es ist im Einzelfall ratsam zu prüfen, ob die eigenen Maßnahmen auch erfolgreich waren. Die Diskussionen [http://www.mikrocontroller.net/topic/132624] bzw. [http://www.mikrocontroller.net/topic/180800#new] können als Anhaltspunkte dienen, wie eine solche Prüfung ablaufen kann.&lt;br /&gt;
&lt;br /&gt;
== Prinzipien der Optimierung ==&lt;br /&gt;
&lt;br /&gt;
Wie so oft sollte man nicht einfach wild drauf los optimieren und sich zunächst ein paar Dinge klar machen.&lt;br /&gt;
&lt;br /&gt;
* Warum will ich optimieren?&lt;br /&gt;
* Was kann man sinnvoll optimieren?&lt;br /&gt;
* Wieviel Rechenzeit oder Speicher soll dabei gespart werden?&lt;br /&gt;
* Wie kann optimiert werden?&lt;br /&gt;
* &#039;&#039;&#039;&amp;quot;Verfrühte Optimierung ist die Wurzel allen Übels!&amp;quot;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Viele Optimierungen sind &amp;quot;Angst-Optimierungen&amp;quot;, die nicht wirklich nötig sind. Die Gefahr mit Optimierungen ist, den Code tot zu optimieren, sprich Lesbarkeit, Portierbarkeit und ggf. Fehlerfreiheit sinken massgeblich. Kurz und knapp in diesem [http://blogs.msdn.com/b/audiofool/archive/2007/06/14/the-rules-of-code-optimization.aspx BLOG] formuliert.&lt;br /&gt;
&lt;br /&gt;
=== Warum ===&lt;br /&gt;
&lt;br /&gt;
Optimieren sollte man nur, wenn&lt;br /&gt;
* der Speicher nicht mehr ausreicht (RAM, Flash)&lt;br /&gt;
* Die Laufzeit für bestimmte Programmteile zu groß wird und somit bestimmte (Echtzeit-)Ausgaben nicht im erforderlichen Zeitrahmen erledigt werden&lt;br /&gt;
&lt;br /&gt;
Weiter sollte man folgende Punkte gegeneinander abwägen:&lt;br /&gt;
&lt;br /&gt;
* Codeverbrauch&lt;br /&gt;
* Datenverbrauch. Statisch/Stack/Heap&lt;br /&gt;
* Mittlere Laufzeit/maximale Laufzeit&lt;br /&gt;
* Entwicklungszeit&lt;br /&gt;
* Portabilität (Compiler, Hardware, ...)&lt;br /&gt;
* Verständlichkeit der Quelle, siehe [[Strukturierte Programmierung auf Mikrocontrollern]] &lt;br /&gt;
* ABI-Konformität&lt;br /&gt;
&lt;br /&gt;
=== Was ===&lt;br /&gt;
&lt;br /&gt;
Die goldene Regel lautet:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;90% der Rechenleistung werden in 10% des Codes verbraucht.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Diese 10% muss man finden und zum richtigen Zeitpunkt optimieren. Der Rest muss nur sauber und lesbar geschrieben sein. Was jedoch nichts bringt, ist eine Funktion, die von 1 Minute Programmlaufzeit lediglich 1 Sekunde verbraucht, um den Faktor 10 schneller zu machen. Die Programmlaufzeit sinkt dann von 60 Sekunden auf 59.1 Sekunden. Der Aufwand, die Funktion um einen Faktor 10 schneller zu machen ist aber meistens beträchtlich!  Kann ich aber den Code, der für die 59 Sekunden verantwortlich ist um lediglich einen Faktor 2 schneller machen (was immer noch oft schwer genug ist, aber auf jeden Fall leichter als ein Faktor 10), dann sinkt die Gesamtlaufzeit von 60 Sekunden auf 30.5 Sekunden. Dort bringt Optimieren augenscheinlich viel mehr!&lt;br /&gt;
&lt;br /&gt;
Um die optimierungswürdigen Stellen zu finden, muss man sein Programm analysieren. Dazu gibt es verschiedene Möglichkeiten.&lt;br /&gt;
&lt;br /&gt;
====Speicherverbrauch nach Funktionen aufschlüsseln====&lt;br /&gt;
&lt;br /&gt;
;map-File:&lt;br /&gt;
:dort sind alle globalen und statischen Variablen enthalten. Eine Map-Datei kann mit den GNU-Tools während des Linkens angelegt werden:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-gcc ... -Wl,-Map,foo.map&amp;lt;/pre&amp;gt;&lt;br /&gt;
: Die Option -Wl bewirkt, daß avr-gcc die angehängen Optionen unverändert an den Linker weiterreicht. Dieser erzeugt dann das Mapfile &amp;quot;foo.map&amp;quot;, eine Textdatei.&lt;br /&gt;
;avr-size: Mit Tools wie avr-size kann die Platzbelegung einzelner Module ermittelt werden:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-size -x foo1.o foo2.o ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
:bzw. die Platzbelegung der elf-Datei:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-size foo.elf&amp;lt;/pre&amp;gt;&lt;br /&gt;
;avr-nm:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-nm --size-sort -S foo.elf&amp;lt;/pre&amp;gt;&lt;br /&gt;
:ergibt eine Liste mit der Größe aller Objekte: der erste Spalte enthälte die Adresse, die zweite Spalte die Größe, die dritte den Typ und die vierte Spalte den zugehörigen Symbolnamen. Der Typ ergibt sich aus der folgenden Zuordnung, wobei Großbuchstaben globale Symbole kennzeichnen und Kleinbuchstaben Symbole, die Modul-lokal sind:&lt;br /&gt;
:;T/t: Objekte in der text-Section: Funktionen, Daten im Flash&lt;br /&gt;
:;D/d: Objekte im data-Segment (initialisierte Daten)&lt;br /&gt;
:;B/b: Objekte im bss-Segment (Null-initialisierte Daten)&lt;br /&gt;
&lt;br /&gt;
;avr-gcc: Der Compiler hat bereits Informationen über die übersetzten Funktionen, die man direkt zur Analyse verwenden kann. Dazu lässt man avr-gcc die Assembler-Ausgabe, die ohne weiteres Zutun nur als temporäre Datei angelegt wird, abspeichern. Etwa für die Quelldatei foo.c:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-gcc -save-temps foo.c -c ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
:Die Assembler-Datei wird damit als foo.s angelegt und nicht gelöscht. (Das ebenfalls angelegte Präcompilat foo.i wird nicht benötigt). Für jede Funktion gibt avr-gcc 3.4.x im Prolog einen Kommentar der Form&amp;lt;ref&amp;gt;Für avr-gcc 4.x sehen die Kommentare anders aus oder fehlen je nach Compilerversion ganz&amp;lt;/ref&amp;gt;&lt;br /&gt;
::&amp;lt;pre&amp;gt;/* prologue: frame size=0 */&amp;lt;/pre&amp;gt;&lt;br /&gt;
:aus, was die Größe des aktuellen Frames angibt. Dies ist der Platz auf dem Stack, der für lokale Variablen benötigt wird. Am besten ist es, wenn die Frame-Size wie im Beispiel gleich 0 ist. Ansonsten sollte man versuchen, diese Größe auf Null zu bringen. Für Variablen, die nicht in Registern gehalten werden können, müssen Speicherzugriffe in den Stack erzeugt werden. Diese machen das Programm sowohl größer aus auch langsamer. Zudem reserviert avr-gcc bei solche Funktionen das Y-Register als Frame-Pointer; das Y-Register steht damit nicht mehr für lokale Variablen zur Verfügung was sich ebenfalls ungünstig auf die Codegüte auswirkt. Ein Grund für das Anlegen eines Frames können zu viele lokale Variablen sein (zB lokale Puffer/Arrays) oder lokale Variablen/Strukturen/Parameter mit ungünstigen Größen, etwa eine 3-Byte große Struktur. &lt;br /&gt;
&lt;br /&gt;
: Neben dieser Information gibt avr-gcc Kommentare der Gestalt&lt;br /&gt;
::&amp;lt;pre&amp;gt;/* prologue end (size=2) */&amp;lt;/pre&amp;gt;&lt;br /&gt;
:aus die darüber informieren, wie viele Register auf dem Stack gesichert wurden.&lt;br /&gt;
&lt;br /&gt;
: Zusammen mit Werkzeugen wie grep, die in jedem Linux und jeder WinAVR-Distribution enthalten sind, findet man schnell Übeltäter wie Funktionen mit Frame.&lt;br /&gt;
&lt;br /&gt;
;Assembler-Code sichten: Ein kurzer Blick auf den erzeugten Assembler-Code zeigt oft, wie gut der Compiler den Code umgesetzt hat. Den erzeugten Assembler-Code zu überfliegen ist wesentlich zeitsparender als selbst in Assembler zu programmieren. Je nach Gusto verwendet man zur Einsicht den Assembler-Code, den avr-gcc ausgibt (s.o.), Assembler-Dumps des Assemblers, List-Files oder HEX-Dumps. Siehe auch&amp;lt;ref&amp;gt;[http://rn-wissen.de/index.php/Assembler-Dump_erstellen_mit_avr-gcc roboternetz.de: Assembler-Dump erstellen mit avr-gcc]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Hilfsmittel: einkaufen oder selber bauen. Es gilt herauszufinden, welche Funktion massig Stack durch lokale Variablen verbraucht. Stacktracer können das. Wenn man keinen hat, dann muss man sich eben selber einen bauen, indem man den Stackpointer mitloggt. Zur Not einen Code-Review machen: Alle Funktionen optisch durchgehen und die identifizieren, die viele Variablen anlegen. Dann die Aufrufhierarchie der Funktion feststellen: Wirken sich die vielen Variablen überhaupt aus oder entsteht mein Problem durch eine tiefe Funktionsaufrufhierarchie, bei der zwar wenige Variablen pro Funktion im Spiel sind, aber die Menge der ineinandergeschachtelten Aufrufe &#039;das Kraut fett macht&#039;&lt;br /&gt;
;Profitools: können das alles fast auf Knopfdruck, kosten aber viel Geld&lt;br /&gt;
&lt;br /&gt;
====Laufzeit messen====&lt;br /&gt;
&lt;br /&gt;
*Simulator&lt;br /&gt;
*In Echtzeit mittels Testpin, welche an Anfang einer Funktion/Blocks gesetzt wird und am Ende wieder gelöscht wird. Mit einem [[Oszilloskop]] kann man so sehr einfach die Laufzeit messen.&lt;br /&gt;
&lt;br /&gt;
; Anmerkung: Solche Messverfahren liefern immer nur eine &#039;&#039;untere&#039;&#039; Schranke für die Laufzeit, niemals eine obere Schranke. Eine obere Schranke, wie man sie etwa in sicherheitsktitischen Systemen benötigt, liefert eine statische Codeanalyse.&lt;br /&gt;
&lt;br /&gt;
=== Wieviel ===&lt;br /&gt;
&lt;br /&gt;
Der Aufwand von Optimierungen wächst exponentiell. Die letzten paar Prozent brauchen überproportional viel Aufwand.&lt;br /&gt;
&lt;br /&gt;
=== Wie ===&lt;br /&gt;
&lt;br /&gt;
Meist muss man die Wahl treffen ob man Speicher oder Rechenzeit sparen will, beides gleichzeitg geht meist nicht. Das Konzept heißt &#039;Space for Time&#039; und kann in beide Richtungen verwendet werden. Als Beispiel soll eine komplizierte Berechnung dienen. Diese kann man relativ kompakt in eine Funktion packen, welche dann aber eher langsam ist. Oder man benutzt eine sehr große Tabelle, in welcher die Ergebnisse schon für jeden Eingangswert vorausberechnet wurden. Diese Lösung ist sehr schnell, verbraucht aber sehr viel Speicher.&lt;br /&gt;
&lt;br /&gt;
* Inlining von Funktionen erhöht den Speicherverbrauch, senkt aber die Laufzeit. Beispiel: Funktion A ist 50 Byte groß und wird 10 mal im Programm aufgerufen. Ein Aufruf kostet 10 Byte:&lt;br /&gt;
** Ohne Inline: 10 * 10Byte + 50 Byte = 150 Byte Platzverbrauch&lt;br /&gt;
** Mit Inline: 10 * 50 Byte = 500 Byte&lt;br /&gt;
* Optimierer einschalten&lt;br /&gt;
* möglichst keine Floating Point Operationen, besser ist meist [[Festkommaarithmetik]]&lt;br /&gt;
* Formeln umstellen und zusammenfassen&lt;br /&gt;
* Variablen so klein wie möglich, uint8_t wo&#039;s nur geht.&lt;br /&gt;
* Wirklich zeitkritische Funktionen und Interrupts als Assemblercode in separater Datei&lt;br /&gt;
&lt;br /&gt;
== GCC-Optionen ==&lt;br /&gt;
&lt;br /&gt;
=== Optimierungs-Level ===&lt;br /&gt;
&lt;br /&gt;
avr-gcc kennt mehrere Optimierungsstufen:&lt;br /&gt;
;&amp;lt;tt&amp;gt;-O0&amp;lt;/tt&amp;gt;: Keine Optimierung des erzeugten Codes. Diese Optimierungsstufe optimiert den Resourcenverbrauch des &#039;&#039;Hostrechners&#039;&#039; und die Nachvollziehbarkeit der erzeugten Codes anhand von Debug-Information. Alle lokalen Variablen werden auf dem Stack angelegt und nicht in Registern gehalten. Es werden keine komplexen Optimierungsalgorithmen angewandt; lediglich Konstanten wie 1+2 werden zu 3 gefaltet.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-O1&amp;lt;/tt&amp;gt;: Je höher die Optimierungsstufe, desto schwieriger ist der erzeugte Code nachvollziehbar — auch mit Debugger. Diese O-Stufe ist ein Kompromiss zwischen aggressiver Optimierung und Nachvollziehbarkeit des erzeugten Codes. Ein ehernes Gesetz in GCC ist, dass er den gleichen Code erzeugen muss unabhängig davon, ob Debug-Information erzeugt wird oder nicht. Im Umkehrschluss erlaubt volle Debug-Unterstützung nicht alle Optimierungen, wozu diese Optimierungsstufe dient.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-O2&amp;lt;/tt&amp;gt;: Optimierung auf Geschwindigkeit. Für AVR nur mässig sinnvoll, da sich der Codezuwachs nicht in einen entsprechenden Geschwindigkeitszuwachs transformiert. Dies liegt vor allem daran, daß Sprünge und Funktionsaufrufe auf AVR im Vergleich zu anderen Architekturen sehr billig sind. Es bringt also kaum einen Geschwindigkeitszuwachs, einen Block zu kopieren um einen Sprung zu sparen. Hingegen vergrößert dies den Code deutlich.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-O3&amp;lt;/tt&amp;gt;: Dito. Auf Teufel-komm-raus Funktionen zu inlinen, Schleifen aufzurollen oder gar Funktionen mehrfach für unterschiedliche Aufruf-Szenarien zu implementieren, ist auf einem kleinen µC wie AVR der Overkill.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-Os&amp;lt;/tt&amp;gt;: Optimierung auf Codegröße. Die bevorzugte Optimierungsstufe für AVR und viele andere µC.&lt;br /&gt;
&lt;br /&gt;
Jede O-Option ist ein Sammlung von verschiedenen Schaltern, welche bestimmte Optimierungsstrategien aktivieren. Um zu sehen, welche Schalter dies genau sind, erzeugt man wie oben beschrieben mit den Schalten&lt;br /&gt;
   -save-temps -fverbose-asm&lt;br /&gt;
die Assembler-Ausgabe von gcc und schaut die Optionen im s-File nach. Einzelne Optionen lassen sich gezielt aktivieren bzw. deaktivieren und damit zum Beispiel zum &amp;lt;tt&amp;gt;-Os&amp;lt;/tt&amp;gt;-Paket hinzufügen. &lt;br /&gt;
&lt;br /&gt;
Eine Ausnahme bildet &amp;lt;tt&amp;gt;-O0&amp;lt;/tt&amp;gt;: Hier ist Code-Optimierung generell deaktiviert, und Optimierungsschalter bleiben ohne Wirkung.&lt;br /&gt;
&lt;br /&gt;
=== Feinabstimmung der Optimizer ===&lt;br /&gt;
&lt;br /&gt;
Kandidaten für Optimierungsoptionen sind folgende Schalter. &amp;lt;tt&amp;gt;-m&amp;lt;/tt&amp;gt; kennzeichnet maschinenspezifische Schalter, die nur für AVR gültig sind. &amp;lt;tt&amp;gt;-f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;-fno-&amp;lt;/tt&amp;gt; sind maschinenunabhängige Schalter, die auch für andere Architekturen verfügbar sind.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-split-wide-types&amp;lt;/tt&amp;gt;: Je nach Quelle kann die Deaktivierung von &amp;lt;tt&amp;gt;-fsplit-wide-types&amp;lt;/tt&amp;gt; besseren Code ergeben.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-inline-small-functions&amp;lt;/tt&amp;gt;: Relativ kleine Funktionen /immer/ zu inlinen kann den Code unnötig vergrößern, dieser Schalter unterbindet das automatische Inlinen kleiner Funktionen.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-finline-limit=&amp;lt;/tt&amp;gt;&#039;&#039;wert&#039;&#039;: Maximalwert für automatisch geinlinte Funktionen. In einschlägigen Foren werden kleine Werte für &#039;&#039;wert&#039;&#039; vorgeschlagen, z.B.&amp;amp;nbsp;1…3&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-mcall-prologues&amp;lt;/tt&amp;gt;: Die für aufwändige Funktionen mitunter recht langen push/pop-Sequenzen werden durch Hilfsfunktionen ersetzt. Das kann vor allem bei grossen Programmen Platz sparen. Die Ausführungszeit steigt an.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-jump-tables&amp;lt;/tt&amp;gt;: Switch-Statements werden hierdurch mitunter deutlich kürzer.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-move-loop-invariants&amp;lt;br/&amp;gt;-fno-tree-loop-optimize&amp;lt;/tt&amp;gt;: Einige Schleifenoptimierungen, welche die Registerlast erhöhen und für AVR kaum zu einem Geschwindigkeitszuwachs führen, werden deaktiviert.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-tree-switch-conversion&amp;lt;/tt&amp;gt;: Neue GCC-Versionen können switch/case Anweisungen u.U. in Lookup-Tabellen umwandeln, die im RAM abgelegt werden, siehe auch [http://gcc.gnu.org/PR49857 PR49857]. Dieser Optimierung ist bei RAM-Knappheit in Betracht zu ziehen, bring aber natürlich nur dann etwas, wenn diese Optimierung auch ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-optimize-sibling-calls&amp;lt;/tt&amp;gt;: Ab 4.7 wirksam: Tailcall-Optimierung kann den Code vergrößern, wenn Epiloge mehrfach erzeugt werden. In diesem Fall deaktiviert man die Tailcall-Optimierung.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-maccumulate-args&amp;lt;/tt&amp;gt;: Ab 4.7: Funktionen, die mehrere printf-artige Aufrufe enthalten und viele Artumente per Stack an diese übergeben, werden u.U kleiner.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-mstrict-X&amp;lt;/tt&amp;gt;: Ab 4.7: Beeinflusst die Art und Weise, wie das X-Register zur Adressierung verwendet wird.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-mbranch-cost=&amp;lt;/tt&amp;gt;&#039;&#039;wert&#039;&#039;: Ab 4.7: Setzt die Kosten, mit der der Compiler einen bedingten Sprunge veranschlagt. Default-Wert ist &#039;&#039;wert&#039;&#039;&amp;lt;tt&amp;gt;=0&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-caller-saves&amp;lt;/tt&amp;gt;: Kann zu effizienteren Pro-/Epilogen beitragen.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-tree-ter&amp;lt;/tt&amp;gt;: Es gibt Fälle, in denen der Compiler die Berechnung temporärer Variablen über volatile-Zugriffe und Memory-Barriers zieht, siehe [http://gcc.gnu.org/PR53033 PR53033]. Von der  C-Spezifikation her ist dies zulässig, kann aber zu unerwünschter Umsortierung der volatile-Operation führe, z.B. wenn es sich dabei um eine &amp;lt;tt&amp;gt;SEI&amp;lt;/tt&amp;gt;-Instruktion handelt. Ohne diese Optimierung wird der Code evtl. etwas größer, aber Probleme wie im PR beschrieben können vermieden werden.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;--param case-values-threshold=&amp;lt;/tt&amp;gt;&#039;&#039;wert&#039;&#039;: Ab 4.7: Schwellwert an Einträgen in einem switch/case, ab dem anstatt eines binären if/else-Entscheidungsbaums eine Sprungtabelle zu den case-Labels erzeugt wird. Voreinstellung ab 4.7 ist &#039;&#039;wert&#039;&#039;&amp;lt;tt&amp;gt;=7&amp;lt;/tt&amp;gt;. Ältere Compilerversionen verwenden andere Werte. Siehe auch &amp;lt;tt&amp;gt;-f[no-]jump-tables&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Generell gilt für all diese Optionen, daß sie abhängig vom Projekt zu einer Codeverbesserung oder -verschlechterung führen können — dies ist i.d.R. vom Projektcode abhängig.&lt;br /&gt;
&lt;br /&gt;
=== Linker-Optionen ===&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-ffunction-sections&amp;lt;br/&amp;gt;-Wl,--gc-sections&amp;lt;/tt&amp;gt;: Der Linker wirft nicht referenzierte Sections weg, was die Codegröße günstig beeinflussen kann.  Diese Optimierung verkleinert den Code nur dann, wenn nicht verwendete Funktionen in der Anwendung rumgammeln. Weil der Linker nur auf Section-Ebene optimieren kann, muss zusätzlich der Compiler mit &amp;lt;tt&amp;gt;-ffunction-sections&amp;lt;/tt&amp;gt; aufgerufen werden, um die Anwendung auf möglichst viele Sections zu verteilen.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-Wl,--relax&amp;lt;br/&amp;gt;-mrelax&amp;lt;/tt&amp;gt;: Der Linker fasst Tail-Calls wie&lt;br /&gt;
::&amp;lt;tt&amp;gt;CALL some_function&amp;lt;br/&amp;gt;RET&amp;lt;/tt&amp;gt;&lt;br /&gt;
: zusammen als&lt;br /&gt;
::&amp;lt;tt&amp;gt;JMP some_function&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Siehe auch die Compiler-Option &amp;lt;tt&amp;gt;-f[no-]optimize-sibling-calls&amp;lt;/tt&amp;gt; von oben. Zudem wird &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; umgewandelt zur kürzeren &amp;lt;tt&amp;gt;RCALL&amp;lt;/tt&amp;gt;-Instruktion falls das Sprungziel im ±4&amp;amp;nbsp;KiB-Zielbereich von &amp;lt;tt&amp;gt;RCALL&amp;lt;/tt&amp;gt; liegt. Analog für &amp;lt;tt&amp;gt;JMP&amp;lt;/tt&amp;gt; zu &amp;lt;tt&amp;gt;RJMP&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
: Die beiden Optionen sind gleichwertig; die erste Variante veranlasst den Compiler, den Linker mit &amp;lt;tt&amp;gt;--relax&amp;lt;/tt&amp;gt; aufzurufen. Die zweite Variante verwendet den allgemeinen &amp;lt;tt&amp;gt;-Wl&amp;lt;/tt&amp;gt;-Mechanismus, um eine Option von der Compiler-Kommandozeile an den Linker durchzureichen.&lt;br /&gt;
&lt;br /&gt;
=== Weitere Optionen ===&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-mtiny-stack&amp;lt;/tt&amp;gt;: Der Compiler ändert nur das Low-Byte des Stackpointers (SP), was auf Controllern mit 16-Bit SP zu kleinerem Code führen kann.  Benötigt der Code Platz auf dem Stack, so erzeugt der Compiler u.U. Code, der den SP liest, einen Offset aufaddiert/abzieht und den SP dann zurückschreibt. Dies ist aufwändig. Für den Fall, daß sich dabei das High-Byte SP nicht ändert, kann Code eingespart werden.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;u&amp;gt;Beispiel&amp;lt;/u&amp;gt;: ATtiny44 hat RAM von &amp;lt;tt&amp;gt;0x60&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;0x15f&amp;lt;/tt&amp;gt;. Braucht die Anwendung nicht mehr als &amp;lt;tt&amp;gt;0x60&amp;lt;/tt&amp;gt;&amp;amp;nbsp;=&amp;amp;nbsp;96 Bytes an Stack, dann kann mit &amp;lt;tt&amp;gt;-mtiny-stack&amp;lt;/tt&amp;gt; compiliert werden.&lt;br /&gt;
&lt;br /&gt;
=== Änderung des Binärinterfaces per Option ===&lt;br /&gt;
&lt;br /&gt;
{{Warnung|&lt;br /&gt;
;Warnung: Im Gegensatz zu den Optionen der vorherigen Abschnitte, bei denen es sich um reine Optimierungsoptionen handelt, ändern die folgenden Optionen das Binärinterface (ABI) des vom Compiler erzeugten Codes und sind daher nur nach eingehender Prüfung anzuwenden! Wird eine Anwendung mit diesen Schaltern übersetzt, dann ist sicher zu stellen, daß &#039;&#039;alle&#039;&#039; Module inclusive Libraries damit derzeugt werden oder die ABI-Änderung sich nicht auf Code in Bibliotheken auswirkt!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Vorsicht in auch deshalb geboten, weil manche Entwicklungsumgebungen wie &amp;quot;Atmel Studio&amp;quot; das ABI &#039;&#039;per Default&#039;&#039; verändern und ohne daß der Anwender es extra anfordert.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-funsigned-char&amp;lt;/tt&amp;gt;: Anders als im avr-gcc ABI ist der Typ &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; unsigned anstatt signed.&lt;br /&gt;
:&amp;lt;u&amp;gt;Besser&amp;lt;/u&amp;gt;: Verwende die C99-Typen wie &amp;lt;tt&amp;gt;uint8_t&amp;lt;/tt&amp;gt; aus dem C99-Header &amp;lt;tt&amp;gt;stdint.h&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-funsigned-bitfields&amp;lt;/tt&amp;gt;: Bitfelder mit Basetype &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt; werden als unsigned implementiert anstatt als signed wie in der avr-gcc ABI.&lt;br /&gt;
:&amp;lt;u&amp;gt;Besser&amp;lt;/u&amp;gt;: Wenn ein Bitfeld unsigned sein soll, dann mach es unsigned!&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fpack-struct&amp;lt;/tt&amp;gt;: Im Gegensatz zur avr-gcc ABI werden Strukturen und Unions per default gepackt.&lt;br /&gt;
:&amp;lt;u&amp;gt;Besser&amp;lt;/u&amp;gt;: Wenn ein zusammengesetzter Typ gepackt werden soll, mache ein Typedef mit explizitem &amp;lt;tt&amp;gt;__attribute__((packed))&amp;lt;/tt&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fshort-enums&amp;lt;/tt&amp;gt;: Enum-Typen werden so kurz wie möglich implementiert anstatt als &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; gemäß avr-gcc ABI.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-mint8&amp;lt;/tt&amp;gt;: Ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ist nur nocht 8 Bits breit. Dies entspricht nicht mehr dem C-Standard und wird nicht durch die C-Bibliotheken wie AVR-Libc oder newlib unterstützt! Die Codegröße von 8-Bit Operationen kann sich verkleinern, weil andere Integer-Promotion Regeln angewandt werden. Literals müssen ggf. angepasst bzw gecastet werden, siehe auch C99-Makros wie &amp;lt;tt&amp;gt;UINT16_C&amp;lt;/tt&amp;gt; aus &amp;lt;tt&amp;gt;stdint.h&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Anpassungen der Quelle ==&lt;br /&gt;
&lt;br /&gt;
=== Attribute noreturn, OS_main und OS_task ===&lt;br /&gt;
&lt;br /&gt;
Mikrocontroller-Programme laufen normalerweise in einer Endlosschleife, so dass die main-Routine nie verlassen wird.&lt;br /&gt;
Teilt man dies dem Compiler mit, kann er bestimmte Optimierungen durchführen.&lt;br /&gt;
So ist es zum Beispiel unnötig, Code zum Sichern und Zurücklesen von Registern zu erzeugen.&lt;br /&gt;
&lt;br /&gt;
Das Mitteilen funktioniert beim gcc über Attribute, die man der Deklaration oder bei der Implementierung einer Funktion anhängt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;static void main_loop (void) __attribute__((noreturn));&lt;br /&gt;
void main_loop (void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
     // Hauptschleife&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
oder&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;static void __attribute__((noreturn))&lt;br /&gt;
main_loop (void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
     // Hauptschleife&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;main_loop&amp;lt;/tt&amp;gt; kann dann in &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; aufgerufen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;int main (void)&lt;br /&gt;
{&lt;br /&gt;
  main_loop();&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Das abschließende &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; wird vom Compiler wegoptimiert und belegt keinen Speicher.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;avr-gcc&amp;lt;/tt&amp;gt; kennt weiterhin die Attribute &amp;lt;tt&amp;gt;OS_main&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;OS_task&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Die Verwendung von &amp;lt;tt&amp;gt;OS_main&amp;lt;/tt&amp;gt; kann etwa aussehen wie folgt. Natürlich kann auch wie oben die Hauptschleife in einer eigenen Funktion implementiert werden, und das &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; verursacht keinen zusätzlichen Code:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;int __attribute__((OS_main))&lt;br /&gt;
main (void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
     // Hauptschleife&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Statische Variablen in einer Struktur sammeln ===&lt;br /&gt;
&lt;br /&gt;
Gibt es in einem Programm mehrere inhaltlich zusammengehörende Variablen, dann ist es sinnvoll diese in einer Struktur zu vereinigen.  Neben einer klareren Programm- bzw. Datenstruktur kann dies auch zu kleinerem Code führen.&lt;br /&gt;
&lt;br /&gt;
Beispiel ist die folgende kleine Routine, welche die Zeit in der globalen &amp;lt;tt&amp;gt;time&amp;lt;/tt&amp;gt;-Strukture um eine Sekunde erhöht:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
typedef struct &lt;br /&gt;
{&lt;br /&gt;
    uint8_t second;&lt;br /&gt;
    uint8_t minute;&lt;br /&gt;
    uint8_t hour;&lt;br /&gt;
} time_t;&lt;br /&gt;
 &lt;br /&gt;
// Globale time-Struktur enthält die Zeit&lt;br /&gt;
time_t time;&lt;br /&gt;
 &lt;br /&gt;
void next_second (void)&lt;br /&gt;
{&lt;br /&gt;
    // Zeiger auf die globale time-Struktur&lt;br /&gt;
    time_t *ptime = &amp;amp;time;&lt;br /&gt;
    &lt;br /&gt;
    // time um 1 Sekunde erhöhen&lt;br /&gt;
&lt;br /&gt;
    if (++ptime-&amp;gt;second == 60)&lt;br /&gt;
    {&lt;br /&gt;
        ptime-&amp;gt;second = 0;&lt;br /&gt;
        &lt;br /&gt;
        if (++ptime-&amp;gt;minute == 60)&lt;br /&gt;
        {&lt;br /&gt;
            ptime-&amp;gt;minute = 0;&lt;br /&gt;
            &lt;br /&gt;
            if (++ptime-&amp;gt;hour == 24)&lt;br /&gt;
                ptime-&amp;gt;hour = 0;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion enthält mehrere indirekte Zugriffe auf die &amp;lt;tt&amp;gt;time&amp;lt;/tt&amp;gt;-Struktur, und es wäre günstig, wenn &amp;lt;tt&amp;gt;avr-gcc&amp;lt;/tt&amp;gt; indirekte Adressierung für die Zugriffe verwendet: Alle Zugriffe geschehen über den Struktur-Zeiger &amp;lt;tt&amp;gt;ptime&amp;lt;/tt&amp;gt;, und ein indirekter Zugriff per &amp;lt;tt&amp;gt;LD&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;LDD&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;ST&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;STT&amp;lt;/tt&amp;gt; kostet 2&amp;amp;nbsp;Bytes, während die direkten Spreicherzugriffe &amp;lt;tt&amp;gt;LDS&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;STS&amp;lt;/tt&amp;gt; jeweils 4&amp;amp;nbsp;Bytes verbrauchen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;avr-gcc&amp;lt;/tt&amp;gt; erzeugt mit Optimierung auf Größe jedoch folgenden Code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
next_second:&lt;br /&gt;
    // if (++ptime-&amp;gt;second == 60)&lt;br /&gt;
    lds  r24, time&lt;br /&gt;
    subi r24, -1&lt;br /&gt;
    sts  time, r24&lt;br /&gt;
    cpi  r24, 60&lt;br /&gt;
    brne .L1&lt;br /&gt;
    // ptime-&amp;gt;second = 0;&lt;br /&gt;
    sts  time, __zero_reg__&lt;br /&gt;
    // if (++ptime-&amp;gt;minute == 60)&lt;br /&gt;
    lds  r24, time+1&lt;br /&gt;
    subi r24, -1&lt;br /&gt;
    sts  time+1, r24&lt;br /&gt;
    cpi  r24, 60&lt;br /&gt;
    brne .L1&lt;br /&gt;
    // ptime-&amp;gt;minute = 0;&lt;br /&gt;
    sts  time+1, __zero_reg__&lt;br /&gt;
    // if (++ptime-&amp;gt;hour == 24)&lt;br /&gt;
    lds  r24,time+2&lt;br /&gt;
    subi r24, -1&lt;br /&gt;
    sts  time+2, r24&lt;br /&gt;
    cpi  r24, 24&lt;br /&gt;
    brne .L1&lt;br /&gt;
    // ptime-&amp;gt;hour = 0;&lt;br /&gt;
    sts  time+2, __zero_reg__&lt;br /&gt;
.L1:&lt;br /&gt;
    ret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
D.h. obwohl der C-Code indirekt zugreift, enthält das Compilat direkte Zugriffe und der Code belegt 56&amp;amp;nbsp;Bytes an Flash. Grund ist, daß der Compiler den Inhalt der Variablen &amp;lt;tt&amp;gt;ptime&amp;lt;/tt&amp;gt; kennt und daher die indirekten Struktur-Zugriffe in direkte umwandelt.&lt;br /&gt;
&lt;br /&gt;
Um indirekte Adressierung im erzeugten Code zu erzwingen, kann man die Struktur-Adresse als Parameter übergeben:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void next_second (time_t *ptime)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
oder – als hässliche Lösung – dem Compiler des Wissen um den Inhalt von &amp;lt;tt&amp;gt;ptime&amp;lt;/tt&amp;gt; per Inline-Assembler nehmen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
asm (&amp;quot;&amp;quot; : &amp;quot;+r&amp;quot; (ptime));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dies führt denn zu folgendem Code, der um 25% kleiner ist und nur noch 42&amp;amp;nbsp;Bytes Flash belegt:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
next_second:&lt;br /&gt;
    // time_t *ptime = &amp;amp;time;&lt;br /&gt;
    // asm (&amp;quot;&amp;quot; : &amp;quot;+r&amp;quot; (ptime));&lt;br /&gt;
    ldi  r30, lo8(time)&lt;br /&gt;
    ldi  r31, hi8(time)&lt;br /&gt;
    // if (++ptime-&amp;gt;second == 60)&lt;br /&gt;
    ld   r24, Z&lt;br /&gt;
    subi r24, -1&lt;br /&gt;
    st   Z, r24&lt;br /&gt;
    cpi  r24, 60&lt;br /&gt;
    brne .L1&lt;br /&gt;
    // ptime-&amp;gt;second = 0;&lt;br /&gt;
    st   Z, __zero_reg__&lt;br /&gt;
    // if (++ptime-&amp;gt;minute == 60)&lt;br /&gt;
    ldd  r24, Z+1&lt;br /&gt;
    subi r24, -1&lt;br /&gt;
    std  Z+1, r24&lt;br /&gt;
    cpi  r24, 60&lt;br /&gt;
    brne .L1&lt;br /&gt;
    // ptime-&amp;gt;minute = 0;&lt;br /&gt;
    std  Z+1, __zero_reg__&lt;br /&gt;
    // if (++ptime-&amp;gt;hour == 24)&lt;br /&gt;
    ldd  r24, Z+2&lt;br /&gt;
    subi r24, -1&lt;br /&gt;
    std  Z+2, r24&lt;br /&gt;
    cpi  r24, 24&lt;br /&gt;
    brne .L1&lt;br /&gt;
    // ptime-&amp;gt;hour = 0;&lt;br /&gt;
    std  Z+2, __zero_reg__&lt;br /&gt;
.L1:&lt;br /&gt;
    ret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weil AVRs nur zwei Zeiger-Register haben, die über diese Addressierungsart verfügen (Y und Z), ist diese Optimierung nur eingeschränkt anwendbar.&lt;br /&gt;
&lt;br /&gt;
Werden etwa Z oder Y für andere Zwecke benötigt – etwa für Flash-Adressierung per &amp;lt;tt&amp;gt;LPM&amp;lt;/tt&amp;gt; oder Y als Frame-Pointer gebraucht – verkleinert sich das Anwendungsfeld noch weiter. Zudem müssen genügend Struktur-Zugriffe nacheinander erfolgen, damit ein positiven Effekt auf die Codegröße zustande kommt. Immerhin muss die Adresse geladen werden, das Zeiger-Register wird belegt und steht nicht für andere Variablen zur Verfügung, und im Falle von Y kommen &amp;lt;tt&amp;gt;PUSH&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;POP&amp;lt;/tt&amp;gt; im Prolog/Epilog hinzu. Werden viele unterschiedliche Struktur-Pointer verwendet (&amp;quot;viele&amp;quot; relativ zur Anzahl der verfügbaren Pointer-Registern), kann die Codegröße auch ansteigen.&lt;br /&gt;
&lt;br /&gt;
Direkte Zugriffe sind in jedem Falle schneller, denn direkte und indirekte Zugriffe kosten die gleiche Zeit. Die Indirekten Zugriffe erfordern jedoch die Initialisierung des Zeiger-Registers und evl &amp;lt;tt&amp;gt;PUSH&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;POP&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Multiplikationen mit Konstanten ===&lt;br /&gt;
&lt;br /&gt;
Der Compiler instanziiert sofort eine teure allgemeine Bibliotheksfunktion, auch wenn es anders ginge. Ich hatte eine einzige 32-bit Multiplikation mit 10 drin, die mir ein mulsi3 beschert hat. Mit a = (b&amp;lt;&amp;lt;3) + (b&amp;lt;&amp;lt;1) geht es in dem Fall kürzer. Wie gesagt, map-File beobachten.&lt;br /&gt;
 &lt;br /&gt;
;Anmerkung: Variablen als unsigned definieren, dann sollte der Compiler das selbst machen.&lt;br /&gt;
&lt;br /&gt;
;Anmerkung: Auch Schieben ist teuer auf AVR. Schauen wir uns also mal an, was aus folgendem Code wird:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint32_t foo (uint32_t i)&lt;br /&gt;
{&lt;br /&gt;
    return i*10;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint32_t bar (uint32_t i)&lt;br /&gt;
{&lt;br /&gt;
    return (i &amp;lt;&amp;lt; 1) + (i &amp;lt;&amp;lt; 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Scrollbox|15ex;|&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000032 &amp;lt;foo&amp;gt;:&lt;br /&gt;
  32:	2a e0       	ldi	r18, 0x0A	; 10&lt;br /&gt;
  34:	30 e0       	ldi	r19, 0x00	; 0&lt;br /&gt;
  36:	40 e0       	ldi	r20, 0x00	; 0&lt;br /&gt;
  38:	50 e0       	ldi	r21, 0x00	; 0&lt;br /&gt;
  3a:	19 d0       	rcall	.+50     	; 0x6e &amp;lt;__mulsi3&amp;gt;&lt;br /&gt;
  3c:	08 95       	ret&lt;br /&gt;
&lt;br /&gt;
0000003e &amp;lt;bar&amp;gt;:&lt;br /&gt;
  3e:	26 2f       	mov	r18, r22&lt;br /&gt;
  40:	37 2f       	mov	r19, r23&lt;br /&gt;
  42:	48 2f       	mov	r20, r24&lt;br /&gt;
  44:	59 2f       	mov	r21, r25&lt;br /&gt;
  46:	22 0f       	add	r18, r18&lt;br /&gt;
  48:	33 1f       	adc	r19, r19&lt;br /&gt;
  4a:	44 1f       	adc	r20, r20&lt;br /&gt;
  4c:	55 1f       	adc	r21, r21&lt;br /&gt;
  4e:	e3 e0       	ldi	r30, 0x03	; 3&lt;br /&gt;
  50:	66 0f       	add	r22, r22&lt;br /&gt;
  52:	77 1f       	adc	r23, r23&lt;br /&gt;
  54:	88 1f       	adc	r24, r24&lt;br /&gt;
  56:	99 1f       	adc	r25, r25&lt;br /&gt;
  58:	ea 95       	dec	r30&lt;br /&gt;
  5a:	d1 f7       	brne	.-12     	; 0x50 &amp;lt;__SREG__+0x11&amp;gt;&lt;br /&gt;
  5c:	26 0f       	add	r18, r22&lt;br /&gt;
  5e:	37 1f       	adc	r19, r23&lt;br /&gt;
  60:	48 1f       	adc	r20, r24&lt;br /&gt;
  62:	59 1f       	adc	r21, r25&lt;br /&gt;
  64:	95 2f       	mov	r25, r21&lt;br /&gt;
  66:	84 2f       	mov	r24, r20&lt;br /&gt;
  68:	73 2f       	mov	r23, r19&lt;br /&gt;
  6a:	62 2f       	mov	r22, r18&lt;br /&gt;
  6c:	08 95       	ret&lt;br /&gt;
&lt;br /&gt;
0000006e &amp;lt;__mulsi3&amp;gt;:&lt;br /&gt;
  6e:	ff 27       	eor	r31, r31&lt;br /&gt;
  70:	ee 27       	eor	r30, r30&lt;br /&gt;
  72:	bb 27       	eor	r27, r27&lt;br /&gt;
  74:	aa 27       	eor	r26, r26&lt;br /&gt;
&lt;br /&gt;
00000076 &amp;lt;__mulsi3_loop&amp;gt;:&lt;br /&gt;
  76:	60 ff       	sbrs	r22, 0&lt;br /&gt;
  78:	04 c0       	rjmp	.+8      	; 0x82 &amp;lt;__mulsi3_skip1&amp;gt;&lt;br /&gt;
  7a:	a2 0f       	add	r26, r18&lt;br /&gt;
  7c:	b3 1f       	adc	r27, r19&lt;br /&gt;
  7e:	e4 1f       	adc	r30, r20&lt;br /&gt;
  80:	f5 1f       	adc	r31, r21&lt;br /&gt;
&lt;br /&gt;
00000082 &amp;lt;__mulsi3_skip1&amp;gt;:&lt;br /&gt;
  82:	22 0f       	add	r18, r18&lt;br /&gt;
  84:	33 1f       	adc	r19, r19&lt;br /&gt;
  86:	44 1f       	adc	r20, r20&lt;br /&gt;
  88:	55 1f       	adc	r21, r21&lt;br /&gt;
  8a:	96 95       	lsr	r25&lt;br /&gt;
  8c:	87 95       	ror	r24&lt;br /&gt;
  8e:	77 95       	ror	r23&lt;br /&gt;
  90:	67 95       	ror	r22&lt;br /&gt;
  92:	89 f7       	brne	.-30     	; 0x76 &amp;lt;__mulsi3_loop&amp;gt;&lt;br /&gt;
  94:	00 97       	sbiw	r24, 0x00	; 0&lt;br /&gt;
  96:	76 07       	cpc	r23, r22&lt;br /&gt;
  98:	71 f7       	brne	.-36     	; 0x76 &amp;lt;__mulsi3_loop&amp;gt;&lt;br /&gt;
&lt;br /&gt;
0000009a &amp;lt;__mulsi3_exit&amp;gt;:&lt;br /&gt;
  9a:	9f 2f       	mov	r25, r31&lt;br /&gt;
  9c:	8e 2f       	mov	r24, r30&lt;br /&gt;
  9e:	7b 2f       	mov	r23, r27&lt;br /&gt;
  a0:	6a 2f       	mov	r22, r26&lt;br /&gt;
  a2:	08 95       	ret&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
: Der Funktionsaufruf samt Lib-Funktion ist garnicht sooo teuer. Bereits mit zwei Multiplikationen im Programm &amp;amp;mdash; auch einer Multiplikation mit einer anderen Konstanten oder einer Variablen &amp;amp;mdash; gewinnt die lib-Version, da der Code wiederverwendet wird. Übrigens sind diese Multiplikationsroutinen und auch die in die libgcc enthaltenen Divisionen keine &amp;quot;normalen&amp;quot; Funktionen wie sie von C erzeugt werden. avr-gcc weiß genau, welche Register diese Routinen belegen und welche nicht. Damit ist der Aufruf einer solchen Funktion billiger als ein herkömmlicher Funktionsaufruf, bei dem die Funktion als Blackbox behandelt werden muss, die alle call-clobbered Register zerstört.&lt;br /&gt;
&lt;br /&gt;
=== Alle Variablen nur so breit wie nötig ===&lt;br /&gt;
&lt;br /&gt;
Hatte ich eigentlich schon, nur an einigen wenigen Stellen war ich da etwas nachlässig. Mitunter reicht ein kleinerer Typ doch, wenn man z.&amp;amp;nbsp;B. vorher geeignet skaliert. Am besten nur die skalaren Typen aus &amp;lt;stdint.h&amp;gt; verwenden, das erleichtert auch das Folgende. Bei RAM Knappheit: kann ich Strings sinnvollerweise aus dem RAM ins Flash verbannen? Kann ich es mir leisten mehrere Flag-Variablen in ein Byte zusammenzufassen, auch wenn dann die Zugriffe möglicherweise etwas langsamer werden.&lt;br /&gt;
&lt;br /&gt;
=== Logische Operatoren werden auf int-Größe erweitert ===&lt;br /&gt;
&lt;br /&gt;
Obwohl der AVR ein 8-Bit Controller ist, verlangt der C-Standard, daß ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; mindestens 16&amp;amp;nbsp;Bits groß ist. Wegen den Promotion-Regeln von C werden 8-Bit Operanden in Operationen auf 16&amp;amp;nbsp;Bits aufgeweitet. Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
uint8_t c;&lt;br /&gt;
&lt;br /&gt;
void foo (uint8_t a, uint8_t b)&lt;br /&gt;
{&lt;br /&gt;
    if (a == ~b)&lt;br /&gt;
        c = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Den zweiten Operanden mit dem Komplement weitet der Compiler auf 16 Bit auf, wodurch alle high-Bits von &amp;lt;tt&amp;gt;~b&amp;lt;/tt&amp;gt; gesetzt werden. Der Compiler erkennt, daß der Vergleich niemals wahr ist und optimiert ihn weg:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
foo:&lt;br /&gt;
    ret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Cast verhindert dieses:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void foo (uint8_t a, uint8_t b)&lt;br /&gt;
{&lt;br /&gt;
    if (a == (uint8_t) ~b)&lt;br /&gt;
        c = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
was übersetzt wird zu:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
foo:&lt;br /&gt;
    // if (a == (uint8_t) ~b)&lt;br /&gt;
    com  r22&lt;br /&gt;
    cpse r24, r22   &lt;br /&gt;
    rjmp .L1&lt;br /&gt;
    // c = 0&lt;br /&gt;
    sts c, __zero_reg__&lt;br /&gt;
.L1:&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Achtung: Tatsächlich handelt es sich dabei nicht um ein Optimierungsproblem, sondern einen typischen Programmierfehler. Die beiden Varianten sind keineswegs identisch! Bei Variablen vom Typ &amp;lt;tt&amp;gt;uint8_t&amp;lt;/tt&amp;gt; ist der Ausdruck &amp;lt;tt&amp;gt;(a == ~b)&amp;lt;/tt&amp;gt; immer falsch! Dies unterstreicht mehr als eindringlich, daß eine gute Kenntnis der Programmiersprache das A und O jedes erfolgreichen Programmierers ist. Kenne zuallerst mal deine Programmiersprache - und zwar auch in den intimen Details!&lt;br /&gt;
&lt;br /&gt;
=== Speichern von globalen Flags ===&lt;br /&gt;
&lt;br /&gt;
Oft werden in den Programmen Flags verwendet um beispielsweise eingetroffene Interrupts in der main-Routine auszuwerten. Hierzu wird üblicherweise eine globale Variable verwendet.&lt;br /&gt;
&lt;br /&gt;
Um den Wert dieser Variable abzufragen, muss sie jedoch erst aus dem SRAM in ein Register geladen werden, und kann dann erst auf ihren Status hin überprüft werden. Eine Möglichkeit ist, der globalen Variablen ein einziges Register fest zuzuordnen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
register uint8_t counter8_1 asm(&amp;quot;r2&amp;quot;);&lt;br /&gt;
register uint8_t counter8_2 asm(&amp;quot;r3&amp;quot;);&lt;br /&gt;
register uint16_t counter16_1 asm(&amp;quot;r4&amp;quot;); // r4:r5&lt;br /&gt;
register uint16_t counter16_2 asm(&amp;quot;r6&amp;quot;); // r6:r7&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
siehe auch: http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_regbind&lt;br /&gt;
&lt;br /&gt;
Als Alternative kann man ein nicht verwendetes Register des I/O-Bereichs verwenden. Dabei würde sich z.&amp;amp;nbsp;B. das Register eines zweiten UARTs, oder das  EEPROM-Register anbieten, falls diese nicht benötigt werden.&lt;br /&gt;
&lt;br /&gt;
Neuere AVR-Modelle besitzen für diesen Zweck 3 frei verwendbare Bytes im bitadressierbaren I/O-Bereich: GPIOR0-2, die neueren ATXmegas haben sogar 16 Stück!&lt;br /&gt;
&lt;br /&gt;
{{Warnung|&lt;br /&gt;
;Warnung: Dieses Vorgehen verändert das ABI! Um dieses Feature fehlerfrei anzuwenden, ist einiges an Wissen über die Interna von GCC notwendig. Auch ein korrekt funktionierendes Programm ist keine Garantie dafür, daß die globalen Register fehlerfrei implementiert wurden. Unter Umständen bringen erst spätere Codeänderungen/-erweiterung den Fehler zum Vorschein, und weil der Fehler vorher nicht akut war, sucht man sich den Wolf an der falschen Stelle im Code anstatt bei der globalen Registern. Siehe auch [[Globale Register]].}}&lt;br /&gt;
&lt;br /&gt;
=== Puffern von volatile-Variablen ===&lt;br /&gt;
&lt;br /&gt;
Der Compiler behandelt volatile-Variablen bei mehreren Manipulationen wie heiße Kartoffeln. Für jeden einzelnen Vorgang wiederholt sich das Spiel:&lt;br /&gt;
&lt;br /&gt;
* aus dem Speicher holen&lt;br /&gt;
* bearbeiten&lt;br /&gt;
* zurückspeichern&lt;br /&gt;
&lt;br /&gt;
Unter Umständen ist dieses Verhalten unsinnig. Ein Minimalbeispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
volatile char var;&lt;br /&gt;
&lt;br /&gt;
ISR()&lt;br /&gt;
{&lt;br /&gt;
    var++;&lt;br /&gt;
&lt;br /&gt;
    if (var &amp;gt; 100)&lt;br /&gt;
        var = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main (void)&lt;br /&gt;
{&lt;br /&gt;
    while (1)&lt;br /&gt;
        printf (var);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Hier wird &#039;&#039;&#039;var&#039;&#039;&#039; pro [[ISR]]-Ausführung zwei mal aus dem RAM geholt und zurückgeschrieben. Das ist überflüssig, weil die Interruptroutine nicht unterbrochen werden kann. Aus Sicht der ISR bräuchte man eigentlich kein volatile, kann es aber wegen des Zugriffs aus main heraus nicht weglassen. Eine Lösung findet sich im folgenden Schnipsel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
volatile char var;&lt;br /&gt;
&lt;br /&gt;
ISR()&lt;br /&gt;
{&lt;br /&gt;
    char temp = var;&lt;br /&gt;
&lt;br /&gt;
    if (++temp &amp;gt; 100)&lt;br /&gt;
        temp=0;&lt;br /&gt;
&lt;br /&gt;
    var = temp;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main (void)&lt;br /&gt;
{&lt;br /&gt;
    while (1)&lt;br /&gt;
        printf (var);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Hier wird die globale Variable &#039;&#039;&#039;var&#039;&#039;&#039; in der lokalen Variable &#039;&#039;&#039;temp&#039;&#039;&#039; gepuffert. Ein Nachteil durch das Anlegen von &#039;&#039;&#039;temp&#039;&#039;&#039; ergibt sich nicht, da das dafür verwendete Register für die Manipulation sowieso benötigt wird. &lt;br /&gt;
&lt;br /&gt;
Wie alle Optimierungen kann dieses Vorgehen auch nach hinten losgehen: Wenn Laden und Zurückspeichern von &#039;&#039;&#039;var&#039;&#039;&#039; weit auseinanderliegen (extrem lange ISR), müllt man sich die Register zu. Im schlimmsten Fall wird &#039;&#039;&#039;temp&#039;&#039;&#039; sogar zwischenzeitlich auf dem Stack ausgelagert.&lt;br /&gt;
&lt;br /&gt;
=== Schleifen ===&lt;br /&gt;
&lt;br /&gt;
Bei Schleifen, die eine bestimmte Anzahl an Durchläufen ausgeführt werden sollen, ist es besser den Schleifenzähler vorher auf einen Wert zu setzen, und am Ende einer Do-While Schleife diesen zu dekrementieren.&lt;br /&gt;
So beschränkt sich die Sprungbedingung auf ein brne (branch if not equal).&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t counter;	&lt;br /&gt;
counter = 100;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
    // mach irgendetwas&lt;br /&gt;
} while (--counter);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Achtung: Derartige Optimierungen sind meistens zweifelhaft und sehr Compilerabhängig. Compiler betreiben aufwendige Code- und Datenflussanalysen, in denen sie viele Dinge ins Kalkül ziehen, die ein menschlicher Programmierer im Regelfall nicht mehr überblicken kann. Von einem ordentlichen Compiler kann erwartet werden, dass er derartige Umstellungen (sofern sie möglich sind) in Eigenregie erledigt. Auch wenn es einzelne Compiler bzw. Compilerversionen gibt, in denen ein manueller Umbau einer derartigen Schleife tatsächlich eine Verbesserung bringt, sollte man immer im Hinterkopf behalten, dass sich in der nächsten Compilerversion alles umdrehen kann. Im Zweifelsfall lieber die Schleifenvariante benutzen, die der Situation angemessen ist und die den gewünschten Vorgang am klarsten beschreibt. Wenn dieser Vorgang im weitesten Sinne einen Countdown darstellt, dann ist natürlich nichts gegen eine derartige Schleifenkonstruktion einzuwenden.&lt;br /&gt;
&lt;br /&gt;
=== Schiebeoperationen ===&lt;br /&gt;
&lt;br /&gt;
Oft benötigt man Schiebeoperationen, um Daten Bit für Bit zu [[Bitmanipulation | verarbeiten]], z.B. für [http://www.mikrocontroller.net/articles/AVR-Tutorial:_Schieberegister Soft]-[[SPI]]. Hier empfiehlt es sich DRINGEND, möglichst nur Schiebeoperationen mit konstanten Verschiebungszähler durchzuführen, diese sind auf dem AVR deutlich schneller als Schiebeoperationen mit Variablen, welche meist durch mehrfache Funktionsaufrufe mit Scheifen etc. gelöst werden. Dabei verwendet man oft konstante Bitmasken, um die einzelnen Bits nacheinander zu maskieren.&lt;br /&gt;
&lt;br /&gt;
Noch schneller geht das Schieben von Konstanten um einen konstanten Wert, denn das macht der Compiler bei eingeschalteter Optimierung noch während des Compilierens. Gerade für schnelle IO-Operationen kommt dann meist nur ein einziger ASM-Befehl heraus (sbi, cbi).&lt;br /&gt;
&lt;br /&gt;
Ebenso ist es wenig empfehlenswert, 32 oder gar 64 Bit Datentypen zu schieben, das dauert sehr lange. Besser ist es, die Daten als Array von 8 Bit Werten zu handhaben und diese zu schieben, das ist meist deutlich schneller. Gute Beispiele findet man [http://www.mikrocontroller.net/topic/179566#1729219 hier] und [http://www.mikrocontroller.net/topic/169509#1631439 hier].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define DATAPORT PORTD&lt;br /&gt;
#define IO_BIT PD4&lt;br /&gt;
&lt;br /&gt;
uint8_t a, b, i;&lt;br /&gt;
&lt;br /&gt;
i=5&lt;br /&gt;
a = b &amp;lt;&amp;lt; i;    // variabler Verschiebewert, langsam&lt;br /&gt;
a = b &amp;lt;&amp;lt; 5;    // konstanter Verschiebewert, schnell&lt;br /&gt;
&lt;br /&gt;
DATAPORT |= (1&amp;lt;&amp;lt;IO_BIT);   // alles Konstanten, sehr schnell&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Optimierung der Ausführungsgeschwindigkeit==&lt;br /&gt;
&lt;br /&gt;
Hierzu gibt es schon eine Application-Note von Atmel. Diese AppNote bezieht sich auf den IAR-Compiler. Die darin genannten &amp;quot;Optimierungen&amp;quot; sind für avr-gcc größtenteils obsolet oder bleiben bestenfalls ohne Effekt.&lt;br /&gt;
&lt;br /&gt;
Weblinks:&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc1497.pdf AVR035]: Efficient C Coding for AVR&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Program_optimization Program optimization] auf Wikipedia, engl.&lt;br /&gt;
* [http://bleaklow.com/2012/06/20/sensor_smoothing_and_optimised_maths_on_the_arduino.html Sensor smoothing and optimised maths on the Arduino] - Multiplikation vs. Division&lt;br /&gt;
&lt;br /&gt;
== Fußnoten ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
[http://www.atmel.com/Images/doc8453.pdf Atmel AVR4027]: Tips and Tricks to Optimize Your C Code for 8-bit AVR Microcontrollers ([http://www.atmel.com/Images/AVR4027.zip Beispiel-Code])&lt;br /&gt;
&lt;br /&gt;
[[Category:avr-gcc]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Digitale_Signalverarbeitung&amp;diff=90668</id>
		<title>Digitale Signalverarbeitung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Digitale_Signalverarbeitung&amp;diff=90668"/>
		<updated>2015-12-13T08:32:04Z</updated>

		<summary type="html">&lt;p&gt;Maybee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Begriffsdefinition ==&lt;br /&gt;
&lt;br /&gt;
Als &#039;Digitale Signalverarbeitung&#039; bezeichnet man allgemein die Analyse und Weiterverarbeitung von digitalisierten Analogsignalen und nicht etwa (nur) die Rechnung mit binären Signalen, wenngleich die Berechnung praktisch letztlich im Binärsystem erfolgt.&lt;br /&gt;
&lt;br /&gt;
== Anwendungsgebiete ==&lt;br /&gt;
&lt;br /&gt;
* Modulation/Demodulation zur Datenübertragung (z.&amp;amp;nbsp;B. Telefonmodem, DSL, GSM) - &amp;quot;Software Defined Radio&amp;quot; (SDR)&lt;br /&gt;
* Multimediacodierung (MP3, H.264, JPEG)&lt;br /&gt;
* Bildverarbeitung (Bildverbesserung)&lt;br /&gt;
* Mustererkennung, Objekterkennung, Objektverfolgung&lt;br /&gt;
* Audiosignalverarbeitung&lt;br /&gt;
* Echo- und Störgeräuschunterdrückung bei Telefonen, Sprechgarnituren (Headsets) und Hörgeräten&lt;br /&gt;
&lt;br /&gt;
== Algorithmen ==&lt;br /&gt;
&lt;br /&gt;
Bei der Verarbeitung von Signalen kommen im Grunde bei allen Anwendungen die selben Algorithmen zum Einsatz, von denen die wichtigsten im Folgenden vorgestellt werden.&lt;br /&gt;
&lt;br /&gt;
=== FIR- und IIR-Filter ===&lt;br /&gt;
&lt;br /&gt;
Die häufigste Aufgabe in der DSV ist das Filtern, das heißt, bestimmte Frequenzanteile zu unterdrücken, zu verstärken oder in der Phase zu verschieben. Man kann grundsätzlich zwischen zwei Filterarten unterscheiden:&lt;br /&gt;
&lt;br /&gt;
Bei den sogenannten &#039;&#039;&#039;FIR-Filtern&#039;&#039;&#039;n (&#039;&#039;&#039;F&#039;&#039;&#039;inite &#039;&#039;&#039;I&#039;&#039;&#039;mpulse &#039;&#039;&#039;R&#039;&#039;&#039;esponse) wird jeder Ausgangswert aus der Summe einer begrenzten Anzahl unterschiedlich gewichteter Eingangswerte zusammengesetzt, die dazu in Schieberegistern vorgehalten werden. Dabei bezeichnet man die maximale Anzahl an Werten, die bei der Berechnung berücksichtigt werden, als &#039;&#039;&#039;Ordnung&#039;&#039;&#039; oder auch als Filtertiefe. Je höher diese Ordnungszahl, desto besser nähern sich die Eigenschaften des realen Filters bez. ripple, Steilheit und z.B. Dämpfung dem des theoretischen Ideals an, desto höher ist aber auch der Rechenaufwand.&lt;br /&gt;
&lt;br /&gt;
Werden bei FIR-Filtern zur Bildung des Ausgangswertes zum Zielzeitpunkt nur zurückliegende Werte verwendet, so handelt es sich um ein &amp;quot;look back&amp;quot; - Filter. Dieses ist typisch für real time Anwendungen. Werden aber auch Werte verwendet, die nach dem eigentlichen Bezugzeitpunkt liegen, spricht man von einem look ahead-Filter. Dieses kann naturgemäß nicht in Echtzeit angewendet werden, bzw die Ausgabezeitpunkte müssen um mindestens um die halbe Filtertiefe verzögert werden, womit ein virtueller Bezugspunkt entsteht.&lt;br /&gt;
&lt;br /&gt;
==== Merkmale von FIR-Filtern ====&lt;br /&gt;
* immer stabil&lt;br /&gt;
* linearer Phasengang -&amp;gt; keine Phasenverzerrungen&lt;br /&gt;
* Ordnungen oft im zwei- bis dreistelligen Bereich&lt;br /&gt;
&lt;br /&gt;
==== Beispiel ====&lt;br /&gt;
Seien D(0), D(1) ... D(t) die eingehenden Daten, so wäre Y(t) = 1/k * (D(t) + D(t-1) + D(t-2) + ... + D(t-k)) ein einfaches FIR-Filter der Ordnung &amp;quot;k&amp;quot;, das als gleitender Mittelwert bezeichnet wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Im Gegensatz zu den FIR-Filtern werden bei den sogenannten &#039;&#039;&#039;IIR-Filter&#039;&#039;&#039;n (&#039;&#039;&#039;I&#039;&#039;&#039;nfinite &#039;&#039;&#039;I&#039;&#039;&#039;mpulse &#039;&#039;&#039;R&#039;&#039;&#039;esponse) formell alle früheren &#039;&#039;&#039;Eingangs&#039;&#039;&#039;werte in die Berechnung des aktuellen Ausgangswertes mit einbezogen. Dies wird dadurch bewerkstelligt, dass mindestens ein Informationspeicher (entspricht in der Physik einem Energiespeicher) existiert, der mit in die Rechnung einfließt. Im einfachsten Fall ist der Speicher der Ausgangswert selbst. Wie man sich leicht vorstellen kann, kann dadurch die Antwort auf einen Eingangsimpuls theoretisch unendlich lang werden, was die Einordnung dieser Filter in die Gruppe mit unendlicher Antwort erklärt.&lt;br /&gt;
&lt;br /&gt;
====Merkmale von IIR-Filtern====&lt;br /&gt;
* durch Rundungsfehler kann das [[Filter]] instabil werden -&amp;gt; &amp;quot;Aufschaukeln&amp;quot; durch Rückkopplung -&amp;gt; schwierigere Realisierung&lt;br /&gt;
* kein linearer Phasengang -&amp;gt; verschiedene Frequenzanteile werden durch den Filter unterschiedlich lange verzögert -&amp;gt; &amp;quot;Verzerrung&amp;quot;&lt;br /&gt;
* einziger Vorteil gegenüber FIR: Um einen gewünschten Frequenzgang zu erzielen, ist eine sehr viel niedrigere Ordnung ausreichend -&amp;gt; weniger Rechenaufwand&lt;br /&gt;
* Ordnung üblicherweise &amp;lt; 10&lt;br /&gt;
&lt;br /&gt;
==== Beispiel====&lt;br /&gt;
Seien D(0), D(1) ... D(t) wieder die eingehenden Daten, wie oben und Y(t-1) der um einen Berechnungsschritt zeitlich verzögerte Wert des Filterausgangswertes Y(t), dann wäre Y(t) = Y(t-1) * (1-k)  +  D(t) * k ein IIR-Filter erster Ordnung, wobei 1/k die Dämpfung und damit die Grenzfrequenz des Filters bestimmt. Das Verhalten dieses Filters entspricht dem einer Kondensatorladekurve.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Viele nützliche Informationen zur Realisierung gibt es im [http://www.dspguru.com/dsp/faqs/ FIR- und IIR-FAQ auf dspguru.com] (der dort erwähnte Sourcecode FirAlgs.c kann [[Media:FirAlgs.c|hier]] direkt heruntergeladen werden).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Berechnungssoftware&#039;&#039;&#039;:&lt;br /&gt;
* [http://www.filter-solutions.com/digital.html Beschreibung der Digitalfiltertypen], [http://www.nuhertz.com/download.html hier kostenlose Testversion Filter Free]&lt;br /&gt;
&lt;br /&gt;
=== DFT/FFT und andere Transformationen ===&lt;br /&gt;
&lt;br /&gt;
Die [[FFT]] (Fast Fourier Transform) ist ein schneller Algorithmus zur Berechnung der DFT (Discrete Fourier Transform). Damit bezeichnet man die Transformation eines Zeitsignals (= eine Abfolge von Samples) in den Frequenzbereich (= Frequenzbestandteile des Signals). Die Transformation kann theoretisch auch ohne Verlust umgekehrt durchgeführt werden, also vom Frequenz- in den Zeitbereich (Inverse Discrete Fourier Transform, IDFT). Eine DFT wird praktisch immer mit dem FFT-Algorithmus realisiert, weshalb die Bezeichnungen oft FFT/DFT oft gleichwertig verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Die offensichtlichste Anwendung der FFT ist die Darstellung des Frequenzspektrums eines Signals. Beispiel:&lt;br /&gt;
&lt;br /&gt;
Ein Audiosignal wird mit einer Frequenz von 44,1 kHz abgetastet und mit den erhaltenen Daten eine DFT mit 512 Punkten durchgeführt. Man erhält ein Amplitudenspektrum mit 512 Frequenzwerten von 0 bis 511, wobei die Werte 0 bis 255 zu denen der oberen Hälfte spiegelsymmetrisch sind. Bei der o.g. Abtastfrequenz ergibt sich nach Nyquist ein Frequenzbereich von 0 bis 22,05 kHz, mit einer Auflösung von 44100/512 = 86,13 Hz. Dabei repräsentiert die erste Frequenz 0, den Bereich von 0 Hz bis 86,13 Hz, u.s.w. - die letzte Frequenz 255 den Bereich von 21963,87 bis 22050 Hz.&lt;br /&gt;
&lt;br /&gt;
Die Spektralanalyse ist jedoch nur ein kleiner Teil der Anwendungsmöglichkeiten. Viele Verarbeitungen lassen sich im Frequenzbereich einfacher durchführen als im Zeitbereich, z.&amp;amp;nbsp;B. Korrelationen oder sehr lange FIR-Filter. Das zu verarbeitende Signal wird dazu in den Frequenzbereich transformiert, dort manipuliert, und wieder in den Zeitbereich zurücktransformiert. Das klingt vielleicht umständlich, kann aber in der Praxis sehr viel schneller sein als eine Realisierung im Zeitbereich.&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/25095 Diskussion: FFT auf dem AVR]&lt;br /&gt;
* [http://sourceforge.net/projects/kissfft/ Kiss FFT] - einfache FFT-Bibliothek, in C, Floating- und Fixed Point, BSD-Lizenz, geeignet für Mikrocontroller&lt;br /&gt;
* [http://www.fftw.org/ FFTW] - &#039;&#039;&#039;die&#039;&#039;&#039; Floating Point FFT-Bibliothek für PCs, GPL-Lizenz&lt;br /&gt;
*[http://www.sprut.de/electronic/pic/16bit/dsp/fft/fft.htm FFT - verständlich auch für Nichtakademiker (Deutsch)]&lt;br /&gt;
* [http://www.science.smith.edu/departments/Physics/fstaff/gfelder/ffteasy/ ffteasy - Einfache Routinen zur FFT]&lt;br /&gt;
&lt;br /&gt;
Weitere wichtige Transformationen sind z.&amp;amp;nbsp;B. die in der Bildcodierung (JPEG) verwendete DCT (Discrete Cosine Transform), und die WHT (Welsh-Hadamard-Transformation). Im Gegensatz zur DFT wird das Signal nicht mehr in den Frequenzbereich transformiert, sondern in einen nicht mehr ganz so anschaulichen Transformationsbereich. Der Sinn der Transformation ist z.B. bei der Bildkompression, dass die Signalinformation im Transformationsbereich in nur wenigen Koeffizienten konzentriert ist, und sich somit effizienter codieren lässt.&lt;br /&gt;
&lt;br /&gt;
==== Goertzel-Algorithmus ====&lt;br /&gt;
&lt;br /&gt;
Liegt das Interesse bei der Berechnung einer DFT / FFT nur bei wenigen bestimmten Frequenz-Linien, so gibt es eine weniger rechenaufwendige Alternative mit diesem Algorithmus. Die Grenze, ab der Goertzel-Algo nicht mehr effektiv genug ist, liegt grob bei etwa 15% der Spektralfrequenzen.&lt;br /&gt;
&lt;br /&gt;
Das typische Anwendungsgebiet sind DTMF-Dekoder in Software.&lt;br /&gt;
Hierfür sind sogar die üblichen 8-bit-AVR-Controller ausreichend schnell.&lt;br /&gt;
&lt;br /&gt;
=== Signalerzeugung ===&lt;br /&gt;
&lt;br /&gt;
Für die Korrelation von Eingangssignalen mit zuvor ausgesendeten oder bekannten Signalformen zwecks Mustererkennung müssen oftmals eigene Signale generiert werden.&lt;br /&gt;
&lt;br /&gt;
Rechteck-, Sägezahn- und Dreieckssignale lassen sich mit einfachen Zählern realisieren. &lt;br /&gt;
&lt;br /&gt;
Möchte man Sinus- oder beliebige andere Signalformen erzeugen, bietet es sich an, vorausberechnete Funktionswerte im Speicher abzulegen und der Reihe nach auszugeben. Eine variable Frequenzeinstellung kann man durch die Methode der Direkten Digitalen Synthese (&#039;&#039;&#039;DDS&#039;&#039;&#039;) realisieren.&lt;br /&gt;
&lt;br /&gt;
* [[Digitaler Funktionsgenerator]] - ausführliche Erklärung des Verfahrens im PDF, Beispielcode für AVR&lt;br /&gt;
* http://www.myplace.nu/avr/minidds/ - noch ein AVR-Projekt&lt;br /&gt;
* http://www.hit.bme.hu/~papay/sci/DDS/start.htm - noch eine Erklärung&lt;br /&gt;
* [http://www.analog.com/static/imported-files/tutorials/450968421DDS_Tutorial_rev12-2-99.pdf Aplication Note von Analog Devices, DDS]&lt;br /&gt;
* http://www.mikrocontroller.net/topic/324429 - Sinusschwingung mit IIR-Filter&lt;br /&gt;
&lt;br /&gt;
Eine weitere Methode zur Realisierung von (mehr oder weniger beliebigen) Funktionen ist die &#039;&#039;&#039;Polynomapproximation&#039;&#039;&#039;. Dabei nähert man die zu erzeugende Funktion durch ein Polynom an und verwendet das Horner-Schema, um die einzelnen Funktionswerte zu berechnen. Für ein Polynom der Ordnung N benötigt man damit pro Wert N+1 Multiplikationen (N ist üblicherweise &amp;lt;= 10).&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
Zur Entwicklung von Signalverarbeitungsverfahren gibt es eine ganze Reihe von Programmen. Neben kleinen Werkzeugen für den Filterentwurf und spezialisierten Bibliotheken zum Einbinden in eigene Programme existieren mehrere Mathematikprogramme, mit denen sich Signale verarbeiten und darstellen lassen. Die drei wichtigsten sind Matlab, Octave und Scilab.&lt;br /&gt;
&lt;br /&gt;
=== MATLAB ===&lt;br /&gt;
&lt;br /&gt;
MATLAB ist das Standardprogramm für numerische Mathematik. In der digitalen Signalverarbeitung wird es häufig verwendet, um einen Algorithmus vor der Umsetzung in C-Code oder auf einen DSP zu entwickeln und zu testen. Zum schon recht hohen Preis der Grundsoftware muss man noch einige hundert Euro für diverse Toolboxes einplanen (Signal Processing, Filter Design, Image Processing). Die [http://www.mikrocontroller.net/link/isbn/0979223903 Studentenversion] kostet ca. 80 Euro (die Signal Processing Toolbox und ein paar andere sind bereits enthalten).&lt;br /&gt;
&lt;br /&gt;
MATLAB ist für Windows, Linux, Mac OS X, Solaris und HP-UX erhältlich.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Weblinks&#039;&#039;&#039;:&lt;br /&gt;
* http://users.ece.gatech.edu/%7Ebonnie/book/TUTORIAL/tutorial.html - Englischsprachiges MATLAB-Tutorial&lt;br /&gt;
* http://www.mathworks.com/access/helpdesk/help/techdoc/matlab.shtml - MATLAB-Referenz&lt;br /&gt;
* http://www.eng.auburn.edu/~sjreeves/Classes/DSP/DSP.html - MATLAB for DSP (allgemeine Tipps und Hinweise)&lt;br /&gt;
&lt;br /&gt;
=== GNU Octave ===&lt;br /&gt;
&lt;br /&gt;
GNU Octave ist eine (zum größten Teil zu Matlab (R) kompatible) höhere Programmiersprache, die hauptsächlich für numerische Berechnungen gedacht ist. Sie stellt eine komfortable Kommandozeilenschnittstelle zur numerischen Lösung linearer und nichtlinearer Probleme bereit. Durch den hohen Grad an Matlab-Kompatibilität kann man problemlos die Matlab-Online-Hilfe und Matlab-Einführungen zum Lernen verwenden.&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich ist Octave ein reines Kommandozeilenprogramm es wird aber aktiv an einer GUI auf Basis von Qt entwickelt (siehe http://wiki.octave.org/FAQ#Is_there_a_GUI_for_Octave.3F).&lt;br /&gt;
&lt;br /&gt;
Ideone.com bietet seit einiger Zeit einen online-Interpreter auch für Octave an. Hier kann man die Sprache ohne Installation kurz antesten: [http://ideone.com/E5Cxz9 Sombrero und &amp;quot;Hallo Mikrocontroller Leser&amp;quot; Beispiel]&lt;br /&gt;
&lt;br /&gt;
Zum Plotten unter GNU/Linux kann wahlweise gnuplot oder das neue FLTK backend verwendet werden. Unter Windows stehen noch weitere backends wie wxWidgets zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
Octave-Forge beheimatet Pakete, die (noch) nicht in &amp;quot;octave core&amp;quot; aufgenommen wurden. Hier sind auch viele Funktionen der Matlab-Toolboxes enthalten (z.B. Filterdesign, Signalverarbeitung).&lt;br /&gt;
&lt;br /&gt;
Octave kann unter GNU/Linux oder *BSD über den jeweiligen Paketmanager (wie z.B. apt-get, aptitude, synaptics in Ubuntu oder Debian) installiert werden. Für Windows stehen vorkompilierte Pakete mit MinGW, MSVC oder für cygwin zur Verfügung. Für MacOS gibt es Möglichkeiten mit Fink, MacPorts und Homebrew zu installieren.&lt;br /&gt;
[http://wiki.octave.org/Main_Page#Installation_Instructions_for_Windows.2C_MacOS_X_and_GNU.2FLinux Octave Wiki Installationsanleitung Windows, MacOS X und GNU/Linux]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Weblinks&#039;&#039;&#039;:&lt;br /&gt;
* http://www.gnu.org/software/octave/ Projektseite&lt;br /&gt;
* http://wiki.octave.org/Main_Page Wiki, u.A. mit Installationsanleitungen&lt;br /&gt;
* http://octave.sourceforge.net/ - Octave-Forge Zusatzpakete&lt;br /&gt;
&lt;br /&gt;
=== Scilab / Scicos ===&lt;br /&gt;
&lt;br /&gt;
Auch das Open-Source-Programmpaket Scilab / Scicos, ähnlich leistungsfähig wie Matlab und seine Zusatzmodule, ist kostenlos und im Quelltext erhältlich. Während die Grundsyntax (Kontrollstrukturen, Ausdrücke) weitgehend Matlab-kompatibel ist, gibt es bei den Funktionen z.T. deutliche Abweichungen. Dafür bietet Scilab / Scicos verglichen mit Octave umfangreichere Möglichkeiten zur grafischen Darstellung, die über das 2D- und 3D-Plotten von Funktionen weit hinausgehen, z.&amp;amp;nbsp;B. lassen sich Linien, Kreise usw. zeichnen.&lt;br /&gt;
&lt;br /&gt;
Scilab / Scicos läuft unter Windows, Linux/Unix und Mac OS X. Für die wichtigsten Linux-Distributionen sind fertige, komplette Binärpakete (RPM, ...) zur einfachen Installation frei verfügbar. Für Windows gibt es ebenfalls ein einfach zu installierendes Komplettpaket.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Weblinks&#039;&#039;&#039;:&lt;br /&gt;
* [http://www.scilab.org/ Scilab Homepage (Universelles Wissenschaftlich-Technisches Mathematik-Paket)]&lt;br /&gt;
* [http://www.scicos.org/ Scicos Homepage (Modellations- und Simulations-Paket für Scilab, ist im Scilab-Download enthalten)]&lt;br /&gt;
* [http://www-rocq.inria.fr/scicos/scicosmodnum.html ModNum Digital communication toolbox zu Scicos]&lt;br /&gt;
* [http://www.scilab.org/publications/index_publications.php?page=freebooks Übersicht zur Literatur: Webtexte, Bücher und Zeitschriftenartikel]&lt;br /&gt;
&#039;&#039;&#039;Bücher&#039;&#039;&#039;:&lt;br /&gt;
* [http://www.scicos.org/book.html Modeling and Simulation in Scilab/Scicos, (für Version 3.0, aktuell ist Version 4.1.2)]&lt;br /&gt;
&#039;&#039;&#039;Tutorials&#039;&#039;&#039;:&lt;br /&gt;
* [http://wiki.scilab.org/Tutorials?action=AttachFile&amp;amp;do=get&amp;amp;target=signal.pdf Signal Processing with Scilab (1998)], [http://wuarchive.wustl.edu/pub/aminet/misc/math/scilab-doc.lha Beispielfiles dazu lha-gepackt (1996)] [http://aminet.net/package/misc/math/scilab-doc oder hier], [http://viewvc.scilab.org/bin/cgi/viewvc.cgi/trunk/scilab_doc/signal/Nfigs_source/ hier auch einzeln erhältlich]&lt;br /&gt;
* [http://www.scilab.org/publications/delicado/scilab.pdf DSP-Tutorial in spanisch, teilweise aus dem englischen Tutorial entnommen]&lt;br /&gt;
* [http://www.neurotraces.com/scilab/scilab2/index.html Treatment of neurophysiological signals using Scilab, HTML-Texte mit Kapiteln zu Filtern, FFT usw.]&lt;br /&gt;
* [http://www.scilab.org/publications/TELECOM/ComNumSc.zip Digital-Kommunikation - französisches Tutorial, gezipptes Postscript]&lt;br /&gt;
* [http://www.mate.tue.nl/mate/pdfs/6827.pdf Beispielprojekt mit Vergleich SciCos und SciLab]&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
&lt;br /&gt;
Ein DSP (&#039;&#039;&#039;D&#039;&#039;&#039;igital &#039;&#039;&#039;S&#039;&#039;&#039;ignal &#039;&#039;&#039;P&#039;&#039;&#039;rocessor) ist eine spezielle CPU mit einem auf die Verarbeitung von Signalen optimierten Kern und Befehlssatz. Unterschieden wird hauptsächlich zwischen Gleitkomma- und Festkomma-DSPs.&lt;br /&gt;
&lt;br /&gt;
Charakteristisches Merkmal vieler DSPs ist eine VLIW-Architektur (&#039;&#039;&#039;V&#039;&#039;&#039;ery &#039;&#039;&#039;L&#039;&#039;&#039;ong &#039;&#039;&#039;I&#039;&#039;&#039;nstruction &#039;&#039;&#039;W&#039;&#039;&#039;ord). Dabei werden Anweisungen für mehrere parallele Ausführungseinheiten (Multiplizierer/Addierer/Akkumulatoren) und mehrere Lade-/Speicherbefehle in einem einzigen, langen Befehlswort kodiert, und in einem Takt ausgeführt. Dazu kommen häufig mehrere gleichzeitig adressierbare Speicherbänke, Unterstützung für Ringpuffer, Schleifen ohne Sprung-Overhead, Bit-Reverse-Adressierung (wichtig für FFT) und Arithmetik mit Sättigungs- statt Überlaufverhalten (wichtig für die Realisierung von IIR-Filtern).&lt;br /&gt;
&lt;br /&gt;
Die Grenzen zwischen Mikrocontrollern und DSPs sind mittlerweile schon etwas verschwommen. Viele Mikrocontroller sind mit zusätzlichen DSP-Funktionen ausgestattet ([[PICCOLO]], [[dsPIC]], [[ARM#ARM_Cortex_M4|ARM Cortex M4]]), während DSPs zunehmend in Richtung der Aufgabenbereiche eines Mikrocontrollers oder Allround-Prozessors vordringen und immer öfter um Unterstützung für Betriebssysteme (MMU) oder I/O-Funktionen wie Ethernet oder USB erweitert werden ([[Blackfin]]).&lt;br /&gt;
&lt;br /&gt;
Eine noch größere DSP-Rechenleistung kann mit programmierbaren Logikbausteinen (&#039;&#039;&#039;[[FPGA]]&#039;&#039;&#039;s) erzielt werden, da die Anzahl gleichzeitig ausführbarer Rechenoperationen nur durch die Größe des FPGAs begrenzt wird. Nachteilig sind die gegenüber DSPs um ein vielfaches höheren Kosten, höherer Stromverbrauch und höherer Entwicklungsaufwand, weshalb FPGAs für Signalverarbeitung nur in sehr speziellen Anwendungen verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Aktuelle &#039;&#039;&#039;PC-Prozessoren&#039;&#039;&#039; sind sehr gut für Gleitkomma-Signalverarbeitung geeignet. Für Aufgaben bei denen sehr viele Daten parallel verarbeitet werden können kann die Leistungsfähigkeit mit GPUs weiter gesteigert werden (CUDA, OpenCL). Wenn keine besonderen Anforderungen an Echtzeitfähigkeit, Strom- oder Platzbedarf gestellt werden, hat ein normaler PC mit Abstand das beste Preis/Leistungsverhältnis. Der erste Schritt bei einem DSP-Projekt sollte somit eine Implementierung auf dem PC sein. Es macht wenig Sinn, ein Eval-Board für einen Signalprozessor zu kaufen und einfach loszulegen.&lt;br /&gt;
&lt;br /&gt;
=== Fest- oder Gleitkomma? ===&lt;br /&gt;
&lt;br /&gt;
Signalverarbeitung auf einem Gleitkomma- (Floating-Point-) Rechner ist grundsätzlich einfacher als auf einem Festkomma- (Fixed-Point-) Rechner. Da die Ungenauigkeiten bei der Rechnung mit Floating-Point-Zahlen in vielen Fällen vernachlässigbar sind, kann man einen Algorithmus i.d.R. 1:1 in Programmcode umsetzen. Hat man nur Festkomma-Rechenoperationen zur Verfügung wird es etwas ungemütlich. Man muss sich Gedanken um die Skalierung der Daten, die Reihenfolge von Rechenoperationen, Überläufe, Rundungsrauschen usw. machen. Da Gleitkomma-DSPs allerdings teurer sind und mehr Strom verbrauchen, werden für Massenprodukte fast ausschließlich Festkomma-DSPs bzw. ASICs mit Festkomma-Rechenwerken verwendet.&lt;br /&gt;
&lt;br /&gt;
=== TI C2000 ===&lt;br /&gt;
&lt;br /&gt;
Eine komplette 32-bit DSC Controller Familie vom low-cost ([http://www.ti.com/corp/docs/landing/f280xx-piccolo/index.htm PICCOLO]) bis high-end Controller mit FPU ([http://focus.ti.com/paramsearch/docs/parametricsearch.tsp?family=mcu&amp;amp;sectionId=95&amp;amp;tabId=2108&amp;amp;familyId=1414&amp;amp;paramCriteria=no TMS320F28335]).&lt;br /&gt;
Die Peripherie umfasst Mehrkanal A/D Wandler mit 12-bit Aufloesung und bis zu 4 Megasamples Abtastrate. Die PWMs haben einen hochauflösenden Modus, der bis zu 150ps auflösen kann. Als Interface stehen CAN, I2C, schnelle generelle serielle Ports und Quadratureingänge für Drehgeber zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
=== TI C5000 ===&lt;br /&gt;
&lt;br /&gt;
DSP für batteriebetriebene Anwendungen. Die gesamte Architektur wurde auf Stromverbrauch optimiert. Dazu werden spezielle Werkzeuge zur Verfügung gestellt, die zur Anwendung passende Optimierungslösungen generiert. [[TMS320VC5505 eZDSP USB Stick‎]] mit IDE als preisgünstiges Entwicklungssystem ( &amp;lt; 50€)&lt;br /&gt;
&lt;br /&gt;
=== TI C6000 ===&lt;br /&gt;
&lt;br /&gt;
DSP-Familie vom Marktführer Texas Instruments enthält sowohl Fest- als auch Gleitkomma-DSPs.&lt;br /&gt;
&lt;br /&gt;
=== TI DM6400 (DaVinci) ===&lt;br /&gt;
&lt;br /&gt;
DSP für Videoanwendungen. Einige Derivate enthalten auch einen ARM9 als Co-Prozessor. Diese Familie wird unter dem Namen [http://focus.ti.com/paramsearch/docs/parametricsearch.tsp?family=dsp&amp;amp;sectionId=2&amp;amp;tabId=1852&amp;amp;familyId=1300 DaVinci] vermarktet.&lt;br /&gt;
&lt;br /&gt;
=== TI OMAP ===&lt;br /&gt;
&lt;br /&gt;
Prozessor für mobile Geräte, enthält einen ARM-Kern und einen C6000-DSP. Ein interessantes und mit $149 sehr preisgünstiges Evalboard ist das [http://www.beagleboard.org Beagle Board]. Ein kostenloser Assembler für den DSP ist verfügbar.&lt;br /&gt;
&lt;br /&gt;
=== SHARC/TigerSHARC ===&lt;br /&gt;
&lt;br /&gt;
32-Bit-Gleitkomma-DSP von Analog Devices.&lt;br /&gt;
&lt;br /&gt;
=== Blackfin ===&lt;br /&gt;
&lt;br /&gt;
Der Blackfin ist ein 16/32-Bit-Festkomma-DSP von Analog Devices. Im Gegensatz zu den 16-bittigen Vorgängern ADSP-21xx, die häufig als Co-Prozessoren zur Signalverarbeitung zusammen mit einem Mikrocontroller verwendet werden, geht der Blackfin schon weit in den Einsatzbereich eines Allround-Prozessors hinein. So gibt es z.&amp;amp;nbsp;B. einen Linux-Port für Blackfin, Eval-Boards mit Ethernet, CAN, USB und vielen MB SDRAM. Dank der verbesserten Stromsparfunktionen der BF52x-Reihe ist diese eher neue Architektur vermehrt in mobilen Geräten (Kameras, Mediaplayer, etc.) anzutreffen.&lt;br /&gt;
&lt;br /&gt;
Wichtig für die Entwicklung ist zu wissen:&lt;br /&gt;
&lt;br /&gt;
* Keine Fließkomma-Unterstützung in Hardware&lt;br /&gt;
* Keine MMU, keine Unterstützung für virtuellen Speicher (kein Unix fork(), etc.)&lt;br /&gt;
&lt;br /&gt;
Unterstützte Entwicklungswerkzeuge:&lt;br /&gt;
&lt;br /&gt;
* Visual DSP++: Hauseigenes Entwicklungswerkzeug von Analog Devices, kommerziell&lt;br /&gt;
* GCC: Freie GNU-Umgebung mit Assembler, Compiler, Linker, Debugger&lt;br /&gt;
* Eclipse für uClinux-Entwicklung wie auch &#039;nackt&#039; ohne OS&lt;br /&gt;
&lt;br /&gt;
Aufgrund der ausgereiften GNU-Toolchain ist der Blackfin eine der kostengünstigsten Plattformen für die Entwicklung. Die Werkzeuge laufen sowohl unter Windows32 als auch Linux, bevorzugt wird jedoch Linux eingesetzt. Für die Kernel-Entwicklung ist Linux unabdingbar.&lt;br /&gt;
Dank offener JTAG-Spezifikation existieren einige Werkzeuge von Drittherstellern zum Hardware-Debugging (In-Circuit Emulation) und zur Programmierung:&lt;br /&gt;
&lt;br /&gt;
* [http://www.section5.ch/icebear ICEbear] JTAG: schneller USB-&amp;gt;JTAG adapter&lt;br /&gt;
* [http://www.ronetix.at/ PEEDI] High end JTAG, Ethernet&lt;br /&gt;
* [http://www.bluetechnix.at/rainbow2006/site/blackfin_family/__dev_tools/__gnice_jtag/409/gnice_jtag.aspx gnICE von Bluetechnix]&lt;br /&gt;
* [http://www.analog.com/en/processors-dsp/blackfin/emulator-100/processors/product.html JTAG-Adapter von Analog Devices]&lt;br /&gt;
&lt;br /&gt;
Beide Werkzeuge arbeiten auch mit ARM-Prozessoren.&lt;br /&gt;
&lt;br /&gt;
Weitere Links:&lt;br /&gt;
&lt;br /&gt;
* [http://www.bluetechnix.com/rainbow2006/default.aspx Bluetechnix Core-Module]&lt;br /&gt;
* [http://www.analog.com/blackfin Herstellerwebsite]&lt;br /&gt;
* [http://blackfin.uclinux.org/ uClinux Port und GNU toolchain]&lt;br /&gt;
&lt;br /&gt;
=== dsPIC ===&lt;br /&gt;
&lt;br /&gt;
Der [[dsPIC]] ist ein kleiner 16-Bit-Mikrocontroller mit DSP-Funktionen. Mit dem klassischen 8-Bit-PIC hat er außer dem Namen nichts gemeinsam.&lt;br /&gt;
&lt;br /&gt;
Er basiert auf der modernen RISC-Architektur des PIC24 und bietet zusätzlich 40-Bit-Register und spezielle Befehle für DSP-Anwendungen. Der derzeit schnellste dsPIC33E arbeitet mit bis zu 70MIPS. dsPIC33 gibt es auch im DIL28-Gehäuse. &lt;br /&gt;
&lt;br /&gt;
Ein kostenloser C-Compiler (C30) und eine DSP-Bibliothek werden von Microchip angeboten. Dabei handelt es sich um eine &amp;quot;Light&amp;quot;-Version des kommerziellen C30, bei dem nur eine Optimierungsstufe freigeschaltet ist, aber ansonsten keine Einschränkungen (Codegröße o.ä.) bestehen.&lt;br /&gt;
&lt;br /&gt;
=== Cortex M4 ===&lt;br /&gt;
&lt;br /&gt;
Von mehreren Herstellern gibt es Mikrocontroller mit [[ARM#ARM_Cortex_M4|ARM Cortex M4]]-Kern, welcher DSP-Funktionen wie single-cycle 32 Bit MAC (Multiply-ACcumulate), Addition mit Sättigungsverhalten [http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/CHDBHGFC.html], SIMD-Befehle, und bei manchen Exemplaren eine FPU [http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/CHDBHGFC.html] beinhaltet. Der große Vorteil gegenüber &amp;quot;echten&amp;quot; DSPs ist, dass für ARM zahlreiche Entwicklungsumgebungen frei verfügbar sind, und man sich nicht an einen bestimmten Hersteller und seine Entwicklungstools bindet. Mit CMSIS-DSP stellt ARM eine Bibliothek mit DSP-Funktionen (Vektoroperationen, FFT, etc.) zur Verfügung [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php].&lt;br /&gt;
&lt;br /&gt;
=== TriCore ===&lt;br /&gt;
&lt;br /&gt;
Der &#039;&#039;&#039;TriCore&#039;&#039;&#039; von Infineon ist ein 32-Bit-Mikrocontroller mit DSP-Funktionen, mit derzeitigem Schwerpunkt im Bereich der High Performance Embedded Real-Time Systems für Industrie-  und Automobilanwendungen (Beispiele: Motorsteuerungen, Servomotoren, Solarinverter, Multi-Axis-Conrol) &lt;br /&gt;
&lt;br /&gt;
* [http://www.infineon.com/cgi-bin/ifx/portal/ep/channelView.do?channelId=-78991&amp;amp;channelPage=%2Fep%2Fchannel%2FleafNote.jsp&amp;amp;pageTypeId=17099  Übersicht über die &#039;&#039;&#039;TriCore&#039;&#039;&#039; Produktfamilie]&lt;br /&gt;
&lt;br /&gt;
=== Bezugsquellen für Starterkits/Evalboards ===&lt;br /&gt;
&lt;br /&gt;
* http://www.spectrumdigital.com - große Auswahl an Starterkits mit TI-DSPs, ab $300&lt;br /&gt;
* http://www.bluetechnix.com - Blackfin-Module ab € 150&lt;br /&gt;
* http://www.zbrain.ch/ - Blackfin-Modul, Preis: ?&lt;br /&gt;
* http://www.danvillesignal.com/ - ADSP-218x-Boards ab $200, Sharc-Boards ab $400&lt;br /&gt;
* http://docs.blackfin.uclinux.org/doku.php?id=buy_stuff - Blackfin BF533 STAMP $170 (keine analogen Schnittstellen, aber über Pfostenstecker leicht zu erweitern)&lt;br /&gt;
* http://www.sundance.com - High-End-Module mit TI C6000&lt;br /&gt;
* http://www.spectrumsignal.com/ - TMS320 und SHARC&lt;br /&gt;
* http://www.pentek.com/dspcentral/ - TMS430 und PowerPC&lt;br /&gt;
* http://www.bittware.com/ - SHARC und TigerSHARC&lt;br /&gt;
* http://www.hunteng.co.uk/ - C6000&lt;br /&gt;
* http://www.kanecomputing.co.uk&lt;br /&gt;
* http://www.dsp-systeme.net - DSP-Module mit DSP von TI und ADI&lt;br /&gt;
* http://search.digikey.com/scripts/DkSearch/dksus.dll?lang=de&amp;amp;site=DE&amp;amp;WT.z_homepage_link=hp_go_button&amp;amp;KeyWords=TMDX5505EZDSP&amp;amp;x=22&amp;amp;y=22  eZDSP  USB Stick , &amp;lt;50€&lt;br /&gt;
* http://www.ehitex.de/artikel.php?xPD=131_132&amp;amp;kat_name= - Infineon TriCore Starter Kits&lt;br /&gt;
&lt;br /&gt;
== Weitere Infos==&lt;br /&gt;
&lt;br /&gt;
===Literatur ===&lt;br /&gt;
* Oppenheim, Schaefer: &amp;quot;Discrete Time Signal Processing&amp;quot;, ISBN 0131988425&lt;br /&gt;
* Proakis: &amp;quot;Digital Signal Processing&amp;quot;, ISBN 0131873741&lt;br /&gt;
* Lyons: &amp;quot;Understanding Digital Signal Processing&amp;quot;, ISBN 0131089897&lt;br /&gt;
* Smith: &amp;quot;The Scientist and Engineer&#039;s Guide to Digital Signal Processing&amp;quot;, ISBN  075067444X (unter http://dspguide.com/ als PDF verfügbar)&lt;br /&gt;
* Sanjit K. Mitra: &amp;quot;Handbook for Digital Signal Processing&amp;quot; (1993,1312 Seiten), ISBN 0471619957&lt;br /&gt;
&lt;br /&gt;
=== Foren ===&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/list-10-1.html DSP-Forum auf mikrocontroller.net (deutsch)]&lt;br /&gt;
* [http://groups.google.de/group/comp.dsp Newsgroup comp.dsp (Englisch)]&lt;br /&gt;
* [http://www.dsprelated.com/groups.php Discussion Groups (Englisch)]&lt;br /&gt;
&lt;br /&gt;
=== Webseiten ===&lt;br /&gt;
* http://www.dspguru.com/ - FAQs, Infos, Beispielcode, ...&lt;br /&gt;
* http://docs.google.com/View?docid=dg2hppb_4gtgk89 - evtl. interessant als Rohmaterial für diesen Artikel&lt;br /&gt;
* http://www.dsprelated.com - Blogs, Jobs, Comp.DSP, ...&lt;br /&gt;
* http://www.unidsp56.de/ Eine Entwicklungsplattform für den Amateur&lt;br /&gt;
* http://de.wikipedia.org/wiki/Datei:Aircraft-recognition-and-tracking-by-dsp-based-signal-processing.jpg&lt;br /&gt;
* http://www.micromodeler.com - Online DSP Filter Designer&lt;br /&gt;
&lt;br /&gt;
=== Artikel aus der Kategorie DSP ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ncl style=compact maxdepth=2 headings=bullet headstart=2&lt;br /&gt;
      showcats=1 showarts=1&amp;gt;DSP&amp;lt;/ncl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:DSP]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Schmitt-Trigger&amp;diff=90434</id>
		<title>Schmitt-Trigger</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Schmitt-Trigger&amp;diff=90434"/>
		<updated>2015-11-30T08:37:21Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
Ein Schmitt-Trigger hat einen Eingang und einen Ausgang und liefert abhängig vom Eingangspegel immer einen wohl definierten Ausgangspegel. Dabei gilt stets:&lt;br /&gt;
[[Bild:Schmitt-trigger-diagramm.png|thumb|Beispiel]]&lt;br /&gt;
* Am Ausgang liegt HIGH an, wenn der Pegel am Eingang eine Spannung U&amp;lt;sub&amp;gt;H&amp;lt;/sub&amp;gt; &#039;&#039;&#039;über&#039;&#039;&#039;schreitet. &lt;br /&gt;
* Am Ausgang liegt LOW an, wenn der Pegel am Eingang eine Spannung U&amp;lt;sub&amp;gt;L&amp;lt;/sub&amp;gt; &#039;&#039;&#039;unter&#039;&#039;&#039;schreitet.&lt;br /&gt;
* Dabei wird der bisherige Ausgangspegel aufrechterhalten, wenn sich der Eingangspegel zwischen U&amp;lt;sub&amp;gt;L&amp;lt;/sub&amp;gt; und U&amp;lt;sub&amp;gt;H&amp;lt;/sub&amp;gt; befindet (Hysterese)&lt;br /&gt;
* Der Übergang von LOW auf HIGH bzw. von HIGH auf LOW erfolgt stets mit steiler Flanke.&lt;br /&gt;
Dieses Verhalten kann man beispielsweise ausnutzen, um mittels Schmitt-Trigger ein verrauschtes digitales Signal wieder aufzufrischen. Ebenso &amp;lt;B&amp;gt;müssen&amp;lt;/B&amp;gt; mechanische Taster bzw. Relaiskontakte [[Entprellung |entprellt]] werden, wenn sie digitale ICs ansteuern sollen, besonders wenn sie Taktsignale generieren sollen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Integrierte Schmitt-Trigger ==&lt;br /&gt;
Es existieren fertige ICs mit Schmitt-Trigger-Funktionalität. In der 74xx-Reihe ist das beispielsweise der 74xx14. Weitere Typen sind unter [[74xx]] aufgeführt. In der 4000er-Serie gibt es die Typen 4093 und 40106. Viele Mikrocontroller wie z.&amp;amp;nbsp;B. der [[AVR]] haben bereits Schmitt-Trigger Eingänge, sodass nur noch die beiden Widerstände und der Kondensator benötigt werden.&lt;br /&gt;
&lt;br /&gt;
[[Bild:taster_entprellen.png|framed|left|&#039;&#039;&#039;Taster entprellen mit 74HC14&#039;&#039;&#039;]]&lt;br /&gt;
&amp;lt;BR clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Schmitt-Trigger mit Operationsverstärker oder Komparator ==&lt;br /&gt;
&lt;br /&gt;
Ein Schmitt-Trigger lässt sich auch mit Hilfe eines [[Operationsverstärker-Grundschaltungen|Operationsverstärkers]] oder besser eines [[Komparator|Komparators]] aufbauen.&lt;br /&gt;
&lt;br /&gt;
=== Nichtinvertierender Schmitt-Trigger ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:st_generic.png | framed | Nichtinvertierender Schmitt-Trigger]]&lt;br /&gt;
&lt;br /&gt;
Am - Eingang des OPV wird die Referenzspannung angelegt. Achtung! Diese liegt im allgemeinen NICHT mittig zwischen den beiden Schaltschwellen. R2 sorgt für die Mitkopplung und damit für die Hysterese. Über das Verhältnis von R1/R2 wird die Hysteresebreite festgelegt. Wird also U&amp;lt;sub&amp;gt;H&amp;lt;/sub&amp;gt; am Eingang überschritten, geht der Operationsverstärker in die positive Sättigung U&amp;lt;sub&amp;gt;HA&amp;lt;/sub&amp;gt;, wird U&amp;lt;sub&amp;gt;L&amp;lt;/sub&amp;gt; unterschritten, geht er in die negative Sättigung U&amp;lt;sub&amp;gt;LA&amp;lt;/sub&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U_{ref}=U_{LA} + (U_H - U_{LA} ) \frac{R_2}{R_1 + R_2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U_{ref}=U_{L} + (U_{HA}-U_L) \frac{R_1}{R_1 + R_2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Durch Gleichsetzen und Umformen der beiden Gleichungen kann man R2 berechnen, wobei R1 vorher festgelegt werden muss.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;R_2=R_1 \cdot \frac{U_{HA}-U_{LA}}{U_H - U_L}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Durch Einsetzen in die 1. oder 2. Gleichung kann man abschließend U&amp;lt;sub&amp;gt;ref&amp;lt;/sub&amp;gt; berechnen. Die Referenzspannung kann man direkt aus einer [[Standardbauelemente#Shuntregler/Spannungsreferenz | Spannungsreferenz]] oder mit einem einfachen [[Spannungsteiler]] aus der Betriebsspannung generieren. Bei der Berechung des Spannungsteilers zur Referenzspannungserzeugung kann man einen der Widerstände frei wählen. Alle Berechnungen können mit dieser einfachen [[media:schmitt-trigger.xls | Exceltabelle]] durchgeführt werden.&lt;br /&gt;
&lt;br /&gt;
=== Invertierender Schmitt-Trigger ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:st_generic_inv.png | framed | Invertierender Schmitt-Trigger]]&lt;br /&gt;
&lt;br /&gt;
Durch einfaches Vertauschen von Uein und Uref kann die Schaltung invertierend arbeiten. Dabei ändern sich allerdings die Formeln zur Berechnung der Widerstände bzw. der Referenzspannung. Dafür gelten 2 Formeln.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U_H=U_{ref} + (U_{HA}-U_{ref}) \frac{R_1}{R_1 + R_2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U_L=U_{ref} - (U_{ref}-U_{LA}) \frac{R_1}{R_1 + R_2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Durch Umformen und Einsetzen erhält man:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;R_2=R_1 \frac{U_H-U_{HA}-U_L+U_{LA}}{U_L-U_H}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U_{ref}= \frac{U_H \cdot(R_1+R_2)-R_1 \cdot U_{LA}}{R_2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei der Berechung des Spannungsteilers zur Erzeugung der Referenzspannung kann man keinen der Widerstände R3 und R4 frei wählen (welche zusammen R1 ersetzen), sie berechnen sich direkt aus R1 und den anderen Eingangsparametern, abgeleitet aus den beiden Formeln.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;R_{1}= R3//R4 = \frac{R_3 \cdot R_4}{R_3 + R_4}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;U_{ref}= V_{CC} \frac{R_3}{R_3 + R_4}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Durch Umformen und Einsetzen erhält man: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;R_{4}= R_1 \cdot \frac{V_{CC}}{U_{ref}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;R_{3}= R_4 \cdot \frac{U_{ref}}{V_{CC} - U_{ref}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch diese Berechungen sind in der [[media:schmitt-trigger.xls | Exceltabelle]] verfügbar.&lt;br /&gt;
&lt;br /&gt;
[[Category:Bauteile]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Transistor&amp;diff=90128</id>
		<title>Transistor</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Transistor&amp;diff=90128"/>
		<updated>2015-10-30T07:45:07Z</updated>

		<summary type="html">&lt;p&gt;Maybee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Kunstwort aus &amp;quot;transfer resistor&amp;quot;, was etwa so viel bedeutet wie &amp;quot;übertragener [[Widerstand]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
In den 1950-ern als praktische Anwendung des [[Halbleiter]]-Effekts erfundenes &amp;quot;solid state&amp;quot; Schalt- und Verstärkerelement, welches sehr klein ist, ohne bewegte Teile auskommt (anders als ein klassisches Relais) und keine energiefressende Heizung benötigt (anders als eine Röhre).&lt;br /&gt;
&lt;br /&gt;
Vom &amp;quot;bipolaren Transistor&amp;quot; (PNP, NPN) weiterentwickelt zum &amp;quot;Feldeffekt-Transistor&amp;quot; ([[FET]]), der heute - gefertigt mit einem preiswerten Verfahren unter Verwendung von Metall-Oxid-Schichten (MOS) - ein wesentliches Element integrierter Schaltkreise (ICs, integrated circuits) darstellt, und damit natürlich auch von [[Mikrocontroller]]n, um die es in diesem Wiki hauptsächlich geht (bzw. gehen sollte).&lt;br /&gt;
&lt;br /&gt;
== Schaltzeichen ==&lt;br /&gt;
http://electronicsclub.info/images/transbce.gif&lt;br /&gt;
&lt;br /&gt;
* E: Emitter&lt;br /&gt;
* B: Basis&lt;br /&gt;
* C: Collector    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In ASCII Schaltplänen sehen Transistoren so aus:&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
                       |&amp;gt;                 |/&lt;br /&gt;
NPN      |&amp;gt;   oder    -|       oder      -|&lt;br /&gt;
                       |\                 |&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                       |&amp;lt;                 |/&lt;br /&gt;
PNP:     |&amp;lt;   oder    -|       oder      -|&lt;br /&gt;
                       |\                 |&amp;lt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um zu erkennen, ob ein NPN oder PNP Transistor im Schaltplan verwendet wird, gibt es Eselsbrücken:&lt;br /&gt;
*Für Dichter: &#039;&#039;&#039;Tut der Pfeil der Basis weh, handelt&#039;s sich um PNP.&#039;&#039;&#039;&lt;br /&gt;
*Für Praktiker: &#039;&#039;&#039;PNP heisst &amp;quot;Pfeil Nach Platte&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
*Mit Dialekt: &#039;&#039;&#039;NPN &amp;quot;&#039;naus, Pfeil, &#039;naus&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
*..und für Gleichberechtigungsverfechter: &#039;&#039;&#039;NPN means &amp;quot;Not Pointing iN&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
JFET: [[Bild:Transistor_JFET.png]]&lt;br /&gt;
&lt;br /&gt;
MOSFET: [[Bild:Transistor_MOSFET.png]]&lt;br /&gt;
&lt;br /&gt;
* S: Source&lt;br /&gt;
* G: Gate&lt;br /&gt;
* D: Drain&lt;br /&gt;
&lt;br /&gt;
Eigentlich haben MOSFETs noch einen vierten Anschluss namens Bulk. Der ist aber nur bei Spezialtypen als Pin herausgeführt. Im Normalfall kann man ihn vergessen, da er nicht gesondert beschaltet werden muss, er ist praktisch und auch im Symbol mit Source verbunden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achtung:&#039;&#039;&#039; Die NPN/PNP Eselsbrücken funktionieren bei FETs nicht, denn bei einem P-Kanal FET zeigt der Pfeil weg vom FET!&lt;br /&gt;
Ein Bipolartransistor, im Englischen als bipolar junction transistor (BJT) bezeichnet, ist ein Transistor, bei dem Ladungsträger – negativ geladene Elektronen und positiv geladene Defektelektronen – zum Stromtransport durch den Bipolartransistor beitragen. Der BJT wird mittels eines elektrischen Stroms gesteuert und wird zum Schalten und Verstärken von Signalen ohne mechanisch bewegte Teile eingesetzt.&lt;br /&gt;
&lt;br /&gt;
Bipolare Leistungstransistoren sind für das Schalten und Verstärken von Signalen höherer Stromstärken und Spannungen ausgelegt.&lt;br /&gt;
&lt;br /&gt;
== Typbezeichnungen == &lt;br /&gt;
&lt;br /&gt;
Neben den Typbezeichnungen wie 2Nxxxx, TIPxxx, MJxxx, MJExx gibt es noch die in Europa geläufigere  Kennzeichnung bestehend aus zwei Buchstaben und drei Ziffern. Die diversen Kennzeichnungsmöglichkeiten sind in einem eigenen Artikel ([[Kennzeichnung von Halbleitern]]) zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
== Kenndaten/Parameter ==&lt;br /&gt;
&lt;br /&gt;
Im [http://www.mikrocontroller.net/topic/197676#1938546 Beitrag: Transistorparameter Erklärung] sind Links zu Erläuterungen spezieller Kürzel.&lt;br /&gt;
&lt;br /&gt;
== Transistor Grundschaltungen ==&lt;br /&gt;
&lt;br /&gt;
Generell gilt, dass Strom vom Kollektor zum Emitter nur dann fließen kann, wenn die Basis positiver (NPN) bzw. negativer (PNP) wird als der Emitter. Dabei darf die Basis nicht direkt mit Vcc (NPN) oder GND (PNP) verbunden werden, da der Basisstrom sonst zu gross wird. Es muss jeweils ein geeigneter Basiswiderstand (R_Basis) gewählt werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Weitere Links:&#039;&#039;&#039;&lt;br /&gt;
* Artikel [[Basiswiderstand]]&lt;br /&gt;
* [http://www.elektronik-kompendium.de/sites/slt/0203111.htm Transistor Grundschaltungen im ElKo]&lt;br /&gt;
* [http://www.roboternetz.de/wissen/index.php/Transistor Transistor bei RoboterNetz.de]&lt;br /&gt;
&lt;br /&gt;
Es gibt drei Grundschaltungen. Der Name beschreibt den Anschluss, welcher sich auf einem festen Potential (Spannung) befindet. Die beiden anderen Anschlüsse haben bedingt durch die Schaltung ein veränderliches Potential.&lt;br /&gt;
&lt;br /&gt;
=== Kollektorschaltung (Emitterfolger)===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Anwendung:&#039;&#039;&#039;&lt;br /&gt;
* Impedanzwandler&lt;br /&gt;
* Darlington-Schaltung&lt;br /&gt;
* Schalter&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Eigenschaften:&#039;&#039;&#039;&lt;br /&gt;
* Keine Phasendrehung&lt;br /&gt;
* Hohe Stromverstärkung&lt;br /&gt;
* Keine Spannungsverstärkung&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beispiel: Transistor als Schalter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* NPN: Kollektor mit Vcc verbinden, Last an Emitter&lt;br /&gt;
* PNP: Kollektor mit GND verbinden, Last an Emitter&lt;br /&gt;
&lt;br /&gt;
In diesem Fall regelt der Transistor die Spannungen am Emitter, daher wird die Last am Emitter angeschlossen. Die Spannung am Emitter entspricht immer der an der Basis minus 0,6V, sie folgt der Basisspannung, deswegen auch der Name Emitterfolger. Daher ist diese Schaltung nicht geeignet, um 12V mit 5V zu schalten. &lt;br /&gt;
&lt;br /&gt;
[[Bild:NPN_Collector.gif | framed | center | NPN Transistor in Kollektorschaltung]]&lt;br /&gt;
&lt;br /&gt;
Wird &amp;lt;math&amp;gt;R_{Poti}&amp;lt;/math&amp;gt; (Spannungsteiler) erhöht, steigt die Spannung &amp;lt;math&amp;gt;U_{Last}&amp;lt;/math&amp;gt; letztlich bis auf Vcc-0,6V (Basis-Emitter-Übergang). &lt;br /&gt;
&lt;br /&gt;
[[Bild:PNP_Collector.gif | framed | center | PNP Transistor in Kollektorschaltung]]     &lt;br /&gt;
&lt;br /&gt;
Wird &amp;lt;math&amp;gt;R_{Poti}&amp;lt;/math&amp;gt; (Spannungsteiler) erhöht, sinkt Spannung an &amp;lt;math&amp;gt;U_{Last}&amp;lt;/math&amp;gt; letztlich bis auf 0,6V (Basis-Emitter-Übergang).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Weitere Links:&#039;&#039;&#039;&lt;br /&gt;
* [http://www.elektronik-kompendium.de/sites/slt/0204133.htm Kollektorschaltung im ElKo]&lt;br /&gt;
&lt;br /&gt;
=== Emitterschaltung ===&lt;br /&gt;
&lt;br /&gt;
Die Emitterschaltung bietet hohe Spannungs- und Stromverstärkung.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Anwendung:&#039;&#039;&#039;&lt;br /&gt;
* NF- und HF-Verstärker&lt;br /&gt;
* Leistungsverstärker&lt;br /&gt;
* Transistor als Schalter&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Eigenschaften:&#039;&#039;&#039;&lt;br /&gt;
* Phasendrehung 180°&lt;br /&gt;
* Hohe Spannungsverstärkung&lt;br /&gt;
* Hohe Stromverstärkung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beispiel: Transistor als Schalter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Die Last liegt am Kollektor. Der Strom durch den Schalter oder an U_Schalt steuert den Strom zwischen Kollektor und Emitter. Wird der Schalter geschlossen, fließt ein Strom.&lt;br /&gt;
&lt;br /&gt;
[[Bild:NPN_Schalter.gif | framed | center | NPN Transistor als Schalter]]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                   ___                                          ___&lt;br /&gt;
Vcc/+ o-----------------------+          Vcc/+ o-----------------------+&lt;br /&gt;
                              |                                        |&lt;br /&gt;
                     ___    |&amp;lt;            U_schalt (-)       ___     |&amp;lt;  PNP             &lt;br /&gt;
             +------|___|---|  PNP             o------------|___|----|&lt;br /&gt;
             |     R_Basis  |\                             R_Basis   |\&lt;br /&gt;
    Schalter \                |                                        |&lt;br /&gt;
             |       ___      |                               ___      |&lt;br /&gt;
GND/- o------+------|___|-----+          GND/- o-------------|___|-----+&lt;br /&gt;
                   R_Last                                    R_Last     &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Weitere Links:&#039;&#039;&#039;&lt;br /&gt;
* [http://www.elektronik-kompendium.de/sites/slt/0204302.htm Emitterschaltung im ElKo]&lt;br /&gt;
&lt;br /&gt;
=== Basisschaltung ===&lt;br /&gt;
&lt;br /&gt;
Die Basisschaltung findet sich vor allem in Eingangsstufen in der HF-Technik. Im Schaltbetrieb wird sie praktisch nur zur [[Pegelwandler#STEP-UP: 5V -&amp;gt; 9..15V | Pegelwandlung]] für nachfolgende Stufen verwendet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Eigenschaften:&#039;&#039;&#039;&lt;br /&gt;
* Geringe Eingangsimpedanz&lt;br /&gt;
* Keine Phasenverschiebung&lt;br /&gt;
* Hohe Bandbreite&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Weitere Links:&#039;&#039;&#039;&lt;br /&gt;
* [http://www.elektronik-kompendium.de/sites/slt/0205081.htm Basisschaltung im ElKo&lt;br /&gt;
&lt;br /&gt;
== FAQ aus dem Forum ==&lt;br /&gt;
&lt;br /&gt;
=== PNP/NPN als Schalter, wohin mit der Last? === &lt;br /&gt;
Für viele einfache Anwendungen kann man sich merken: &#039;&#039;&#039;Bei Schaltanwendungen darf der Basisstrom nicht durch die Last fließen&#039;&#039;&#039;. Normalerweise kommt dabei die Emitterschaltung zum Einsatz, die Last kommt also an den Kollektor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Vcc o-------------+                  Vcc o-----------+&lt;br /&gt;
                   |                                  |&lt;br /&gt;
                  .-.               An: GND   ___   |&amp;lt;&lt;br /&gt;
                  | | R_Last             o---|___|--|   PNP&lt;br /&gt;
                  &#039;-&#039;               Aus: Vcc        |\&lt;br /&gt;
                   |                                  |&lt;br /&gt;
An: Vcc  ___     |/                                  .-.&lt;br /&gt;
    o---|___|----|   NPN                             | | R_Last&lt;br /&gt;
Aus: GND         |&amp;gt;                                  &#039;-&#039;&lt;br /&gt;
                   |                                  |&lt;br /&gt;
 GND o-------------+                  GND o-----------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Siehe [[Basiswiderstand]] zur Berechnung des notwendigen Basiswiderstandes bei gegebener Last R_Last für einen Transistor als Schalter.&lt;br /&gt;
&lt;br /&gt;
Siehe auch Threads im Forum: &lt;br /&gt;
* http://www.mikrocontroller.net/topic/58567 &lt;br /&gt;
* http://www.mikrocontroller.net/topic/119841&lt;br /&gt;
* oder im [http://www.elektronik-kompendium.de/sites/slt/0208031.htm Elektronik-Kompendium-Forum]&lt;br /&gt;
&lt;br /&gt;
=== Wie kann ich mit 5V vom Mikrocontroller 12V und mehr schalten? === &lt;br /&gt;
Schau mal hier:&lt;br /&gt;
* Wikiartikel [[Pegelwandler]]&lt;br /&gt;
* [http://www.elektronik-kompendium.de/sites/praxis/bausatz_pegelwandler-mit-transistoren.htm Pegelwandler im ElKo]&lt;br /&gt;
* [http://dl6gl.de/grundlagen/schalten-mit-transistoren schalten-mit-transistoren]&lt;br /&gt;
&lt;br /&gt;
oder in diesen Threads:&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/17899 Transistor als Schalter]&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/14437 Vcc schalten mit MOSFET]&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/29830 Schalten mit PNP-Transistor]&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/104027 Transistorschalter für Versorgungsspannung]&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/104951#921417 7-50V strombegrenzt schalten]&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/103116#900247 P-Kanal MOSFET ansteuern]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bei der Kollektor-Schaltung entspricht die Spannung am Emitter immer der an der Basis, daher ist sie nur bedingt geeignet. Zum Schalten können die folgenden Emitter-Schaltungen verwendet werden. Achtung: In der zweiten davon arbeitet T1 in Basisschaltung.&lt;br /&gt;
&lt;br /&gt;
Schalten gegen GND&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 +12V o------------------------+&lt;br /&gt;
                               |&lt;br /&gt;
                              .-. &lt;br /&gt;
                             ( X )  &lt;br /&gt;
                              &#039;-&#039;&lt;br /&gt;
                               |&lt;br /&gt;
                    ___      |/ T1,NPN   &lt;br /&gt;
        uC PIN o---|___|-----| BC547     &lt;br /&gt;
                   R2,4K7    |&amp;gt;&lt;br /&gt;
                               |&lt;br /&gt;
  GND o---------o--------------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Schalten gegen +12V&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 +12V o--------------+----------------------+&lt;br /&gt;
                     |                      |&lt;br /&gt;
                     |   ____              |&amp;lt; T2, PNP&lt;br /&gt;
                     +--|____|----+--------|  BC557&lt;br /&gt;
                        R1,4K7    |        |\&lt;br /&gt;
                                |/T1,NPN    |&lt;br /&gt;
         Vcc/+5V o--------------| BC547     |&lt;br /&gt;
                                |&amp;gt;          |&lt;br /&gt;
                        ___       |        .-. &lt;br /&gt;
          uC PIN o-----|___|------+       ( X )  &lt;br /&gt;
                       R2,4K7              &#039;-&#039;&lt;br /&gt;
                                            |&lt;br /&gt;
  GND o----------o--------------------------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Transistor an µC ohne Vorwiderstand === &lt;br /&gt;
&lt;br /&gt;
Normalerweise sind IO Pins vom µC nicht in der Lage, große Ströme zu treiben, beim AVR maximal ~20mA. Für einen kleinen Transistor ist das immer noch zu viel und es wäre auch Stromverschwendung.&lt;br /&gt;
&lt;br /&gt;
Deshalb kann man den IO-Pin des AVRs einfach als Tristate Eingang einstellen (Portpin als Eingang und Pullup deaktivieren), damit kein Basisstrom fließt.&lt;br /&gt;
&lt;br /&gt;
Aktiviert man nun den internen Pullup-Widerstand des AVRs, agiert dieser als Basisvorwiderstand, und es fließt nur ein geringer Basisstrom (die Pullups eines AVRs liegen irgendwo bei 50k bis 100k Ohm - siehe Datenblatt).&lt;br /&gt;
&lt;br /&gt;
Nur sollte man bei kleinen Transistoren aufpassen, dass man den Portpin in der Software nie als aktiven Ausgang schaltet. &lt;br /&gt;
&lt;br /&gt;
Wenn der verwendete µC zuschaltbare Pulldown-Widerstände an seinen Pins besitzt, kann man das gleiche auch mit einem PNP-Transistor machen (natürlich nur den Pulldown aktivieren).&lt;br /&gt;
&lt;br /&gt;
Eine Anwendung wären z.&amp;amp;nbsp;B. Nixie-Röhren-Kathodentreiber (geringe Stromverstärkung nötig).&lt;br /&gt;
&lt;br /&gt;
=== Wann bipolare (NPN/PNP) und wann FETs (insbesonders, wenn LEDs im Spiel sind)?=== &lt;br /&gt;
Oft sind bipolare Transistoren (NPN/PNP) schon ausreichend, vor allem wenn &amp;quot;normale&amp;quot; LEDs (20mA) verwendet werden. FETs sind u.a. dann gut, wenn mit geringen Eingangsströmen hohe Ausgangsströme (über 300 mA) geschaltet werden sollen, also bei den Power-LEDs (Luxeon...).&lt;br /&gt;
&lt;br /&gt;
Ein Grenzfall: 500mA/5V schalten, siehe http://www.mikrocontroller.net/topic/62327.&lt;br /&gt;
&lt;br /&gt;
=== Wieso gehen bei einer Multiplex-Anzeige mit Schieberegister 74HC595 und (Darlington-)Transistor als Zeilentreiber die LED nicht ganz aus?  ===&lt;br /&gt;
Das liegt an der &#039;&#039;&#039;Miller-Kapazität&#039;&#039;&#039; des übersteuerten (Darlington-)Transistors. Der braucht erst mal einige 10µs, um zu sperren. Du mußt also erstmal beide Zeilen ausschalten, dann etwas warten und dann die nächste Zeile an. Oder Du ersetzt die Darlington durch P-FETs. [http://www.mikrocontroller.net/topic/132545]&lt;br /&gt;
&lt;br /&gt;
=== Wie steuert man ein Relais? ===&lt;br /&gt;
Normalerweise verwendet man zur Ansteuerung von Relais NPN-Transistoren in Emitterschaltung. Freilaufdiode nicht vergessen! &lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* [[Relais mit Logik ansteuern]]&lt;br /&gt;
* [http://www.mikrocontroller.net/attachment/22023/Relaisanteuerung.png Schaltbilder aus dem Forum]&lt;br /&gt;
&lt;br /&gt;
=== Was ist die Spannung &amp;lt;math&amp;gt;U_{BE\_sat}&amp;lt;/math&amp;gt; (lt. Datenblatt max. 1,2V)? ===&lt;br /&gt;
Bekanntlich verhält sich die Basis-Emitter Strecke eines Transistors wie eine Diode und &amp;lt;math&amp;gt;U_{BE\_sat}&amp;lt;/math&amp;gt; ist die bei maximal zulässigem Basisstrom anliegende Vorwärtsspannung.&lt;br /&gt;
&lt;br /&gt;
=== Was bewirkt ein Kondensator (100µF-1nF) parallel zur Basis-Emitter-Strecke nach Masse? === &lt;br /&gt;
Er wirkt mit dem Basisvorwiderstand als RC-Tiefpass. Damit wird der Transistor eigentlich nicht mehr als Schalter, sondern als Linearregler betrieben. Manche Verstärker-Schaltungen sind, gerade bei hohen Lasten, sehr schwingfreudig. Deswegen ist bei PWM so ein C nicht sinnvoll.&lt;br /&gt;
&lt;br /&gt;
=== Gibt es einen IC, der wie mehrere Transistoren funktioniert? ===&lt;br /&gt;
&lt;br /&gt;
Gibt es! Beispielsweise der &#039;&#039;&#039;ULN2803&#039;&#039;&#039; ist ein 8-fach Darlington Transistor Array mit [[Ausgangsstufen_Logik-ICs#Open_Collector|Open-Collector Ausgang]]. Damit lässt sich z.&amp;amp;nbsp;B. ein Leistungstreiber zur Ansteuerung von Schrittmotoren, Relais und anderen induktiven Lasten aufbauen.&lt;br /&gt;
&lt;br /&gt;
=== Gibt es ein Transistor-Array wie ULN28xx, das gegen Vcc schaltet? ===&lt;br /&gt;
&lt;br /&gt;
Such mal nach UDN29xx, z.&amp;amp;nbsp;B. UDN2981, UDN2987 ...&lt;br /&gt;
&lt;br /&gt;
=== Wann setzt man einen MOSFET, Bipolartransistor, IGBT oder Thyristor ein ? ===&lt;br /&gt;
siehe [[Leistungselektronik]]&lt;br /&gt;
&lt;br /&gt;
Die Summe allen Übels ist konstant. Man muss wissen, welches Bauteil sich wofür besonders eignet.&lt;br /&gt;
&lt;br /&gt;
====[[FET | MOSFET]]====&lt;br /&gt;
&lt;br /&gt;
Vorteile&lt;br /&gt;
* Bei niedrigen Spannungen &amp;lt;100V sehr gut geeignet, &amp;lt;200V gut geeignet, sehr geringe R_DS-ON Widerstände möglich (einstelliger mOhm-Bereich)&lt;br /&gt;
* Hohe Schaltgeschwindigkeiten möglich&lt;br /&gt;
* Geringe An- und Ausschaltverluste&lt;br /&gt;
* Statisch praktisch leistungslos steuerbar&lt;br /&gt;
* Bodydiode kann als Freilaufdiode in H-Brücken verwendet werden&lt;br /&gt;
* 2. Durchbruch bei Überschreiten der max. Drain-Source Sperrspannung zerstört das Bauteil nicht, wenn der Strom sowie die Energie begrenzt werden. (Verhalten wie [[Diode | Z-Diode]])&lt;br /&gt;
   &lt;br /&gt;
Nachteile&lt;br /&gt;
*Antiparallele Diode (Bodydiode) ist in nahezu allen MOSFETs unvermeidlich, daduch Sperren nur in einer Polarität möglich, Stromfluss über den MOSFET aber in beiden Richtungen möglich (Inversbetrieb, Synchrongleichrichter)&lt;br /&gt;
* Bei Sperrspannungen &amp;gt;100V deutlich steigende Einschaltwiderstände (R_DS-ON)&lt;br /&gt;
* Schnelles Umschalten erfordert hohe Lade-und Entladeströme ([[MOSFET-Übersicht#Mosfet-Treiber|MOSFET-Treiber]])&lt;br /&gt;
* Leitverluste quadratisch proportional zum Strom, Pv = I²*R_DS-ON&lt;br /&gt;
&lt;br /&gt;
====[[Transistor | Bipolartransistor]]====&lt;br /&gt;
&lt;br /&gt;
Vorteile&lt;br /&gt;
* Hohe Spannungsfestigkeiten möglich, bis zu 2000V&lt;br /&gt;
* Sehr hohe Schaltgeschwindigkeiten möglich&lt;br /&gt;
* Leitverluste etwa linear proportional zum Strom und Kollektor-Emitter-Sättigungsspannung, Pv = I * Uce-sat, U_CEC-sat typ 0,1...2.5 V&lt;br /&gt;
&lt;br /&gt;
Nachteile&lt;br /&gt;
* Stromgesteuert, damit wird immer eine gewisse Ansteuerleistung benötigt&lt;br /&gt;
* Bei grossen Kollektorströmen nimmt die Stromverstärkung deutlich ab, dann wird ein großer Basisstrom benötigt&lt;br /&gt;
* 2. Durchbruch bei Überschreiten der max. Kollektor-Emitter Sperrspannung zerstört das Bauteil&lt;br /&gt;
&lt;br /&gt;
====[[IGBT]]====&lt;br /&gt;
&lt;br /&gt;
Vorteile&lt;br /&gt;
* Hohe Spannungsfestigkeiten möglich, bis zu 6600V, in üblichen Bauformen bis ca 1700V gut verfügbar&lt;br /&gt;
* Statisch praktisch leistungslos steuerbar&lt;br /&gt;
* Mit oder ohne antiparallele Diode zur Kollektor-Emitter-Strecke verfügbar&lt;br /&gt;
* Leitverluste linear proportional zum Strom und Kollektor-Emitter-Sättigungsspannung, Pv = I * Uce-sat, U_CE-sat typ. 2V&lt;br /&gt;
&lt;br /&gt;
Nachteile&lt;br /&gt;
* Nur mäßige Schaltfrequenzen möglich (typ. &amp;lt;30..50kHz)&lt;br /&gt;
* Schnelles Umschalten erfordert hohe Lade-und Entladeströme ([[MOSFET-Übersicht#Mosfet-Treiber|MOSFET-Treiber]])&lt;br /&gt;
* 2. Durchbruch bei Überschreiten der max. Kollektor-Emitter Sperrspannung zerstört das Bauteil&lt;br /&gt;
&lt;br /&gt;
====[[TRIAC]]/Thyristor====&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* Sehr hohe Spannungsfestigkeiten möglich (800V...mehrere kV, Thyristoren bis 12kV)&lt;br /&gt;
* Mit kurzen Pulsen einschaltbar, danach Selbsthaltung des Stromflusses&lt;br /&gt;
* Leitverluste linear proportional zum Strom, Pv = I * Uak, Uak typ. 0,8...1,5 V &lt;br /&gt;
&lt;br /&gt;
Nachteile&lt;br /&gt;
* Auf niedrige Schaltfrequenzen beschränkt (kHz-Bereich, Schaltzeit im Bereich von µs)&lt;br /&gt;
* Anstiegsgeschwindigkeit des Stromes muss begrenzt werden, sonst kommt es zu Bauteilschäden&lt;br /&gt;
* Anstiegsgeschwindigkeit der Spannung muss begrenzt werden, sonst kommt es zum ungewollten Zünden&lt;br /&gt;
* Stromfluss kann nicht ausgeschaltet werden, damit meist nur Einsatz an Wechselspannung&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|- &lt;br /&gt;
! Bauteil               || optimales Einsatzgebiet || Kommentar&lt;br /&gt;
|-&lt;br /&gt;
| MOSFET                || 0..200V, 0..500A || im Kleinspannungsbereich meist die beste Wahl als Schalter&lt;br /&gt;
|-&lt;br /&gt;
| Bipolartransistor     || 0..1000V, 0..10A || wird mehr und mehr von MOSFETs verdrängt&lt;br /&gt;
|-&lt;br /&gt;
| IGBT                  || 200..1700V, 0..500A || optimal für hohe Spannungen und hohe Ströme&lt;br /&gt;
|-&lt;br /&gt;
| Triac/Thyristor       || 230V, 400V, 680V, bis mehrere kV, 0..100A || meist für Wechselspannung, im Pulsbetrieb einige kA. Thyristoren bis 1000A im Dauerbetrieb (Scheibenzelle)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Wie finde ich den richtigen Transistor für eine LED-Ansteuerung? ===&lt;br /&gt;
&lt;br /&gt;
Quelle: Beiträge [http://www.mikrocontroller.net/topic/157763#1493623] und [http://www.mikrocontroller.net/topic/157763#1494972] von yalu&lt;br /&gt;
&lt;br /&gt;
Um am Anfang wenigstens ein bisschen den Durchblick im Transistordschungel zu behalten, kannst du folgendermaßen vorgehen:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nomenklatur&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Nach der amerikanischen Nomenklatur beginnen die Transistornamen meist mit 2N (z.&amp;amp;nbsp;B. 2N2222 oder 2N3055) und nach der japanischen mit 2S (z.&amp;amp;nbsp;B. 2SC1815). Für den Anfang kann man sich auf europäische Transistoren beschränken, da es diese in ausreichender Auswahl gibt und die Bezeichnungen relativ gut den Transistortyp wiedergeben:&lt;br /&gt;
&lt;br /&gt;
Der erste Buchstabe bezeichnet das Halbleitermaterial (A=Germanium, B=Silizium). Germaniumtransistoren werden heute nur noch selten verwendet.&lt;br /&gt;
&lt;br /&gt;
Der zweite Buchstabe steht für den Einsatzzweck (C=Universal, D=hohe Leistung, F=Hochfrequenz, U=hohe Spannung).&lt;br /&gt;
&lt;br /&gt;
So ist also ein ACxxx ein Germaniumuniversaltransistor und ein BDxxx ein Siliziumleistungstransistor.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Auswahl&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Wenn du dich für einen Grundtyp entschieden hast (für die LED ist ein BC-Typ das Richtige), gehst du auf die Webseite eines Elektronikhändlers (Reichelt, Kessler usw.), schlägst die Seite mit den BC-Transistoren auf. Da gibt es natürlich sehr viele  davon, und du brauchst jetzt eine&lt;br /&gt;
Suchreihenfolge. Als erstes Auswahlkriterium nimmst du den Preis, denn:&lt;br /&gt;
&lt;br /&gt;
* Zuviel Geld hast wahrscheinlich nicht einmal du.&lt;br /&gt;
* Billig ist meist das, was in großen Stückzahlen hergestellt wird. Was für die Masse gut ist, ist (zumindest in diesem Fall) meist auch für dich gut.&lt;br /&gt;
* Was billig und damit in Massen verkauft wird, bekommst du auch bei anderen Händlern und auch noch in 10 Jahren. Das ist wichtig, wenn deine Schaltung irgendwann einmal in Serie gefertigt werden soll.&lt;br /&gt;
&lt;br /&gt;
Gleich als nächstes überlegst du, ob du einen NPN- oder einen PNP-Typ brauchst. Das ergibt sich aus der Anordnung der Bauteile in deiner Schaltung. Hast du die Möglichkeit, die Schaltung wahlweise für einen NPN- oder einen PNP-Typ auszulegen, wählst du die Variante mit dem NPN-Typ. Um einfach eine LED über einen Mikrocontroller einzuschalten, ist i.Allg. ein NPN-Typ in Emitterschaltung richtig.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres wichtiges Kriterium ist die Befestigungstechnik: Wenn dir die SMD-Löterei etwas suspekt ist, lässt du die entsprechenden Modelle erst einmal alle außen vor. Ein typisches Nicht-SMD-Gehäuse für Universaltransistoren ist TO-92. Es gibt im Internet bebilderte Listen mit den einzelnen Gehäuseformen ([[IC-Gehäuseformen#Weblinks]])&lt;br /&gt;
&lt;br /&gt;
Wenn du jetzt also bei Reichelt  die BC-Transistoren nach Preis aufsteigend sortiert hast, siehst du erst einen Schwung SMD-Tranistoren. Dann kommen ein paar Transistoren im TO-92-Gehäuse, die sind aber PNP. Etwas weiter unten kommt der erste NPN-Transistor in TO-92, nämlich der BC547C. Netterweise stehen gleich ein paar Eckdaten dabei:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BC547C  45V  0,1A  0,5W&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die 45V sind die maximale Kollektor-Emitter-Spannung, in deinem Fall also die Spannung, die du maximal schalten kannst. Da die LED bei Weitem keine 45V braucht und deine Versorgungsspannung eher in der Gegend von 5V liegt, bist du auf jeden Fall auf der sicheren Seite.&lt;br /&gt;
&lt;br /&gt;
Deine LED wird typisch mit 20mA (max. 30mA) betrieben. Der BC547C kann 100mA, also ist auch hier noch Luft.&lt;br /&gt;
&lt;br /&gt;
Zur maximalen Verlustleistung (0,5W): Wenn deine LED eingeschaltet ist, fließen bspw. 20mA. Ist der Transistor voll durchgesteuert (in Sättigung) beträgt die Kollektor-Emitter-Spannung bei diesem geringen Strom typischerweise zwischen 0,1V und 0,2V (Genaueres steht im Datenblatt). Am Transistor wird also maximal die Leistung 20mA·0,2V=4mW in Wärme umgesetzt. Bis zu 500mW dürfen es sein, also ebenfalls ok.&lt;br /&gt;
&lt;br /&gt;
Nachdem du den Transistor in engere Auswahl gezogen hast, lohnt sich auf jeden Fall ein Blick ins Datenblatt. Aus den Tabellen und Diagrammen erfährst du bspw., wie hoch der Basisstrom sein muss, um den Kollektorstrom von mindestens 20mA bei ausreichend geringer CE-Spannung bereitzustellen. Dort ist auch erklärt warum es einen BC547A, BC547B und BC547C gibt. Der letzte Buchstabe gibt nämlich die Stromverstärkungsklasse an. Da eine hohe Stromverstärkung meist wünschenswert ist und in diesem Fall keinen Aufpreis kostet, ziehst du den BC547C den anderen beiden vor.&lt;br /&gt;
&lt;br /&gt;
Da in deiner Anwendung HF- und Rauschverhalten keine Rolle spielen, bist du schon am Ziel angelangt.&lt;br /&gt;
&lt;br /&gt;
Würde deine LED 100mA statt 20mA benötigen, wären die max. 100mA des BC547 etwas knapp bemessen. Du blätterst also in der Reichelt-Liste weiter und stößt auf den BC337-40 mit 45V, 0,5A und 0,525W. Das ist genau das, wonach du suchst. Bei diesem Transistor sind die Stromverstärkungsklassen durch die Endungen -16, -25 und -40 gekennzeichnet. Es wäre ja auch&lt;br /&gt;
zu einfach, wenn immer nur A, B und C verwendet würde ;-)&lt;br /&gt;
&lt;br /&gt;
Bei Strömen ab etwa 500mA kommt man an die Grenze der Leistungsfähigkeit der BC-Typen. Dann geht es weiter mit BD. Der BD135 geht bspw. schon bis 1,5A. Das Problem bei solchen größeren Transistoren: Die Stromverstärkung ist nicht besonders hoch, so dass irgendwann der Mikrocontroller nicht mehr den benötigten Basisstrom liefern kann. Dann muss dem großen Transistor ein kleiner vorangeschaltet werden, um den erhöhten Basisstrom bereitszustellen. Man kann diese Kombination von zwei Transistoren auch fertig als Darlington-Transistor kaufen, von denen ebenfalls einige in der BD-Reihe zu finden sind (z.&amp;amp;nbsp;B. BD647). Ein Transistortyp, der sich sehr gut zum Schalten höherer Ströme eignet, ist der [[FET | MOSFET]].&lt;br /&gt;
&lt;br /&gt;
Wie schon oben angedeutet: Wenn die 30-80V die die meisten BC- und BD-Transistoren abkönnen, nicht ausreichen, suchst du weiter bei BU.&lt;br /&gt;
&lt;br /&gt;
Steigst du in die HF-Technik ein, sind BF-Transistoren eher das Richtige, wobei bei HF-Anwendungen die Auswahl der Transistoren nicht mehr das Schwierigste ist ;-)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Und wie geht&#039;s weiter?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Man könnte natürlich noch viel mehr zu diesem Thema schreiben. Ich hoffe aber, dass das Geschriebene dir wenigstens grob zeigt, wie man bei nicht allzu speziellem Anforderungen relativ schnell zu einem gewünschten Transistortyp kommt, der nicht nur die technischen Anforderungen erfüllt, sondern auch leicht beschaffbar ist.&lt;br /&gt;
&lt;br /&gt;
Werden die Anforderungen spezieller, helfen oft die Selektionstabellen auf den Webseiten der einschlägigen  Hersteller weiter. Auch Händler wie Farnell haben teilweise ganz gute Auswahlwerkzeuge. &lt;br /&gt;
&lt;br /&gt;
Wenn du dich intensiv mit Elektronik beschäftigst, wirst du wahrscheinlich noch viele  Schaltungen von Leuten zu Gesicht bekommen, die vielleicht schon etwas weiter fortgeschritten sind. Dabei wirst du immer wieder auf bestimmte Standardtypen von Transistoren (und auch anderen Bauteilen wie Operationsverstärker u.ä.) stoßen und sehen, welche [[Standardbauelemente]] &amp;quot;man&amp;quot; üblicherweise für bestimmte Anwendungen einsetzt. Mit der Zeit setzt sich dann eine Auswahl von bspw. 10 oder 20 verschiedenen Transistoren und 5 bis 10 verschiedenen OpAmps im Kopf fest, von denen man die wesentlichen Parameter auswendig kennt, so dass man ohne aufwendige Suche eine schnelle Auswahl treffen kann. Auch hier in der Artikelsammlung gibt es eine solche [[Transistor-Übersicht]].&lt;br /&gt;
&lt;br /&gt;
=== Wo ist die Antwort auf meine Frage? ===&lt;br /&gt;
&lt;br /&gt;
Vielleicht im Forum? Falls du sie da findest, dann pack das ganze doch hier rein.&lt;br /&gt;
&lt;br /&gt;
[http://www.mikrocontroller.net/topic/165580 Gegen Vcc oder GND schalten]&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [[Basiswiderstand]]&lt;br /&gt;
* [[Transistor-Übersicht]]&lt;br /&gt;
* [[AVR-Transistortester]]&lt;br /&gt;
* [[Leistungselektronik]]&lt;br /&gt;
&lt;br /&gt;
== Gehäusebauformen von Transistoren ==&lt;br /&gt;
&lt;br /&gt;
=== TO-92 ===&lt;br /&gt;
Ein kleiner Aufsatz über TO-92 Transistorgehäuse und Footprints findet sich unter: [[Media:TO-92-Gehaeuse_RevB2.pdf]]. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://de.wikipedia.org/wiki/transistor &amp;quot;Transistor&amp;quot; bei Wikipedia]&lt;br /&gt;
* [http://www.elektronik-kompendium.de www.elektronik-kompendium.de]&lt;br /&gt;
** [http://www.elektronik-kompendium.de/sites/bau/0201291.htm Elko/Transistor]&lt;br /&gt;
* http://www.elektronikinfo.de/strom/bipolartransistoren.htm&lt;br /&gt;
* http://www.ferromel.de/tronic_1870.htm&lt;br /&gt;
* [http://www.DieElektronikerseite.de Die Elektronikerseite] Lehrgang: Der Transistor - Ein Tausendsassa&lt;br /&gt;
* [http://www.infoplease.com/encyclopedia/science/transistor-types-transistors.html Transistortypen]&lt;br /&gt;
* [http://electronics-electrical.exportersindia.com/electronic-components/transistors.htm Transistoren Industrieunternehmen Geschäftsauflistungen]&lt;br /&gt;
&lt;br /&gt;
[[Category:Bauteile]]&lt;br /&gt;
[[Category:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=LED-Pendellampe&amp;diff=89848</id>
		<title>LED-Pendellampe</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=LED-Pendellampe&amp;diff=89848"/>
		<updated>2015-09-28T08:11:09Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von [http://www.mikrocontroller.net/user/show/mclausen Martin Clausen]&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
Ziel bei diesem Projekt war die helle, gleichmäßige, farbgetreue und blendfreie Beleuchtung eines Wohnzimmer-Tisches. In einer Variante wird die gleiche Elektronik auch in einer Lampe in der Küche verwendet.&lt;br /&gt;
=== Features für den Nutzer ===&lt;br /&gt;
* Bedienung über Tasten &amp;amp; Drehencoder oder per IR-Fernbedienung&lt;br /&gt;
* Behält Dimstufe auch nach Abschalten der Versorgungsspannung&lt;br /&gt;
* Unterstützt Bewegungsmelder, wertet Umgebungshelligkeit aus&lt;br /&gt;
* Anpassung der Helligkeit an Umgebungslicht&lt;br /&gt;
* Temperaturüberwachung der LED&lt;br /&gt;
* RGB-Status-LED&lt;br /&gt;
* Konfigurierbar via Menü&lt;br /&gt;
* Koppelbar mit anderen Lampen&lt;br /&gt;
* LCD optional&lt;br /&gt;
* Leuchtet!&lt;br /&gt;
&lt;br /&gt;
=== Technische Eigenschaften ===&lt;br /&gt;
* MCU &lt;br /&gt;
** NXP 89LPC935, 8051 mit 2-Takt Kern&lt;br /&gt;
** 8k Byte Flash (ca. 6,4k Byte ohne LCD belegt), 768 Byte RAM, 512 Byte EEPROM, ISP&lt;br /&gt;
** 3 Volt, niedriger Stromverbrauch&lt;br /&gt;
** interne Takterzeugung&lt;br /&gt;
* Kommunikation&lt;br /&gt;
** Empfängt IR-Signale gemäß RC5-Protokoll&lt;br /&gt;
* Stromversorgung&lt;br /&gt;
** Dimmbares Osram Konstantstrom-Netzteil mit LEDset&lt;br /&gt;
** Stellt 12V zur Versorgung der Steuerung bereit&lt;br /&gt;
** Standby-Leistungsaufnahme von 1,5W&lt;br /&gt;
** Alternativ Netzteil von Meanwell bietet größeren Dimbereich und eine niedrigere Standby-Leistungsaufnahme&lt;br /&gt;
** Netzteile können per PWM-Signal oder 0-10V Analogsignal gesteuert werden (Bestückungsoptionen)&lt;br /&gt;
&lt;br /&gt;
* LEDs&lt;br /&gt;
** Nichia NS6W183 mit CRI90+ auf Streifen-Alu-Kern-Platinen&lt;br /&gt;
** Kann nach zu beliebig angepasst werden&lt;br /&gt;
** Überwachung der Temperatur via KTY81-220, bei Überschreitung von ca. 70°C abdimmen, Abschaltung bei 90°C&lt;br /&gt;
&lt;br /&gt;
* Mechanik&lt;br /&gt;
** Konstruktion aus eloxierten Aluminium Profilen&lt;br /&gt;
&lt;br /&gt;
* Software&lt;br /&gt;
** Open Source C für SDCC 3.3&lt;br /&gt;
** Verwendet Stromsparmodi der MCU&lt;br /&gt;
** State-Machines für RC5-Dekodierung&lt;br /&gt;
** LCD per #define aktivierbar&lt;br /&gt;
** Helligkeit wird erst nach einigen Sekunden ohne Bedienvorgang gespeichert, um das EEPROM zu schonen&lt;br /&gt;
** Viele Parameter vom Benutzer konfigurierbar&lt;br /&gt;
&lt;br /&gt;
== Bilder ==&lt;br /&gt;
&lt;br /&gt;
* Bei maximaler und minimaler Leistung&lt;br /&gt;
[[Bild:PendellampeMax.jpg|200px]]&lt;br /&gt;
[[Bild:PendellampeMin.jpg|214px]]&lt;br /&gt;
* Variante als Küchenlampe&lt;br /&gt;
[[Bild:KuechenlampeMax.jpg|200px]]&lt;br /&gt;
[[Bild:KuechenlampeMin.jpg|195px]]&lt;br /&gt;
&lt;br /&gt;
Die Bilder wurden alle bei den gleichen fixen Kamera-Einstellungen aufgenommen. Der effektive dimmbare Bereich liegt zwischen 25 und 100%. Mit dem Netzteil von Meanwell ist ein größer Dim-Bereich möglich.&lt;br /&gt;
Die Küchenlampe ist in der Leistung durch die Kühlmöglichkeiten des verwendeten Aluminium-Profils beschränkt. Die Küchenlampe verwendet zwei LED-Module mit einer Farbtemperatur von 2700K.&lt;br /&gt;
&lt;br /&gt;
== Beschreibung ==&lt;br /&gt;
&lt;br /&gt;
=== Bedienung ===&lt;br /&gt;
&lt;br /&gt;
Mit einem kurzem Tastendruck wird zwischen Standby und Betrieb gewechselt. Ein langer Tastendruck aktiviert das Optionsmenü, bzw. verlässt dieses wieder. Bei einem sehr langen Tastendruck wird der Tastendruck ignoriert.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Hauptmenü&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Funktion || Status-LED || Erklärung&lt;br /&gt;
|-&lt;br /&gt;
| Standby || rot || LED nicht bestromt, IR-Signale, Umgebungshelligkeit und Bewegungsmelder werden ausgewertet&lt;br /&gt;
|-&lt;br /&gt;
| Betrieb || weiß || LED bestromt, IR-Signale und Temperatur werden ausgewertet&lt;br /&gt;
|-&lt;br /&gt;
| Betrieb || rot aufblinkend || minimale Helligkeit erreicht&lt;br /&gt;
|-&lt;br /&gt;
| Betrieb || grün aufblinkend || maximale Helligkeit erreicht&lt;br /&gt;
|-&lt;br /&gt;
| Optionsmenü || blau, blinkend || Wahl der Option über Drehencoder und Taste&lt;br /&gt;
|-&lt;br /&gt;
| Tastendruck ignorieren || grün || Tastendruck wird nach dem loslassen ignoriert&lt;br /&gt;
|-&lt;br /&gt;
| Übertemperatur || weiß / rot, blinkend || Temperatur der LED erhöht, Leistung reduziert&lt;br /&gt;
|-&lt;br /&gt;
| Übertemperatur || rot, blinkend || Temperatur der LED zu hoch, Abschaltung&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Im Optionsmenü wird die Option durch die Anzahl der blauen Blitze der Status-LED angezeigt. Bei der Wahl eines Menüpunktes durch Tastendruck, gibt die Status-LED durch ihre Farbe die Einstellung der Option wieder.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Optionsmenü&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Nr. || Funktion || Status-LED || Erklärung&lt;br /&gt;
|-&lt;br /&gt;
| 0 || Min. Light || wechselt Farbe nach Wert || minimale Helligkeit beim Einschalten der LED&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Offset Light || wechselt Farbe nach Wert || minimales Ausgangssignal, ab dem das Netzteil anfängt die LED zu bestromen, wird auf das Netzteil eingestellt&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Light Alarm || wechselt Farbe nach Wert || maximale Helligkeit der LED beim Ende eines Alarms&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Detector Timeout || wechselt Farbe nach Wert || Zeit in Minuten nach der die LED nach der Detektion einer Bewegung ausgeschaltet wird, der Wert null schaltet den Bewegungsmelder ab.&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Det.Bright.Limit || wechselt Farbe nach Wert || maximale Helligkeit, bei der der Bewegungsmelder noch aktiv ist&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Set RC Address || wechselt Farbe bei Empfang eines gültigen RC5-Codes || Lernt RC5 Adresse&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Receiver Mode  || wechselt Farbe nach Wert || bestimmt das Zusammenspiel mit anderen Lampen&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Reset settings || wechselt Farbe für Freigabe des Resets || Setzt Steuerung auf Werkseinstellungen zurück&lt;br /&gt;
|-&lt;br /&gt;
| 8 || LCD Contrast || - || nur mit LCD&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Version || - || nur mit LCD&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
&lt;br /&gt;
Die Software besteht aus folgenden Teilen:&lt;br /&gt;
* Hauptschleife&lt;br /&gt;
&lt;br /&gt;
* Interrupt-Routinen&lt;br /&gt;
** RC5 Decoder, ausgelöst durch Timer 0 mit 4,5kHz, mit Software Timer auch Auswertung der Drehencoder bei 500Hz&lt;br /&gt;
** Update PWM-Werte mit 40Hz und Einlesen der Tasten usw., ausgelöst durch Timer aus RTC der MCU bei 10Hz&lt;br /&gt;
&lt;br /&gt;
* Initialisierung der MCU&lt;br /&gt;
** Core Funktionen, hauptsächliche Stromsparfunktionen&lt;br /&gt;
** I/O Pins&lt;br /&gt;
** Interne RTC als 40Hz Taktgeber: 6*10^6/4/128/40&lt;br /&gt;
** Watchdog wird abgeschaltet&lt;br /&gt;
** ADC fixed channel, single conversion mode für ADC0&lt;br /&gt;
** DAC&lt;br /&gt;
** CCU output compare: non-inverted PWM, PLL: auf Lock-in abwarten&lt;br /&gt;
** Interrupts freischalten&lt;br /&gt;
&lt;br /&gt;
* RC5 Decoder&lt;br /&gt;
Der RC5 Decoder beruht auf einer State-Machine, die schrittweise die einzelnen Bits erkennt und dann in Adresse und Daten zerlegt. Nach der Erkennung eines kompletten Komandos wird steht rCounter auf dem Wert 12 und das Hauptprogramm beginnt mit der Decodierung (Aufruf &amp;quot;DecodeRemote()&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
* Auswertung Tasten&lt;br /&gt;
Es werden die Tasten entprellt und die Dauer des Tastendrucks wird festgestellt.&lt;br /&gt;
&lt;br /&gt;
* Messung der externen Helligkeit&lt;br /&gt;
Der SFH320 Fototransistor wird über durch die Portpins umschaltbare Vorwiderstände von 3V aus bestromt. Mittels ADC wird dann der Spannungsabfall über dem Fototransistor gemessen. Am Bereichsende des ADC wird dann entsprechend auf den größeren oder kleiner Vorwiderstand umgeschaltet. Die Portpins wechseln für die Umschaltung zwischen Open-Drain und Push-Pull. Der Ausgabewert ist immer 1. Die Messwerte werden entsprechend ihrem Bereich gewichtet und durchlaufen einen exponentiellen Mittelwert-Filter.&lt;br /&gt;
Da der DAC des ADCs für die Helligkeitsmessung für die Ausgabe des Analogsignals an das Netzteil verwendet wird, ist eine Helligkeitsmessung nur im Standby möglich.&lt;br /&gt;
Beim Einschalten erfolgt zunächst eine Helligkeitsmessung bevor die LED bestromt wird, um den Strom entsprechend der Umgebungshelligkeit anzupassen.&lt;br /&gt;
Der Fototransistor muss gegen das Licht der Status-LED geschirmt werden.&lt;br /&gt;
&lt;br /&gt;
* Bewegungsmelder&lt;br /&gt;
Wenn der Eingang Bewegungsmelder aktiviert ist und die Helligkeit unter der eingestellten Schwelle liegt, kann durch ein Pegel von 0V am Pin 1.3 für die zuvor eingestellte Zeit, die LED aktiviert werden.&lt;br /&gt;
&lt;br /&gt;
* Temperaturüberwachung&lt;br /&gt;
Die Temperatur wird vom OPV für den ADC in den Bereich zwischen 25°C und 125°C skaliert. Mit 10Hz werden die Werte digitalisiert und dann stark gefiltert. Jeden Zyklus wird geprüft, ob die Temperatur niedrig ist (LED wird nach Helligkeitseinstellung bestromt), über der ersten Schwelle liegt (LED wird weniger als nach nach Helligkeitseinstellung bestromt) oder über der zweiten Schwelle liegt (LED wird abgeschaltet). Nach einer temperaturbedingten Abschaltung wird erst nach dem Unterschreiten der ersten Schwelle wieder eingeschaltet. Während dessen blinkt die Status-LED rot.&lt;br /&gt;
&lt;br /&gt;
=== Elektronik ===&lt;br /&gt;
&lt;br /&gt;
Die Stromversorgung der LED-Kette erfolgt über ein steuerbares Konstantstrom-Netzteil vom Typ Osram OT 45/220-240/700 LTCS ( [http://www.distrelec.de distrelec] , 46,05€). Es bietet eine maximale Ausgangsleistung von 45W und eine maximale Ausgangsspannung von 120V. Je nach Ausgangsspannung werden maximal 350mA (120V) bis 700mA (64V) geliefert. Das Netzteil wird dafür per DIP-Schalter konfiguriert. Zusätzlich gibt es einen LEDset Anschluss, der zur Versorgung von externen Komponenten 12V bei max. 50mA und einen analogen 0-10V Steuereingang bietet.&lt;br /&gt;
Negativ fallen der minimale Laststrom von 100mA und der Standby-Verbrauch von 1,5W auf.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann das LED-Netzteil LCM-60 (60W, 2-90V) oder LCM-40 (40W, 2-100V) von Meanwell ([http://www.reichelt.de Reichelt] , 45,20€ bzw.41,75€) verwendet werden, wenn man sich auf auf 2 LED-Module beschränkt. Diese können dann im Strom auch komplett von 0 bis 100% gesteuert werden. Dies kann auch per 10V PWM Signal erfolgen (also nicht direkt vom Mikrocontroller!). Das Netzteil bietet zusätzlich einen Anschluss zur Temperaturüberwachung per NTC. Der Standby-Verbrauch beträgt weniger als 1W.&lt;br /&gt;
&lt;br /&gt;
Die Steuerung gruppiert sich um eine MCU von NXP der 8051 Serie. Das Steuersignal wird per PWM mit der CCU (0/Ub PWM Signal) oder per DAC (0-10V) erzeugt. Das kärgliche On-Chip der klassischen 8051 hat NXP um 512 Byte aufgebessert, was die Programmierung mit dem SDCC erleichtert. Die Einstellungen werden im internen EEPROM abgelegt. Der interne Takt ist für RC5-Dekoder und PWM-Erzeugung ausreichend.&lt;br /&gt;
Die Software sollte auch einfach auf einen Atmel AVR o.ä. portiert werden können.&lt;br /&gt;
&lt;br /&gt;
Die MCU und der IR-Empfänger werden durch einen sparsamen Linearspannungsregler mit 3,0V oder 3,3Vversorgt. LP2951-3.X oder LP2950-3.X vertragen die 12V Eingangsspannung leicht. Sie sind jedoch nur mit Tanal-Kondensator am Ausgang zu betreiben. Die Nachbauten von Taiwan Semiconductor (TS295X-3.X) funktionieren auch mit Keramikkondensatoren. Je nach Betriebsspannung muss die Verstärkung des Analogausgangs angepasst werden.&lt;br /&gt;
&lt;br /&gt;
Das Ausgangssignal des DAC wird von einem OPV verstärkt, um den Signalhub bis 10V zu erreichen. Der Ausgang des OPV muss von vom LEDset Ausgang mittels 270 Ohm entkoppelt werden, sonst flackern die LEDs.&lt;br /&gt;
Das PWM-Signal wird mittels eines NPN-Transistors auf Betriebsspannungs-Niveau gehoben.&lt;br /&gt;
Je nach Anforderung sollte nur &#039;&#039;&#039;eine&#039;&#039;&#039; Variante also PWM &#039;&#039;&#039;oder&#039;&#039;&#039; analog Steuerung bestückt werden.&lt;br /&gt;
&lt;br /&gt;
Die Steuerplatine trägt eine 5*2 polige Pfostenleiste, diese dient primär zur Programmierung der MCU, kann aber auch für Erweiterungen verwendet werden.&lt;br /&gt;
Statt auf einer geätzten Platine, lässt sich die Schaltung aber auch leicht auf einer Lochrasterplatine aufbauen, wenn man noch einer &amp;quot;sockelbaren&amp;quot; MCU im PLCC habhaft werden kann (oder die Portierung auf eine andere MCU durchführt).&lt;br /&gt;
&lt;br /&gt;
Die MCU wird mit der kostenlosen Software [http://www.flashmagictool.com/ FlashMagic] und einer [http://www.keil.com/mcb900/mcb900-schematics.pdf Schaltung von Keil] über RS232 geflasht. Bei der Inbetriebnahme müssen folgende Punkte beachtet werden:&lt;br /&gt;
* Die Kondensatoren auf der Steuerungsplatine müssen schnell genug entladen werden können, damit die MCU beim Start in den Programmiermodus gebracht werden kann. Eine zusätzliche Last von z.B. 100 Ohm über die Betriebsspannung hilft.&lt;br /&gt;
* Es muss keine &amp;quot;echte&amp;quot; RS232 Schnittstelle sein. Ein USB-RS232 Adapter mit FTDI-Chip funktioniert bei mir auch.&lt;br /&gt;
* Einstellungen Flash Magic:&lt;br /&gt;
** Select: 89LPC936 oder 89LPC935 je nach Chip&lt;br /&gt;
** Baud Rate: 7200&lt;br /&gt;
** Interface: None (ISP)&lt;br /&gt;
** Oscillator (MHz): 7,373&lt;br /&gt;
** Erase block used by Hex File&lt;br /&gt;
* Die Device Configuration wird wie folgt geschrieben: interner Oszillator, Rest-Pin aus, Brown-out an&lt;br /&gt;
&lt;br /&gt;
Nach der Programmierung der MCU muss diese im Optionsmenü unbedingt auf Werkseinstellungen zurückgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
=== Optoelektronik ===&lt;br /&gt;
&lt;br /&gt;
Die Auswahl der LEDs wird primär von den Wünschen nach der Lichtwirkung bestimmt. Es wurden 3 LED-Leisten Typ &amp;quot;PowerBar LED Leiste, 12 Nichia LEDs, CRI 90+&amp;quot; von [http://www.leds.de/LED-Leisten-Module/High-Power-LED-Leisten/PowerBar-LED-Leiste-12-Nichia-LEDs-CRI-90.html Leds.de] in das Leuchtenprofil sorgfältig eingeklebt (WK 709-5ML, [http://www.reichelt.de Reichelt]). Die kalte Variante ist mit 6500K wirklich recht kühl, die meisten werden die Variante mit 2700K bevorzugen.&lt;br /&gt;
&lt;br /&gt;
Kosten ca. 75€ + Kleber&lt;br /&gt;
&lt;br /&gt;
=== Mechanik ===&lt;br /&gt;
Bei einer Lampe ist natürlich das Design eine wichtiges Merkmal. Ich bevorzuge ein klares einfaches Design und Materialien wie Glas und eloxiertes Aluminium. Die verwendeten Profile ermöglichen es die Kabel und die Leistungselektronik im Inneren zu verstecken. Zwei IR-Empfänger &amp;quot;schauen&amp;quot; aus den Enden des Vierkant-Rohres nach RC5-Signalen.&lt;br /&gt;
Das Alu-Leuchtenprofil gibt es mit opaler oder klarer Abdeckung. Die opale schluckt deutlich Licht, was jedoch genug vorhanden ist, belohnt aber mit gleichmäßiger, blendfreier Beleuchtung.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Mechanik&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Anzahl || Länge || Bezeichnung || Preis&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 850mm || Alu-Leuchtenprofil 80mm breit, Abdeckung opal oder klar, Nr. 9458020, [http://www.pur-led.de/LED-Aluminiumprofile/LED-Alu-U-Profile/LED-Aluminium-U-Profil-80mm-silber-eloxiert-mit-Abdeckung.html pur-led] || 99,75€ mit Zuschnitt&lt;br /&gt;
|-&lt;br /&gt;
| 2 || - || Abdeckkappen, Nr. 94580201, [http://www.pur-led.de/LED-Aluminium-Profile/LED-Alu-Zubehoer/LED-Endkappe-fuer-LED-Aluminium-U-Profil-Wide-15x23mm-ohne-Kabeldurchgang.html pur-led] || 19,98€&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 160mm x 22,0mm || Profil-Gehäusehalbschale, KOH-2160, [http://www.reichelt.de Reichelt] || 6,70€&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 160mm x 42,4mm || Profil-Gehäusehalbschale, KOH-6160, [http://www.reichelt.de Reichelt] || 8,45€&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 105mm x 64,4mm || Deckelsatz für Profil-Gehäusehalbschale, DPL 2-6, [http://www.reichelt.de Reichelt] || 7,75€&lt;br /&gt;
|-&lt;br /&gt;
| 8 || - || Kabelzugentlastungschelle, KAZU 0440, [http://www.reichelt.de Reichelt] || 0,36€&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 850mm || Alu-Vierkantrohr 25mmx25mm, eloxiert, aus dem Baumarkt ||&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 4m || Leitung für Halogenseilsysteme mit transparenter Isolierung, aus dem Baumarkt || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Ein 3D-Model für FreeCAD befindet sich weiter unten.&lt;br /&gt;
&lt;br /&gt;
2D-Zeichnungen auf Anfrage per PM bei [http://www.mikrocontroller.net/user/show/mclausen Martin Clausen]&lt;br /&gt;
&lt;br /&gt;
== Downloads ==&lt;br /&gt;
&lt;br /&gt;
* [[Datei:LED-Pendellampe.zip]] Schaltpläne und Layout als Eagle Dateien, hex-File, 3D-Model für FreeCAD&lt;br /&gt;
** Es sind noch Platinen und MCU vorhanden, bitte bei Interesse beim Autor melden!&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/nachttischlampe/branch/Lampensteuerung Link zum SVN Repository für Software]&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Nachttischlampe]]&lt;br /&gt;
* [[Wake-Up Light]]&lt;br /&gt;
* [[LED]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Projekte]]&lt;br /&gt;
[[Kategorie:8051]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR_Transistortester&amp;diff=89593</id>
		<title>AVR Transistortester</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR_Transistortester&amp;diff=89593"/>
		<updated>2015-08-20T06:57:57Z</updated>

		<summary type="html">&lt;p&gt;Maybee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Original Entwurf: http://www.mikrocontroller.net/articles/AVR-Transistortester&lt;br /&gt;
&lt;br /&gt;
Weiterentwickelt von Karl-Heinz Kübbeler&lt;br /&gt;
&lt;br /&gt;
Ich habe das Transistortester Projekt von Markus Frejek weitergeführt und speziell die Software weiterentwickelt.&lt;br /&gt;
Aufgrund der verbesserten Eigenschaften wurde schon der Name Komponententester vorgeschlagen. Ich selbst sehe aber immer noch die herausragende Eigenschaft in der automatischen Bestimmung von Transistortyp und Eigenschaft, wie sie von&lt;br /&gt;
Markus Frejek entwickelt wurde.&lt;br /&gt;
&lt;br /&gt;
Hier möchte ich die wichtigsten &#039;&#039;&#039;Eigenschaften&#039;&#039;&#039; aufführen&lt;br /&gt;
&lt;br /&gt;
* Arbeitet mit ATmega8, ATmega168 und ATmega328 Prozessoren.&lt;br /&gt;
* Anzeige der Meßergebnisse auf ein 2x16 Zeichen LCD.&lt;br /&gt;
* Statt dem 2x16 Zeichen LCD kann auch ein graphisches Display mit ST7565 Controller benutzt werden. Auch ein Anschluß eines OLED Display mit SSD1306 Controller ist mit SPI oder I2C Schnittstelle möglich.&lt;br /&gt;
* Ein-Tastenbedienung mit automatischer Abschaltung.&lt;br /&gt;
* Das Gerät besitzt drei universelle Meßports (Test Pin).&lt;br /&gt;
* Automatische Erkennung von NPN, PNP, N- und P-Kanal MOSFET, JFET, Dioden und Kleinsignal Thyristor und TRIAC.&lt;br /&gt;
* Automatische Erkennung der Pin-Belegung der Bauteile, die Bauelemente können beliebig angeschlossen werden.&lt;br /&gt;
* Messung des Stromverstärkungsfaktors und der Basis-Emitter Spannung für bipolare Transistoren, auch für Darlingtontransistoren.&lt;br /&gt;
* Automatische Erkennung eine Schutzdiode für bipolare Transistoren und MOSFETs.&lt;br /&gt;
* Bei bipolaren Transistoren mit Schutzdiode wird ein parasitärer Transistor erkannt (NPNp = NPN + parasitär PNP).&lt;br /&gt;
* Bis zu zwei Widerstände werden in einer Messung mit einer Auflösung von bis zu 0,1 Ohm gemessen, wobei der Meßbereich bis über 50 MOhm reicht. Widerstandswerte unter 10 Ohm werden für den ATmega168/328 mit der ESR-Meßmethode mit einer Auflösung von 0.01 Ohm angezeigt.&lt;br /&gt;
* Ein angeschlossener Kondensator kann gemessen werden im Bereich 35pF bis 100mF mit einer Auflösung von bis zu 1 pF.&lt;br /&gt;
* Widerstände und Kondensatoren werden mit ihren Symbolen dargestellt, umgeben von den gefundenen Anschlußpin Nummern.&lt;br /&gt;
* Die Widerstands und Kondensator-Werte werden mit bis zu vier Dezimalstellen in der richtigen Dimension angezeigt.&lt;br /&gt;
* Bis zu zwei Dioden werden ebenfalls mit ihrer Symboldarstellung flußrichtungsrichtig angezeigt, umgeben von den Anschlußpin Nummern und der zusätzlichen Angabe der Flußspannung.&lt;br /&gt;
* Bei einzelnen Dioden wird zusätzlich der Kapazitätswert und ab Version 1.08k auch der Strom in Sperr-Richtung gemessen.&lt;br /&gt;
* Für ATmega168/328 ist eine Kalibration der Nullkapazität, des Nullwiderstandes und weiterer Parameter im Selbsttest-Zweig möglich.&lt;br /&gt;
* Für ATmega168/328 können auch Induktivitäten von etwa 0.01mH bis über 20H erkannt und gemessen werden.&lt;br /&gt;
* Für ATmega168/328 ist eine ESR-Messung (Equivalent Series Resistance) für Kondensatoren über 90 nF mit einer Auflösung von 0.01 Ohm integriert.&lt;br /&gt;
* für ATmega168/328 wird für Kondensatoren über 5 nF der Spannungsverlust Vloss nach einem Ladepuls untersucht. Damit läßt sich die Güte der Kondensatoren abschätzen.&lt;br /&gt;
* für ATmega328 sind mit einer Menüfunktion, die mit einem längeren Tastendruck (&amp;gt; 0.5 s) aufgerufen werden kann, weitere Funktionen aus einer Liste möglich. Ein kurzer Tastendruck zeigt die nächste Funktion. Ein längerer Tastendruck startet die angezeigte Funktion. Nachfolgend die Liste der bisher eingebauten Zusatzfunktionen:&lt;br /&gt;
** Frequenzmessung an dem PD4 Pin, der aber auch für den LCD-Anschluß benutzt wird. Der Pin wird für die Messung auf Eingang umgeschaltet. Die anliegende Frequenz wird zunächst für 1 Sekunde ausgezählt. Wenn die Frequenz unter 25 kHz liegt, wird auch eine mittlere Periode gemessen und daraus eine Frequenz berechnet mit einer Auflösung von bis zu 0.001 mHz.&lt;br /&gt;
** Spannungsmessung am PC3 Pin, wenn dieser nicht für die serielle Ausgabe benutzt wird. Bei ATmega328 mit 32 Pins (PLCC) kann aber auch der ADC6 oder ADC7 Pin benutzt werden. Da ein 10:1 Teiler am Eingang benutzt wird, können Spannungen bis zu 50V gemessen werden. Mit einer Erweiterung der Schaltung (DC-DC Konverter) können auch Zenerdioden gemessen werden.&lt;br /&gt;
** Frequenzerzeugung am TP2 Port. Über den am PB2 Pin angeschlossenen 680 Ohm Widerstand kann ein Signal mit einer aus einer Liste einstellbaren Frequenz von 1 Hz bis 2 MHz am TP2 Port ausgegeben werden. Der TP1 Port ist dabei auf Masse geschaltet.&lt;br /&gt;
** Pulsweitenmodulation mit fester Frequenz und einstellbarer Pulsweite auf dem TP2 Port. Der Zähler 1 wird für diese Funktion als 10-Bit Zähler benutzt. Der TP1 Port ist auf Masse geschaltet. Die Pulsweite kann durch kurzen Tastendruck um 1% und durch längeren Tastendruck um 10% erhöht werden.&lt;br /&gt;
** Mit einer separaten Kapazitäts- und ESR-Messung können an TP1 und TP3 angeschlossene Kondensatoren mit einer Kapazität von etwa 2µF bis 50mF meist auch in der Schaltung gemessen werden. Hierbei sollte aber immer sichergestellt sein, daß die Kondensatoren keine Restladung mehr haben.&lt;br /&gt;
&lt;br /&gt;
Die zusätzlichen Funktionen sind zeitbegrenzt wie die Dialogfunktion selbst auch, wenn die POWER_OFF Option in der Konfigurationsdatei (Makefile) eingeschaltet ist.&lt;br /&gt;
Ausführlichere Informationen mit Meßbeispielen kann man in den pdf-Dokumentationen in deutscher und englischer Sprache nachlesen. Auch russische Übersetzung der Dokumentationen sind verfügbar.&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Software wurde basierend auf der Arbeit von Markus F. weiterentwickelt.&lt;br /&gt;
Der Teil für die Kondensatormessung wurde komplett neu geschrieben und auch die Widerstandsmessung wurde erheblich überarbeitet. Bei Schwierigkeiten und Problemen sollte man mich über E-mail oder über den Diskussionsteil (thread) benachrichtigen.  Nur wenn ich von Problemen weiß, kann ich hoffentlich Abhilfe schaffen.&lt;br /&gt;
&lt;br /&gt;
Weitere Einzelheiten sowie Beschreibung der einzelnen Meßverfahren und Beispiel-Ergebnisse habe ich in der pdf-Dokumentation (deutsche und englische Version) beschrieben. Hier findet man auch Hinweise zum Konfigurieren der Software mit Makefile Parametern und Optionen. &lt;br /&gt;
Die Kommentare im Quellcode sind in englischer Sprache.&lt;br /&gt;
Neu eingebaut in der Software ist eine Selbsttest-Funktion, in der die Funktion des Testers gemessen wird. In diesen Selbsttest ist auch ein Kalibrationsteil integriert.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
&lt;br /&gt;
Im Prinzip ist die neue Software so zu konfigurieren, daß sie auf der bereits von Markus F. vorgestellten Hardware ohne Änderungen läuft.&lt;br /&gt;
&lt;br /&gt;
Sinnvoll sind dennoch einige Änderungen:&lt;br /&gt;
&lt;br /&gt;
* Der Prozessor sollte auf einen 8 MHz Taktfrequenz umgestellt werden, am besten mit einem externen Quarz. Dazu müssen die fuses des ATmega geändert werden.&lt;br /&gt;
* Ein &amp;quot;pull up&amp;quot; Widerstand von etwa 27 kOhm sollte von Pin 13 (PD7) des ATmega nach VCC nachgerüstet werden.&lt;br /&gt;
* Der 100 nF Kondensator am Pin 21 (AREF) kann entweder ganz entfernt werden oder besser durch einen 1 nF Kondensator ersetzt werden.&lt;br /&gt;
* Wenn die elektronische Einschaltung des Testers Probleme macht, sollte wenigstens der C2 Kondensator an der Basis von Transistor T1 auf 10 nF reduziert werden und ggf. auch der Widerstand R7 auf 3,3 kOhm reduziert werden. Das komplette Schaltbild und Einzelheiten dazu findet man in der PDF Dokumentation.&lt;br /&gt;
&lt;br /&gt;
Die Gründe und die Einzelheiten für diese Änderungen sowie weitere Hinweise für einen Neuaufbau sind im Hardware-Kapitel meiner pdf-Dokumentation beschrieben. Empfohlen wird ein ATmega168 Prozessor oder auch ein ATmega328 Prozessor, weil der ADC mit der Autoscale Funktion im Bedarfsfall von der 5V Referenz (VCC) auf die interne Referenz-Spannung umgeschaltet wird. Die interne Referenz hat für der ATmega8 eine Spannung von 2,56V, für die anderen Prozessoren aber 1,1 Volt. Mit 1,1 V kann eine bessere Auflösung des ADC für gemessene Spannungen unter 1 Volt erreicht werden.&lt;br /&gt;
Man kann den ATmega8 ohne Hardwareänderung gegen einen ATmega168 oder ATmega328 austauschen!&lt;br /&gt;
Hier ist der Teil der Schaltung, der für die Messung erforderlich ist.&lt;br /&gt;
Die Elektronik für die Batterieversorgung und die automatische Abschaltung fehlt in diesem Schaltbild.[[Datei:TransistorTesterVC1.png|miniatur|Schaltbild ohne Stromversorgung]]&lt;br /&gt;
&lt;br /&gt;
Die rot markierten Bauteile sind nicht unbedingt erforderlich, können aber zu einer Verbesserung der Messgenauigkeit beitragen. Die grün markierten Bauteile sind gegenüber dem ersten Entwurf von Markus F. geändert.&lt;br /&gt;
Die Eagle Dateien von Asko B. für drei Varianten sind im Thread zu finden bei der Adresse: http://www.mikrocontroller.net/topic/248078?page=4#2891344&lt;br /&gt;
&lt;br /&gt;
Hier ist der Artikel der 1. Transistortester Version von Markus F. zu finden: [[AVR-Transistortester]]&lt;br /&gt;
&lt;br /&gt;
== Diskussionen zur neuen Version ==&lt;br /&gt;
Der Thread mit meinen älteren Software-Versionen und einigen Problemfällen sowie Hardware-Vorschlägen ist unter [https://www.mikrocontroller.net/topic/248078#new https://www.mikrocontroller.net/topic/248078#new] zu finden.&lt;br /&gt;
&lt;br /&gt;
== Downloads (deutsch) ==&lt;br /&gt;
Alle Versionen von der Software und der Doku sind im SVN gespeichert.&lt;br /&gt;
&lt;br /&gt;
[[Media:ttinfo_ger111k.pdf|Kurzbeschreibung (deutsch) Version 1.11k (2015-01-30)]]&lt;br /&gt;
&lt;br /&gt;
[[Media:ttester_ger111k.pdf|Anleitung (deutsch) Version 1.11k (2015-02-08)]]&lt;br /&gt;
&lt;br /&gt;
Die Benutzer können über den svnbrowser [https://www.mikrocontroller.net/svnbrowser/transistortester/ https://www.mikrocontroller.net/svnbrowser/transistortester/] das gewählte Verzeichnis als &amp;quot;GNU tarball&amp;quot; runterladen.&lt;br /&gt;
Beim Aufruf des svnbrowsers steht dazu unter der Datei/Verzeichnis Liste der Eintrag &amp;quot;Download GNU tarball&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Zum Auspacken der heruntergeladenen transistortester*.tar.gz Datei benötigen Windows Benutzer eine geeignete Software wie das Freeware Paket [http://www.7-zip.org/ 7-Zip].&lt;br /&gt;
Nach dem Auspacken hat man den vorher mit dem svnbrowser ausgewählten Verzeichnisbaum auf seinem eigenen Rechner.&lt;br /&gt;
Ein direkter Zugriff auf die Dateien mit dem svnbrowser ist nicht möglich!&lt;br /&gt;
&lt;br /&gt;
Eine andere Methode auf den Inhalt des svn Archivs zuzugreifen besteht mit der Installation des TortoiseSVN Plugins für den Windows Explorer.&lt;br /&gt;
Damit ist dann der Zugriff über [svn://mikrocontroller.net/transistortester svn://mikrocontroller.net/transistortester] direkt auf das Archiv mit dem Browser möglich.&lt;br /&gt;
&lt;br /&gt;
Linux Benutzer können auch direkt über svn auf das Archiv zugreifen.&lt;br /&gt;
&lt;br /&gt;
== Downloads (russisch) - Загрузки (русский) ==&lt;br /&gt;
Для загрузок доступны все версии программного обеспечения и документации, хранящиеся в SVN&lt;br /&gt;
&lt;br /&gt;
[[Media:ttinfo_rus111k.pdf|краткое описание (русский) Версия 1.11k (2015-01-11)]]&lt;br /&gt;
&lt;br /&gt;
[[Media:ttester_rus111k.pdf|инструкции (русский) Версия 1.11k (2015-02-07)]]&lt;br /&gt;
&lt;br /&gt;
Пользователь может загрузить выбранный каталог в качестве &amp;quot;GNU архива&amp;quot; через svnbrowser [https://www.mikrocontroller.net/svnbrowser/transistortester/ https://www.mikrocontroller.net/svnbrowser/transistortester/].&lt;br /&gt;
&lt;br /&gt;
При вызове svnbrowsers, смотрите в список файлов / каталогов, запись &amp;quot;Скачать GNU архив&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для распаковки загруженного файла * .tar.gz пользователи Windows могут воспользоваться любым подходящим программным обеспечением, таким как бесплатная программа [http://www.7-zip.org/ 7-Zip].&lt;br /&gt;
&lt;br /&gt;
После распаковки архива у вас на компьютере будет архив с заранее выбранным через svnbrowser содержимым в дереве каталогов.&lt;br /&gt;
&lt;br /&gt;
Прямой доступ к файлам через svnbrowser не возможен!&lt;br /&gt;
&lt;br /&gt;
Еще один способ получить доступ к содержимому хранилища SVN состоит в установке TortoiseSVN плагина для Windows Explorer. Это затем кнопкой [svn://mikrocontroller.net/transistortester svn://mikrocontroller.net/transistortester] прямо в вашем архиве, используя браузер.&lt;br /&gt;
&lt;br /&gt;
Пользователи Linux могут получить доступ непосредственно из SVN к архиву.&lt;br /&gt;
&lt;br /&gt;
== Downloads (english) ==&lt;br /&gt;
All versions of the software and documentation are saved in the SVN archive.&lt;br /&gt;
&lt;br /&gt;
[[Media:ttinfo_eng111k.pdf|Short description (english) Version 1.11k (2015-01-05)]]&lt;br /&gt;
&lt;br /&gt;
[[Media:ttester_eng111k.pdf|Manual (english) Version 1.11k (2015-02-08)]]&lt;br /&gt;
&lt;br /&gt;
Users can download a &amp;quot;GNU tarball&amp;quot; of the previous selected directory with the svnbrowser [https://www.mikrocontroller.net/svnbrowser/transistortester/ https://www.mikrocontroller.net/svnbrowser/transistortester/].&lt;br /&gt;
&lt;br /&gt;
Windows users need a additional tool like the freeware [http://www.7-zip.org/ 7-Zip] to unpack the downloaded transistortester*.tar.gz file.&lt;br /&gt;
After unpacking you have a copy of the selected directory at your own computer.&lt;br /&gt;
The direct access is not possible with the svnbrowser!&lt;br /&gt;
&lt;br /&gt;
Another way to get access to the SVN data is to install the TortoiseSVN plugin for the windows explorer. After installing you can access the data with [svn://mikrocontroller.net/transistortester svn://mikrocontroller.net/transistortester].&lt;br /&gt;
&lt;br /&gt;
Linux users can also access the data with svn directly.&lt;br /&gt;
&lt;br /&gt;
== Downloads (Português - Brasil) ==&lt;br /&gt;
&lt;br /&gt;
Todas as versões de software e documentação estão salvas no arquivador SVN.&lt;br /&gt;
&lt;br /&gt;
Usuários podem descarregar um pacote &amp;quot;GNU&amp;quot; de todos os diretórios anteriores com o svnbrowser [https://www.mikrocontroller.net/svnbrowser/transistortester/ https://www.mikrocontroller.net/svnbrowser/transistortester/].&lt;br /&gt;
&lt;br /&gt;
Usuários de Windows precisam de uma ferramenta adicional como o freeware [http://www.7-zip.org/ 7-Zip] para descompactar o arquivo transistortester*.tar.gz. Depois de descompactado você terá uma cópia do diretório selecionado no seu computador. O acesso direto não é possível com o svnbrowser!&lt;br /&gt;
&lt;br /&gt;
Outra forma de acessar os dados no SVN é instalar o TortoiseSVN plugin para Windows Exporer. Depois de instalar você pode acessar soa dados com o endereçco [svn://mikrocontroller.net/transistortester svn://mikrocontroller.net/transistortester].&lt;br /&gt;
&lt;br /&gt;
Usuários Linux podem acessar os dados com svn diretamente.&lt;br /&gt;
&lt;br /&gt;
== Downloads (Español) ==&lt;br /&gt;
Todas la versiones del software y la documentación están en SVN.&lt;br /&gt;
&lt;br /&gt;
Los usuarios pueden descargar un &amp;quot;GNU tarball&amp;quot; del directorio seleccionado utlizando svnbrowser [https://www.mikrocontroller.net/svnbrowser/transistortester/ https://www.mikrocontroller.net/svnbrowser/transistortester/]&lt;br /&gt;
&lt;br /&gt;
Los usuarios de Windows requieren de una herramienta adicional como el freeware [http://www.7-zip.org/ 7-Zip] (gratis) para desempacar el archivo descargado, transistortester*.tar.gz.&lt;br /&gt;
&lt;br /&gt;
Luego de desempacar el archivo, tendrá en su computador una copia completa del directorio seleccionado.&lt;br /&gt;
Acceso directo no es posible con svnbrowser.&lt;br /&gt;
&lt;br /&gt;
La otra manera de accesar el respositorio SVN es instalando el plugin TortoiseSVN; éste le permitirá acceso a la información con el URI: [svn://mikrocontroller.net/transistortester svn://mikrocontroller.net/transistortester]&lt;br /&gt;
&lt;br /&gt;
Los usuarios de Linux pueden, por supuesto, accesar SVN directamente.&lt;br /&gt;
&lt;br /&gt;
== Downloads (Slovak) ==&lt;br /&gt;
&lt;br /&gt;
Všetky verzie softvéru a dokumentácie sú uložené v SVN archíve.&lt;br /&gt;
&lt;br /&gt;
Prostredníctvom &#039;&#039;svnbrowsera&#039;&#039;, ktorý sa nachádza na adrese [https://www.mikrocontroller.net/svnbrowser/transistortester/ https://www.mikrocontroller.net/svnbrowser/transistortester/] je možné kliknutím na odkaz &#039;&#039;&amp;quot;Download GNU tarball&amp;quot;&#039;&#039; stiahnuť kompletný obsah aktuálne zobrazeného adresára.&lt;br /&gt;
&lt;br /&gt;
Na rozbalenie stiahnutého súboru &#039;&#039;transistortester*.tar.gz&#039;&#039; pod systémom Windows je možné použiť bezplatný software &#039;&#039;[http://www.7-zip.org/ 7-Zip]&#039;&#039;. Po extrahovaní je na lokálnom PC k dispozícii kópia vybraného adresára. Priamy prístup k jednotlivým súborom SVN archívu cez &#039;&#039;svnbrowser&#039;&#039; nie je možný!&lt;br /&gt;
&lt;br /&gt;
Alternatívnym spôsobom prístupu k SVN archívu je inštalácia a použitie pluginu &#039;&#039;TortoiseSVN&#039;&#039; pre Windows Explorer. Potom je možné pristupovať k dátam prostredníctvom odkazu [svn://mikrocontroller.net/transistortester svn://mikrocontroller.net/transistortester].&lt;br /&gt;
&lt;br /&gt;
Užívatelia systému Linux môžu k SVN dátam pristupovať priamo.&lt;br /&gt;
&lt;br /&gt;
== Downloads (your-language) ==&lt;br /&gt;
You can put a translation &#039;&#039;here&#039;&#039;, but only if its done by yourself, not Google Translate.&lt;br /&gt;
You can also put a translation of the whole article here, if its done by yourself.&lt;br /&gt;
&lt;br /&gt;
Only little understanding of the Wiki-Syntax is needed therefore.&lt;br /&gt;
&lt;br /&gt;
== Verzeichnisstruktur des SVN ==&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; style=&amp;quot;border-collapse:collapse&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Ordnerstruktur und Beschreibung der  &#039;&#039;Pfade&#039;&#039; im SVN&#039;&#039;&#039;&lt;br /&gt;
|- style=&amp;quot;background-color:#B3B7FF&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; colspan=&amp;quot;2&amp;quot; | &#039;&#039;&#039;Ordner/directory&#039;&#039;&#039; || &#039;&#039;&#039;Dateien/files&#039;&#039;&#039; || &#039;&#039;&#039;Beschreibung/description&#039;&#039;&#039;&lt;br /&gt;
|-   style=&amp;quot;background-color:#B9FFC5&amp;quot;&lt;br /&gt;
| &#039;&#039;&#039;Doku&#039;&#039;&#039; || || || Enthält die Dokumentation als PDF und als pdflatex-Quelltext&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk&#039;&#039;&#039; || || Letzter Entwicklungsstand der Dokumentation inclusive Bilder und Diagrammen&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/pdftex/german&#039;&#039;&#039; || || enthält die deutschen Texte, Makefile und PDF-Dokumentation der Entwicklerversion&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/pdftex/english&#039;&#039;&#039; || || contains the English text, Makefile and PDF documentation of the developer version&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/pdftex/russian&#039;&#039;&#039; || || contains the Russian text, Makefile and PDF documentation of the developer version&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags&#039;&#039;&#039; ||&#039;&#039;changelog.txt&#039;&#039; || &#039;&#039;Hier sollte jede Änderung mit Versionsnummer eingetragen werden&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/german&#039;&#039;&#039; || || &#039;&#039;Aktuelle PDF Dokumentation in deutsch&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/english&#039;&#039;&#039; || || &#039;&#039;Current PDF documentation in English&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/russian&#039;&#039;&#039; || || &#039;&#039;Current PDF documentation in Russian language&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/old/german&#039;&#039;&#039; || || &#039;&#039;PDF Dokumentationen zu früheren Softwareversionen&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/old/english&#039;&#039;&#039; || || &#039;&#039;PDF documentation for earlier software versions&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
|- style=&amp;quot;background-color:#B9FFC5&amp;quot;&lt;br /&gt;
| &#039;&#039;&#039;Hardware&#039;&#039;&#039; || || || Hardware Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid&#039;&#039;&#039; || || Verzeichnis für eine Streifenleiterplatine&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid/ttester_strip_grid.diy&#039;&#039;&#039; || || Beispiel einer Streifenleiterplatine, DIYLC-Datei&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid/TTester_strip.pdf&#039;&#039;&#039; || || Ergebnis der Streifenleiterplatine im PDF Format&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid/LiesMich.txt&#039;&#039;&#039; || || Kurzdokumentation für Streifenleiter-Platine&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid/ReadMe.txt&#039;&#039;&#039; || || Short documentation for the strip grid board&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;Markus&#039;&#039;&#039; || || Entwurf von Markus R. mit LED-Dimmer im Eagle 6.4.0 Format&lt;br /&gt;
&lt;br /&gt;
|- style=&amp;quot;background-color:#B9FFC5&amp;quot;&lt;br /&gt;
| &#039;&#039;&#039;Software&#039;&#039;&#039; || || || Software für AVR-GCC 4.8.2&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk&#039;&#039;&#039; || || Aktueller Software-Entwicklungszweig&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/default&#039;&#039;&#039; || || Makefile und Programmierdaten für ATmega168 mit Standard-Layout&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega168_1.9V&#039;&#039;&#039; || || Makefile und Daten für ATmega168 mit Knopfzellenbetrieb (FiFi)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega168_3.3V&#039;&#039;&#039; || || Makefile und Daten für ATmega168 mit LiPo-Akkubetrieb (FiFi)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega168_strip_grid&#039;&#039;&#039; || || Makefile und Daten für ATmega168 für Streifenleiter-Platine&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Standard-Layout (ab Version 1.08k)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_1.9V&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Knopfzellenbetrieb (Funkamateur)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_3.3V&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit LiPo-Akkubetrieb (Funkamateur)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_2X16_menu&#039;&#039;&#039; || || Makefile und Daten für ATmega328, 2x16 Zeichen Textdisplay, Impulsdrehgeber + Spannungsmessung&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_dogm&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Standard-Layout, 2x16 Zeichen DOG-M LCD&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_strip_grid&#039;&#039;&#039; || || Makefile und Daten für ATmega328 für Streifenleiter-Platine (ab Version 1.08k)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_strip_grid_dogm&#039;&#039;&#039; || || Makefile und Daten für ATmega328 für Streifenleiter-Platine mit DOG-M Display&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_st7565&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Standard-Layout, 126x64 Pixel LCD, ST7565 Controller&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_st7108&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Standard-Layout, 126x64 Pixel LCD, ST7108 Controller&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_st7920&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Standard-Layout, 126x64 Pixel LCD, ST7920 Controller&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_fish8840&#039;&#039;&#039; || || Makefile und Daten für chinesische Fish8840 Version, ATmega328, 126x64 Pixel LCD, ST7565 Controller&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_wei_st7565&#039;&#039;&#039; || || Makefile und Daten für chinesische WEI_M8_LGTST Version, 126x64 Pixel LCD, ST7565 Controller, LiIon Accu&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_GM328&#039;&#039;&#039; || || Makefile und Daten für chinesische GM328 Version, ATmega328, 126x64 Pixel LCD, ST7565 Controller&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_T3_T4_st7565&#039;&#039;&#039; || || Makefile und Daten für chinesische T3 oder T4 Version, ATmega328, 126x64 Pixel LCD, ST7565 Controller&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_T5_st7565&#039;&#039;&#039; || || Makefile und Daten für chinesische T5 Version, ATmega328, 126x64 Pixel LCD, ST7565 Controller, LiIon Accu&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_ssd1306I2C&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Standard-Layout, 126x64 Pixel OLED, SSD1306 Controller, I2C Schnittstelle&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_ssd1306SPI&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Standard-Layout, 126x64 Pixel OLED, SSD1306 Controller, SPI Schnittstelle&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega644_LCD2004&#039;&#039;&#039; || || Makefile und Daten für ATmega644/1284 mit 4x20 Zeichen LCD&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/arduino_m2560&#039;&#039;&#039; || || Makefile und Daten für Arduino Mega (ATmega2560) mit 2x16 Zeichen LCD &lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega8&#039;&#039;&#039; || || Makefile und Daten für ATmega8. Ab Version 1.00k ist der Selbsttest für den ATmega8 nicht mehr konfigurierbar.&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags&#039;&#039;&#039; || || Fertige Software Versionen als ZIP gepackt&lt;br /&gt;
|-&lt;br /&gt;
| || || &#039;&#039;changelog.txt&#039;&#039; || &#039;&#039;Hier sollte jede Änderung mit Versionsnummer eingetragen werden&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;Markus&#039;&#039;&#039; || || Alternative Software von Markus R., bitte README beachten! Die Software wurde aufgeräumt und ist viel besser strukturiert, läuft aber nur auf einem ATmega168 oder ATmega328. Die Software läuft nur auf dem Standard-Layout.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR_Transistortester&amp;diff=89513</id>
		<title>AVR Transistortester</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR_Transistortester&amp;diff=89513"/>
		<updated>2015-08-12T05:11:47Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Änderung 89503 von 95.244.122.48 (Diskussion) rückgängig gemacht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Original Entwurf: http://www.mikrocontroller.net/articles/AVR-Transistortester&lt;br /&gt;
&lt;br /&gt;
Weiterentwickelt von Karl-Heinz Kübbeler&lt;br /&gt;
&lt;br /&gt;
Ich habe das Transistortester Projekt von Markus Frejek weitergeführt und speziell die Software weiterentwickelt.&lt;br /&gt;
Aufgrund der verbesserten Eigenschaften wurde schon der Name Komponententester vorgeschlagen. Ich selbst sehe aber immer noch die herausragende Eigenschaft in der automatischen Bestimmung von Transistortyp und Eigenschaft, wie sie von&lt;br /&gt;
Markus Frejek entwickelt wurde.&lt;br /&gt;
&lt;br /&gt;
Hier möchte ich die wichtigsten &#039;&#039;&#039;Eigenschaften&#039;&#039;&#039; aufführen&lt;br /&gt;
&lt;br /&gt;
* Arbeitet mit ATmega8, ATmega168 und ATmega328 Prozessoren.&lt;br /&gt;
* Anzeige der Meßergebnisse auf ein 2x16 Zeichen LCD.&lt;br /&gt;
* Statt dem 2x16 Zeichen LCD kann auch ein graphisches Display mit ST7565 Controller benutzt werden. Auch ein Anschluß eines OLED Display mit SSD1306 Controller ist mit SPI oder I2C Schnittstelle möglich.&lt;br /&gt;
* Ein-Tastenbedienung mit automatischer Abschaltung.&lt;br /&gt;
* Das Gerät besitzt drei universelle Meßports (Test Pin).&lt;br /&gt;
* Automatische Erkennung von NPN, PNP, N- und P-Kanal MOSFET, JFET, Dioden und Kleinsignal Thyristor und TRIAC.&lt;br /&gt;
* Automatische Erkennung der Pin-Belegung der Bauteile, die Bauelemente können beliebig angeschlossen werden.&lt;br /&gt;
* Messung des Stromverstärkungsfaktors und der Basis-Emitter Spannung für bipolare Transistoren, auch für Darlingtontransistoren.&lt;br /&gt;
* Automatische Erkennung eine Schutzdiode für bipolare Transistoren und MOSFETs.&lt;br /&gt;
* Bei bipolaren Transistoren mit Schutzdiode wird ein parasitärer Transistor erkannt (NPNp = NPN + parasitär PNP).&lt;br /&gt;
* Bis zu zwei Widerstände werden in einer Messung mit einer Auflösung von bis zu 0,1 Ohm gemessen, wobei der Meßbereich bis über 50 MOhm reicht. Widerstandswerte unter 10 Ohm werden für den ATmega168/328 mit der ESR-Meßmethode mit einer Auflösung von 0.01 Ohm angezeigt.&lt;br /&gt;
* Ein angeschlossener Kondensator kann gemessen werden im Bereich 35pF bis 100mF mit einer Auflösung von bis zu 1 pF.&lt;br /&gt;
* Widerstände und Kondensatoren werden mit ihren Symbolen dargestellt, umgeben von den gefundenen Anschlußpin Nummern.&lt;br /&gt;
* Die Widerstands und Kondensator-Werte werden mit bis zu vier Dezimalstellen in der richtigen Dimension angezeigt.&lt;br /&gt;
* Bis zu zwei Dioden werden ebenfalls mit ihrer Symboldarstellung flußrichtungsrichtig angezeigt, umgeben von den Anschlußpin Nummern und der zusätzlichen Angabe der Flußspannung.&lt;br /&gt;
* Bei einzelnen Dioden wird zusätzlich der Kapazitätswert und ab Version 1.08k auch der Strom in Sperr-Richtung gemessen.&lt;br /&gt;
* Für ATmega168/328 ist eine Kalibration der Nullkapazität, des Nullwiderstandes und weiterer Parameter im Selbsttest-Zweig möglich.&lt;br /&gt;
* Für ATmega168/328 können auch Induktivitäten von etwa 0.01mH bis über 20H erkannt und gemessen werden.&lt;br /&gt;
* Für ATmega168/328 ist eine ESR-Messung (Equivalent Series Resistance) für Kondensatoren über 90 nF mit einer Auflösung von 0.01 Ohm integriert.&lt;br /&gt;
* für ATmega168/328 wird für Kondensatoren über 5 nF der Spannungsverlust Vloss nach einem Ladepuls untersucht. Damit läßt sich die Güte der Kondensatoren abschätzen.&lt;br /&gt;
* für ATmega328 sind mit einer Menüfunktion, die mit einem längeren Tastendruck (&amp;gt; 0.5 s) aufgerufen werden kann, weitere Funktionen aus einer Liste möglich. Ein kurzer Tastendruck zeigt die nächste Funktion. Ein längerer Tastendruck startet die angezeigte Funktion. Nachfolgend die Liste der bisher eingebauten Zusatzfunktionen:&lt;br /&gt;
** Frequenzmessung an dem PD4 Pin, der aber auch für den LCD-Anschluß benutzt wird. Der Pin wird für die Messung auf Eingang umgeschaltet. Die anliegende Frequenz wird zunächst für 1 Sekunde ausgezählt. Wenn die Frequenz unter 25 kHz liegt, wird auch eine mittlere Periode gemessen und daraus eine Frequenz berechnet mit einer Auflösung von bis zu 0.001 mHz.&lt;br /&gt;
** Spannungsmessung am PC3 Pin, wenn dieser nicht für die serielle Ausgabe benutzt wird. Bei ATmega328 mit 32 Pins (PLCC) kann aber auch der ADC6 oder ADC7 Pin benutzt werden. Da ein 10:1 Teiler am Eingang benutzt wird, können Spannungen bis zu 50V gemessen werden. Mit einer Erweiterung der Schaltung (DC-DC Konverter) können auch Zenerdioden gemessen werden.&lt;br /&gt;
** Frequenzerzeugung am TP2 Port. Über den am PB2 Pin angeschlossenen 680 Ohm Widerstand kann ein Signal mit einer aus einer Liste einstellbaren Frequenz von 1 Hz bis 2 MHz am TP2 Port ausgegeben werden. Der TP1 Port ist dabei auf Masse geschaltet.&lt;br /&gt;
** Pulsweitenmodulation mit fester Frequenz und einstellbarer Pulsweite auf dem TP2 Port. Der Zähler 1 wird für diese Funktion als 10-Bit Zähler benutzt. Der TP1 Port ist auf Masse geschaltet. Die Pulsweite kann durch kurzen Tastendruck um 1% und durch längeren Tastendruck um 10% erhöht werden.&lt;br /&gt;
** Mit einer separaten Kapazitäts- und ESR-Messung können an TP1 und TP3 angeschlossene Kondensatoren mit einer Kapazität von etwa 2µF bis 50mF meist auch in der Schaltung gemessen werden. Hierbei sollte aber immer sichergestellt sein, daß die Kondensatoren keine Restladung mehr haben.&lt;br /&gt;
&lt;br /&gt;
Die zusätzlichen Funktionen sind zeitbegrenzt wie die Dialogfunktion selbst auch, wenn die POWER_OFF Option in der Konfigurationsdatei (Makefile) eingeschaltet ist.&lt;br /&gt;
Ausführlichere Informationen mit Meßbeispielen kann man in den pdf-Dokumentationen in deutscher und englischer Sprache nachlesen. Auch russische Übersetzung der Dokumentationen sind verfügbar.&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Software wurde basierend auf der Arbeit von Markus F. weiterentwickelt.&lt;br /&gt;
Der Teil für die Kondensatormessung wurde komplett neu geschrieben und auch die Widerstandsmessung wurde erheblich überarbeitet. Bei Schwierigkeiten und Problemen sollte man mich über E-mail oder über den Diskussionsteil (thread) benachrichtigen.  Nur wenn ich von Problemen weiß, kann ich hoffentlich Abhilfe schaffen.&lt;br /&gt;
&lt;br /&gt;
Weitere Einzelheiten sowie Beschreibung der einzelnen Meßverfahren und Beispiel-Ergebnisse habe ich in der pdf-Dokumentation (deutsche und englische Version) beschrieben. Hier findet man auch Hinweise zum Konfigurieren der Software mit Makefile Parametern und Optionen. &lt;br /&gt;
Die Kommentare im Quellcode sind in englischer Sprache.&lt;br /&gt;
Neu eingebaut in der Software ist eine Selbsttest-Funktion, in der die Funktion des Testers gemessen wird. In diesen Selbsttest ist auch ein Kalibrationsteil integriert.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
&lt;br /&gt;
Im Prinzip ist die neue Software so zu konfigurieren, daß sie auf der bereits von Markus F. vorgestellten Hardware ohne Änderungen läuft.&lt;br /&gt;
&lt;br /&gt;
Sinnvoll sind dennoch einige Änderungen:&lt;br /&gt;
&lt;br /&gt;
* Der Prozessor sollte auf einen 8 MHz Taktfrequenz umgestellt werden, am besten mit einem externen Quarz. Dazu müssen die fuses des ATmega geändert werden.&lt;br /&gt;
* Ein &amp;quot;pull up&amp;quot; Widerstand von etwa 27 kOhm sollte von Pin 13 (PD7) des ATmega nach VCC nachgerüstet werden.&lt;br /&gt;
* Der 100 nF Kondensator am Pin 21 (AREF) kann entweder ganz entfernt werden oder besser durch einen 1 nF Kondensator ersetzt werden.&lt;br /&gt;
* Wenn die elektronische Einschaltung des Testers Probleme macht, sollte wenigstens der C2 Kondensator an der Basis von Transistor T1 auf 10 nF reduziert werden und ggf. auch der Widerstand R7 auf 3,3 kOhm reduziert werden. Das komplette Schaltbild und Einzelheiten dazu findet man in der PDF Dokumentation.&lt;br /&gt;
&lt;br /&gt;
Die Gründe und die Einzelheiten für diese Änderungen sowie weitere Hinweise für einen Neuaufbau sind im Hardware-Kapitel meiner pdf-Dokumentation beschrieben. Empfohlen wird ein ATmega168 Prozessor oder auch ein ATmega328 Prozessor, weil der ADC mit der Autoscale Funktion im Bedarfsfall von der 5V Referenz (VCC) auf die interne Referenz-Spannung umgeschaltet wird. Die interne Referenz hat für der ATmega8 eine Spannung von 2,56V, für die anderen Prozessoren aber 1,1 Volt. Mit 1,1 V kann eine bessere Auflösung des ADC für gemessene Spannungen unter 1 Volt erreicht werden.&lt;br /&gt;
Man kann den ATmega8 ohne Hardwareänderung gegen einen ATmega168 oder ATmega328 austauschen!&lt;br /&gt;
Hier ist der Teil der Schaltung, der für die Messung erforderlich ist.&lt;br /&gt;
Die Elektronik für die Batterieversorgung und die automatische Abschaltung fehlt in diesem Schaltbild.[[Datei:TransistorTesterVC1.png|miniatur|Schaltbild ohne Stromversorgung]]&lt;br /&gt;
&lt;br /&gt;
Die rot markierten Bauteile sind nicht unbedingt erforderlich, können aber zu einer Verbesserung der Messgenauigkeit beitragen. Die grün markierten Bauteile sind gegenüber dem ersten Entwurf von Markus F. geändert.&lt;br /&gt;
Die Eagle Dateien von Asko B. für drei Varianten sind im Thread zu finden bei der Adresse: http://www.mikrocontroller.net/topic/248078?page=4#2891344&lt;br /&gt;
&lt;br /&gt;
Hier ist der Artikel der 1. Transistortester Version von Markus F. zu finden: [[AVR-Transistortester]]&lt;br /&gt;
&lt;br /&gt;
== Diskussionen zur neuen Version ==&lt;br /&gt;
Der Thread mit meinen älteren Software-Versionen und einigen Problemfällen sowie Hardware-Vorschlägen ist unter [https://www.mikrocontroller.net/topic/248078#new https://www.mikrocontroller.net/topic/248078#new] zu finden.&lt;br /&gt;
&lt;br /&gt;
== Downloads (deutsch) ==&lt;br /&gt;
Alle Versionen von der Software und der Doku sind im SVN gespeichert.&lt;br /&gt;
&lt;br /&gt;
[[Media:ttinfo_ger111k.pdf|Kurzbeschreibung (deutsch) Version 1.11k (2015-01-30)]]&lt;br /&gt;
&lt;br /&gt;
[[Media:ttester_ger111k.pdf|Anleitung (deutsch) Version 1.11k (2015-02-08)]]&lt;br /&gt;
&lt;br /&gt;
Die Benutzer können über den svnbrowser [https://www.mikrocontroller.net/svnbrowser/transistortester/ https://www.mikrocontroller.net/svnbrowser/transistortester/] das gewählte Verzeichnis als &amp;quot;GNU tarball&amp;quot; runterladen.&lt;br /&gt;
Beim Aufruf des svnbrowsers steht dazu unter der Datei/Verzeichnis Liste der Eintrag &amp;quot;Download GNU tarball&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Zum Auspacken der heruntergeladenen transistortester*.tar.gz Datei benötigen Windows Benutzer eine geeignete Software wie das Freeware Paket [http://www.7-zip.org/ 7-Zip].&lt;br /&gt;
Nach dem Auspacken hat man den vorher mit dem svnbrowser ausgewählten Verzeichnisbaum auf seinem eigenen Rechner.&lt;br /&gt;
Ein direkter Zugriff auf die Dateien mit dem svnbrowser ist nicht möglich!&lt;br /&gt;
&lt;br /&gt;
Eine andere Methode auf den Inhalt des svn Archivs zuzugreifen besteht mit der Installation des TortoiseSVN Plugins für den Windows Explorer.&lt;br /&gt;
Damit ist dann der Zugriff über [svn://mikrocontroller.net/transistortester svn://mikrocontroller.net/transistortester] direkt auf das Archiv mit dem Browser möglich.&lt;br /&gt;
&lt;br /&gt;
Linux Benutzer können auch direkt über svn auf das Archiv zugreifen.&lt;br /&gt;
&lt;br /&gt;
== Downloads (russisch) - Загрузки (русский) ==&lt;br /&gt;
Для загрузок доступны все версии программного обеспечения и документации, хранящиеся в SVN&lt;br /&gt;
&lt;br /&gt;
[[Media:ttinfo_rus111k.pdf|краткое описание (русский) Версия 1.11k (2015-01-11)]]&lt;br /&gt;
&lt;br /&gt;
[[Media:ttester_rus111k.pdf|инструкции (русский) Версия 1.11k (2015-02-07)]]&lt;br /&gt;
&lt;br /&gt;
Пользователь может загрузить выбранный каталог в качестве &amp;quot;GNU архива&amp;quot; через svnbrowser [https://www.mikrocontroller.net/svnbrowser/transistortester/ https://www.mikrocontroller.net/svnbrowser/transistortester/].&lt;br /&gt;
&lt;br /&gt;
При вызове svnbrowsers, смотрите в список файлов / каталогов, запись &amp;quot;Скачать GNU архив&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для распаковки загруженного файла * .tar.gz пользователи Windows могут воспользоваться любым подходящим программным обеспечением, таким как бесплатная программа [http://www.7-zip.org/ 7-Zip].&lt;br /&gt;
&lt;br /&gt;
После распаковки архива у вас на компьютере будет архив с заранее выбранным через svnbrowser содержимым в дереве каталогов.&lt;br /&gt;
&lt;br /&gt;
Прямой доступ к файлам через svnbrowser не возможен!&lt;br /&gt;
&lt;br /&gt;
Еще один способ получить доступ к содержимому хранилища SVN состоит в установке TortoiseSVN плагина для Windows Explorer. Это затем кнопкой [svn://mikrocontroller.net/transistortester svn://mikrocontroller.net/transistortester] прямо в вашем архиве, используя браузер.&lt;br /&gt;
&lt;br /&gt;
Пользователи Linux могут получить доступ непосредственно из SVN к архиву.&lt;br /&gt;
&lt;br /&gt;
== Downloads (english) ==&lt;br /&gt;
All versions of the software and documentation are saved in the SVN archive.&lt;br /&gt;
&lt;br /&gt;
[[Media:ttinfo_eng111k.pdf|Short description (english) Version 1.11k (2015-01-05)]]&lt;br /&gt;
&lt;br /&gt;
[[Media:ttester_eng111k.pdf|Manual (english) Version 1.11k (2015-02-08)]]&lt;br /&gt;
&lt;br /&gt;
Users can download a &amp;quot;GNU tarball&amp;quot; of the previous selected directory with the svnbrowser [https://www.mikrocontroller.net/svnbrowser/transistortester/ https://www.mikrocontroller.net/svnbrowser/transistortester/].&lt;br /&gt;
&lt;br /&gt;
Windows users need a additional tool like the freeware [http://www.7-zip.org/ 7-Zip] to unpack the downloaded transistortester*.tar.gz file.&lt;br /&gt;
After unpacking you have a copy of the selected directory at your own computer.&lt;br /&gt;
The direct access is not possible with the svnbrowser!&lt;br /&gt;
&lt;br /&gt;
Another way to get access to the SVN data is to install the TortoiseSVN plugin for the windows explorer. After installing you can access the data with [svn://mikrocontroller.net/transistortester svn://mikrocontroller.net/transistortester].&lt;br /&gt;
&lt;br /&gt;
Linux users can also access the data with svn directly.&lt;br /&gt;
&lt;br /&gt;
== Downloads (Português - Brasil) ==&lt;br /&gt;
&lt;br /&gt;
Todas as versões de software e documentação estão salvas no arquivador SVN.&lt;br /&gt;
&lt;br /&gt;
Usuários podem descarregar um pacote &amp;quot;GNU&amp;quot; de todos os diretórios anteriores com o svnbrowser [https://www.mikrocontroller.net/svnbrowser/transistortester/ https://www.mikrocontroller.net/svnbrowser/transistortester/].&lt;br /&gt;
&lt;br /&gt;
Usuários de Windows precisam de uma ferramenta adicional como o freeware [http://www.7-zip.org/ 7-Zip] para descompactar o arquivo transistortester*.tar.gz. Depois de descompactado você terá uma cópia do diretório selecionado no seu computador. O acesso direto não é possível com o svnbrowser!&lt;br /&gt;
&lt;br /&gt;
Outra forma de acessar os dados no SVN é instalar o TortoiseSVN plugin para Windows Exporer. Depois de instalar você pode acessar soa dados com o endereçco [svn://mikrocontroller.net/transistortester svn://mikrocontroller.net/transistortester].&lt;br /&gt;
&lt;br /&gt;
Usuários Linux podem acessar os dados com svn diretamente.&lt;br /&gt;
&lt;br /&gt;
== Downloads (Español) ==&lt;br /&gt;
Todas la versiones del software y la documentación están en SVN.&lt;br /&gt;
&lt;br /&gt;
Los usuarios pueden descargar un &amp;quot;GNU tarball&amp;quot; del directorio seleccionado utlizando svnbrowser [https://www.mikrocontroller.net/svnbrowser/transistortester/ https://www.mikrocontroller.net/svnbrowser/transistortester/]&lt;br /&gt;
&lt;br /&gt;
Los usuarios de Windows requieren de una herramienta adicional como el freeware [http://www.7-zip.org/ 7-Zip] (gratis) para desempacar el archivo descargado, transistortester*.tar.gz.&lt;br /&gt;
&lt;br /&gt;
Luego de desempacar el archivo, tendrá en su computador una copia completa del directorio seleccionado.&lt;br /&gt;
Acceso directo no es posible con svnbrowser.&lt;br /&gt;
&lt;br /&gt;
La otra manera de accesar el respositorio SVN es instalando el plugin TortoiseSVN; éste le permitirá acceso a la información con el URI: [svn://mikrocontroller.net/transistortester svn://mikrocontroller.net/transistortester]&lt;br /&gt;
&lt;br /&gt;
Los usuarios de Linux pueden, por supuesto, accesar SVN directamente.&lt;br /&gt;
&lt;br /&gt;
== Downloads (Slovak) ==&lt;br /&gt;
&lt;br /&gt;
Všetky verzie softvéru a dokumentácie sú uložené v SVN archíve.&lt;br /&gt;
&lt;br /&gt;
Prostredníctvom &#039;&#039;svnbrowsera&#039;&#039;, ktorý sa nachádza na adrese [https://www.mikrocontroller.net/svnbrowser/transistortester/ https://www.mikrocontroller.net/svnbrowser/transistortester/] je možné kliknutím na odkaz &#039;&#039;&amp;quot;Download GNU tarball&amp;quot;&#039;&#039; stiahnuť kompletný obsah aktuálne zobrazeného adresára.&lt;br /&gt;
&lt;br /&gt;
Na rozbalenie stiahnutého súboru &#039;&#039;transistortester*.tar.gz&#039;&#039; pod systémom Windows je možné použiť bezplatný software &#039;&#039;[http://www.7-zip.org/ 7-Zip]&#039;&#039;. Po extrahovaní je na lokálnom PC k dispozícii kópia vybraného adresára. Priamy prístup k jednotlivým súborom SVN archívu cez &#039;&#039;svnbrowser&#039;&#039; nie je možný!&lt;br /&gt;
&lt;br /&gt;
Alternatívnym spôsobom prístupu k SVN archívu je inštalácia a použitie pluginu &#039;&#039;TortoiseSVN&#039;&#039; pre Windows Explorer. Potom je možné pristupovať k dátam prostredníctvom odkazu [svn://mikrocontroller.net/transistortester svn://mikrocontroller.net/transistortester].&lt;br /&gt;
&lt;br /&gt;
Užívatelia systému Linux môžu k SVN dátam pristupovať priamo.&lt;br /&gt;
&lt;br /&gt;
== Downloads (your-language) ==&lt;br /&gt;
You can put a translation &#039;&#039;here&#039;&#039;, but only if its done by yourself, not Google Translate.&lt;br /&gt;
You can also put a translation of the whole article here, if its done by yourself.&lt;br /&gt;
&lt;br /&gt;
Only little understanding of the Wiki-Syntax is needed therefore.&lt;br /&gt;
&lt;br /&gt;
== Verzeichnisstruktur des SVN ==&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; style=&amp;quot;border-collapse:collapse&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Ordnerstruktur und Beschreibung der  &#039;&#039;Pfade&#039;&#039; im SVN&#039;&#039;&#039;&lt;br /&gt;
|- style=&amp;quot;background-color:#B3B7FF&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; colspan=&amp;quot;2&amp;quot; | &#039;&#039;&#039;Ordner/directory&#039;&#039;&#039; || &#039;&#039;&#039;Dateien/files&#039;&#039;&#039; || &#039;&#039;&#039;Beschreibung/description&#039;&#039;&#039;&lt;br /&gt;
|-   style=&amp;quot;background-color:#B9FFC5&amp;quot;&lt;br /&gt;
| &#039;&#039;&#039;Doku&#039;&#039;&#039; || || || Enthält die Dokumentation als PDF und als pdflatex-Quelltext&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk&#039;&#039;&#039; || || Letzter Entwicklungsstand der Dokumentation inclusive Bilder und Diagrammen&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/pdftex/german&#039;&#039;&#039; || || enthält die deutschen Texte, Makefile und PDF-Dokumentation der Entwicklerversion&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/pdftex/english&#039;&#039;&#039; || || contains the English text, Makefile and PDF documentation of the developer version&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/pdftex/russian&#039;&#039;&#039; || || contains the Russian text, Makefile and PDF documentation of the developer version&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags&#039;&#039;&#039; ||&#039;&#039;changelog.txt&#039;&#039; || &#039;&#039;Hier sollte jede Änderung mit Versionsnummer eingetragen werden&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/german&#039;&#039;&#039; || || &#039;&#039;Aktuelle PDF Dokumentation in deutsch&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/english&#039;&#039;&#039; || || &#039;&#039;Current PDF documentation in English&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/russian&#039;&#039;&#039; || || &#039;&#039;Current PDF documentation in Russian language&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/old/german&#039;&#039;&#039; || || &#039;&#039;PDF Dokumentationen zu früheren Softwareversionen&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/old/english&#039;&#039;&#039; || || &#039;&#039;PDF documentation for earlier software versions&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
|- style=&amp;quot;background-color:#B9FFC5&amp;quot;&lt;br /&gt;
| &#039;&#039;&#039;Hardware&#039;&#039;&#039; || || || Hardware Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid&#039;&#039;&#039; || || Verzeichnis für eine Streifenleiterplatine&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid/ttester_strip_grid.diy&#039;&#039;&#039; || || Beispiel einer Streifenleiterplatine, DIYLC-Datei&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid/TTester_strip.pdf&#039;&#039;&#039; || || Ergebnis der Streifenleiterplatine im PDF Format&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid/LiesMich.txt&#039;&#039;&#039; || || Kurzdokumentation für Streifenleiter-Platine&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid/ReadMe.txt&#039;&#039;&#039; || || Short documentation for the strip grid board&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;Markus&#039;&#039;&#039; || || Entwurf von Markus R. mit LED-Dimmer im Eagle 6.4.0 Format&lt;br /&gt;
&lt;br /&gt;
|- style=&amp;quot;background-color:#B9FFC5&amp;quot;&lt;br /&gt;
| &#039;&#039;&#039;Software&#039;&#039;&#039; || || || Software für AVR-GCC 4.8.2&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk&#039;&#039;&#039; || || Aktueller Software-Entwicklungszweig&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/default&#039;&#039;&#039; || || Makefile und Programmierdaten für ATmega168 mit Standard-Layout&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega168_1.9V&#039;&#039;&#039; || || Makefile und Daten für ATmega168 mit Knopfzellenbetrieb (FiFi)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega168_3.3V&#039;&#039;&#039; || || Makefile und Daten für ATmega168 mit LiPo-Akkubetrieb (FiFi)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega168_strip_grid&#039;&#039;&#039; || || Makefile und Daten für ATmega168 für Streifenleiter-Platine&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Standard-Layout (ab Version 1.08k)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_1.9V&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Knopfzellenbetrieb (Funkamateur)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_3.3V&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit LiPo-Akkubetrieb (Funkamateur)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_2X16_menu&#039;&#039;&#039; || || Makefile und Daten für ATmega328, 2x16 Zeichen Textdisplay, Impulsdrehgeber + Spannungsmessung&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_dogm&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Standard-Layout, 2x16 Zeichen DOG-M LCD&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_strip_grid&#039;&#039;&#039; || || Makefile und Daten für ATmega328 für Streifenleiter-Platine (ab Version 1.08k)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_strip_grid_dogm&#039;&#039;&#039; || || Makefile und Daten für ATmega328 für Streifenleiter-Platine mit DOG-M Display&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_st7565&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Standard-Layout, 126x64 Pixel LCD, ST7565 Controller&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_st7108&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Standard-Layout, 126x64 Pixel LCD, ST7108 Controller&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_st7920&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Standard-Layout, 126x64 Pixel LCD, ST7920 Controller&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_fish8840&#039;&#039;&#039; || || Makefile und Daten für chinesische Fish8840 Version, ATmega328, 126x64 Pixel LCD, ST7565 Controller&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_wei_st7565&#039;&#039;&#039; || || Makefile und Daten für chinesische WEI_M8_LGTST Version, 126x64 Pixel LCD, ST7565 Controller, LiIon Accu&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_GM328&#039;&#039;&#039; || || Makefile und Daten für chinesische GM328 Version, ATmega328, 126x64 Pixel LCD, ST7565 Controller&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_T3_T4_st7565&#039;&#039;&#039; || || Makefile und Daten für chinesische T3 oder T4 Version, ATmega328, 126x64 Pixel LCD, ST7565 Controller&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_T5_st7565&#039;&#039;&#039; || || Makefile und Daten für chinesische T5 Version, ATmega328, 126x64 Pixel LCD, ST7565 Controller, LiIon Accu&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_ssd1306I2C&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Standard-Layout, 126x64 Pixel OLED, SSD1306 Controller, I2C Schnittstelle&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_ssd1306SPI&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Standard-Layout, 126x64 Pixel OLED, SSD1306 Controller, SPI Schnittstelle&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega644_LCD2004&#039;&#039;&#039; || || Makefile und Daten für ATmega644/1284 mit 4x20 Zeichen LCD&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/arduino_m2560&#039;&#039;&#039; || || Makefile und Daten für Arduino Mega (ATmega2560) mit 2x16 Zeichen LCD &lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega8&#039;&#039;&#039; || || Makefile und Daten für ATmega8. Ab Version 1.00k ist der Selbsttest für den ATmega8 nicht mehr konfigurierbar.&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags&#039;&#039;&#039; || || Fertige Software Versionen als ZIP gepackt&lt;br /&gt;
|-&lt;br /&gt;
| || || &#039;&#039;changelog.txt&#039;&#039; || &#039;&#039;Hier sollte jede Änderung mit Versionsnummer eingetragen werden&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;Markus&#039;&#039;&#039; || || Alternative Software von Markus R., bitte README beachten! Die Software wurde aufgeräumt und ist viel besser strukturiert, läuft aber nur auf einem ATmega168 oder ATmega328. Die Software läuft nur auf dem Standard-Layout.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=K%C3%BChlk%C3%B6rper&amp;diff=89423</id>
		<title>Kühlkörper</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=K%C3%BChlk%C3%B6rper&amp;diff=89423"/>
		<updated>2015-07-29T07:27:57Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Änderung 89416 von 217.234.142.25 (Diskussion) rückgängig gemacht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieser Artikel versteht sich als Unterpunkt zum Artikel [[Leistungselektronik]].&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Ein Kühlkörper (engl. &#039;&#039;heat sink&#039;&#039;) wird benötigt, wenn die Verlustleistung von elektronischen Bauteilen einen bestimmten Wert übersteigt. Der Kühlkörper hat dabei die Aufgabe, die entstehende Wärme möglichst gut auf eine große Fläche zu verteilen, um sie dann an die Umgebung abzugeben.&lt;br /&gt;
&lt;br /&gt;
[[bild: Rippenkuehlkoerper.png | thumb | 300px| Rippenkühlkörper, Schnittdarstellung]]&lt;br /&gt;
&lt;br /&gt;
Das grundlegende Prinzip sieht man an jedem Rippenkühlkörper. An der Stelle, wo das Kühlobjekt angeschraubt/gepresst ist (rotes Viereck), ist ein dicker &amp;quot;Klumpen&amp;quot; Material, der erstmal die Wärme auf eine etwas größere Fläche verteilen soll. Bei CPU-Lüftern ist dort teilweise Kupfer eingepresst, weil das noch besser als Aluminium Wärme leitet (engl. heat spreader, Wärmespreizer). Danach folgen viele, nach aussen dünner werdende Rippen. In der Mitte noch dick, dort muss die Wärme ja verlustarm durchgeleitet werden, aussen dünn, dort ist fast alle Wärme schon abgegeben. Ein guter Kühlkörper hat eine möglichst große Oberfläche bei möglichst kleiner Masse. Viele Kühlkörper werden aus preiswerten [http://de.wikipedia.org/wiki/Strangpressen Strangpressprofilen] hergestellt.&lt;br /&gt;
&lt;br /&gt;
== Wärmewiderstand ==&lt;br /&gt;
&lt;br /&gt;
Die wichtigste Kennzahl eines Kühlkörpers ist der Wärmewiderstand. Er gibt an, um wie viel Kelvin sich die Temperatur zwischen Wärmequelle und Umgebung unterscheidet, wenn eine bestimmte Wärmeleistung abgeführt werden muss. Die Einheit ist K/W, Kelvin pro Watt. (Hinweis: Oft wird die Einheit °C/W angegeben, das ist allerdings nicht ganz korrekt. Temperaturdifferenzen werden in Kelvin angegeben). Je niedriger der Wärmewiderstand, umso besser der Kühlkörper, weil er die gleiche Wärmeleistung mit einem kleineren Temperaturunterschied abführen kann. Dadurch bleibt das Bauteil kühler, was der Lebensdauer und Funktionssicherheit zu Gute kommt.&lt;br /&gt;
&lt;br /&gt;
Allgemein gilt die Formel&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\Delta T = P_{\theta} \cdot R_{\theta}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt;\Delta T&amp;lt;/math&amp;gt; - Temperaturdifferenz zwischen Wärmequelle und Umgebung in K&lt;br /&gt;
*&amp;lt;math&amp;gt;P_{\theta}&amp;lt;/math&amp;gt; - Wärmeleistung in W&lt;br /&gt;
*&amp;lt;math&amp;gt;R_{\theta}&amp;lt;/math&amp;gt; - Wärmewiderstand in K/W&lt;br /&gt;
&lt;br /&gt;
Der griechische Buchstabe Theta wird als Symbol für Wärmekenngrößen verwendet, denn es geht bei diesen Rechnungen um Wärmewiderstände und Wärmeleistungen, keine elektrischen Widerstände und elektrische Leistungen.&lt;br /&gt;
&lt;br /&gt;
== Berechnung des Wärmewiderstands ==&lt;br /&gt;
&lt;br /&gt;
Für einen Kühlkörper ist der Wärmewiderstand im Datenblatt angegeben. Diesen rein aus dem Aufbau zu berechnen ist sehr schwierig, auch das Messen ist nicht so einfach. Was man jedoch berechnen kann und muss ist der Wärmewiderstand eines Gesamtaufbaus, d.h. Bauteil + Kühlkörper. Dazu muss man im Wesentlichen zwei Fälle unterscheiden.&lt;br /&gt;
&lt;br /&gt;
=== Bauteil ohne Kühlkörper ===&lt;br /&gt;
&lt;br /&gt;
Ohne Kühlkörper kann ein Bauteil seine Wärme über zwei Wege abgeben. Über das Gehäuse direkt an die Luft (Abstrahlung oder Konvektion) oder über die Anschlüsse auf die Platine (Wärmeleitung). Dies alles findet parallel statt, aber je nach Gehäusetyp und Platinengestaltung ist die Verteilung auf die Kühlwege verschieden. Transistoren im Metallgehäuse (z.&amp;amp;nbsp;B. TO-3) oder mit Metallfahne (z.&amp;amp;nbsp;B. TO220) können recht viel Wärme über das Gehäuse abgeben. Leistungsdioden im Plastikgehäuse hingegen können den Großteil der Wärme nur über die Anschlüsse abgeben. Deshalb sollten diese möglichst kurz sein, und auf der Platine an dicke Leiterbahnen oder gar Kupferflächen angeschlossen werden. Ähnliches gilt für leistungsverstärkte DIL- oder SOIC-[[IC-Gehäuseformen | Gehäuse]], welche oft für [[H-Brücken_Übersicht | Leistungstreiber]] oder [[FET | MOSFETs]] verwendet werden. In diesen Fällen sollten die Pins direkt an Kupferflächen &#039;&#039;&#039;ohne&#039;&#039;&#039; Wärmefallen (Thermals) angeschlossen werden, auch wenn dadurch das [[Löten]] erschwert wird. &lt;br /&gt;
&lt;br /&gt;
Für die meisten Bauteile ist im Datenblatt der Wärmewiderstand zwischen dem eigentlichen Chip (engl. &amp;quot;&#039;&#039;&#039;j&#039;&#039;&#039;unction&amp;quot;) und der Umgebung (engl. &amp;quot;&#039;&#039;&#039;a&#039;&#039;&#039;mbient&amp;quot;) angegeben.&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt;R_{\theta JA}&amp;lt;/math&amp;gt; - Wärmewiderstand zwischen Sperrschicht und Umgebung ohne zusätzlichen Kühlkörper in K&lt;br /&gt;
&lt;br /&gt;
Damit kann man direkt in die oben genannte Formel gehen und die Temperaturdifferenz ausrechnen. Die Temperatur der Sperrschicht errechnet sich einfach aus der maximalen Umgebungstemperatur (meist Luft) und dem errechneten Temperaturunterschied.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;T_J = T_A + \Delta T &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt;T_J&amp;lt;/math&amp;gt; - Temperatur der Sperrschicht in °C (engl. &amp;quot;&#039;&#039;&#039;j&#039;&#039;&#039;unction&amp;quot;)&lt;br /&gt;
*&amp;lt;math&amp;gt;T_A&amp;lt;/math&amp;gt; - Temperatur der Umgebung in °C (engl. &amp;quot;&#039;&#039;&#039;a&#039;&#039;&#039;mbient&amp;quot;)&lt;br /&gt;
*&amp;lt;math&amp;gt;\Delta T&amp;lt;/math&amp;gt; - Temperaturdifferenz zwischen Wärmequelle und Umgebung in K&lt;br /&gt;
&lt;br /&gt;
=== Bauteil mit Kühlkörper ===&lt;br /&gt;
&lt;br /&gt;
Will man mit einem IC größere Verlustleistungen umsetzen (Linearer Spannungsregler, [[Transistor]], etc.] muss meist ein Kühlkörper her. Die jeweiligen Gehäuse besitzen dazu meist eine Kühlfahne, an die man den Kühlkörper anschrauben kann. Bei anderen gibt es Klemmen, die den Kühlkörper fest klemmen. Hier gibt es einiges zu beachten. Der Kühlkörper darf nicht zu schwach angeschraubt werden, sonst ist der Wärmewiderstand zwischen Gehäuse und Kühlkörper zu gross. Er darf aber auch nicht zu stark angeschraubt/angepresst werden, um das Gehäuse nicht zu deformieren. Wichtig ist der Übergang zwischen IC und Kühlkörper. Hier muss bei größeren Leistungen (&amp;gt;5W) Wärmeleitpaste verwendet werden. Ihre Aufgabe ist es, die Luft zwischen den Oberflächen zu verdrängen, welche sich in den mikroskopischen Unebenheiten befindet und den Wärmewiderstand &#039;&#039;&#039;deutlich&#039;&#039;&#039; erhöht. Dabei sollte die Schicht sehr dünn sein, denn die Wärmeleitpaste ist im Vergleich zu Aluminium oder Kupfer ein schlechter Wärmeleiter, allerdings deutlich besser als Luft.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
! Material || Wärmeleitfähigkeit&amp;lt;br/&amp;gt;[W/(m*K)]&lt;br /&gt;
|-&lt;br /&gt;
| Luft            || 0,026&lt;br /&gt;
|-&lt;br /&gt;
| Wärmeleitpaste  ||   4 -  10&lt;br /&gt;
|-&lt;br /&gt;
| Aluminium       || 221*&lt;br /&gt;
|-&lt;br /&gt;
| ALMg3           || 140 - 160&lt;br /&gt;
|-&lt;br /&gt;
| ALMg4,5Mn       || 120 - 140&lt;br /&gt;
|-&lt;br /&gt;
| ALMgSi1         || 170 - 220&lt;br /&gt;
|-&lt;br /&gt;
| ALCuMg1         || 160 - 200&lt;br /&gt;
|-&lt;br /&gt;
| ALCu6,5Mn0,3    ||   95 - 130&lt;br /&gt;
|-&lt;br /&gt;
| Kupfer          || 370*&lt;br /&gt;
|-&lt;br /&gt;
| Messing MS60    ||   90 - 113&lt;br /&gt;
|- &lt;br /&gt;
| Cu Be 2         ||   92 - 125&lt;br /&gt;
|-&lt;br /&gt;
| Cu Co 2 Be      || 192 - 239&lt;br /&gt;
|-&lt;br /&gt;
| Cu Cr 1 Zr      || 167 - 320&lt;br /&gt;
|-&lt;br /&gt;
| Cu Ni 2 Si      ||   67 - 120&lt;br /&gt;
|-&lt;br /&gt;
| Stahl 0,2%C     ||   50&lt;br /&gt;
|-&lt;br /&gt;
| Stahl 8%Cr      ||   21&lt;br /&gt;
|-&lt;br /&gt;
| Zinn            ||   65&lt;br /&gt;
|-&lt;br /&gt;
| Blei            ||   35&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
*Werte DIN V 4108-4, Achtung: bei den verfügbaren Legierungen sind weit geringere Wärmeleitfähigkeiten zu erwarten!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Das oft verwendete TO220 Gehäuse hat ca. 1cm^2 Kühlfläche. Wird ein Kühlkörper ohne Wärmeleitpaste aufgeschraubt und entsteht dabei ein angenommener Luftspalt von 10µm, hat dieser einen Wärmewiderstand von ca. 4K/W! Mit Wärmeleitpaste sind es rein rechnerisch nur 1/150tel, also etwa 0,026 K/W. Real muss man jedoch eher mit 0,5-1K/W rechnen.&lt;br /&gt;
&lt;br /&gt;
Für die Berechnung des gesamten Wärmewiderstandes müssen hier drei Widerstände in Reihe betrachtet werden. Der Erste ist im Datenblatt zwischen Chip und Gehäuse angeben (engl. junction to case). Danach kommt der Übergang Gehäuse-Kühlkörper. Dieser ist von der Oberflächengüte und der Wärmeleitpaste abhängig und kann nur abgeschätzt werden. Ein TO220 Gehäuse mit dünner Schicht Wärmeleitpaste hat hier ca. 0,5-1K/W. Zum Schluss muss noch der Wärmewiderstand des Kühlkörpers addiert werden, dieser ist im Datenblatt angegeben. Vorsicht, bei größeren Kühlkörpern mit großen Rippen ist die Einbaulage wichtig, damit der Luftstrom frei strömen und gut kühlen kann (freie Konvektion, warme Luft strömt nach oben und kalte strömt unten nach). Die drei Wärmewiderstände werden addiert und über die oben angegebene Formel der Gesamtwärmewiderstand und damit die Temperaturerhöhung der Sperrschicht berechnet.&lt;br /&gt;
Dabei muss man aufpassen, dass man nicht aus Versehen den Wärmewiderstand ohne Kühlkörper (&amp;lt;math&amp;gt;R_{\theta JA}&amp;lt;/math&amp;gt;) in die Formel einsetzt!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;R_{\theta} = R_{\theta JC} + R_{\theta CS} + R_{\theta S}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt;R_{\theta}&amp;lt;/math&amp;gt; - Gesamtwärmewiderstand in K/W&lt;br /&gt;
*&amp;lt;math&amp;gt;R_{\theta JC}&amp;lt;/math&amp;gt; - Wärmewiderstand zwischen Sperrschicht und Gehäuse (engl. &#039;&#039;&#039;j&#039;&#039;&#039;unction - &#039;&#039;&#039;c&#039;&#039;&#039;ase)&lt;br /&gt;
*&amp;lt;math&amp;gt;R_{\theta CS}&amp;lt;/math&amp;gt; - Wärmewiderstand zwischen Gehäuse und Kühlkörper (engl. &#039;&#039;&#039;c&#039;&#039;&#039;ase - heat &#039;&#039;&#039;s&#039;&#039;&#039;ink)&lt;br /&gt;
*&amp;lt;math&amp;gt;R_{\theta S}&amp;lt;/math&amp;gt; - Wärmewiderstand des Kühlkörpers (engl. heat &#039;&#039;&#039;s&#039;&#039;&#039;ink)&lt;br /&gt;
&lt;br /&gt;
Wird eine Schaltung in einem Gehäuse eingesetzt, muss man dafür sorgen dass die warme Luft abgeführt wird, vor allem in Kunststoffgehäusen. Ansonsten gibt es einen Wärmestau und die Temperatur steigt deutlich!&lt;br /&gt;
&lt;br /&gt;
=== Zwangskühlung  ===&lt;br /&gt;
&lt;br /&gt;
Natürlich muss der Kühlkörper die Wärme auch abführen können. Was aber, wenn der für den Wärmeabtransport benötigte Kühlkörper mechanisch nicht ins Gehäuse paßt?&lt;br /&gt;
Hier kommen die Lüfter zum Einsatz, das Ganze nennt sich dann Zwangskühlung.&lt;br /&gt;
&lt;br /&gt;
Durch den Einsatz eines Lüfters lässt sich die der Wärmewiderstand des Kühlkörpers etwa um den Faktor 4 verbessern, bzw. der Kühlkörper lässt sich in der Größe ungefähr um den Faktor 7..8 reduzieren. Dies sind jedoch nur Richtwerte für den ersten Entwurf, eine Prüfung durch Messung ist unbedingt erforderlich. Der Effekt beruht darauf, daß mittels eines Lüfters wesentlich mehr Luft wesentlich schneller am Kühlkörper vorbeiströmen kann, und dabei mehr Wärme bei gleicher Temperaturerhöhung aufnehmen kann.&lt;br /&gt;
&lt;br /&gt;
Beim Einsatz eines Lüfters ist auch daran zu denken, daß sowohl die Ansaugöffnung als auch der Kühlkörper verschmutzen und regelmäßig gereinigt werden müssen. Weiterhin erzeugt ein Lüfter natürlich auch Lärm. Je kleiner der Lüfter und je größer die benötigte Luftlieferleistung, umso lauter wird der Lüfter. Umgekehrt kann man aber mit einem großen, eher langsam laufenden Lüfter den Geräuschpegel stark absenken. Und letztendlich kann ein Lüfter auch kaputt gehen, womit die Kühlung deutlich verschlechtert wird und das Bauteil überhitzt. Hier empfiehlt sich bei wertvolleren Objekten eine Lüfterüberwachung, wie sie seit längerem bei PCs eingesetzt wird.&lt;br /&gt;
&lt;br /&gt;
==== Physikalischer Hintergrund der Zwangskühlung mit Luft ====&lt;br /&gt;
&lt;br /&gt;
Luft hat eine Wärmekapazität von ungefähr 1kJ/kg/K was bedeutet, daß für die Erwärmung von 1kg Luft um 1K eine Energiemenge von 1kJ = 1000Ws erforderlich ist. D.h. für den kontinuierlichen Abtransport von 100W Wärme werden mindestens 100g Luft pro Sekunde benötigt, wenn man diese nur um 1K erwärmen will. &lt;br /&gt;
Um also 100W von einem Kühlkörper abzuführen, der sich hier im Beispiel um 8K erwärmen darf, sind  100W / 8K  = 12,5g Luft pro Sekunde erforderlich. Ein Gramm Luft hat ein Volumen von etwa 0,77l, d.h. bei 12,5 g muss der Lüfter 9,6 l/s bzw. 34,5 m³/h liefern, die dann auch durch den gesamten Kühlkörper geblasen werden müssen.&lt;br /&gt;
&lt;br /&gt;
== Die Platine als Kühlkörper ==&lt;br /&gt;
&lt;br /&gt;
Bei kleineren Leistungen (&amp;lt; 5W) kann man auch die Platine als Kühlkörper benutzten. Dabei muss jedoch die Wärme vom Bauteil möglichst schnell auf eine größere Fläche verteilt werden. Dazu nutzt man große Kupferflächen direkt am Bauteil. Diese werden teilweise beidseitig angebracht. Die Wärme muss man dann jedoch mit vielen Vias von der einen Seite, auf der das Bauteil sitzt, auf die andere geleitet werden. Diese Vias heißen thermische Vias, da sie nicht als elektrische Verbindung sondern als Wärmeleiter dienen. Das funktioniert deshalb so gut, weil die Vias innen mit Kupfer beschichtet sind, welches die Wärme wesentlich besser leitet als das Material der Leiterplatte (FR2, FR4).&lt;br /&gt;
Verfügt ein SMD-Bauteil über eine sogenannte &amp;quot;heat slug&amp;quot; oder thermal pad auf der Unterseite, muss dieses zur Wärmeableitung unbedingt angelötet werden. Dies ist mit einem normalen Lötkolben möglich, wenn die Platine an dieser Stelle mehrere Durchkontaktierungen mit einem Durchmesser von ca. 1,5mm aufweist. Durch diese Durchkontaktierungen kann genug Lötzinn auf die andere Seite fließen um diese Fläche mit der Platine zu verlöten. &lt;br /&gt;
&lt;br /&gt;
Mit modernen Technologien ist es auch möglich, deutlich größere Wärmeleistungen von der Platine abzuführen. Dazu werden z.&amp;amp;nbsp;B. Platinen mit Aluminium- oder Kupferkern  oder auf einen Metallträger laminierte PCBs benutzt (IMS = &#039;&#039;&#039;I&#039;&#039;&#039;nsulated &#039;&#039;&#039;M&#039;&#039;&#039;etal &#039;&#039;&#039;S&#039;&#039;&#039;ubstrat). Diese kommen z.&amp;amp;nbsp;B. bei Hochleistungs-[[LED]]s zum Einsatz. Für Hobbyzwecke sind sie aber noch wesentlich zu teuer, vor allem bei Einzelstücken.&lt;br /&gt;
&lt;br /&gt;
== Peltierelement ==&lt;br /&gt;
&lt;br /&gt;
Ein [http://de.wikipedia.org/wiki/Peltier-Element Peltierelement] arbeitet nach dem [http://de.wikipedia.org/wiki/Thermoelektrizit%C3%A4t#Peltier-Effekt Peltier-Effekt]. Dabei wird in einem Halbleiter durch Stromfluss eine Seite des Elements kalt, die andere heiß. Damit kann man ein kleines Objekt beliebig kühlen oder heizen. Allerdings sind Peltierelemente nur in eher kleinen Abmessungen und Leistung verfügbar (bis einige Dutzend Watt) und deren Effizienz ist auch nicht sonderlich hoch. Die allgemeine Auffassung, die könnten Wärme einfach verschwinden lassen ist falsch. Denn die heiße Seite muss klassisch gekühlt werden, je nach Temperaturunterschied mit mehr als der doppelten Kühlleistung als auf der kalten Seite an Wärme abgeführt wird.&lt;br /&gt;
&lt;br /&gt;
== Heat pipe ==&lt;br /&gt;
&lt;br /&gt;
Eine [http://de.wikipedia.org/wiki/Heatpipe Heat pipe],auf deutsch Wärmerohr genannt, ist ein Rohr, welches mit einer leicht verdampfenden Flüssigkeit gefüllt ist. Wird ein Ende erhitzt, verdampft die Flüssigkeit und nimmt dabei sehr viel Wärme auf. Der Dampf steigt im Rohr ans andere Ende, kondensiert dort und gibt dabei seine Wärme wieder ab.&lt;br /&gt;
&lt;br /&gt;
Heat pipes werden auch als Wärmesuperleiter bezeichnet, weil sie Wärme 100-10.000 mal besser leiten als ein massiver Kupferstab mit gleichen Abmessungen.&lt;br /&gt;
&lt;br /&gt;
Auch hier muss gesagt werden, dass eine Heat pipe allein &#039;&#039;&#039;kein&#039;&#039;&#039; Kühlsystem ist, denn die Seite, auf der das Wärmetransportmedium wieder kondensiert, muss auch wieder klassisch gekühlt werden. Der grosse Vorteil ist die Abführung großer Wärmemengen auf engstem Raum, wie z.&amp;amp;nbsp;B. bei CPUs in Laptops.&lt;br /&gt;
&lt;br /&gt;
== Flüssigkühlung ==&lt;br /&gt;
&lt;br /&gt;
Im PC-Bereich ist es unter einigen Enthusiasten verbreitet, den Rechner entweder zu übertakten, um eine höhere Leistung zu erzielen oder super leise zu machen, um angenehmer arbeiten oder spielen zu können. In beiden Fällen muss eine große Wärmemenge abgeführt werden. Dabei wird die sehr hohe Wärmekapazität von Wasser genutzt, um auf kleinem Raum die Wärme von CPU, GPU, Festplatten etc. abzuführen. Aber auch hier ist zu beachten, dass am Ende einer Flüssigkühlung praktisch immer ein klassischer Wärmetauscher steht, welcher die Wärme an die Umgebungsluft abgibt. Dieser kann sich aber deutlich weiter entfernt vom zu kühlenden Objekt befinden als ein einfacher, direkt montierter Kühlkörper. &lt;br /&gt;
&lt;br /&gt;
Bei der Verwendung von Wasser statt Luft als Kühlmedium reduziert sich die Durchflußmasse in etwa um den Faktor 4,2, da die Wärmekapazität von Wasser bei ca. 4,182 kJ/kg/K liegt. Da Wasser aber auch eine deutlich höhere Dichte als Luft besitzt (Wasser = 1g/cm³; Luft = 1,3mg/cm³) kommt noch der Faktor von ~770 dazu, woraus sich ein Gesamtfaktor für das Durchflußvolumen von ~3230 ergibt.&lt;br /&gt;
&lt;br /&gt;
D.h. die Durchflußmenge in unserem oben genannten Beispiel (100W) sinkt auf ca. 2,9 ml/s bzw. 10,7 l/h.&lt;br /&gt;
&lt;br /&gt;
Vorteile&lt;br /&gt;
*Abtransport großer Wärmemengen auf kleinstem Raum&lt;br /&gt;
*nahezu lautlos&lt;br /&gt;
&lt;br /&gt;
Nachteile&lt;br /&gt;
*höherer Aufwand und Kosten&lt;br /&gt;
*Gefahr durch auslaufendes Kühlmittel&lt;br /&gt;
&lt;br /&gt;
Im Bereich der Leistungselektronik wird Flüssigkühlung eingesetzt, im Hobbybereich nahezu nicht.&lt;br /&gt;
&lt;br /&gt;
== Bauteilmontage auf dem Kühlkörper ==&lt;br /&gt;
&lt;br /&gt;
Die Montage der klassischen Halbleitergehäuse nach TO220 und ähnlichen gestaltet sich augenscheinlich simpel: Die Kühlfahne hat ein Loch. Da ist es doch sehr verlockend, das Bauteil mit einer Schraube durch ebendieses Loch auf dem Kühlkörper zu befestigen...&lt;br /&gt;
&lt;br /&gt;
Bei fachgerechter Ausführung spricht auch wenig gegen diese Montageweise. Dazu gehört dann auch das richtige Anzugsmoment für die Schraube. Zu lose angezogen und zwischen Bauteilgehäuse und wärmeabführender Oberfläche entsteht ein Luftspalt. Ein Wärmeleitpad oder Wärmeleitpaste schaffen zwar Abhilfe, aber die Wärmeleitfähigkeit dieser Stoffe liegt um Größenordnungen unter der von Aluminium (Kühlkörper) und Kupfer (Kühlfahne). Ein vorhandenes Wärmeleitpad wird mitunter auch nicht weit genug zusammengedrückt, sodass auch noch Optimierung möglich wäre. Nämlich durch festeres Anziehen der Schraube.&lt;br /&gt;
Zu fest angezogen und die Kühlfahne wölbt sich minimal. Dabei hebt der Bauteilkörper von der Oberfläche des Kühlkörpers ab und es entsteht wieder ein Spalt. Ungünstigerweise liegt aber genau dort der Usprung des Wärmeflusses (Silizium-Chip). Bei Conrad gibt es [http://www.conrad.de/ce/de/overview/0205045/Transistor-Halteklammern-Haltefedern Klammern] zur Befestigung von Transistoren von [http://www.fischerelektronik.de/web_fischer/de_DE/K%C3%BChlk%C3%B6rper/A06/Transistorhaltefedern/$search_result_naviActualPage/1/$search_result_naviLinesPerPage/100/search.xhtml;jsessionid=2C868850DA0202334B26912FF6948496#search_result_naviPoint Fischer].&lt;br /&gt;
&lt;br /&gt;
[[Datei: kuehlkoerper-montage.jpeg | thumb | 300px | Montagebeispiel]] Weitaus einfacher zu handhaben ist folgende Montageweise: Die Bauteile werden, ungeachtet der Montagebohrung, lose auf den Kühlkörper gelegt. Falls notwending natürlich mit Isolierstoff dazwischen und in jedem Fall hauchdünn mit einem Wärmeleitmittel bestrichen. Über die Bauteile wird dann ein Aluminiumprofil gelegt und erst dieses wird, weiterhin mit einer Schraube pro Bauteil, auf den Kühlkörper gespannt. Abgesehen davon, dass so auch SMD-Bauteile (IPAK!) auf einem Kühlkörper Platz finden, entsteht Druck genau über dem Hot Spot.&lt;br /&gt;
&lt;br /&gt;
{{clear}}&lt;br /&gt;
&lt;br /&gt;
== Weitere Hinweise ==&lt;br /&gt;
&lt;br /&gt;
*Große Hochlastwiderstände mit Keramikgehäuse werden im Normalbetrieb recht heiß (200-350°C). Diese Temperaturen sollten nicht auf die Platine kommen, denn das macht das Material nicht lange mit. Hier muss genau das Gegenteil von dem gemacht werden, was weiter oben für Bauteile ohne Kühlkörper empfohlen wurde. Die Anschlüsse müssen möglichst lang sein, damit wenig Wärme über sie abgegeben werden kann. Die Kühlung erfolgt nahezu nur über den Keramikkörper durch Wärmestrahlung und Konvektion.&lt;br /&gt;
* Ein TO220 Gehäuse kann ca. 1W ohne Kühlkörper abgeben.&lt;br /&gt;
* Bei der Dimensionierung des Kühlkörpers sollte man sich nicht an der maximal zulässigen Sperrschichttemperatur orientieren, sondern möglichst um 10..50K kühler bleiben. Das verbessert die Funktionssicherheit und vor allem die Lebensdauer erheblich!&lt;br /&gt;
* Merksatz über den dicken Daumen: Pro 10 Grad Temperaturerhöhung halbiert sich die Lebenserwartung eines Bauteils. (Arrheniusgesetz, RGT-Regel, 10-Grad-Gesetz)&lt;br /&gt;
* Temperaturzyklen verkürzen die Lebensdauer von Schaltungen erheblich&lt;br /&gt;
* Meist sind mehrere kleine Kühlkkörper deutlich kleiner und billiger als ein Großer.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* [[Leistungselektronik]]&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/308826?goto=3325027#3325027 Forumsbeitrag]: Wärmewiderstand und Sperrschichttemperatur messen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/351187#3905083 Forumsbeitrag]: Dicker MOSFET, dünnes Anschlusspin?&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
* [http://sound.westhost.com/heatsinks.htm The Design of Heat sinks]. Eine ausführliche Seite zum Thema Kühlkörper, englisch&lt;br /&gt;
* [http://ludens.cl/Electron/Thermal.html Noch eine gute Seite, englisch]&lt;br /&gt;
* [http://wiki.oliverbetz.de/owiki.php/FormelSammlung Universelle Formelsammlung mit kurzen Erklärungen]&lt;br /&gt;
* [http://www.thermoconsult.de/01_TechInfo/Physik.pdf Grundlagen zur Kühlung, inhaltlich gut, Formatierung eher mies]&lt;br /&gt;
* [http://tangentsoft.net/elec/diy-hs.html DIY Heat Sinks]&lt;br /&gt;
* [http://www.fischerelektronik.de/ Kühlkörper bei Fischer Elektronik]&lt;br /&gt;
* [http://www.leiton.de/leiterplatten_teaser_alu.html Leiterplatten mit Alukern bei Leiton]&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/84303 Guter Beitrag im Forum mit einer Beispielrechnung]&lt;br /&gt;
*[http://www.shop.display3000.com/mikrocontrollerloesungen/uc-mit-21-tft/d074-mikrocontroller-atmega-tft-farbdisplay-212.html Berechnung in der Praxis: Unter Downloads das Handbuch laden, dann Seite 14]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Bauteile]]&lt;br /&gt;
[[Kategorie:Leistungselektronik]]&lt;br /&gt;
[[Category:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Konstantstromquelle&amp;diff=88819</id>
		<title>Konstantstromquelle</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Konstantstromquelle&amp;diff=88819"/>
		<updated>2015-06-03T06:03:49Z</updated>

		<summary type="html">&lt;p&gt;Maybee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Eine &#039;&#039;&#039;Konstantstromquelle&#039;&#039;&#039; ist eine Schaltung, deren Zweck es ist, den Strom durch eine Last (z.&amp;amp;nbsp;B. eine [[LED]]) möglichst konstant zu halten, das heißt Änderungen des Stroms durch Variationen der Betriebsspannung und/oder des Lastwiderstands entgegen zu wirken.&lt;br /&gt;
&lt;br /&gt;
Es gibt viele verschiedene Schaltungen, die zu diesem Zweck eingesetzt werden. Sie unterscheiden sich in ihrer Präzision, der minimalen und maximalen Betriebsspannung, und dem Bauteilaufwand. Es sollen hier nur einige besonders einfache Schaltungen vorgestellt werden.&lt;br /&gt;
&amp;lt;div class=&amp;quot;toclimit-2&amp;quot;&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konstantstromquelle mit J-FET ==&lt;br /&gt;
&lt;br /&gt;
=== Beschreibung ===&lt;br /&gt;
&lt;br /&gt;
Eine sehr einfache Konstantstromquelle lässt sich mit einem [[FET|JFET]] realisieren. Der resultierende Strom ist durch den verwendeten FET bestimmt, dabei wird die Eigenschaft genutzt, dass der JFET selbstleitend ist, also bei einer Gate-Source-Spannung von 0V seinen maximal möglichen Strom leitet und bei ansteigender negativer Gate-Source-Spannung U_GS den Drain-Source-Kanal zunehmend abschnürt. Es werden Bauteile angeboten, bei denen die Verbindung zwischen Gate und Source des FET schon intern vorgenommen wurde (Konstantstromdiode, engl. current regulator diode). Diese werden mit engeren Toleranzen gefertigt und erlauben daher eine genauere Definition des Stroms. Außerdem benötigen diese keinen Widerstand in der Sourceleitung und haben damit weniger Spannungsabfall im Betrieb.&lt;br /&gt;
&lt;br /&gt;
=== Vorteile ===&lt;br /&gt;
&lt;br /&gt;
* Großer Betriebsspannungsbereich, nach oben nur durch die maximale Drain-Source-Spannung (V_DS) des FETs und seine maximale Verlustleistung begrenzt.&lt;br /&gt;
* Einfachster Aufbau&lt;br /&gt;
&lt;br /&gt;
=== Nachteile ===&lt;br /&gt;
&lt;br /&gt;
* Beeinflussung durch Toleranzen der Fertigungsparameter des FET, typ. +/- 10%&lt;br /&gt;
* hohe Sättigungsspannung über dem FET, typ. 1-3V&lt;br /&gt;
* nur mäßig temperaturstabil&lt;br /&gt;
* selbstleitende FETs für Ströme größer als 30mA sind selten und entsprechend teuer&amp;lt;ref&amp;gt;Es gibt aber einige Depletion-Mode Mosfets mit sehr hohen Sperrspannungen und z.T. auch grösseren Strömen.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Schaltung ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:Konstantstrom.gif]]&lt;br /&gt;
&lt;br /&gt;
=== Weblinks ===&lt;br /&gt;
* [http://www.vishay.com/docs/70596/70596.pdf Vishay AN103 - The FET Constant-Current Source/Limiter]&lt;br /&gt;
* [http://www.elektronik-kompendium.de/sites/slt/0207011.htm ELKO: FET als Konstantstromquelle]&lt;br /&gt;
* [http://www.elektronik-kompendium.de/public/schaerer/curr2pol.htm ELKO: Der Transistor-LED-und der FET-Konstantstromzweipol]&lt;br /&gt;
* [[Mosfet-Übersicht#N-Kanal J-FET | Liste von J-FETs]]&lt;br /&gt;
* [http://search.datasheetcatalog.net/key/LM334 LM334] betagter, aber guter IC, programmierbare Konstantstromquelle mit 1µA-10mA, 0,8-1V Spannungsabfall, kann per Transistor auf deutlich größere Ströme erweitert werden.&lt;br /&gt;
&lt;br /&gt;
== Konstantstromquelle mit bipolaren Transistoren ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:Ksq.png|thumb|right|231px|U&amp;lt;sub&amp;gt;BE&amp;lt;/sub&amp;gt;-Konstantstromquelle]]&lt;br /&gt;
Die auch als U&amp;lt;sub&amp;gt;BE&amp;lt;/sub&amp;gt;-Konstantstromquelle bekannte Stromquelle funktioniert folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
Über R2 wird ein Strom in die Basis von T1 eingespeist, dadurch fließt in T1 ein Kollektorstrom, welcher gleichzeitig der Laststrom ist, welcher konstant gehalten werden soll. Die Summe aus Kollektor- und Basisstrom von T1 fließt durch R1 und erzeugt über ihm einen Spannungsabfall. Wenn die Spannung über R1 die Basis-Emitter-Flußspannung von T2 überschreitet (ca. 0,7V), beginnt ein Kollektorstrom durch T2 zu fließen. Dadurch fließt ein Teil des Basisstroms von T1 in den Kollektor von T2 ab. Da der Basisstrom von T1 nun nicht weiter ansteigen kann, weil jeder Zuwachs als Kollektorstrom von T2 abfließt, bleibt der Strom durch R1 und damit auch die Last konstant. So stellt sich diese Schaltung auf eine konstante BE-Spannung von ca. 0,7V über R1 ein, je nach verwendetem Transistor. R1 berechnet sich daher wie folgt:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
R1 &amp;amp; = \frac{U_{BE,T2}}{I_{\text{soll}}} = \frac{0.7\text{V}}{I_{\text{soll}}}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
R2 wird so ausgelegt, dass T1 grundsätzlich sättigen kann. Siehe dazu [[Basiswiderstand]]. Ein guter Richtwert bei 5V Vcc ist 4,7kΩ. Anstatt &#039;&#039;&#039;T2&#039;&#039;&#039; kann auch eine Leuchtdiode verwendet werden, dazu den Basisanschluss weglassen. Die LED leuchtet auf, wenn die Stromquelle regelt, und verlischt bei Leerlauf. So lassen sich einfache Konstantstrom-Ladegeräte mit Kontrollanzeige aufbauen. Eine temperaturstabile Präzisions-Stromquelle entsteht durch Ersetzen von &#039;&#039;&#039;T2&#039;&#039;&#039; durch einen TL431[http://www.mikrocontroller.net/part/TL431].&lt;br /&gt;
&lt;br /&gt;
=== Vorteile ===&lt;br /&gt;
* Gut bei niedriger Betriebsspannung, da Schaltung bereits mit kleiner Restspannung am Transistor T1 läuft und die Regelung auch dann erfolgt, wenn nur noch wenige hundert mV zwischen Kollektor und Emitter des Transistors T1 anliegen.&lt;br /&gt;
:: &amp;lt;math&amp;gt;U_{BE,T2}+U_{CE,T1} \approx 0{,}65\,\text{V}+0{,}15\,\text{V}&amp;lt;/math&amp;gt;&lt;br /&gt;
* Einfachster Aufbau mit Standardbauteilen, d.h. kann aus Resten aus der Bastelkiste aufgebaut werden&lt;br /&gt;
&lt;br /&gt;
=== Nachteile ===&lt;br /&gt;
* Nicht temperaturkompensiert, der Strom schwankt um ca. 0,26%/K&lt;br /&gt;
:: &amp;lt;math&amp;gt;\frac{\Delta U_{BE}}{R1} \quad\text{ mit }\quad \Delta U_{BE} \left(\Delta\vartheta\right) \approx -1{,}7 \,\frac{\text{mV}}{\text{K}} \cdot \Delta\vartheta&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:Ksq_2T_sim.svg|thumb|right|300px|Analyse bei steigender Versorgungsspannung]]&lt;br /&gt;
&lt;br /&gt;
=== Weblinks ===&lt;br /&gt;
* [http://www.elektronik-kompendium.de/sites/slt/0210253.htm ELKO: Transistor als Konstantstromquelle]&lt;br /&gt;
* [http://www.elektronik-kompendium.de/public/schaerer/currled.htm ELKO: Die Transistor-LED-Konstantstromquelle mit ein oder zwei Transistoren und Konstantstromquelle mit Bandgap und Opamp]&lt;br /&gt;
* [http://www.elektronik-kompendium.de/public/schaerer/curr2pol.htm ELKO: Der Transistor-LED-und der FET-Konstantstromzweipol]&lt;br /&gt;
* [http://www.ferromel.de/tronic_6.htm Verschiedene Konstantstromquellen mit Beschreibung]&lt;br /&gt;
* [http://www.elexs.de/kap5_9.htm Konstantstromquelle bei ELEXS]&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
== Konstantstromquelle mit Operationsverstärker und Transistor ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:Ksq_opv.png|thumb|right|231px|Konstantstromquelle mit OPV und Bipolartransistor]]&lt;br /&gt;
&lt;br /&gt;
Der Strom, welcher konstant gehalten werden soll, wird durch R2 gemessen (Shunt). Der OPV arbeitet als Spannungsfolger und versucht, die Spannung am - Eingang so groß wie am + Eingang zu halten. Ist z.B. die Spanunng am - Eingang etwas kleiner als am + Eingang (Bruchteile von mV!), dann steigt die Ausgangsspannung des OPV um einige mV und erhöht damit die Basis-Emitter-Spannung von T1 und damit den Basisstrom. Dadurch fließt ein höherer Kollerktorstom, welcher wiederum einen höheren Spannungsabfall über R2 verursacht, bis die Spannungen am - und + Eingang des OPV wieder absolut gleich sind (die Offsetspannung wird hier zunächst vernachlässigt). Die Beispielschaltung hier ist bei ausreichender [[Kühlkörper|Kühlung]] für T1 für ca. 1A brauchbar. Der Strom wird mit 0-100mV eingestellt. Der [[Basiswiderstand]] R4 wird nicht klassisch berechnet, da er hier eine etwas andere Funktion hat. Er dient mehreren Zwecken:&lt;br /&gt;
* Strombegrenzung des OPV im Extremfall, wenn die Last am Kollektor nicht angeschlossen ist. Dann versucht der OPV mit maximaler Ausgangsspannung den Strom durch R2 zu treiben, schafft das aber nicht.&lt;br /&gt;
* Verringerung der Verstärkung des Regelkreises. Damit kann man je nach Schaltung und OPV den Regelkreis stabil bekommen, falls er schwingt. Das ist auch von der internen Kompensation des OPVs abhängig und kann sehr verschieden sein.&lt;br /&gt;
* Schutz des OPV-Ausgangs im Fall der Überlastung von T1. Sollte dieser wegen Überlastung, Überspannung etc. kaputt gehen, so kann die Kollektorspannung an den OPV-Ausgang gelangen und diesen zerstören. Durch R4 wird der Strom begrenzt und damit eine Zerstörung verhindert.&lt;br /&gt;
Die Dimensionierung ist ein Kompromiss dieser drei Aufgaben, wobei man entscheiden muss, welche wichtiger ist. Um den den optimalen Wert zu finden, muss man meist auch einige Versuche durchführen. &lt;br /&gt;
&lt;br /&gt;
Nachteilig ist, dass der Basisstrom von T1 nicht durch die Last fließt, aber durch R2 und somit die Konstantstromregelung verfälscht. Als Gegenmaßnahme nutzt man einen Darlingtontransistor mit sehr hoher Stromverstärkung von 1000 und mehr, was bedeutet, dass der verfälschende Basisstrom nur noch 1 Promille Fehler verursacht. Alternativ kann man mit gerade mal zwei clever platzierten Widerständen den Fehler des Basisstroms nahezu vollständig kompensieren, wie es in diesem [http://www.edn.com/design/power-management/4318484/Error-compensation-improves-bipolar-current-sinks Artikel] in [http://m.eet.com/media/1128969/12734-figure_3.pdf Figure 3] dargestellt ist. Das hat den Vorteil, dass man einfache Bipolartransistoren nutzen kann, welche deutlich höhere Grenzfrequenzen als Darlingtons aufweisen. &lt;br /&gt;
Eine weitere Möglichkeit ist die Verwendung eines MOSFET, dieser hat Gateströme (Leckströme) im Bereich von unter einem Mikroampere. Dieser Fehler fällt bei 99,9% der Anwendungen nicht ins Gewicht. Prüfen sollte man dabei, dass der MOSFET für [[FET#Linearbetrieb_von_MOSFETs | Linearbetrieb]] geeignet ist, denn das sind viele Hochleistungs-MOSFETs nicht! Hier wird noch ein zusätzlicher Widerstand vor dem Gate des MOSFETs geschaltet, um die hohe Kapazität des Gates vom OPV-Ausgang zu entkoppeln, welche viele OPVs wieder instabil machen würde.&lt;br /&gt;
&lt;br /&gt;
[[Datei:Ksq_opv_mosfet.png|thumb|right|231px|Konstantstromquelle mit OPV und N-Kanal-MOSFET]]&lt;br /&gt;
&lt;br /&gt;
Wichtig sind R1 und C1. In vielen Schaltungen im Internet fehlen sie, die Spannung über R2 geht direkt an den - Eingang des OPV. Das ist aber falsch und funktioniert oft nur durch Zufall. Denn R1 und C1 sind wichtig für die Frequenzgangkompensation des OPV. Die Schaltung ist ein [http://de.wikipedia.org/wiki/Regelkreis Regelkreis] und diese sind für notorische Instabilitäten bekannt, d.h. sie schwingen. Durch Rechnung oder Probieren muss der richtige Wert für R1 und C1 gefunden werden, bei denen die Stromquelle ausreichend schnell reagiert ohne zu schwingen. Testen kann man das u.a. dadurch, dass man einen Sprung auf den Eingang gibt, z.B. mit einem Funktionsgenerator oder einfach einem NE555 als Taktgeber. Dabei beobachtet man die Spannung über R2 mit dem Oszilloskop, ggf. auch am Ausgang des OPV. Hier sieht man wie schnell die Stromquelle reagiert und ob sie schwingt.&lt;br /&gt;
&lt;br /&gt;
=== Vorteile ===&lt;br /&gt;
* Große Ströme können sehr genau und schnell geregelt werden, nur durch T1 und dessen Kühlung begrenzt&lt;br /&gt;
* einfacher Aufbau mit Standardkomponenten&lt;br /&gt;
* wird oft als Stromregler in elektronischen Lasten benutzt&lt;br /&gt;
&lt;br /&gt;
=== Nachteile ===&lt;br /&gt;
* bei sehr hohen Stömen muss man eine Vierdrahtmessung an R2 vornehmen&lt;br /&gt;
* hohe Verlustleistung bei kleinen Lastwiderständen und hoher Betriebsspannung (lineare Stromquelle)&lt;br /&gt;
* nur Einquadrantenbetrieb möglich&lt;br /&gt;
&lt;br /&gt;
=== Weblinks ===&lt;br /&gt;
*Analog by Design Show - Hosted by Bob Pease&lt;br /&gt;
** [http://www.youtube.com/watch?v=411f0DvXu18 Konstantstromquellen]&lt;br /&gt;
** [http://www.youtube.com/watch?v=2N6cjGS7lUE Präzise 1A Konstantstromquelle ]&lt;br /&gt;
&lt;br /&gt;
== Stromspiegel als Konstantstromquelle ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:Stromspiegel als Konstantstromquelle.svg|miniatur|Stromspiegel mit Widerstand]]&lt;br /&gt;
Bei stabiler Versorgungsspannung eignet sich ein Stromspiegel mit Widerstand als Spannungs-Stromwandler und findet sich beispielsweise in älteren Operationsverstärkern wie dem LM741. Das Konzept des Stromspiegels wird an dieser Stelle nicht weiter erläutert.&lt;br /&gt;
&lt;br /&gt;
Die Widerstände R2 und R3 reduzieren die Auswirkungen von Bauteiltoleranzen und den Temperaturdrift. Als grober Richtwert sollte deren Spannungsabfall 0,2 V oder mehr betragen. T1 und T2 sind identische Transistortypen (z.B. BC557B), die idealerweise von einer Bauteilrolle stammen.&lt;br /&gt;
&lt;br /&gt;
Bei geeigneter Wahl von R2 und R3 oder Parallelschaltung von Transistoren wird aus dem Stromspiegel ein Stromvervielfacher. Bei gleichen Transistoren und gleichen Widerständen entsteht ein 1:1 Stromspiegel.&lt;br /&gt;
&lt;br /&gt;
Berechnung:&lt;br /&gt;
&lt;br /&gt;
Die Versorgungsspannung U&amp;lt;sub&amp;gt;B&amp;lt;/sub&amp;gt; und der gewünschte Strom I sind bekannt&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;I_{ref} = \frac{U_B - 0{,}65 V}{R1+R2}&amp;lt;/math&amp;gt; (Ausgangsformel)&lt;br /&gt;
:&amp;lt;math&amp;gt;R3 = R2&amp;lt;/math&amp;gt; (1:1 Stromspiegel)&lt;br /&gt;
:&amp;lt;math&amp;gt;I = I_{ref}&amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt;R1 + R2 = R_g = \frac{U_B - 0{,}65 V}{I}&amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt;U_{R2} \approx 0{,}2 V&amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt;R2 = \frac{U_{R2}}{I}=\frac{0{,}2 V}{I}&amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt;R1 = R_g - R2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vorteile ===&lt;br /&gt;
&lt;br /&gt;
* wenige, günstige Bauteile&lt;br /&gt;
* sehr einfache Konstruktion&lt;br /&gt;
* mäßiger Spannungsabfall (ca. 1V)&lt;br /&gt;
* schnell, da keine ausgeprägte Rückkopplung vorhanden&lt;br /&gt;
* zur Stromsenke umformbar (Überkopf stellen und npn-Typen verwenden)&lt;br /&gt;
&lt;br /&gt;
=== Nachteile ===&lt;br /&gt;
&lt;br /&gt;
* geringer Wirkungsgrad, doppelt wegen Referenzstrom&lt;br /&gt;
* mäßig hoher Quellenwiderstand (einfacher Stromspiegel)&lt;br /&gt;
&lt;br /&gt;
== PTAT-Konstantstromquelle ==&lt;br /&gt;
&lt;br /&gt;
:→ siehe  [[PTAT-Stromquelle]]&lt;br /&gt;
&lt;br /&gt;
== Konstantstromquelle mit Linearreglern ==&lt;br /&gt;
&lt;br /&gt;
=== Grundschaltung mit LM317 ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:LM317_constant_current.png|thumb|right|280px|Konstantstromquelle mit LM317]]&lt;br /&gt;
&lt;br /&gt;
Eine sehr einfache, günstige und doch genaue Konstantstromquelle kann mittels LM317 aufgebaut werden. Für einen LED-Strom von 20mA ist ein R1 von 62,5 Ω erforderlich, praktisch wird man 68Ω wählen. Dabei ist zu beachten, daß die Eingangsspannung &#039;&#039;V&#039;&#039;&amp;lt;sub&amp;gt;in&amp;lt;/sub&amp;gt; mindestens 3,5V + &#039;&#039;U&#039;&#039;&amp;lt;sub&amp;gt;f,LED&amp;lt;/sub&amp;gt; (Flußspannung der LED) betragen muss.&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
==== Vorteile ====&lt;br /&gt;
&lt;br /&gt;
* temperaturstabil&lt;br /&gt;
* sehr wenige, billige Bauteile&lt;br /&gt;
&lt;br /&gt;
==== Nachteile ====&lt;br /&gt;
&lt;br /&gt;
* Überschwinger beim Einschalten können vorkommen, so dass sensible Lasten zerstört werden können.&lt;br /&gt;
* Hoher Spannungsabfall über der Schaltung von mind. 3,5V&lt;br /&gt;
* Verlustleistung&lt;br /&gt;
:: &amp;lt;math&amp;gt;PV_\text{LM317} = I_\text{out}\cdot (V_\text{in}- U_\text{f,LED} -1,25\,\mathrm V)&amp;lt;/math&amp;gt;&lt;br /&gt;
* Abhängig vom Gehäuse ist bei höheren Eingangsspannungen ein [[Kühlkörper]] am LM317 nötig:&lt;br /&gt;
** TO220: 1W&lt;br /&gt;
** TO92: 500mW&lt;br /&gt;
** SO-8: 600mW&lt;br /&gt;
* Bei niedrigen Strömen unter 3.5 mA ungenau (min. Load Current 3.5 mA laut Datenblatt)&lt;br /&gt;
&lt;br /&gt;
==== Schrittweise einstellbare Variante ====&lt;br /&gt;
&lt;br /&gt;
Eine schrittweise voreinstellbare Variante der Grundschaltung wurde 2008 von einem Mitarbeiter von National Semiconductor (Hersteller des LM317) im EDN-Magazin vorgestellt: [http://m.eet.com/media/1132369/14758-figure_1.pdf  Programmable current source requires no power supply]. Dabei ist hier mit &#039;&#039;programmable&#039;&#039; manuell voreinstellbar gemeint, nicht Mikrocontroller-gesteuert. Auch der Teil des Titles &#039;&#039;requires no power supply&#039;&#039; ist irreführend. Die Konstantstromquelle benötigt sehr wohl eine externe Stromversorgung. Die Schaltung benötigt lediglich keine zusätzlichen Hilfsspannungen, entspricht sie doch der oben genannten Grundschaltung.&lt;br /&gt;
&lt;br /&gt;
Mittels dreier 0−9 BCD-Schalter werden geschickt gewählte Widerstände zwischen ADJ und OUT parallel geschaltet. Die Widerstände sind so gewählt, dass der erste Schalter mit seinen zehn Stellungen und Widerständen zwischen 0 mA und 9 mA in 1 mA Schritten zum Gesamtstrom beiträgt, der zweite 0 mA bis 90 mA in 10 mA Schritten und der dritte 0 mA bis 900 mA in 100 mA Schritten. &lt;br /&gt;
&lt;br /&gt;
In dieser Kombination ergibt das eine einstellbare Konstantstromquelle bis 999 mA in 1mA-Schritten bei rund 2% Genauigkeit.&lt;br /&gt;
&lt;br /&gt;
Insgesamt werden &lt;br /&gt;
&lt;br /&gt;
* 45 Widerstände, alle 1%, 1/4 W&lt;br /&gt;
** 15 × 1,24 kΩ&lt;br /&gt;
** 15 × 124 Ω&lt;br /&gt;
** 15 × 12,4 Ω&lt;br /&gt;
* ein LM317&lt;br /&gt;
* drei 0−9 BCD-Schalter und&lt;br /&gt;
* Gehäusematerial (Gehäuse, Kühlkörper für den LM317, Polklemmen, ...)&lt;br /&gt;
benötigt.&lt;br /&gt;
&lt;br /&gt;
Der LM317 wird bei dieser einstellbaren Stromquelle gerade noch innerhalb seiner Spezifikation betrieben - wenn man den Spannungsabfall über ihn gering hält. Im Stromquellen-Beispiel im Datenblatt wird ein maximaler Widerstand von 120 Ω genannt, wohingegen die einstellbare Stromquelle bis zu 1,24 kΩ (nominell 1 mA Ausgangsstrom) und ∞ Ω (offen, nominell 0 mA Ausgangsstrom) verwendet. Mit etwas Geduld kann man aus dem Datenblatt herauslesen, dass 1,24 kΩ gerade noch ausreichen, damit die Regelung des LM317 nicht aussetzt. Dies findet man im Datenblatt in der Grafik &#039;&#039;Minimum Operating Current&#039;&#039; und im Beispiel &#039;&#039;1.2V-20V Regulator with Minimum Program Current&#039;&#039;. Mit ∞ Ω ist man definitiv außerhalb des Arbeitsbereiches.&lt;br /&gt;
&lt;br /&gt;
Der Strom bei der Einstellung 000 mA (Widerstand → ∞ Ω, d.h. offen) entspricht nicht 0,0 mA, sondern dem Strom aus dem ADJ-Anschluss für den nicht spezifizierten Fall, dass der LM317 außerhalb seines Arbeitsbereiches betrieben wird. Die im Datenblatt angegebenen 50 µA (typ.), 100 µA (max.) für den Arbeitsbereich können dabei je nach Exemplar überschnitten werden und sind nicht konstant. &lt;br /&gt;
&lt;br /&gt;
Die Messung an neueren Chargen (gefertigt nach 2006) des LM317 diverser Hersteller zeigt, dass auch 1mA nicht sicher erreichbar sind. Es ist vielmehr so, das diese KSQ erst korrekt ab 003 mA bis hoch zu den 999 mA funktioniert. Das heißt konkret, die Einstellungen 000 mA, 001 mA und 002 mA sind nicht mehr stromstabilsiert. Das sollte man beachten, sofern man unbedingt den LM317 bei sehr kleinen Strömen einsetzen möchte.&lt;br /&gt;
&lt;br /&gt;
In der Praxis lohnt es sich besonders bei kleinen Strömen ein Strommessgerät in Reihe zu schalten. Dabei ist Vorsicht bei billigen Multimetern geboten&amp;lt;ref&amp;gt;Bei billigen Multimetern ist auch aus anderen Gründen immer Vorsicht geboten. Siehe [http://gps.sozialnetz.de/global/show_document.asp?id=aaaaaaaaaaaajxn Schwerpunktaktion „Handmultimeter“ der hessischen Marktüberwachung ...]&amp;lt;/ref&amp;gt;. Deren niedrige Strommessbereiche sind häufig mit einer 200 mA oder 250 mA Schmelzsicherung abgesichert. Schaltet man die Stromquelle versehentlich über 200 mA, beziehungsweise 250 mA, ist ein Sicherungswechsel fällig.&lt;br /&gt;
&lt;br /&gt;
==== Weblinks ====&lt;br /&gt;
&lt;br /&gt;
* National Semiconductor Datenblatt [http://www.national.com/ds/LM/LM117.pdf LM117/LM317A/LM317 3-Terminal Adjustable Regulator]&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/konstantstrom.php Passenden Widerstand für Konstantstromschaltung mit LM317 berechnen]&lt;br /&gt;
* [http://www.lumitronixforum.de/viewtopic.php?t=2611&amp;amp;highlight=lm317 Einfachste Konstantstromquelle mit dem LM317]&lt;br /&gt;
* [http://www.umnicom.de/Elektronik/Schaltungssammlung/Strom/Quelle/Stromquelle.html Konstantstromquelle bis 3A mit LM2576]&lt;br /&gt;
*[http://www.edn.com/contents/images/6566536.pdf Programmable current source requires no power supply]&lt;br /&gt;
&lt;br /&gt;
==== Preise ====&lt;br /&gt;
&lt;br /&gt;
; LM317:&lt;br /&gt;
* TO3: 1,90 €&lt;br /&gt;
* TO-220: &amp;lt; 0,25 €&lt;br /&gt;
* TO-92: &amp;lt; 0,15 €&lt;br /&gt;
* SO-8: &amp;lt; 0,20 €&lt;br /&gt;
&lt;br /&gt;
=== Andere Linearregler ===&lt;br /&gt;
&lt;br /&gt;
Der zuvor beschriebene LM317 eignet sich besonders gut als Stromquelle, da er seine Regelspannung auf der &#039;high-side&#039; erwartet (1,25 V zwischen Vout und ADJ) und man den Regelpfad als Konstantstrompfad missbrauchen kann (ADJ als Ausgang nach GND, wobei der Strom über den Widerstand und nicht von ADJ geliefert wird)).&lt;br /&gt;
&lt;br /&gt;
==== Mittels Shunt und Messverstärker ====&lt;br /&gt;
&lt;br /&gt;
Die meisten anderen Linearregler messen ihre Regelspannung im Bezug auf GND. Um einen solchen Regler als Konstantstromquelle zu benutzen, kann man einen Stromsensor und einen Messverstärker verwenden. Letzterer steuert dann die Regelung des Linearreglers. Maxim hat in [http://www.maxim-ic.com/app-notes/index.mvp/id/921] ein Beispiel veröffentlicht, das so oder so ähnlich auch mit anderen Linearreglern funktioniert. Maxim misst den Strom auf der Eingangsseite. Vorteil: der Innenwiderstand des Ausgangs des Linearreglers wird durch den Messwiderstand nicht erhöht. Nachteil: Der Eigenverbrauch des Linearreglers wird mitgemessen.&lt;br /&gt;
&lt;br /&gt;
Man kann den Strom auch auf der Ausgangsseite messen.&lt;br /&gt;
&lt;br /&gt;
Das gleiche Prinzip funktioniert für Schaltregler, siehe zum Beispiel [[#LM2576_Step_Down| LM2576 Step Down]] auf dieser Seite.&lt;br /&gt;
&lt;br /&gt;
==== Im Regelpfad - High-Side ====&lt;br /&gt;
&lt;br /&gt;
              .-----------.&lt;br /&gt;
 VCC       IN |           | OUT&lt;br /&gt;
  ------------o           o------&amp;gt;----.&lt;br /&gt;
              |           |      I    |                 |&lt;br /&gt;
              |           |           |                 |&lt;br /&gt;
              |           |          .-.                |&lt;br /&gt;
              |           |          | |                |&lt;br /&gt;
              |           |          | |  Rload, R1     |&lt;br /&gt;
              |           |          &#039;-&#039;                |&lt;br /&gt;
              |           |           |                 |&lt;br /&gt;
              |           | FB        |                 |&lt;br /&gt;
              |           o------&amp;lt;----o                 |Vout&lt;br /&gt;
              |           |    Iref   |        |        |&lt;br /&gt;
              |           |           |        |        |&lt;br /&gt;
              |           |          .-.       |        |&lt;br /&gt;
              |           |          | |       | Vref   |&lt;br /&gt;
              |           |          | |  R2   |        |&lt;br /&gt;
              &#039;-----o-----&#039;          &#039;-&#039;       |        |&lt;br /&gt;
                    | GND             |        |        |&lt;br /&gt;
                    |                 |        |        |&lt;br /&gt;
                   ===               ===       v        v&lt;br /&gt;
                   GND               GND&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                             Iref &amp;lt;&amp;lt; I&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die meisten einstellbaren Linearregeler werden durch einen Spannungsteiler (R&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;, R&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;) zwischen Ausgangsspannung (V&amp;lt;sub&amp;gt;out&amp;lt;/sub&amp;gt;) und Masse (GND) eingestellt. Der Spannungsteiler wird dabei so dimensioniert, dass eine vorgegebene Spannung V&amp;lt;sub&amp;gt;ref&amp;lt;/sub&amp;gt; (meist 1,25 V) gegen GND an der Anzapfung des Spannungsteilers abfällt, die dann zum Regeleingang des Linearreglers geführt wird. Dabei wird üblicherweise angenommen, dass der Strom I&amp;lt;sub&amp;gt;ref&amp;lt;/sub&amp;gt; in den Regler hinein vernachlässigbar ist.&lt;br /&gt;
&lt;br /&gt;
Dann gilt für den Strom I im Spannungsteiler:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;I = I_{R_1} = I_{R_2} = \frac{V_\text{out}}{R_1 + R_2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
und &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;I_{R_2} = \frac{V_\text{ref}}{R_2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Strom I im Spannungsteiler ist somit alleine durch Wahl von R&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; bestimmt und unabhängig von R&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; bei vorgegebenem R&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ersetzt man daher R&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; durch die Last, so erzeugt der Linearregler durch Steuerung von V&amp;lt;sub&amp;gt;out&amp;lt;/sub&amp;gt; einen konstanten Strom&lt;br /&gt;
&lt;br /&gt;
:{|cellpadding=&amp;quot;2&amp;quot; style=&amp;quot;border:2px solid #ccccff&amp;quot;&lt;br /&gt;
|&amp;lt;math&amp;gt;I = \frac{V_\text{ref}}{R_2}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
durch die Last.&lt;br /&gt;
&lt;br /&gt;
Dabei muss man die Grenzen des Linearreglers beachten:&lt;br /&gt;
&lt;br /&gt;
Der maximale Strom &#039;&#039;I&#039;&#039;&amp;lt;sub&amp;gt;max&amp;lt;/sub&amp;gt; des Reglers darf nicht überschritten werden. Damit die Annahme gilt, dass der Reglerstrom &#039;&#039;I&#039;&#039;&amp;lt;sub&amp;gt;ref&amp;lt;/sub&amp;gt; gegenüber dem Strom &#039;&#039;I&#039;&#039; im Spannungsteiler vernachlässigbar ist muss R&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; klein gegenüber dem Innenwiderstand des Regeleingangs sein. Dass bedeutet, dass R&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; so zu wählen ist, dass immer gilt:&lt;br /&gt;
&lt;br /&gt;
:{|cellpadding=&amp;quot;2&amp;quot; style=&amp;quot;border:2px solid #ccccff&amp;quot;&lt;br /&gt;
|&amp;lt;math&amp;gt;\frac{V_\text{ref}}{I_\text{max}} \leqq R_2 \ll R_\text{in,ref} = \frac{V_\text{ref}}{I_\text{ref}}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Es muss ein Minimalstrom &#039;&#039;I&#039;&#039;&amp;lt;sub&amp;gt;min&amp;lt;/sub&amp;gt; durch den Spannungsteiler fließen, damit die Regelung nicht aussetzt. Für diesen Strom gilt gegenüber dem Regelstrom &#039;&#039;I&#039;&#039;&amp;lt;sub&amp;gt;ref&amp;lt;/sub&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;I_\text{min} = \frac{V_\text{out,min}}{R_1 + R_2} \gg I_\text{ref}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;V_\text{out,min} = V_\text{ref}\,&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
folgt&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;R_1 \ll \frac{V_\text{ref}}{I_\text{ref}} - R_2 = R_\text{in,ref} - R_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Angenähert:&lt;br /&gt;
&lt;br /&gt;
:{|cellpadding=&amp;quot;2&amp;quot; style=&amp;quot;border:2px solid #ccccff&amp;quot;&lt;br /&gt;
|&amp;lt;math&amp;gt;R_\text{load} \approx R_1 \ll \frac{V_\text{ref}}{I_\text{ref}}&amp;lt;/math&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Neben diesen Einschränkungen ist auch zu beachten, dass Die Last R&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; auf der High-Side hängt und nicht gegen GND.&lt;br /&gt;
&lt;br /&gt;
== Konstantstromquelle mit Schaltregler ==&lt;br /&gt;
Am günstigsten erscheinen Tiefsetzsteller (StepDown-Schaltregler), die mit einer großen Drossel im nichtlückenden Bereich arbeiten. Dann ist der Strom-Ripple (Wechselspannungsanteil) durch die Induktivität und Schaltfrequenz vorgegeben. Ein weiteres Glätten des Stromes ist dann gar nicht mehr erforderlich. Es sind nahezu beliebig große Gleichströme bereitstellbar.&lt;br /&gt;
=== MC34063, Step Up ===&lt;br /&gt;
==== Beschreibung ====&lt;br /&gt;
Der Ausgangsstrom beträgt 1,25V/Rx. Die Stromquelle ist &#039;&#039;&#039;nicht&#039;&#039;&#039; kurzschlussfest. Der Widerstand Rsc dient der Strombegrenzung der einzelnen Strompulse (Schaltregler), was u.a. einen gewissen Überlastschutz für den MC34063 darstellt. Rsc = 0.3/I_max, wobei I_max der maximale Pulsstrom ist und dieser kleiner 1.5A sein muss, weil der IC nicht mehr hergibt. In den meisten Anwendungen nimmt man hier 0,22Ω oder mehr. &lt;br /&gt;
Das Ganze kann man z.&amp;amp;nbsp;B. für mehrere LEDs in Reihe verwenden um diese mit&lt;br /&gt;
5V oder mit 4x 1,5V Batterien zu betreiben. Weiterhin ist zu beachten,&lt;br /&gt;
dass die Schaltung nicht leerlauffest ist: Im Leerlauf läuft die&lt;br /&gt;
Spannung auf &amp;gt;40V, und dann geht der MC34063 kaputt. Daher sollte man&lt;br /&gt;
zur Sicherheit eine Z-Diode parallel zum Ausgang legen, deren Z-Spannung 2..3V über der maximal zu erwartenden Ausgangsspannung liegt, wenn es&lt;br /&gt;
passieren kann, dass die Last abgeklemmt wird.&lt;br /&gt;
Aufgrund des Elkos am Ausgang ist die Stromquelle recht träge. R1 dient dazu den MC34063 vor dem Stromstoß zu schützen, wenn sich der Elko in eine zu kleine Last entlädt und der Strom kurzzeitig höher als der eingestellte Wert wird.&lt;br /&gt;
Die Bauteilwerte sind alle relativ unkritisch. Je nach Betriebsspannung sind die Bauteilwerte etwas anzupassen um den optimalen Wirkungsgrad und die beste Performance zu erzielen. Die eingezeichneten Bauteilwerte sind für geringe Ströme (&amp;lt;100mA) und Eingangsspannungen zwischen 5 und 15V ausgelegt. R2 sollte bei hohen Spannungen vergrößert werden. Wie man die Werte genau berechnet, steht in der Application Note AN920/D.&lt;br /&gt;
http://www.onsemi.com/pub/Collateral/AN920-D.PDF&lt;br /&gt;
&lt;br /&gt;
Stromquellen sollten grundsätzlich &#039;&#039;keinen&#039;&#039; Ausgangselko aufweisen! Wie die Schaltregler-Schaltung dann stabil arbeitet muss gesondert herausgefunden werden.&lt;br /&gt;
&lt;br /&gt;
==== Schaltung ====&lt;br /&gt;
&lt;br /&gt;
[[Bild:mc34063_constant_current.gif]]&lt;br /&gt;
&lt;br /&gt;
==== Vorteile ====&lt;br /&gt;
* überschüssige Spannung wird nicht verheizt&lt;br /&gt;
&lt;br /&gt;
==== Nachteile ====&lt;br /&gt;
* nicht kurzschlussfest&lt;br /&gt;
* ohne Z-Diode D2 nicht leerlauffest&lt;br /&gt;
* träge beim Einschalten&lt;br /&gt;
&lt;br /&gt;
=== MC34063, Step Down ===&lt;br /&gt;
==== Beschreibung ====&lt;br /&gt;
&lt;br /&gt;
Die Step-Down Version funktioniert im Prinzip genauso wie die normale, lineare Konstantstromquelle, nur dass die ungenutzte Spannung nicht sinnlos verheizt wird. Der Ausgangsstrom beträgt 1,25V/Rx. Die Eingangsspannung muss mindestens 2V größer sein als die Ausgangsspannung.&lt;br /&gt;
&lt;br /&gt;
Diese Version ist auch ohne die Z-Diode leerlauffest. Kurzschlussfest wird sie durch Rsc. Allerdings entlädt sich der Elko erstmal in die Last, wenn man diese im Betrieb anklemmt. Dadurch kann die Last und der MC34063 beschädigt werden, der Widerstand R1 verhindert aber letzteres.&lt;br /&gt;
&lt;br /&gt;
Bei der Step-Down Version kann man die Elkos etwas kleiner machen, als bei der Step-Up Version, da der Stromfluss durch die Spule in die Last nahezu konstant ist. Wenn man die Spule vergrößert, wird der Strom gleichmäßiger und man kann die Elkos verkleinern. Allerdings wird der Wirkungsgrad aufgrund des höheren Gleichstromwiderstands der Spule schlechter und die Schaltung reagiert langsamer auf Laständerungen. Wie immer ist es also ein Kompromiss zwischen Wirkungsgrad, Kosten und Bauteilgröße.&lt;br /&gt;
&lt;br /&gt;
Konstantstromregler sollten grundsätzlich &#039;&#039;keinen&#039;&#039; Ausgangskondensator haben, weil dieser den gewünschten Regeleffekt zunichte macht. Wie die Rückführung zum Regelverstärker im Schaltregler regelschwingungsfrei gemacht wird muss dann gesondert herausgefunden werden.&lt;br /&gt;
&lt;br /&gt;
==== Schaltung ====&lt;br /&gt;
&lt;br /&gt;
[[Bild:mc34063_constant_current_2.gif]]&lt;br /&gt;
&lt;br /&gt;
==== Vorteile ====&lt;br /&gt;
* überschüssige Spannung wird nicht verheizt&lt;br /&gt;
* leerlauf &lt;br /&gt;
* kurzschlussfest&lt;br /&gt;
&lt;br /&gt;
==== Nachteile ====&lt;br /&gt;
* träge beim Ausschalten&lt;br /&gt;
&lt;br /&gt;
Besser ist hier eine [[Konstantstromquelle fuer Power LED]].&lt;br /&gt;
&lt;br /&gt;
=== LM2576 Step Down ===&lt;br /&gt;
In einem [http://www.mikrocontroller.net/topic/97838#new Beitrag] im Forum  wird folgende [http://www.mikrocontroller.net/attachment/34179/current_source.pdf Schaltung] genannt. Der vollständige Artikel ist [http://www.ednindia.com/article-621-switchingregularformsconstantcurrentsource-Asia.html hier] verfügbar.&lt;br /&gt;
&lt;br /&gt;
== Konstantstromquelle mit Komparatoren ==&lt;br /&gt;
=== Einfache Abwärtswandlung (Vout &amp;lt; Vin)===&lt;br /&gt;
&lt;br /&gt;
==== Beschreibung ====&lt;br /&gt;
&lt;br /&gt;
Diese Schaltung wurde eigentlich für 1W LEDs entworfen, kann aber sicherlich auch anderweitig verwendet werden. Sie ähnelt sehr der eines vollintegrierten Schaltreglers wie MC34063 oder LM2576, ohne jedoch einen solchen zu verwenden.&lt;br /&gt;
Der Komparator vergleicht den Spannungsabfall über einem Shunt mit dem einer Referenzspannungsquelle. Ist die Spannung über dem Shunt zu groß, so schaltet er ab und der P-Kanal MOSFET sperrt. Umgekehrt, ist die Spannung über dem Shunt kleiner als die Referenzspannung, leitet der P-FET. Q4 arbeitet als [[Konstantstromquelle]] und sorgt dafür, dass die Gateansteuerung auch bei unterschiedlichen Versorgungsspannungen immer gleich bleibt. Die Referenzspannung von 100mV wird hier einfach durch eine Z-Diode und einen Spannungsteiler eingestellt. Für D4 muss eine schnelle Diode eingesetzt werden, entweder eine Schottkydiode oder schnelle Siliziumdiode! Q2 und Q3 dienen als sehr einfacher [[FET|MOSFET]]-[[Treiber]]. D3 ist nur aus Sicherheitsgründen vorhanden, um die Gate-Source Spannung des MOSFETs zu begrenzen, sie kann ggf. auch weggelassen werden. Über den Anschluß PWM kann ein invertiertes [[PWM]]-Signal zur Dimmung eingespeist werden. Hierbei muss das PWM-Signal im HIGH-Zustand größer als ca. 1V sein, ein einfaches 3,3V oder 5V Logiksignal ist also voll OK.&lt;br /&gt;
&lt;br /&gt;
Der Ausgangsstrom kann durch Veränderung von R1 eingestellt werden. Der Wert kann einfach über die Formel&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;I_{aus}=\frac{V_{Ref}}{R1} = \frac{100mV}{R1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
bestimmt werden.&lt;br /&gt;
&lt;br /&gt;
==== Schaltung ====&lt;br /&gt;
&lt;br /&gt;
Platinendatei im Eagle-Format gibt es [http://www.mikrocontroller.net/wikifiles/3/38/LED_Stromregler.sch hier].&lt;br /&gt;
&lt;br /&gt;
[[Bild:LED_Stromregler.png|thumb|left|600px| Einfacher Stromregler aus Standardbauteilen]]&lt;br /&gt;
&lt;br /&gt;
[[Bild:LED_Stromregler_brd.png|thumb|left|600px| Beispiel eines Platinenlayouts]]&lt;br /&gt;
&lt;br /&gt;
{{clear}}&lt;br /&gt;
&lt;br /&gt;
==== Vorteile ====&lt;br /&gt;
&lt;br /&gt;
* Kurzschlussfest&lt;br /&gt;
* guter Wirkungsgrad bei hohen Eingangsspannungen, Energie wird nicht wie bei einem Linearregler in Wärme umgesetzt&lt;br /&gt;
* einfachste Komponenten&lt;br /&gt;
* sehr preiswert, max. 2 EUR &lt;br /&gt;
* Dimmung per [[PWM]] möglich&lt;br /&gt;
* Eingangsspannungsbereich sehr groß, ca. 6-30V&lt;br /&gt;
* sehr einfach auch auf anderen Strom einstellbar&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
== Platzhalter == &lt;br /&gt;
=== Beschreibung ===&lt;br /&gt;
=== Vorteile ===&lt;br /&gt;
=== Nachteile ===&lt;br /&gt;
=== Schaltung ===&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Threads im Forum  ==&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/75355#new Philosophiestunde Konstantstromquelle]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/71573#new Suche regelbare Konstantstromquelle für ACULED]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/67593#new Konstantstrom für Windmessung]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/66825#new Konstantstromdiode]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/66033#new Konstantstromquelle als IC und einstellbar]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/59467#new Konstantstromquelle für einen Haufen LEDs]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/58036#new Konstantstromquelle]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/61778#new temperaturunabhängige Konstantstromquelle]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/45039#new Konstanter Strom für LED bei 2,5V bis 5,5V]&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Konstantstromquelle Konstantstromquelle bei Wikipedia]&lt;br /&gt;
* [http://www.dcdcselector.com/de/dc-dc-led-driver DC/DC LED Treiber IC parametrische Suche]&lt;br /&gt;
* [http://www.dse-faq.elektronik-kompendium.de/dse-faq.htm DSE FAQ]&lt;br /&gt;
* [http://www.led-treiber.de Seite zu LED Treibern]&lt;br /&gt;
* [http://www.christiankoch.de/archiv/led-ksq/ Diskrete LED-Konstantstromquelle auf Schaltregler-Basis]&lt;br /&gt;
* [http://www.national.com/an/AN/AN-1392.pdf NATIONAL Application Note 1392: LM3485 LED Demo Board]&lt;br /&gt;
* [http://www.circuit-fantasia.com/circuit_stories/understanding_circuits/current_source/howland_current_source/howland_current_source.htm Howland Current Source]&lt;br /&gt;
* [http://www.national.com/an/AN/AN-1515.pdf &amp;quot;A Comprehensive Study of the Howland Current Pump&amp;quot;, Application Note von National Semiconductior, engl.]&lt;br /&gt;
* [http://www.nomad.ee/micros/mc34063a/index.shtml MC34063A Design Tool (engl.)]&lt;br /&gt;
* [http://www.onsemi.com/pub_link/Collateral/MC34063A-D.PDF Datenblatt des MC34063 bei ON Semi]&lt;br /&gt;
* [http://www.stromflo.de/dokuwiki/doku.php?id=led-tutorial LED_Tutorial]&lt;br /&gt;
* [[Konstantstromquelle fuer Power LED]]&lt;br /&gt;
* [http://www.joretronik.de/Web_NT_Buch/Kap3/Kapitel3_2.html weitere Beispiele von Konstantstromquellen]&lt;br /&gt;
* [http://www.edn.com/design/power-management/4318484/Error-compensation-improves-bipolar-current-sinks Error compensation improves bipolar current sinks, EDN, engl.]&lt;br /&gt;
*[http://www.nxp.com/documents/application_note/AN10739.pdf] Diskreter LED Treiber, Konstantstromquellen&lt;br /&gt;
&lt;br /&gt;
== Fußnoten ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Spannungsversorgung und Energiequellen]]&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR_Transistortester&amp;diff=88413</id>
		<title>AVR Transistortester</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR_Transistortester&amp;diff=88413"/>
		<updated>2015-04-25T06:44:13Z</updated>

		<summary type="html">&lt;p&gt;Maybee: /* Downloads (your-language) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Original Entwurf: http://www.mikrocontroller.net/articles/AVR-Transistortester&lt;br /&gt;
&lt;br /&gt;
Weiterentwickelt von Karl-Heinz Kübbeler&lt;br /&gt;
&lt;br /&gt;
Ich habe das Transistortester Projekt von Markus Frejek weitergeführt und speziell die Software weiterentwickelt.&lt;br /&gt;
Aufgrund der verbesserten Eigenschaften wurde schon der Name Komponententester vorgeschlagen. Ich selbst sehe aber immer noch die herausragende Eigenschaft in der automatischen Bestimmung von Transistortyp und Eigenschaft, wie sie von&lt;br /&gt;
Markus Frejek entwickelt wurde.&lt;br /&gt;
&lt;br /&gt;
Hier möchte ich die wichtigsten &#039;&#039;&#039;Eigenschaften&#039;&#039;&#039; aufführen&lt;br /&gt;
&lt;br /&gt;
* Arbeitet mit ATmega8, ATmega168 und ATmega328 Prozessoren.&lt;br /&gt;
* Anzeige der Meßergebnisse auf ein 2x16 Zeichen LCD.&lt;br /&gt;
* Statt dem 2x16 Zeichen LCD kann auch ein graphisches Display mit ST7565 Controller benutzt werden. Auch ein Anschluß eines OLED Display mit SSD1306 Controller ist mit SPI oder I2C Schnittstelle möglich.&lt;br /&gt;
* Ein-Tastenbedienung mit automatischer Abschaltung.&lt;br /&gt;
* Das Gerät besitzt drei universelle Meßports (Test Pin).&lt;br /&gt;
* Automatische Erkennung von NPN, PNP, N- und P-Kanal MOSFET, JFET, Dioden und Kleinsignal Thyristor und TRIAC.&lt;br /&gt;
* Automatische Erkennung der Pin-Belegung der Bauteile, die Bauelemente können beliebig angeschlossen werden.&lt;br /&gt;
* Messung des Stromverstärkungsfaktors und der Basis-Emitter Spannung für bipolare Transistoren, auch für Darlingtontransistoren.&lt;br /&gt;
* Automatische Erkennung eine Schutzdiode für bipolare Transistoren und MOSFETs.&lt;br /&gt;
* Bei bipolaren Transistoren mit Schutzdiode wird ein parasitärer Transistor erkannt (NPNp = NPN + parasitär PNP).&lt;br /&gt;
* Bis zu zwei Widerstände werden in einer Messung mit einer Auflösung von bis zu 0,1 Ohm gemessen, wobei der Meßbereich bis über 50 MOhm reicht. Widerstandswerte unter 10 Ohm werden für den ATmega168/328 mit der ESR-Meßmethode mit einer Auflösung von 0.01 Ohm angezeigt.&lt;br /&gt;
* Ein angeschlossener Kondensator kann gemessen werden im Bereich 35pF bis 100mF mit einer Auflösung von bis zu 1 pF.&lt;br /&gt;
* Widerstände und Kondensatoren werden mit ihren Symbolen dargestellt, umgeben von den gefundenen Anschlußpin Nummern.&lt;br /&gt;
* Die Widerstands und Kondensator-Werte werden mit bis zu vier Dezimalstellen in der richtigen Dimension angezeigt.&lt;br /&gt;
* Bis zu zwei Dioden werden ebenfalls mit ihrer Symboldarstellung flußrichtungsrichtig angezeigt, umgeben von den Anschlußpin Nummern und der zusätzlichen Angabe der Flußspannung.&lt;br /&gt;
* Bei einzelnen Dioden wird zusätzlich der Kapazitätswert und ab Version 1.08k auch der Strom in Sperr-Richtung gemessen.&lt;br /&gt;
* Für ATmega168/328 ist eine Kalibration der Nullkapazität, des Nullwiderstandes und weiterer Parameter im Selbsttest-Zweig möglich.&lt;br /&gt;
* Für ATmega168/328 können auch Induktivitäten von etwa 0.01mH bis über 20H erkannt und gemessen werden.&lt;br /&gt;
* Für ATmega168/328 ist eine ESR-Messung (Equivalent Series Resistance) für Kondensatoren über 90 nF mit einer Auflösung von 0.01 Ohm integriert.&lt;br /&gt;
* für ATmega168/328 wird für Kondensatoren über 5 nF der Spannungsverlust Vloss nach einem Ladepuls untersucht. Damit läßt sich die Güte der Kondensatoren abschätzen.&lt;br /&gt;
* für ATmega328 sind mit einer Menüfunktion, die mit einem längeren Tastendruck (&amp;gt; 0.5 s) aufgerufen werden kann, weitere Funktionen aus einer Liste möglich. Ein kurzer Tastendruck zeigt die nächste Funktion. Ein längerer Tastendruck startet die angezeigte Funktion. Nachfolgend die Liste der bisher eingebauten Zusatzfunktionen:&lt;br /&gt;
** Frequenzmessung an dem PD4 Pin, der aber auch für den LCD-Anschluß benutzt wird. Der Pin wird für die Messung auf Eingang umgeschaltet. Die anliegende Frequenz wird zunächst für 1 Sekunde ausgezählt. Wenn die Frequenz unter 25 kHz liegt, wird auch eine mittlere Periode gemessen und daraus eine Frequenz berechnet mit einer Auflösung von bis zu 0.001 mHz.&lt;br /&gt;
** Spannungsmessung am PC3 Pin, wenn dieser nicht für die serielle Ausgabe benutzt wird. Bei ATmega328 mit 32 Pins (PLCC) kann aber auch der ADC6 oder ADC7 Pin benutzt werden. Da ein 10:1 Teiler am Eingang benutzt wird, können Spannungen bis zu 50V gemessen werden. Mit einer Erweiterung der Schaltung (DC-DC Konverter) können auch Zenerdioden gemessen werden.&lt;br /&gt;
** Frequenzerzeugung am TP2 Port. Über den am PB2 Pin angeschlossenen 680 Ohm Widerstand kann ein Signal mit einer aus einer Liste einstellbaren Frequenz von 1 Hz bis 2 MHz am TP2 Port ausgegeben werden. Der TP1 Port ist dabei auf Masse geschaltet.&lt;br /&gt;
** Pulsweitenmodulation mit fester Frequenz und einstellbarer Pulsweite auf dem TP2 Port. Der Zähler 1 wird für diese Funktion als 10-Bit Zähler benutzt. Der TP1 Port ist auf Masse geschaltet. Die Pulsweite kann durch kurzen Tastendruck um 1% und durch längeren Tastendruck um 10% erhöht werden.&lt;br /&gt;
** Mit einer separaten Kapazitäts- und ESR-Messung können an TP1 und TP3 angeschlossene Kondensatoren mit einer Kapazität von etwa 2µF bis 50mF meist auch in der Schaltung gemessen werden. Hierbei sollte aber immer sichergestellt sein, daß die Kondensatoren keine Restladung mehr haben.&lt;br /&gt;
&lt;br /&gt;
Die zusätzlichen Funktionen sind zeitbegrenzt wie die Dialogfunktion selbst auch, wenn die POWER_OFF Option in der Konfigurationsdatei (Makefile) eingeschaltet ist.&lt;br /&gt;
Ausführlichere Informationen mit Meßbeispielen kann man in den pdf-Dokumentationen in deutscher und englischer Sprache nachlesen. Auch russische Übersetzung der Dokumentationen sind verfügbar.&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Software wurde basierend auf der Arbeit von Markus F. weiterentwickelt.&lt;br /&gt;
Der Teil für die Kondensatormessung wurde komplett neu geschrieben und auch die Widerstandsmessung wurde erheblich überarbeitet. Bei Schwierigkeiten und Problemen sollte man mich über E-mail oder über den Diskussionsteil (thread) benachrichtigen.  Nur wenn ich von Problemen weiß, kann ich hoffentlich Abhilfe schaffen.&lt;br /&gt;
&lt;br /&gt;
Weitere Einzelheiten sowie Beschreibung der einzelnen Meßverfahren und Beispiel-Ergebnisse habe ich in der pdf-Dokumentation (deutsche und englische Version) beschrieben. Hier findet man auch Hinweise zum Konfigurieren der Software mit Makefile Parametern und Optionen. &lt;br /&gt;
Die Kommentare im Quellcode sind in englischer Sprache.&lt;br /&gt;
Neu eingebaut in der Software ist eine Selbsttest-Funktion, in der die Funktion des Testers gemessen wird. In diesen Selbsttest ist auch ein Kalibrationsteil integriert.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
&lt;br /&gt;
Im Prinzip ist die neue Software so zu konfigurieren, daß sie auf der bereits von Markus F. vorgestellten Hardware ohne Änderungen läuft.&lt;br /&gt;
&lt;br /&gt;
Sinnvoll sind dennoch einige Änderungen:&lt;br /&gt;
&lt;br /&gt;
* Der Prozessor sollte auf einen 8 MHz Taktfrequenz umgestellt werden, am besten mit einem externen Quarz. Dazu müssen die fuses des ATmega geändert werden.&lt;br /&gt;
* Ein &amp;quot;pull up&amp;quot; Widerstand von etwa 27 kOhm sollte von Pin 13 (PD7) des ATmega nach VCC nachgerüstet werden.&lt;br /&gt;
* Der 100 nF Kondensator am Pin 21 (AREF) kann entweder ganz entfernt werden oder besser durch einen 1 nF Kondensator ersetzt werden.&lt;br /&gt;
* Wenn die elektronische Einschaltung des Testers Probleme macht, sollte wenigstens der C2 Kondensator an der Basis von Transistor T1 auf 10 nF reduziert werden und ggf. auch der Widerstand R7 auf 3,3 kOhm reduziert werden. Das komplette Schaltbild und Einzelheiten dazu findet man in der PDF Dokumentation.&lt;br /&gt;
&lt;br /&gt;
Die Gründe und die Einzelheiten für diese Änderungen sowie weitere Hinweise für einen Neuaufbau sind im Hardware-Kapitel meiner pdf-Dokumentation beschrieben. Empfohlen wird ein ATmega168 Prozessor oder auch ein ATmega328 Prozessor, weil der ADC mit der Autoscale Funktion im Bedarfsfall von der 5V Referenz (VCC) auf die interne Referenz-Spannung umgeschaltet wird. Die interne Referenz hat für der ATmega8 eine Spannung von 2,56V, für die anderen Prozessoren aber 1,1 Volt. Mit 1,1 V kann eine bessere Auflösung des ADC für gemessene Spannungen unter 1 Volt erreicht werden.&lt;br /&gt;
Man kann den ATmega8 ohne Hardwareänderung gegen einen ATmega168 oder ATmega328 austauschen!&lt;br /&gt;
Hier ist der Teil der Schaltung, der für die Messung erforderlich ist.&lt;br /&gt;
Die Elektronik für die Batterieversorgung und die automatische Abschaltung fehlt in diesem Schaltbild.[[Datei:TransistorTesterVC1.png|miniatur|Schaltbild ohne Stromversorgung]]&lt;br /&gt;
&lt;br /&gt;
Die rot markierten Bauteile sind nicht unbedingt erforderlich, können aber zu einer Verbesserung der Messgenauigkeit beitragen. Die grün markierten Bauteile sind gegenüber dem ersten Entwurf von Markus F. geändert.&lt;br /&gt;
Die Eagle Dateien von Asko B. für drei Varianten sind im Thread zu finden bei der Adresse: http://www.mikrocontroller.net/topic/248078?page=4#2891344&lt;br /&gt;
&lt;br /&gt;
Hier ist der Artikel der 1. Transistortester Version von Markus F. zu finden: [[AVR-Transistortester]]&lt;br /&gt;
&lt;br /&gt;
== Diskussionen zur neuen Version ==&lt;br /&gt;
Der Thread mit meinen älteren Software-Versionen und einigen Problemfällen sowie Hardware-Vorschlägen ist unter [https://www.mikrocontroller.net/topic/248078#new https://www.mikrocontroller.net/topic/248078#new] zu finden.&lt;br /&gt;
&lt;br /&gt;
== Downloads (deutsch) ==&lt;br /&gt;
Alle Versionen von der Software und der Doku sind im SVN gespeichert.&lt;br /&gt;
&lt;br /&gt;
Die Benutzer können über den svnbrowser [https://www.mikrocontroller.net/svnbrowser/transistortester/ https://www.mikrocontroller.net/svnbrowser/transistortester/] das gewählte Verzeichnis als &amp;quot;GNU tarball&amp;quot; runterladen.&lt;br /&gt;
Beim Aufruf des svnbrowsers steht dazu unter der Datei/Verzeichnis Liste der Eintrag &amp;quot;Download GNU tarball&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Zum Auspacken der heruntergeladenen transistortester*.tar.gz Datei benötigen Windows Benutzer eine geeignete Software wie das Freeware Paket [http://www.7-zip.org/ 7-Zip].&lt;br /&gt;
Nach dem Auspacken hat man den vorher mit dem svnbrowser ausgewählten Verzeichnisbaum auf seinem eigenen Rechner.&lt;br /&gt;
Ein direkter Zugriff auf die Dateien mit dem svnbrowser ist nicht möglich!&lt;br /&gt;
&lt;br /&gt;
Eine andere Methode auf den Inhalt des svn Archivs zuzugreifen besteht mit der Installation des TortoiseSVN Plugins für den Windows Explorer.&lt;br /&gt;
Damit ist dann der Zugriff über [svn://mikrocontroller.net/transistortester svn://mikrocontroller.net/transistortester] direkt auf das Archiv mit dem Browser möglich.&lt;br /&gt;
&lt;br /&gt;
Linux Benutzer können auch direkt über svn auf das Archiv zugreifen.&lt;br /&gt;
&lt;br /&gt;
== Downloads (russisch) - Загрузки (русский) ==&lt;br /&gt;
Для загрузок доступны все версии программного обеспечения и документации, хранящиеся в SVN&lt;br /&gt;
&lt;br /&gt;
Пользователь может загрузить выбранный каталог в качестве &amp;quot;GNU архива&amp;quot; через svnbrowser [https://www.mikrocontroller.net/svnbrowser/transistortester/ https://www.mikrocontroller.net/svnbrowser/transistortester/].&lt;br /&gt;
&lt;br /&gt;
При вызове svnbrowsers, смотрите в список файлов / каталогов, запись &amp;quot;Скачать GNU архив&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для распаковки загруженного файла * .tar.gz пользователи Windows могут воспользоваться любым подходящим программным обеспечением, таким как бесплатная программа [http://www.7-zip.org/ 7-Zip].&lt;br /&gt;
&lt;br /&gt;
После распаковки архива у вас на компьютере будет архив с заранее выбранным через svnbrowser содержимым в дереве каталогов.&lt;br /&gt;
&lt;br /&gt;
Прямой доступ к файлам через svnbrowser не возможен!&lt;br /&gt;
&lt;br /&gt;
Еще один способ получить доступ к содержимому хранилища SVN состоит в установке TortoiseSVN плагина для Windows Explorer. Это затем кнопкой [svn://mikrocontroller.net/transistortester svn://mikrocontroller.net/transistortester] прямо в вашем архиве, используя браузер.&lt;br /&gt;
&lt;br /&gt;
Пользователи Linux могут получить доступ непосредственно из SVN к архиву.&lt;br /&gt;
&lt;br /&gt;
== Downloads (english) ==&lt;br /&gt;
All versions of the software and documentation are saved in the SVN archive.&lt;br /&gt;
&lt;br /&gt;
Users can download a &amp;quot;GNU tarball&amp;quot; of the previous selected directory with the svnbrowser [https://www.mikrocontroller.net/svnbrowser/transistortester/ https://www.mikrocontroller.net/svnbrowser/transistortester/].&lt;br /&gt;
&lt;br /&gt;
Windows users need a additional tool like the freeware [http://www.7-zip.org/ 7-Zip] to unpack the downloaded transistortester*.tar.gz file.&lt;br /&gt;
After unpacking you have a copy of the selected directory at your own computer.&lt;br /&gt;
The direct access is not possible with the svnbrowser!&lt;br /&gt;
&lt;br /&gt;
Another way to get access to the SVN data is to install the TortoiseSVN plugin for the windows explorer. After installing you can access the data with [svn://mikrocontroller.net/transistortester svn://mikrocontroller.net/transistortester].&lt;br /&gt;
&lt;br /&gt;
Linux users can also access the data with svn directly.&lt;br /&gt;
&lt;br /&gt;
== Downloads (Português - Brasil) ==&lt;br /&gt;
&lt;br /&gt;
Todas as versões de software e documentação estão salvas no arquivador SVN.&lt;br /&gt;
&lt;br /&gt;
Usuários podem descarregar um pacote &amp;quot;GNU&amp;quot; de todos os diretórios anteriores com o svnbrowser [https://www.mikrocontroller.net/svnbrowser/transistortester/ https://www.mikrocontroller.net/svnbrowser/transistortester/].&lt;br /&gt;
&lt;br /&gt;
Usuários de Windows precisam de uma ferramenta adicional como o freeware [http://www.7-zip.org/ 7-Zip] para descompactar o arquivo transistortester*.tar.gz. Depois de descompactado você terá uma cópia do diretório selecionado no seu computador. O acesso direto não é possível com o svnbrowser!&lt;br /&gt;
&lt;br /&gt;
Outra forma de acessar os dados no SVN é instalar o TortoiseSVN plugin para Windows Exporer. Depois de instalar você pode acessar soa dados com o endereçco [svn://mikrocontroller.net/transistortester svn://mikrocontroller.net/transistortester].&lt;br /&gt;
&lt;br /&gt;
Usuários Linux podem acessar os dados com svn diretamente.&lt;br /&gt;
&lt;br /&gt;
== Downloads (Español) ==&lt;br /&gt;
Todas la versiones del software y la documentación están en SVN.&lt;br /&gt;
&lt;br /&gt;
Los usuarios pueden descargar un &amp;quot;GNU tarball&amp;quot; del directorio seleccionado utlizando svnbrowser https://www.mikrocontroller.net/svnbrowser/transistortester/&lt;br /&gt;
&lt;br /&gt;
Los usuarios de Windows requieren de una herramienta adicional como el freeware 7-Zip (gratis) para desempacar el archivo descargado, transistortester*.tar.gz.&lt;br /&gt;
&lt;br /&gt;
Luego de desempacar el archivo, tendrá en su computador una copia completa del directorio seleccionado.&lt;br /&gt;
Acceso directo no es posible con svnbrowser.&lt;br /&gt;
&lt;br /&gt;
La otra manera de accesar el respositorio SVN es instalando el plugin TortoiseSVN; éste le permitirá acceso a la información con el URI: svn://mikrocontroller.net/transistortester&lt;br /&gt;
&lt;br /&gt;
Los usuarios de Linux pueden, por supuesto, accesar SVN directamente.&lt;br /&gt;
&lt;br /&gt;
== Downloads (your-language) ==&lt;br /&gt;
&lt;br /&gt;
You can put a translation &#039;&#039;here&#039;&#039;, but only if its done by yourself, not Google Translate.&lt;br /&gt;
&lt;br /&gt;
You can also put a translation of the whole article here, if its done by yourself.&lt;br /&gt;
&lt;br /&gt;
Only little understanding of the Wiki-Syntax is needed therefore.&lt;br /&gt;
&lt;br /&gt;
== Verzeichnisstruktur des SVN ==&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; style=&amp;quot;border-collapse:collapse&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Ordnerstruktur und Beschreibung der  &#039;&#039;Pfade&#039;&#039; im SVN&#039;&#039;&#039;&lt;br /&gt;
|- style=&amp;quot;background-color:#B3B7FF&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; colspan=&amp;quot;2&amp;quot; | &#039;&#039;&#039;Ordner/directory&#039;&#039;&#039; || &#039;&#039;&#039;Dateien/files&#039;&#039;&#039; || &#039;&#039;&#039;Beschreibung/description&#039;&#039;&#039;&lt;br /&gt;
|-   style=&amp;quot;background-color:#B9FFC5&amp;quot;&lt;br /&gt;
| &#039;&#039;&#039;Doku&#039;&#039;&#039; || || || Enthält die Dokumentation als PDF und als pdflatex-Quelltext&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk&#039;&#039;&#039; || || Letzter Entwicklungsstand der Dokumentation inclusive Bilder und Diagrammen&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/pdftex/german&#039;&#039;&#039; || || enthält die deutschen Texte, Makefile und PDF-Dokumentation der Entwicklerversion&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/pdftex/english&#039;&#039;&#039; || || contains the English text, Makefile and PDF documentation of the developer version&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/pdftex/russian&#039;&#039;&#039; || || contains the Russian text, Makefile and PDF documentation of the developer version&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags&#039;&#039;&#039; ||&#039;&#039;changelog.txt&#039;&#039; || &#039;&#039;Hier sollte jede Änderung mit Versionsnummer eingetragen werden&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/german&#039;&#039;&#039; || || &#039;&#039;Aktuelle PDF Dokumentation in deutsch&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/english&#039;&#039;&#039; || || &#039;&#039;Current PDF documentation in English&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/russian&#039;&#039;&#039; || || &#039;&#039;Current PDF documentation in Russian language&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/old/german&#039;&#039;&#039; || || &#039;&#039;PDF Dokumentationen zu früheren Softwareversionen&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/old/english&#039;&#039;&#039; || || &#039;&#039;PDF documentation for earlier software versions&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
|- style=&amp;quot;background-color:#B9FFC5&amp;quot;&lt;br /&gt;
| &#039;&#039;&#039;Hardware&#039;&#039;&#039; || || || Hardware Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid&#039;&#039;&#039; || || Verzeichnis für eine Streifenleiterplatine&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid/ttester_strip_grid.diy&#039;&#039;&#039; || || Beispiel einer Streifenleiterplatine, DIYLC-Datei&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid/TTester_strip.pdf&#039;&#039;&#039; || || Ergebnis der Streifenleiterplatine im PDF Format&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid/LiesMich.txt&#039;&#039;&#039; || || Kurzdokumentation für Streifenleiter-Platine&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid/ReadMe.txt&#039;&#039;&#039; || || Short documentation for the strip grid board&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;Markus&#039;&#039;&#039; || || Entwurf von Markus R. mit LED-Dimmer im Eagle 6.4.0 Format&lt;br /&gt;
&lt;br /&gt;
|- style=&amp;quot;background-color:#B9FFC5&amp;quot;&lt;br /&gt;
| &#039;&#039;&#039;Software&#039;&#039;&#039; || || || Software für AVR-GCC 4.5.3&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk&#039;&#039;&#039; || || Aktueller Software-Entwicklungszweig&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/default&#039;&#039;&#039; || || Makefile und Programmierdaten für ATmega168 mit Standard-Layout&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega168_1.9V&#039;&#039;&#039; || || Makefile und Daten für ATmega168 mit Knopfzellenbetrieb (FiFi)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega168_3.3V&#039;&#039;&#039; || || Makefile und Daten für ATmega168 mit LiPo-Akkubetrieb (FiFi)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Standard-Layout (ab Version 1.08k)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_1.9V&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Knopfzellenbetrieb (Funkamateur)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_3.3V&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit LiPo-Akkubetrieb (Funkamateur)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega168_strip_grid&#039;&#039;&#039; || || Makefile und Daten für ATmega168 für Streifenleiter-Platine&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_strip_grid&#039;&#039;&#039; || || Makefile und Daten für ATmega328 für Streifenleiter-Platine (ab Version 1.08k)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_strip_grid_dogm&#039;&#039;&#039; || || Makefile und Daten für ATmega328 für Streifenleiter-Platine mit DOG-M Display&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega8&#039;&#039;&#039; || || Makefile und Daten für ATmega8. Ab Version 1.00k ist der Selbsttest für den ATmega8 nicht mehr konfigurierbar.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags&#039;&#039;&#039; || || Fertige Software Versionen als ZIP gepackt&lt;br /&gt;
|-&lt;br /&gt;
| || || &#039;&#039;changelog.txt&#039;&#039; || &#039;&#039;Hier sollte jede Änderung mit Versionsnummer eingetragen werden&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;Markus&#039;&#039;&#039; || || Alternative Software von Markus R., bitte README beachten! Die Software wurde aufgeräumt und ist viel besser strukturiert, läuft aber nur auf einem ATmega168 oder ATmega328. Die Software läuft nur auf dem Standard-Layout.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR_Transistortester&amp;diff=88020</id>
		<title>AVR Transistortester</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR_Transistortester&amp;diff=88020"/>
		<updated>2015-03-19T20:54:06Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Änderung 87999 von 36.84.125.217 (Diskussion) rückgängig gemacht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Original Entwurf: http://www.mikrocontroller.net/articles/AVR-Transistortester&lt;br /&gt;
&lt;br /&gt;
Weiterentwickelt von Karl-Heinz Kübbeler&lt;br /&gt;
&lt;br /&gt;
Ich habe das Transistortester Projekt von Markus Frejek weitergeführt und speziell die Software weiterentwickelt.&lt;br /&gt;
Aufgrund der verbesserten Eigenschaften wurde schon der Name Komponententester vorgeschlagen. Ich selbst sehe aber immer noch die herausragende Eigenschaft in der automatischen Bestimmung von Transistortyp und Eigenschaft, wie sie von&lt;br /&gt;
Markus Frejek entwickelt wurde.&lt;br /&gt;
&lt;br /&gt;
Hier möchte ich die wichtigsten &#039;&#039;&#039;Eigenschaften&#039;&#039;&#039; aufführen&lt;br /&gt;
&lt;br /&gt;
* Arbeitet mit ATmega8, ATmega168 und ATmega328 Prozessoren.&lt;br /&gt;
* Anzeige der Meßergebnisse auf ein 2x16 Zeichen LCD.&lt;br /&gt;
* Statt dem 2x16 Zeichen LCD kann auch ein graphisches Display mit ST7565 Controller benutzt werden. Auch ein Anschluß eines OLED Display mit SSD1306 Controller ist mit SPI oder I2C Schnittstelle möglich.&lt;br /&gt;
* Ein-Tastenbedienung mit automatischer Abschaltung.&lt;br /&gt;
* Das Gerät besitzt drei universelle Meßports (Test Pin).&lt;br /&gt;
* Automatische Erkennung von NPN, PNP, N- und P-Kanal MOSFET, JFET, Dioden und Kleinsignal Thyristor und TRIAC.&lt;br /&gt;
* Automatische Erkennung der Pin-Belegung der Bauteile, die Bauelemente können beliebig angeschlossen werden.&lt;br /&gt;
* Messung des Stromverstärkungsfaktors und der Basis-Emitter Spannung für bipolare Transistoren, auch für Darlingtontransistoren.&lt;br /&gt;
* Automatische Erkennung eine Schutzdiode für bipolare Transistoren und MOSFETs.&lt;br /&gt;
* Bei bipolaren Transistoren mit Schutzdiode wird ein parasitärer Transistor erkannt (NPNp = NPN + parasitär PNP).&lt;br /&gt;
* Bis zu zwei Widerstände werden in einer Messung mit einer Auflösung von bis zu 0,1 Ohm gemessen, wobei der Meßbereich bis über 50 MOhm reicht. Widerstandswerte unter 10 Ohm werden für den ATmega168/328 mit der ESR-Meßmethode mit einer Auflösung von 0.01 Ohm angezeigt.&lt;br /&gt;
* Ein angeschlossener Kondensator kann gemessen werden im Bereich 35pF bis 100mF mit einer Auflösung von bis zu 1 pF.&lt;br /&gt;
* Widerstände und Kondensatoren werden mit ihren Symbolen dargestellt, umgeben von den gefundenen Anschlußpin Nummern.&lt;br /&gt;
* Die Widerstands und Kondensator-Werte werden mit bis zu vier Dezimalstellen in der richtigen Dimension angezeigt.&lt;br /&gt;
* Bis zu zwei Dioden werden ebenfalls mit ihrer Symboldarstellung flußrichtungsrichtig angezeigt, umgeben von den Anschlußpin Nummern und der zusätzlichen Angabe der Flußspannung.&lt;br /&gt;
* Bei einzelnen Dioden wird zusätzlich der Kapazitätswert und ab Version 1.08k auch der Strom in Sperr-Richtung gemessen.&lt;br /&gt;
* Für ATmega168/328 ist eine Kalibration der Nullkapazität, des Nullwiderstandes und weiterer Parameter im Selbsttest-Zweig möglich.&lt;br /&gt;
* Für ATmega168/328 können auch Induktivitäten von etwa 0.01mH bis über 20H erkannt und gemessen werden.&lt;br /&gt;
* Für ATmega168/328 ist eine ESR-Messung (Equivalent Series Resistance) für Kondensatoren über 90 nF mit einer Auflösung von 0.01 Ohm integriert.&lt;br /&gt;
* für ATmega168/328 wird für Kondensatoren über 5 nF der Spannungsverlust Vloss nach einem Ladepuls untersucht. Damit läßt sich die Güte der Kondensatoren abschätzen.&lt;br /&gt;
* für ATmega328 sind mit einer Menüfunktion, die mit einem längeren Tastendruck (&amp;gt; 0.5 s) aufgerufen werden kann, weitere Funktionen aus einer Liste möglich. Ein kurzer Tastendruck zeigt die nächste Funktion. Ein längerer Tastendruck startet die angezeigte Funktion. Nachfolgend die Liste der bisher eingebauten Zusatzfunktionen:&lt;br /&gt;
** Frequenzmessung an dem PD4 Pin, der aber auch für den LCD-Anschluß benutzt wird. Der Pin wird für die Messung auf Eingang umgeschaltet. Die anliegende Frequenz wird zunächst für 1 Sekunde ausgezählt. Wenn die Frequenz unter 25 kHz liegt, wird auch eine mittlere Periode gemessen und daraus eine Frequenz berechnet mit einer Auflösung von bis zu 0.001 mHz.&lt;br /&gt;
** Spannungsmessung am PC3 Pin, wenn dieser nicht für die serielle Ausgabe benutzt wird. Bei ATmega328 mit 32 Pins (PLCC) kann aber auch der ADC6 oder ADC7 Pin benutzt werden. Da ein 10:1 Teiler am Eingang benutzt wird, können Spannungen bis zu 50V gemessen werden. Mit einer Erweiterung der Schaltung (DC-DC Konverter) können auch Zenerdioden gemessen werden.&lt;br /&gt;
** Frequenzerzeugung am TP2 Port. Über den am PB2 Pin angeschlossenen 680 Ohm Widerstand kann ein Signal mit einer aus einer Liste einstellbaren Frequenz von 1 Hz bis 2 MHz am TP2 Port ausgegeben werden. Der TP1 Port ist dabei auf Masse geschaltet.&lt;br /&gt;
** Pulsweitenmodulation mit fester Frequenz und einstellbarer Pulsweite auf dem TP2 Port. Der Zähler 1 wird für diese Funktion als 10-Bit Zähler benutzt. Der TP1 Port ist auf Masse geschaltet. Die Pulsweite kann durch kurzen Tastendruck um 1% und durch längeren Tastendruck um 10% erhöht werden.&lt;br /&gt;
** Mit einer separaten Kapazitäts- und ESR-Messung können an TP1 und TP3 angeschlossene Kondensatoren mit einer Kapazität von etwa 2µF bis 50mF meist auch in der Schaltung gemessen werden. Hierbei sollte aber immer sichergestellt sein, daß die Kondensatoren keine Restladung mehr haben.&lt;br /&gt;
&lt;br /&gt;
Die zusätzlichen Funktionen sind zeitbegrenzt wie die Dialogfunktion selbst auch, wenn die POWER_OFF Option in der Konfigurationsdatei (Makefile) eingeschaltet ist.&lt;br /&gt;
Ausführlichere Informationen mit Meßbeispielen kann man in den pdf-Dokumentationen in deutscher und englischer Sprache nachlesen. Auch russische Übersetzung der Dokumentationen sind verfügbar.&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Software wurde basierend auf der Arbeit von Markus F. weiterentwickelt.&lt;br /&gt;
Der Teil für die Kondensatormessung wurde komplett neu geschrieben und auch die Widerstandsmessung wurde erheblich überarbeitet. Bei Schwierigkeiten und Problemen sollte man mich über E-mail oder über den Diskussionsteil (thread) benachrichtigen.  Nur wenn ich von Problemen weiß, kann ich hoffentlich Abhilfe schaffen.&lt;br /&gt;
&lt;br /&gt;
Weitere Einzelheiten sowie Beschreibung der einzelnen Meßverfahren und Beispiel-Ergebnisse habe ich in der pdf-Dokumentation (deutsche und englische Version) beschrieben. Hier findet man auch Hinweise zum Konfigurieren der Software mit Makefile Parametern und Optionen. &lt;br /&gt;
Die Kommentare im Quellcode sind in englischer Sprache.&lt;br /&gt;
Neu eingebaut in der Software ist eine Selbsttest-Funktion, in der die Funktion des Testers gemessen wird. In diesen Selbsttest ist auch ein Kalibrationsteil integriert.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
&lt;br /&gt;
Im Prinzip ist die neue Software so zu konfigurieren, daß sie auf der bereits von Markus F. vorgestellten Hardware ohne Änderungen läuft.&lt;br /&gt;
&lt;br /&gt;
Sinnvoll sind dennoch einige Änderungen:&lt;br /&gt;
&lt;br /&gt;
* Der Prozessor sollte auf einen 8 MHz Taktfrequenz umgestellt werden, am besten mit einem externen Quarz. Dazu müssen die fuses des ATmega geändert werden.&lt;br /&gt;
* Ein &amp;quot;pull up&amp;quot; Widerstand von etwa 27 kOhm sollte von Pin 13 (PD7) des ATmega nach VCC nachgerüstet werden.&lt;br /&gt;
* Der 100 nF Kondensator am Pin 21 (AREF) kann entweder ganz entfernt werden oder besser durch einen 1 nF Kondensator ersetzt werden.&lt;br /&gt;
* Wenn die elektronische Einschaltung des Testers Probleme macht, sollte wenigstens der C2 Kondensator an der Basis von Transistor T1 auf 10 nF reduziert werden und ggf. auch der Widerstand R7 auf 3,3 kOhm reduziert werden. Das komplette Schaltbild und Einzelheiten dazu findet man in der PDF Dokumentation.&lt;br /&gt;
&lt;br /&gt;
Die Gründe und die Einzelheiten für diese Änderungen sowie weitere Hinweise für einen Neuaufbau sind im Hardware-Kapitel meiner pdf-Dokumentation beschrieben. Empfohlen wird ein ATmega168 Prozessor oder auch ein ATmega328 Prozessor, weil der ADC mit der Autoscale Funktion im Bedarfsfall von der 5V Referenz (VCC) auf die interne Referenz-Spannung umgeschaltet wird. Die interne Referenz hat für der ATmega8 eine Spannung von 2,56V, für die anderen Prozessoren aber 1,1 Volt. Mit 1,1 V kann eine bessere Auflösung des ADC für gemessene Spannungen unter 1 Volt erreicht werden.&lt;br /&gt;
Man kann den ATmega8 ohne Hardwareänderung gegen einen ATmega168 oder ATmega328 austauschen!&lt;br /&gt;
Hier ist der Teil der Schaltung, der für die Messung erforderlich ist.&lt;br /&gt;
Die Elektronik für die Batterieversorgung und die automatische Abschaltung fehlt in diesem Schaltbild.[[Datei:TransistorTesterVC1.png|miniatur|Schaltbild ohne Stromversorgung]]&lt;br /&gt;
&lt;br /&gt;
Die rot markierten Bauteile sind nicht unbedingt erforderlich, können aber zu einer Verbesserung der Messgenauigkeit beitragen. Die grün markierten Bauteile sind gegenüber dem ersten Entwurf von Markus F. geändert.&lt;br /&gt;
Die Eagle Dateien von Asko B. für drei Varianten sind im Thread zu finden bei der Adresse: http://www.mikrocontroller.net/topic/248078?page=4#2891344&lt;br /&gt;
&lt;br /&gt;
Hier ist der Artikel der 1. Transistortester Version von Markus F. zu finden: [[AVR-Transistortester]]&lt;br /&gt;
&lt;br /&gt;
== Diskussionen zur neuen Version ==&lt;br /&gt;
Der Thread mit meinen älteren Software-Versionen und einigen Problemfällen sowie Hardware-Vorschlägen ist unter [http://www.mikrocontroller.net/topic/248078#new http://www.mikrocontroller.net/topic/248078#new] zu finden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Downloads ==&lt;br /&gt;
Alle Versionen von der Software und der Doku sind im SVN gespeichert.&lt;br /&gt;
Die Benutzer können über den svnbrowser [http://www.mikrocontroller.net/svnbrowser/transistortester/ http://www.mikrocontroller.net/svnbrowser/transistortester/] das gewählte Verzeichnis als &amp;quot;GNU tarball&amp;quot; runterladen.&lt;br /&gt;
Beim Aufruf des svnbrowsers steht dazu unter der Datei/Verzeichnis Liste der Eintrag &amp;quot;Download GNU tarball&amp;quot;.&lt;br /&gt;
Zum Auspacken der heruntergeladenen transistortester*.tar.gz Datei benötigen Windows Benutzer eine geeignete Software wie das Freeware Paket [http://www.7-zip.org/ 7-Zip].&lt;br /&gt;
Nach dem Auspacken hat man den vorher mit dem svnbrowser ausgewählten Verzeichnisbaum auf seinem eigenen Rechner.&lt;br /&gt;
Ein direkter Zugriff auf die Dateien mit dem svnbrowser ist nicht möglich!&lt;br /&gt;
Eine andere Methode auf den Inhalt des svn Archivs zuzugreifen besteht mit der Installation des TortoiseSVN Plugins für den Windows Explorer.&lt;br /&gt;
Damit ist dann der Zugriff über [svn://mikrocontroller.net/transistortester svn://mikrocontroller.net/transistortester] direkt auf das Archiv mit dem Browser möglich.&lt;br /&gt;
Linux Benutzer können auch direkt über svn auf das Archiv zugreifen.&lt;br /&gt;
&lt;br /&gt;
== Downloads (russisch) ==&lt;br /&gt;
&amp;lt;span class=&amp;quot;notranslate&amp;quot; onmouseover=&amp;quot;_tipon(this)&amp;quot; onmouseout=&amp;quot;_tipoff()&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;google-src-text&amp;quot; style=&amp;quot;direction: ltr; text-align: left&amp;quot;&amp;gt; &amp;lt;/span&amp;gt; == Загрузок == Все версии программного обеспечения и документации, хранятся в SVN.&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;notranslate&amp;quot; onmouseover=&amp;quot;_tipon(this)&amp;quot; onmouseout=&amp;quot;_tipoff()&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;google-src-text&amp;quot; style=&amp;quot;direction: ltr; text-align: left&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/span&amp;gt; Пользователь может загрузить выбранный каталог в качестве &amp;quot;GNU архива&amp;quot; за svnbrowser [http://www.mikrocontroller.net/svnbrowser/transistortester/ http://www.mikrocontroller.net/svnbrowser/transistortester/].&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;notranslate&amp;quot; onmouseover=&amp;quot;_tipon(this)&amp;quot; onmouseout=&amp;quot;_tipoff()&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;google-src-text&amp;quot; style=&amp;quot;direction: ltr; text-align: left&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/span&amp;gt; При вызове svnbrowsers, смотрите в список файлов / каталогов, запись &amp;quot;Скачать GNU архив&amp;quot;.&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;notranslate&amp;quot; onmouseover=&amp;quot;_tipon(this)&amp;quot; onmouseout=&amp;quot;_tipoff()&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;google-src-text&amp;quot; style=&amp;quot;direction: ltr; text-align: left&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/span&amp;gt; Для распаковки загруженного транзистор тестер файл * .tar.gz вам нужно пользователи Windows подходящий программного обеспечения, таких как бесплатный пакет [http://www.7-zip.org/ 7-Zip].&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;notranslate&amp;quot; onmouseover=&amp;quot;_tipon(this)&amp;quot; onmouseout=&amp;quot;_tipoff()&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;google-src-text&amp;quot; style=&amp;quot;direction: ltr; text-align: left&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/span&amp;gt; После распаковки у нас есть собственный заранее с svnbrowser выбран в дереве каталогов на своем компьютере.&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;notranslate&amp;quot; onmouseover=&amp;quot;_tipon(this)&amp;quot; onmouseout=&amp;quot;_tipoff()&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;google-src-text&amp;quot; style=&amp;quot;direction: ltr; text-align: left&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/span&amp;gt; Прямой доступ к файлам с svnbrowser не возможно!&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;notranslate&amp;quot; onmouseover=&amp;quot;_tipon(this)&amp;quot; onmouseout=&amp;quot;_tipoff()&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;google-src-text&amp;quot; style=&amp;quot;direction: ltr; text-align: left&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/span&amp;gt; Еще один способ получить доступ к содержимому хранилища SVN состоит из установки TortoiseSVN плагин для Windows Explorer.&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;notranslate&amp;quot; onmouseover=&amp;quot;_tipon(this)&amp;quot; onmouseout=&amp;quot;_tipoff()&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;google-src-text&amp;quot; style=&amp;quot;direction: ltr; text-align: left&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/span&amp;gt; Это затем кнопкой [SVN://mikrocontroller.net/transistortester SVN://mikrocontroller.net/transistortester] прямо в вашем архиве, используя браузер.&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;notranslate&amp;quot; onmouseover=&amp;quot;_tipon(this)&amp;quot; onmouseout=&amp;quot;_tipoff()&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;google-src-text&amp;quot; style=&amp;quot;direction: ltr; text-align: left&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/span&amp;gt; Пользователи Linux могут получить доступ непосредственно из SVN в архив.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Downloads (english) ==&lt;br /&gt;
All versions of the software and documentation are saved in the SVN archive.&lt;br /&gt;
Users can download a &amp;quot;GNU tarball&amp;quot; of the previous selected directory with the svnbrowser [http://www.mikrocontroller.net/svnbrowser/transistortester/ http://www.mikrocontroller.net/svnbrowser/transistortester/].&lt;br /&gt;
Windows users need a additional tool like the freeware 7-Zip to unpack the downloaded transistortester*.tar.gz file.&lt;br /&gt;
After unpacking you have a copy of the selected directory at your own computer.&lt;br /&gt;
The direct access is not possible with the svnbrowser!&lt;br /&gt;
&lt;br /&gt;
Another way to get access to the SVN data is to install the TortoiseSVN plugin for the windows explorer. After installing you&lt;br /&gt;
can access the data with [svn://mikrocontroller.net/transistortester svn://mikrocontroller.net/transistortester] .&lt;br /&gt;
&lt;br /&gt;
Linux users can also access the data with svn directly.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Ordnerstruktur und Beschreibung der  &#039;&#039;Pfade&#039;&#039; im SVN&#039;&#039;&#039;&lt;br /&gt;
|- style=&amp;quot;background-color:#B3B7FF&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align:center&amp;quot; colspan=&amp;quot;2&amp;quot; | &#039;&#039;&#039;Ordner/directory&#039;&#039;&#039; || &#039;&#039;&#039;Dateien/files&#039;&#039;&#039; || &#039;&#039;&#039;Beschreibung/description&#039;&#039;&#039;&lt;br /&gt;
|-   style=&amp;quot;background-color:#B9FFC5&amp;quot;&lt;br /&gt;
| &#039;&#039;&#039;Doku&#039;&#039;&#039; || || || Enthält die Dokumentation als PDF und als pdflatex-Quelltext&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk&#039;&#039;&#039; || || Letzter Entwicklungsstand der Dokumentation inclusive Bilder und Diagrammen&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/pdftex/german&#039;&#039;&#039; || || enthält die deutschen Texte, Makefile und PDF-Dokumentation der Entwicklerversion&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/pdftex/english&#039;&#039;&#039; || || contains the English text, Makefile and PDF documentation of the developer version&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/pdftex/russian&#039;&#039;&#039; || || contains the Russian text, Makefile and PDF documentation of the developer version&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags&#039;&#039;&#039; ||&#039;&#039;changelog.txt&#039;&#039; || &#039;&#039;Hier sollte jede Änderung mit Versionsnummer eingetragen werden&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/german&#039;&#039;&#039; || || &#039;&#039;Aktuelle PDF Dokumentation in deutsch&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/english&#039;&#039;&#039; || || &#039;&#039;Current PDF documentation in English&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/russian&#039;&#039;&#039; || || &#039;&#039;Current PDF documentation in Russian language&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/old/german&#039;&#039;&#039; || || &#039;&#039;PDF Dokumentationen zu früheren Softwareversionen&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags/old/english&#039;&#039;&#039; || || &#039;&#039;PDF documentation for earlier software versions&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
|- style=&amp;quot;background-color:#B9FFC5&amp;quot;&lt;br /&gt;
| &#039;&#039;&#039;Hardware&#039;&#039;&#039; || || || Hardware Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid&#039;&#039;&#039; || || Verzeichnis für eine Streifenleiterplatine&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid/ttester_strip_grid.diy&#039;&#039;&#039; || || Beispiel einer Streifenleiterplatine, DIYLC-Datei&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid/TTester_strip.pdf&#039;&#039;&#039; || || Ergebnis der Streifenleiterplatine im PDF Format&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid/LiesMich.txt&#039;&#039;&#039; || || Kurzdokumentation für Streifenleiter-Platine&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;strip_grid/ReadMe.txt&#039;&#039;&#039; || || Short documentation for the strip grid board&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;Markus&#039;&#039;&#039; || || Entwurf von Markus R. mit LED-Dimmer im Eagle 6.4.0 Format&lt;br /&gt;
&lt;br /&gt;
|- style=&amp;quot;background-color:#B9FFC5&amp;quot;&lt;br /&gt;
| &#039;&#039;&#039;Software&#039;&#039;&#039; || || || Software für AVR-GCC 4.5.3&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk&#039;&#039;&#039; || || Aktueller Software-Entwicklungszweig&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/default&#039;&#039;&#039; || || Makefile und Programmierdaten für ATmega168 mit Standard-Layout&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega168_1.9V&#039;&#039;&#039; || || Makefile und Daten für ATmega168 mit Knopfzellenbetrieb (FiFi)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega168_3.3V&#039;&#039;&#039; || || Makefile und Daten für ATmega168 mit LiPo-Akkubetrieb (FiFi)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Standard-Layout (ab Version 1.08k)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_1.9V&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit Knopfzellenbetrieb (Funkamateur)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_3.3V&#039;&#039;&#039; || || Makefile und Daten für ATmega328 mit LiPo-Akkubetrieb (Funkamateur)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega168_strip_grid&#039;&#039;&#039; || || Makefile und Daten für ATmega168 für Streifenleiter-Platine&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_strip_grid&#039;&#039;&#039; || || Makefile und Daten für ATmega328 für Streifenleiter-Platine (ab Version 1.08k)&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega328_strip_grid_dogm&#039;&#039;&#039; || || Makefile und Daten für ATmega328 für Streifenleiter-Platine mit DOG-M Display&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;trunk/mega8&#039;&#039;&#039; || || Makefile und Daten für ATmega8. Ab Version 1.00k ist der Selbsttest für den ATmega8 nicht mehr konfigurierbar.&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;tags&#039;&#039;&#039; || || Fertige Software Versionen als ZIP gepackt&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| || || &#039;&#039;changelog.txt&#039;&#039; || &#039;&#039;Hier sollte jede Änderung mit Versionsnummer eingetragen werden&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| || &#039;&#039;&#039;Markus&#039;&#039;&#039; || || Alternative Software von Markus R., bitte README beachten! Die Software wurde aufgeräumt und ist viel besser strukturiert, läuft aber nur auf einem ATmega168 oder ATmega328. Die Software läuft nur auf dem Standard-Layout.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=RFM69&amp;diff=87769</id>
		<title>RFM69</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=RFM69&amp;diff=87769"/>
		<updated>2015-03-08T09:04:57Z</updated>

		<summary type="html">&lt;p&gt;Maybee: /* Funtionsweise */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Datei:rf69cw.png|thumb|300px|RFM69CW, Pinkompatibel zum RFM12]]&lt;br /&gt;
Das RFM69 von HopeRF ist ein universelles Funkmodul für die ISM-Frequenzbänder 315, 433, 868 und 915 MHz. Eine [[SPI]]-Schnitttstelle ermöglicht die einfache Integration in Mikrocontrollerprojekte.&lt;br /&gt;
&lt;br /&gt;
== Ausführungen ==&lt;br /&gt;
* RFM69HCW, mit zusätzlicher PA, 20 dBm, als Ersatz für den RFM22B gedacht&lt;br /&gt;
* RFM69HW, mit zusätzlicher PA, 20 dBm&lt;br /&gt;
* RFM69CW, Pinkompatibel zum RFM12B&lt;br /&gt;
* RFM69W&lt;br /&gt;
&lt;br /&gt;
Die CW-Variante hat 2 Pins weniger (es fehlt der Pin DIO4), und ist Pinkompatibel zum Vorgänger RFM12B.&lt;br /&gt;
Es kann ohne Änderung am Layout oder der Schaltung ausgetauscht werden. Lediglich die Software muss angepasst werden.&lt;br /&gt;
&lt;br /&gt;
== Ausstattung ==&lt;br /&gt;
* Betriebsspannung 1,8 - 3,6 V&lt;br /&gt;
* SPI-Schnittstelle&lt;br /&gt;
* FSK- und OOK-Modulation (Frequency Shift Keying = Frequenzumtastung, On-Off-Keying = Amplitudentastung)&lt;br /&gt;
* Eingebauter Manchesterde- und -encoder&lt;br /&gt;
* Frequenzbereiche 315, 433, 868, 915 MHz&lt;br /&gt;
* Max. Datenrate 300 kbit/s&lt;br /&gt;
* Ausgangsleistung +13 dBm (rund 20 mW)&lt;br /&gt;
* Stromaufnahme 45 mA senden (13 dBm), 16 mA empfangen, 0,1 µA Standby&lt;br /&gt;
* Integrierte Packetengine für Synchronwort, CRC, Scrambling und AES-Verschlüsselung&lt;br /&gt;
* 66 Byte FIFO&lt;br /&gt;
* Modul basiert auf dem SX1231 von Semtech&lt;br /&gt;
&lt;br /&gt;
== Vergleich zum RFM12B ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! RFM12B !! RFM69(C)W&lt;br /&gt;
|-&lt;br /&gt;
| Versorgungsspannung || 2,2 - 3,8 V || 1,8 - 3,6 V&lt;br /&gt;
|-&lt;br /&gt;
| Max. Datenrate || 115,2 kbit/s || 300 kbit/s&lt;br /&gt;
|-&lt;br /&gt;
| Sendeleistung || 5 dBm || 13 dBm&lt;br /&gt;
|-&lt;br /&gt;
| Empfindlichkeit || -105 dB || -120 dB&lt;br /&gt;
|-&lt;br /&gt;
| Stromaufnahme || 22 mA/11 mA/0,3 µA || 45 mA/16 mA/0,1 µA&lt;br /&gt;
|-&lt;br /&gt;
| FIFO Größe || 16 Bit || 66 Bytes&lt;br /&gt;
|-&lt;br /&gt;
| Syncmustererkennung || Fest 0x2DD4 oder 0xD4 || Frei bis zu 8 Bytes&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Ansteuerung ==&lt;br /&gt;
Das Funkmodul kommuniziert über die SPI Schnittstelle mit dem µC. Im einfachsten Fall werden SCK, MISO, MOSI und NSS benötigt. Am besten führt man auch noch DIO0 zum Prozessor. Dieser Pin kann softwareseitig so konfiguriert werden, dass er anzeigt, wenn ein Paket vollständig gesendet oder ein neues Paket empfangen wurde. Ist das Modul in Minimalkonfiguration angeschlossen, müssen dazu die Statusregister RegIrqFlags1 (0x27) oder RegIrqFlags2 (0x28) ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
Die SPI-Ansteuerung erfolgt im Modus CPOL=0, CPHA=0, wobei jeweils 16 Bits vom µC zum Modul geschickt werden:&lt;br /&gt;
Das erste Bit teilt dem Modul mit, ob es sich um einen Lese- (Bitwert 0) oder Schreibvorgang (Bitwert 1) handelt, die restlichen sieben Bit des ersten Bytes geben die Registeradresse an. Mit den zweiten acht Bit wird im Schreibmodus der zu übertragende Befehl an das Modul übermittelt, im Lesemodus kann eine beliebige Bitfolge gesendet werden. Während das zweite Bit gesendet wird, empfängt der µC sowohl im Lese- als auch im Schreibmodus den Inhalt des angesprochenen Registers vor dem aktuellen Zugriff.&lt;br /&gt;
&lt;br /&gt;
Werden nach dem Adressbyte mehrere Bytes empfangen oder gelesen, wird der Adresszeiger im RFM69 automatisch inkrementiert, so dass in einem einzigen Burst mehrere Register gelesen werden können. Zu beachten ist dabei, dass in Registern die mehr als 8 Bit breit sind (Frequenz, Bitrate, ...), das höchstwertige Byte zu erst geschrieben/gelesen wird (big endian). Wird das FIFO Register gelesen/geschrieben, wird der Adresszeiger nicht inkrementiert, so dass auf das FIFO in einem Burst zugegriffen werden kann.&lt;br /&gt;
&lt;br /&gt;
== Funktionsweise ==&lt;br /&gt;
Es gibt zwei grundsätzliche Funktionsmodi, die im Register &amp;quot;RegDataModule&amp;quot; gewählt werden:&lt;br /&gt;
=== Continuous Mode ===&lt;br /&gt;
Für die Datenübertragung vom/zum Modul werden die beiden Pins &amp;quot;DIO1/DCLK&amp;quot; und &amp;quot;DIO2/DATA&amp;quot; verwendet. An DCLK gibt das Modul den Takt vor mit dem die Datenbits an DATA geschrieben oder gelesen werden müssen.&lt;br /&gt;
=== Packet Mode ===&lt;br /&gt;
Die Packetengine des RFM69 kümmert sich um die Erzeugung und Auswertung der Preamble, des Synchronwortes, des Scramblings, der CRC und der Verschlüsselung. Im Sendebetrieb bearbeitet die eingebaute Packet Engine ein Nutzdatenpaket folgendermaßen:&lt;br /&gt;
==== Fixed Length Format ====&lt;br /&gt;
===== Senden =====&lt;br /&gt;
* Einstellbare Anzahl (0-65535) von Preamblebytes (0xAA) an den Anfang setzen&lt;br /&gt;
* Synchronwort hinzufügen (Länge zwischen 0-8 Bytes einstellbar, Synchronwort selbst ebenfalls einstellbar)&lt;br /&gt;
* Nutzdaten hinzufügen (Länge wird in einem Register angegeben)&lt;br /&gt;
* CRC hinzufügen (abschaltbar)&lt;br /&gt;
&lt;br /&gt;
== Interrupts ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Bezeichnung !! Beschreibung !! Verfügbar an&lt;br /&gt;
|-&lt;br /&gt;
| ModeReady || Beispiel || DIO5&lt;br /&gt;
|-&lt;br /&gt;
| RxReady || Beispiel || Beispiel&lt;br /&gt;
|-&lt;br /&gt;
| TxReady || Beispiel || DIO3, DIO0&lt;br /&gt;
|-&lt;br /&gt;
| PllLock || Beispiel || DIO3, DIO1, DIO0&lt;br /&gt;
|-&lt;br /&gt;
| Rssi || Beispiel || DIO3, DIO0&lt;br /&gt;
|-&lt;br /&gt;
| Timeout || Beispiel || DIO1&lt;br /&gt;
|-&lt;br /&gt;
| AutoMode || Beispiel || DIO2&lt;br /&gt;
|-&lt;br /&gt;
| SyncAddressMatch|| Beispiel || DIO3, DIO0&lt;br /&gt;
|-&lt;br /&gt;
| FifoFull || Beispiel || DIO3, DIO1&lt;br /&gt;
|-&lt;br /&gt;
| FifoNotEmpty || || DIO2, DIO1&lt;br /&gt;
|-&lt;br /&gt;
| FifoLevel || || DIO1&lt;br /&gt;
|-&lt;br /&gt;
| FifoOverrun || ||&lt;br /&gt;
|-&lt;br /&gt;
| PacketSent || || DIO0&lt;br /&gt;
|-&lt;br /&gt;
| PayloadReady || || DIO0&lt;br /&gt;
|-&lt;br /&gt;
| CrcOk || || DIO0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Pinbelegung RFM69(H)CW ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Pinnummer !! Name !! Richtung !! Beschreibung !! Pin am RFM12&lt;br /&gt;
|-&lt;br /&gt;
| 1 || ANA || || Antennenanschluss || ANT&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 3.3V || || Versorgungsspannung || VDD&lt;br /&gt;
|-&lt;br /&gt;
| 3 || GND || || || GND&lt;br /&gt;
|-&lt;br /&gt;
| 4 || DIO3 || || FifoFull&amp;amp;nbsp;PllLock&amp;lt;br/&amp;gt;Rssi&amp;lt;br/&amp;gt;SyncAdress&amp;lt;br/&amp;gt;TXReady || nINT/VDI&lt;br /&gt;
|-&lt;br /&gt;
| 5 || MOSI || || SPI Daten Eingang || SDI&lt;br /&gt;
|-&lt;br /&gt;
| 6 || SCK || || SPI Takt || SCK&lt;br /&gt;
|-&lt;br /&gt;
| 7 || NSS || || Chip select || nSEL&lt;br /&gt;
|-&lt;br /&gt;
| 8 || MISO || || SPI Daten Ausgang || SDO&lt;br /&gt;
|-&lt;br /&gt;
| 9 || DIO0 || || PllLock (FS, TX)&amp;lt;br/&amp;gt;CrcOK (RX)&amp;lt;br/&amp;gt;PayloadReady (RX)&amp;lt;br/&amp;gt;SyncAddress (RX)&amp;lt;br/&amp;gt;Rssi (RX)&amp;lt;br/&amp;gt;PacketSent (TX)&amp;lt;br/&amp;gt;TxReady (TX) || nIRQ&lt;br /&gt;
|-&lt;br /&gt;
| 10 || DIO2 || || FifoNotEmpty (Sleep, Stdby, FS, RX, TX)&amp;lt;br/&amp;gt;AutoMode(Sleep, Stdby, FS, RX, TX)&amp;lt;br/&amp;gt;Data (RX, TX) || FSK/DATA/nFFS&lt;br /&gt;
|-&lt;br /&gt;
| 11 || DIO1 || || FifoLevel (Sleep, Stdby, FS, RX, TX)&amp;lt;br/&amp;gt;FifoFull (Sleep, Stdby, FS, RX, TX)&amp;lt;br/&amp;gt;FifoNotEmpty (Sleep, Stdby, FS, RX, TX)&amp;lt;br/&amp;gt;PllLock (FS, TX)&amp;lt;br/&amp;gt;Timeout (RX) || DCLK/CFIL/FFIT&lt;br /&gt;
|-&lt;br /&gt;
| 12 || DIO5 || || ModeReady&amp;lt;br/&amp;gt;ClkOut (Stdby, FS, RX, TX)&amp;lt;br/&amp;gt;Data (RX, TX) || CLK&lt;br /&gt;
|-&lt;br /&gt;
| 13 || RESET || || || nRES&lt;br /&gt;
|-&lt;br /&gt;
| 14 || GND || || || GND&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Register ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Adresse !! Registername !! Beschreibung !! Beispiel&lt;br /&gt;
|-&lt;br /&gt;
| 0x00 || RegFifo || Zugriff auf das FIFO Register&lt;br /&gt;
|-&lt;br /&gt;
| 0x01 || RegOpMode || Betriebsart (senden, empfangen, ...) || 0x04 = Empfangen&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 || RegDataModule || Modulationsart &amp;amp;-shaping, Packetengine || 0x00 = FSK, Packetengine aktiv&lt;br /&gt;
|-&lt;br /&gt;
| 0x03 - 0x04|| RegBitrate || = FXOSC/Bitrate || 0x1A0B = 6667 -&amp;gt; 4,8 kbit/s&lt;br /&gt;
|-&lt;br /&gt;
| 0x05 - 0x06 || RegFdev || Frequenzabweichung (Hub * 2) || 0x52 = 82 -&amp;gt; 5 kHz&lt;br /&gt;
|-&lt;br /&gt;
| 0x07 - 0x09 || RegFrf || Mittenfrequenz || 0xD91333 = 14226227 -&amp;gt; 868,300 MHz&lt;br /&gt;
|-&lt;br /&gt;
| 0x11|| RegPaLevel || Sendeleistung || 0x12 = 18 -&amp;gt; 0 dBm&lt;br /&gt;
|-&lt;br /&gt;
| 0x19|| RegRxBw || Filterbandbreite || 0b01001 -&amp;gt; 200 kHz&lt;br /&gt;
|-&lt;br /&gt;
| 0x25|| RegDioMapping1 || DIO Funktionen ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x27|| RegIrqFlags1 || Statusflags (ModeReady, RxReady, TxReady, PllLock, RSSI, Timeout, AutoMode, SyncAddressMatch) || 0xD0 -&amp;gt; Empfänger bereit zum Datenempfang&lt;br /&gt;
|-&lt;br /&gt;
| 0x28|| RegIrqFlags2 || Statusflags (FifoFull, FifoNotEmpty, FifoLevel, FifoOverrun, PacketSent, PayloadReady, CrcOk, LowBat) || 0x06 -&amp;gt; Daten mit erfolgreichem CRC empfangen&lt;br /&gt;
|-&lt;br /&gt;
| 0x2C - 0x2D|| RegPreamble || Preamblelänge ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x2E || RegSyncConfig || Synchronworteinstellungen ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x2F - 0x36 || RegSyncValue || Synchronwort || 0x2DD4&lt;br /&gt;
|-&lt;br /&gt;
| 0x37 || RegPacketConfig1 || Einstellungen Packetengine ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x38 || RegPayloadLength || Datenpacketgröße ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Projekte ==&lt;br /&gt;
=== FS20 Funksteckdosen schalten ===&lt;br /&gt;
Da das RFM69 OOK modulieren kann, können damit die FS20 Funksteckdosen geschaltet werden. FS20 verwendet allerdings eine Art Pulsdauermodulation; eine 1 wird mit 600&amp;amp;nbsp;µs Träger an gefolgt von 600&amp;amp;nbsp;µs Träger aus, und eine 0 mit 400&amp;amp;nbsp;µs an gefolgt von 400&amp;amp;nbsp;µs aus übertragen. Man teilt einfach das Signal in 200&amp;amp;nbsp;µs Schlitze ein (OOK-Datenrate 5&amp;amp;nbsp;kbit/s), und sendet für eine 1 die Folge 111000 und für eine 0 die Folge 1100. Im FS20 Protokoll wird ein 13 Bit langer Header (0000000000001) übertragen, diesen kann man umrechnen und im RFM69 als Syncword einstellen. So wird der Header vom RFM69 bei jeder Übertragung automatisch vorweg ausgesendet.&lt;br /&gt;
&lt;br /&gt;
=== Conrad Energy Count 3000 ===&lt;br /&gt;
Unter http://forum.jeelabs.net/node/3412679.html?page=1 wurde schon das Protokoll der Conrad Energy Count 3000 (baugleich mit Technoline Cost Control RC) Funk-Energiekostenmessgeräte beschrieben. Mit dem RFM69 lässt sich ein Frame des Messgerätes mit dem konfigurierbarem Synchronwortfinder bequem empfangen.&lt;br /&gt;
&lt;br /&gt;
=== LaCrosse Temperatursensoren empfangen ===&lt;br /&gt;
=== Open Energy Monitor empfangen ===&lt;br /&gt;
&lt;br /&gt;
== Bezugsquellen ==&lt;br /&gt;
* [http://shop.seegel-systeme.de/Bauelemente/Funkmodul-RFM69CW-REV-V1-0-868-MHz-SMD.html Seegel Systeme]&lt;br /&gt;
* Pollin: [http://www.pollin.de/shop/dt/Nzk2OTgxOTk-/Bausaetze_Module/Module/Funkmodul_HOPERF_RFM69CW_433_MHz_TX_RX.html 433 MHz] / [http://www.pollin.de/shop/dt/Njk2OTgxOTk-/Bausaetze_Module/Module/Funkmodul_HOPERF_RFM69CW_868_MHz_TX_RX.html 868 MHz]&lt;br /&gt;
* [http://www.aliexpress.com/item/RFM69CW-13dBm-transceiver-module-pin-to-pin-compatible-to-RFM12B-433-868-915mhz-can-be-selected/2010762457.html AliExpress]&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* [http://www.hoperf.com/upload/rf/RFM69CW-V1.1.pdf Datenblatt RFM69CW]&lt;br /&gt;
* [http://www.hoperf.com/upload/rf/RFM69W-V1.3.pdf Datenblatt RFM69W]&lt;br /&gt;
* [http://www.semtech.com/images/datasheet/sx1231.pdf Datenblatt Semtech SX1231]&lt;br /&gt;
* [http://www.semtech.com/images/datasheet/AN1200.18_STD.pdf Application Note zur Softwareimplementierung von Data-Whitening und CRC]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/332579 Thread im Forum: Wer verwendet RFM69]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:RFM12]]&lt;br /&gt;
[[Kategorie:Funk]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=LED&amp;diff=87704</id>
		<title>LED</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=LED&amp;diff=87704"/>
		<updated>2015-03-05T18:14:08Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Änderung 87703 von 2A02:1205:C694:59C0:FC76:B0D0:853B:7FBC (Diskussion) rückgängig gemacht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Beschreibung == &lt;br /&gt;
&lt;br /&gt;
[[Bild:Ledrgb.jpg|thumb|right|246px|Detailfoto einer RGB-LED [http://www.mikrocontroller.net/topic/109784#990685]]]&lt;br /&gt;
&lt;br /&gt;
Eine LED (engl. &amp;lt;B&amp;gt;L&amp;lt;/B&amp;gt;ight &amp;lt;B&amp;gt;E&amp;lt;/B&amp;gt;mitting &amp;lt;B&amp;gt;D&amp;lt;/B&amp;gt;iode, &#039;&#039;Leuchtdiode&#039;&#039;) besteht aus einem [[Halbleiter]]-PN-Übergang, der durch seine Zusammensetzung Licht eines stark begrenzten Wellenbereiches emittiert, wenn er in Durchlassrichtung von Strom durchflossen wird. Die Helligkeit einer LED ist in erster Näherung proportional zum Strom.&lt;br /&gt;
&lt;br /&gt;
Die Farbe des emittierten Lichts hängt vom verwendeten Halbleitermaterial ab. Es existieren [[Halbleiter | Halbleitermaterialien]] für den gesamten sichtbaren Bereich als auch für den Infrarotbereich und den nahen Ultraviolettbereich. Für kurze Wellenlängen (Blau bis Ultraviolett) ist ein Halbleitermaterial wie z.&amp;amp;nbsp;B. InGaN oder GaN erforderlich. Für die ersten blauen LEDs wurde SiC verwendet, welche aber eine schlechte Effizienz hat (Quelle:Wikipedia).&lt;br /&gt;
&lt;br /&gt;
Weißes Licht oder andere Farbmischungen können erzeugt werden, indem man eine Blau- oder Ultraviolett-LED mit einem Phosphormaterial beschichtet, welches durch das Licht der LED zur Emission angeregt wird. Die entstehende Farbe wird dabei von der Beschichtung bestimmt.&lt;br /&gt;
&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
== Durchlassspannung ==&lt;br /&gt;
&lt;br /&gt;
LEDs haben im Vergleich zu gewöhnlichen [[Diode|Dioden]] eine vergleichsweise hohe, vom Halbleitermaterial abhängige [[Durchlass-Spannung]]. Bevor diese erreicht wird, fließt nur sehr wenig Strom und die LED leuchtet praktisch nicht. Oberhalb der Durchlassspannung (Flussspannung) steigt der Strom schnell an (Diodenkennlinie). Die Flussspannung reicht von ca. 1,2 V bei Infrarot-LEDs bis zu etwa 4 V bei Ultraviolett-LEDs. Auffällig ist die Korrelation zwischen Spannung und der Farbe, die damit zusammenhängt, dass die Emission höherenergetischer Photonen einen größeren Bandabstand im Halbleitermaterial erfordert, welcher von den Elektronen überwunden werden muss, wenn sie ihre Energie abgegeben. Da anfänglich nur Halbleiter mit geringem Bandabstand produziert wurden und aufgrund von mangelnder Reinheit oft Zwischenniveaurekombination stattfand, waren lange Zeit keine blauen oder gar echtvioletten LEDs herstellbar. Die ersten verfügbaren LEDs waren naturgemäß auch rot.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:centre&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Farbe || typische&amp;lt;br&amp;gt;Flussspannung [V]&lt;br /&gt;
|-&lt;br /&gt;
| Infrarot || 1,2&lt;br /&gt;
|-&lt;br /&gt;
| Rot || 1,8&lt;br /&gt;
|-&lt;br /&gt;
| Gelb || 2,0&lt;br /&gt;
|-&lt;br /&gt;
| Grün || 2,2&lt;br /&gt;
|-&lt;br /&gt;
| Grün&amp;lt;br&amp;gt;(Ultrahell) || 3,3&lt;br /&gt;
|-&lt;br /&gt;
| Blau || 3,6&lt;br /&gt;
|-&lt;br /&gt;
| Weiß || 3,6&lt;br /&gt;
|-&lt;br /&gt;
| Ultraviolett || 4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Durchlassstrom == &lt;br /&gt;
&lt;br /&gt;
Da LEDs durch einen zu hohen Strom zerstört werden, muss der Strom begrenzt werden. Der Maximalstrom einer LED ist bei allen Typen sehr ähnlich und liegt bei 25 -30 mA. Eine standard LED wird üblicherweise mit 20 mA betrieben. Moderne LEDs kommen häufig mit sehr viel weniger Strom aus. So benötigt eine Low-Current LED nur 2 mA um sehr hell zu leuchten. Da der Maximalwert auch für eine Low-Current LED gilt, schadet es nicht, wenn man sie mit 20 mA betreibt. Sinnvoll ist es aber nur beim Multiplexen. Genaue Angaben dazu finden sich in entsprechenden Datenblättern.&lt;br /&gt;
&lt;br /&gt;
=== Vorwiderstand ===&lt;br /&gt;
&lt;br /&gt;
Im einfachsten Fall und bei relativ geringfügig variierender Betriebsspannung kann man dazu einen Widerstand einsetzen.&lt;br /&gt;
&lt;br /&gt;
[[bild:led_rv.png|right]]&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;R_V=\frac{Vcc-U_\text{LED}}{I_\text{LED}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;R_V&amp;lt;/math&amp;gt;: Vorwiderstand in Ohm&lt;br /&gt;
* Vcc: Betriebsspannung in Volt&lt;br /&gt;
* &amp;lt;math&amp;gt;U_{LED}&amp;lt;/math&amp;gt;: Durchlassspannung der LED in Volt&lt;br /&gt;
* &amp;lt;math&amp;gt;I_{LED}&amp;lt;/math&amp;gt;: Strom durch die LED in Ampere&lt;br /&gt;
&lt;br /&gt;
Bei 6 V Betriebsspannung, einer Durchlassspannung der LED von 2,4 V und einem gewünschten Strom von 20 mA braucht man nach dem ohmschen Gesetz einen Widerstand von 180Ω, bei 12 V Betriebsspannung sind es 480Ω. In der Praxis wird jeweils der nächstgrößere Standardwert gewählt (E-Reihen).&lt;br /&gt;
&lt;br /&gt;
Was passiert nun, wenn die Flußspannung der LED etwas anders ist als angenommen, z.B. durch Fertigungstoleranzen, höheren Strom oder stark veränderte Temperatur? Bleiben wir bei dem Beispiel mit 6V Versorgungsspannung, 2,4V Flußspannung, 20mA und 180 Ohm Vorwiderstand. Es fallen rechnerisch 3,6V am Vorwiderstand ab. Wenn nun die Flußspannung um 0,2V schwankt (realistischer Wert), ändert sich die Spannung über dem Vorwiderstand um diese 0,2V. Bezogen auf 3,6V Spannungsabfall sind das 5,5%. Bei 12V Betriebsspannung und damit 9,6V Spannungsabfall über dem Vorwiderstand sind es nur noch 2%. Daraus erkennt man, dass der Vorwiderstand umso besser als [[Konstantstromquelle]] wirkt, je höher der Spannungsabfall über diesem ist. Eine echte Konstantstromquelle mit aktiven Elementen (Transistoren) erreicht den gleichen Effekt mit deutlich weniger Spannungsabfall.&lt;br /&gt;
&lt;br /&gt;
Mit einem 480-Ohm-Widerstand, welcher für 12 V Betriebsspannung passend ist, würden bei 6 Volt statt 20 mA nur noch 7,5 mA fließen. Mit einem 180-Ohm-Widerstand, welcher für 6 V Betriebsspannung passend ist, würden bei 12 V statt der gewünschten 20 mA allerdings schon 53 mA fließen. &lt;br /&gt;
&lt;br /&gt;
Beachten muss man auch die als Wärme abgegebene &#039;&#039;&#039;Verlustleistung&#039;&#039;&#039; über dem Vorwiderstand, vor allem wenn man LEDs an eine recht hohe Betriebsspannung von 12 V oder gar 24 V anschließt. Die Verlustleistung berechnet sich einfach aus&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;P_\text{RV} = (V_\text{cc}-U_\text{LED}) \cdot I_\text{LED} = I_\text{LED}^2 \cdot R_\text{V}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel mit der 2,4-V-LED und einem Strom von 20 mA heißt das, dass an dem 480-Ohm-Widerstand eine Verlustleistung von 192 mW abfällt. Ein kleiner SMD-Widerstand der Größe 0805 hält das nicht mehr aus (1/8 W = 125 mW maximal).&lt;br /&gt;
&lt;br /&gt;
Wie man aus dem Beispiel erkennt, ist bei stark variierender Betriebsspannung ein Vorwiderstand weniger geeignet. Es sei denn, man nimmt sehr unterschiedliche LED-Ströme und damit LED-Helligkeiten oder möglicherweise die Zerstörung der LED in Kauf.&lt;br /&gt;
&lt;br /&gt;
Bei Batteriebetrieb werden LEDs häufig ohne Vorwiderstand betrieben. So z.B. bei billigen Taschenlampen und Fahrradlampen. Dabei werden oft sogar zwei 1,5V Batterien in Reihe geschaltet und die LED direkt angeschlossen. Der Grund ist, dass das alles nichts kosten darf und man sich auf den Innenwiderstand der Batterie und der LEDs verlässt, um den Strom halbwegs zu begrenzen.&lt;br /&gt;
&lt;br /&gt;
=== Konstantstromquelle ===&lt;br /&gt;
&lt;br /&gt;
Bei stark schwankender Versorgungsspannung oder Umgebungstemperatur heißt der Ausweg [[Konstantstromquelle]]. Kriterien für die Auswahl einer Schaltung für die Konstantstromquelle sind hierbei z.&amp;amp;nbsp;B. Betriebsspannungsbereich, erforderliche Genauigkeit und Kosten. Auch hier ist zu beachten, daß die Verlustleistung der Konstantstromquelle von den Bauteilen abgeführt werden muss, mit einer gewissen Ausnahme der Lösungen mit Schaltregler.&lt;br /&gt;
&lt;br /&gt;
=== Betriebsstrom ===&lt;br /&gt;
&lt;br /&gt;
In der Praxis werden LEDs oft mit einem weit geringeren als dem maximal zulässigen Durchlassstrom betrieben. Insbesondere im Entwicklungs- und Experimentierumfeld kann eine für maximal 20 mA ausgelegte LED auch mit lediglich 3-5 mA betrieben werden. Der subjektiv wahrgenommene Helligkeitsverlust ist deutlich geringer, als der prozentuale Unterschied der Stromstärke vermuten lässt, siehe Artikel [[LED-Fading]].&lt;br /&gt;
&lt;br /&gt;
== Mehrere LEDs zusammenschalten ==&lt;br /&gt;
&lt;br /&gt;
Diese Frage bewegt immer wieder die Gemüter. Wie schaltet man mehrere LEDs &#039;&#039;&#039;richtig&#039;&#039;&#039; zusammen?&lt;br /&gt;
&lt;br /&gt;
=== Reihenschaltung ===&lt;br /&gt;
&lt;br /&gt;
In einer Reihenschaltung ist der Strom durch alle Verbraucher gleich. Ideal für LEDs. Hat man eine ausreichend hohe Versorgungsspannung, kann man mehrere LEDs in Reihe schalten. Dann reicht ein einziger Widerstand bzw. eine [[Konstantstromquelle]]. Allerdings sollte man das nicht übertreiben. 100-150 LEDs direkt an die Netzspannung zu hängen ist nicht möglich, da die LEDs zu viel Sperrspannung abbekommen würden. Auch bei gleichgerichteter Spannung besteht ein Sicherheitsproblem. Als Hobbybastler sollte man sich auch hier auf Spannungen kleiner als 40V beschränken.&lt;br /&gt;
&lt;br /&gt;
=== Parallelschaltung ===&lt;br /&gt;
&lt;br /&gt;
Das direkte Parallelschalten von LEDs ist sehr kritisch und muss vermieden werden. Grund ist die exponentielle Diodekennlinie, welche bewirkt, dass eine kleine Spannungsänderung eine grosse Stromänderung hervorruft. Schaltet man nun zwei LEDs mit verschiedenen Durchlassspannung parallel, bekommt die mit der niedrigeren Durchlassspannung DEUTLICH mehr Strom ab, dadurch wird sie nicht nur deutlich heller sondern auch wärmer. Das führt zum 2. Problem, denn mit steigender Temperatur sinkt die Durchlassspannung zusätzlich, wodurch sich der Effekt weiter verstärkt! LEDs verschiedender Farben haben sehr unterschiedliche Durchlassspannungen, hier ist ein direktes Parallelschalten vollkommen unmöglich. Aber selbst LEDs mit gleicher Farbe und aus einem Produktionsdurchlauf (Lot) weisen herstellungsbedingt bisweilen erhebliche Streuungen der Durchlassspannung auf!&lt;br /&gt;
&lt;br /&gt;
Richtig Parallelschalten kann man LEDs aber durch&lt;br /&gt;
&lt;br /&gt;
* Vorwiderstand/Konstantstromquelle für jede einzelne LED&lt;br /&gt;
* Auswählen von ausgemessenen LEDs mit sehr ähnlicher Flußspannung&lt;br /&gt;
&lt;br /&gt;
Letztere Methode wird von professionellen Herstellern verwendet, um bei grösseren Anzeigen LEDs direkt parallel schalten zu können. Die Unterschiede in der Flußspannung bei Nennstrom sollten dabei kleiner als 10mV(?) sein. Das gilt natürlich auch für das Parallelschalten von LED-Strängen, also Reihenschaltungen von LEDs.&lt;br /&gt;
&lt;br /&gt;
=== Reihen- plus Parallelschaltung ===&lt;br /&gt;
&lt;br /&gt;
Eine Kombination aus Serien- und Parallelschaltung ist weniger kritisch, da sich die unterschiedlichen Kennlinien statistisch mitteln. Z.B. kann man 20 LEDs in Reihe und mehrere solcher Stränge parallel schalten. Eine einzelne Diode mit geringerer Durchlaßspannung wird im Strom durch 9 andere begrenzt. Der Stromanstieg infolge der Unterschiede der einzelnen Stränge erzeugt an allen Bahnwiderständen der Dioden einen Spannungsabfall, der die ungleiche Stromverteilung begrenzt.&lt;br /&gt;
&lt;br /&gt;
Da LEDs mit bis zu 20% in ihrer effektiven Leuchtkraft bei gleicher scheinbarer Spannung streuen, sollte man wenigstens 10 LEDs in Reihe schalten und diese auch nur zu 70% auslasten, um optische Schwankungen auf ein Maß der Nichtsichtbarkeit zu senken und Mitkopplungseffekte infolge von Erwärmung zu begrenzen. Statistisch streuen die Helligkeiten dann nur noch im Bereich einiger Prozente. Die Variation der Stromaufnahme einzelner Stränge sollte demgemäß ebenfalls auf 5% begrenzt werden, d.h. der regelnde Widerstand muss im Bereich von &amp;gt;10% Spannungsänderungen aufnehmen können.&lt;br /&gt;
&lt;br /&gt;
Eine brauchbare Dimensionierung für 1,7V-LEDs @ 20mA wäre: 10 LEDs mit R=150Ohm an 20Volt. Der Widerstand sollte mit 1W belastbar sein. Noch besser ist ein gegengeregelter FET, der als Kaltleiter eine doppelte Gegenregelung bringt.&lt;br /&gt;
&lt;br /&gt;
Für eine gleichmäßige Lichtversorgung eines Array, sollten die LEDs nicht strangweise parallel, sondern in Schleifen verlegt werden. Man kann z.B. zwei Stränge alternierend verdrahten.&lt;br /&gt;
&lt;br /&gt;
== Direktbetrieb an 230V ==&lt;br /&gt;
Eine Methode, LEDs an 230V direkt zu betreiben, ist die Strombegrenzung mit einem spannungsfesten Kondensator, der in Reihe zur eigentlichen LED-Schaltung liegt, die aus einem 4-Wege-Gleichrichter, einem ELKO und einer Anzahl als Array verschalteter LEDs besteht. Die LEDs können wie im obigen Beispiel auf 20V oder 24V ausgelegt werden und sollten mit zwei antiparallel geschalteten Z-Dioden auf 24/28V limitiert werden, um Spannungsspitzen abzufangen. Die vorgeschaltete Kapazität wird mit einer Reihenschaltung von 4 keramischen Kondensatoren aufgebaut, von denen jeder ca 60V abfangen muss. Die Kapazität richtet sich nach der Stromaufnahme der Summe der LED-Stränge.&lt;br /&gt;
&lt;br /&gt;
Eine andere Möglichkeit befindet sich im Artikel [[LED-Glühbirne]].&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[AVR-Tutorial: IO-Grundlagen#Hardware]]&lt;br /&gt;
* [[LED-&amp;quot;Birnen&amp;quot;]]&lt;br /&gt;
* [[LED-Matrix]]&lt;br /&gt;
* [[LED-Fading]]&lt;br /&gt;
* [[Lichtsensor / Helligkeitssensor#LED]]&lt;br /&gt;
* [[Ambilight in Hardware]]&lt;br /&gt;
* [[Konstantstromquelle]] &lt;br /&gt;
* [[Konstantstromquelle fuer Power LED]]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/158836?goto=2759782#2759782 Forumsbeitrag]: LEDs an 230V Netzspannung mit Konstantstromquelle&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/219681#2197034 Forumsbeitrag]: Darstellung der Toleranzen von LEDs und deren Wirkung, oder &amp;quot;Warum man einen Vorwiderstand braucht&amp;quot;&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/74169#618682 Forumsbeitrag]: 16-Segment Ganganzeige ohne Mikrocontroller&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/267113#2788848 Forumsbeitrag]: Unbekannte LEDs ausmessen.&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/280991?goto=2966997#2966820 Forumsbeitrag]: Konstantstromquelle für LED an 40-420VDC&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/290710?goto=3106790#3106790 Forumsbeitrag]: Graphische Ermittlung des LED-Stroms und der Toleranzen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/311454#new Forumsbeitrag]: Glühbirnen ungepulst betreiben?&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/289238#3073788 Forumsbeitrag]: 2 LEDs mit einem Portpin steuern&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/261525?goto=new#new Forumsbeitrag]: Samsung Hochvolt AC LED Erfahrungen?&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://de.wikibooks.org/wiki/Arbeiten_mit_LEDs/_Grundlagen Wikibooks Arbeiten mit LEDs: Grundlagen] - Sehr gute Erklärung, auch für Anfänger&lt;br /&gt;
* [http://www.theledlight.com/technical.html www.theledlight.com] - LED Information and Technical Data (englisch)&lt;br /&gt;
* [http://forum.electronicwerkstatt.de/phpBB/faq/led/ LED FAQ für Anfänger]&lt;br /&gt;
* [http://members.misty.com/don/ledx.html Don Klipstein&#039;s LED Main Page (engl.)]&lt;br /&gt;
* [http://www.robotroom.com/LEDTester.html Selecting a LED] - LED Tester von David Cook (Beginnerprojekt)&lt;br /&gt;
* [http://www.evilmadscientist.com/article.php/throw Some thoughts on throwies] von Windell H. Oskay von www.evilmadscientist.com&lt;br /&gt;
*[http://www.led-rechner.de www.led-rechner.de]&lt;br /&gt;
*[http://catalog.osram-os.com/catalogue/catalogue.do?act=downloadFile&amp;amp;favOid=02000002000040ac000100b6 Vergleich von LED-Schaltungen ] - Applikationsschrift von OSRAM, engl.&lt;br /&gt;
* [http://catalog.osram-os.com/catalogue/catalogue.do;jsessionid=CBC285EE73F7A4DA3956223C87D46516?act=downloadFile&amp;amp;favOid=0200000200004264000100b6 Ansteuerung von Power TOPLEDs] - Applikationsschrift von OSRAM, engl.&lt;br /&gt;
*[http://catalog.osram-os.com/catalogue/catalogue.do;jsessionid=CBC285EE73F7A4DA3956223C87D46516?act=downloadFile&amp;amp;favOid=0200000200001b48000200b6 Verhalten von InGaN LEDs in Parallelschaltungen] - Applikationsschrift von OSRAM, engl.&lt;br /&gt;
&lt;br /&gt;
[[Category:Bauteile]]&lt;br /&gt;
[[Category:Grundlagen]]&lt;br /&gt;
[[Category:Displays und Anzeigen| ]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR-Tutorial:_Stack&amp;diff=87668</id>
		<title>AVR-Tutorial: Stack</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR-Tutorial:_Stack&amp;diff=87668"/>
		<updated>2015-03-04T11:48:09Z</updated>

		<summary type="html">&lt;p&gt;Maybee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;quot;[[Stack]]&amp;quot; bedeutet übersetzt soviel wie Stapel. Damit ist ein Speicher nach dem LIFO-Prinzip (&amp;quot;last in first out&amp;quot;) gemeint. Das bedeutet, dass das zuletzt auf den Stapel gelegte Element auch zuerst wieder heruntergenommen wird. Es ist nicht möglich, Elemente irgendwo in der Mitte des Stapels herauszuziehen oder hineinzuschieben. &lt;br /&gt;
&lt;br /&gt;
Bei allen aktuellen AVR-Controllern wird der Stack im [[Speicher#RAM|RAM]] angelegt. Der Stack wächst dabei von oben nach unten: Am Anfang wird der Stackpointer (Adresse der aktuellen Stapelposition) auf das Ende des RAMs gesetzt. Wird nun ein Element hinzugefügt, wird dieses an der momentanen Stackpointerposition abgespeichert und der Stackpointer um 1 erniedrigt. Soll ein Element vom Stack heruntergenommen werden, wird zuerst der Stackpointer um 1 erhöht und dann das Byte von der vom Stackpointer angezeigten Position gelesen.&lt;br /&gt;
&lt;br /&gt;
== Aufruf von Unterprogrammen ==&lt;br /&gt;
Dem Prozessor dient der Stack hauptsächlich dazu, Rücksprungadressen beim Aufruf von Unterprogrammen zu speichern, damit er später noch weiß, an welche Stelle zurückgekehrt werden muss, wenn das Unterprogramm mit &#039;&#039;&#039;ret&#039;&#039;&#039; oder die Interruptroutine mit &#039;&#039;&#039;reti&#039;&#039;&#039; beendet wird. &lt;br /&gt;
&lt;br /&gt;
Das folgende Beispielprogramm (AT90S4433) zeigt, wie der Stack dabei beeinflusst wird: &lt;br /&gt;
&lt;br /&gt;
[http://www.mikrocontroller.net/sourcecode/tutorial/stack.asm Download stack.asm]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
.include &amp;quot;4433def.inc&amp;quot;     ; bzw. 2333def.inc&lt;br /&gt;
&lt;br /&gt;
.def temp = r16&lt;br /&gt;
&lt;br /&gt;
         ldi temp, RAMEND  ; Stackpointer initialisieren&lt;br /&gt;
         out SP, temp&lt;br /&gt;
&lt;br /&gt;
         rcall sub1        ; sub1 aufrufen&lt;br /&gt;
&lt;br /&gt;
loop:    rjmp loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sub1:&lt;br /&gt;
                           ; hier könnten ein paar Befehle stehen&lt;br /&gt;
         rcall sub2        ; sub2 aufrufen&lt;br /&gt;
                           ; hier könnten auch ein paar Befehle stehen&lt;br /&gt;
         ret               ; wieder zurück&lt;br /&gt;
&lt;br /&gt;
sub2:&lt;br /&gt;
                           ; hier stehen normalerweise die Befehle,&lt;br /&gt;
                           ; die in sub2 ausgeführt werden sollen&lt;br /&gt;
         ret               ; wieder zurück&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;.def temp = r16&#039;&#039;&#039; ist eine Assemblerdirektive. Diese sagt dem Assembler, dass er überall, wo er &amp;quot;temp&amp;quot; findet, stattdessen &amp;quot;r16&amp;quot; einsetzen soll. Das ist oft praktisch, damit man nicht mit den Registernamen durcheinander kommt. Eine Übersicht über die Assemblerdirektiven findet man [http://www.avr-asm-tutorial.net/avr_de/beginner/diraus.html hier]. &lt;br /&gt;
&lt;br /&gt;
Bei Controllern, die mehr als 256 Byte RAM besitzen (z.&amp;amp;nbsp;B. ATmega8), passt die Adresse nicht mehr in ein Byte. Deswegen gibt es bei diesen Controllern das Stack-Pointer-Register aufgeteilt in &#039;&#039;&#039;SPL&#039;&#039;&#039; (Low) und &#039;&#039;&#039;SPH&#039;&#039;&#039; (High), in denen das Low- und das High-Byte der Adresse gespeichert wird. Damit es funktioniert, muss das Programm dann folgendermaßen geändert werden: &lt;br /&gt;
&lt;br /&gt;
[http://www.mikrocontroller.net/sourcecode/tutorial/stack-bigmem.asm Download stack-bigmem.asm]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
.include &amp;quot;m8def.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
.def temp = r16&lt;br /&gt;
&lt;br /&gt;
         ldi temp, HIGH(RAMEND)            ; HIGH-Byte der obersten RAM-Adresse&lt;br /&gt;
         out SPH, temp&lt;br /&gt;
         ldi temp, LOW(RAMEND)             ; LOW-Byte der obersten RAM-Adresse&lt;br /&gt;
         out SPL, temp&lt;br /&gt;
&lt;br /&gt;
         rcall sub1                        ; sub1 aufrufen&lt;br /&gt;
&lt;br /&gt;
loop:    rjmp loop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sub1:&lt;br /&gt;
                                           ; hier könnten ein paar Befehle stehen&lt;br /&gt;
         rcall sub2                        ; sub2 aufrufen&lt;br /&gt;
                                           ; hier könnten auch Befehle stehen&lt;br /&gt;
         ret                               ; wieder zurück&lt;br /&gt;
&lt;br /&gt;
sub2:&lt;br /&gt;
                                           ; hier stehen normalerweise die Befehle,&lt;br /&gt;
                                           ; die in sub2 ausgeführt werden sollen&lt;br /&gt;
         ret                               ; wieder zurück&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Natürlich ist es unsinnig, dieses Programm in einen Controller zu programmieren. Stattdessen sollte man es mal mit dem AVR-Studio simulieren, um die Funktion des Stacks zu verstehen. &lt;br /&gt;
&lt;br /&gt;
Als erstes wird mit &#039;&#039;&#039;Project/New&#039;&#039;&#039; ein neues Projekt erstellt, zu dem man dann mit &#039;&#039;&#039;Project/Add File&#039;&#039;&#039; eine Datei mit dem oben gezeigten Programm (stack.asm) hinzufügt. Nachdem man unter &#039;&#039;&#039;Project/Project Settings&#039;&#039;&#039; das &#039;&#039;&#039;Object Format for AVR-Studio&#039;&#039;&#039; ausgewählt hat, kann man das Programm mit Strg+F7 assemblieren und den Debug-Modus starten. &lt;br /&gt;
&lt;br /&gt;
Danach sollte man im Menu &#039;&#039;&#039;View&#039;&#039;&#039; die Fenster &#039;&#039;&#039;Processor&#039;&#039;&#039; und &#039;&#039;&#039;Memory&#039;&#039;&#039; öffnen und im Memory-Fenster &#039;&#039;&#039;Data&#039;&#039;&#039; auswählen. &lt;br /&gt;
&lt;br /&gt;
Das Fenster &#039;&#039;&#039;Processor&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;Program Counter&#039;&#039;: Adresse im Programmspeicher (FLASH), die gerade abgearbeitet wird&lt;br /&gt;
* &#039;&#039;Stack Pointer&#039;&#039;: Adresse im Datenspeicher (RAM), auf die der Stackpointer gerade zeigt&lt;br /&gt;
* &#039;&#039;Cycle Counter&#039;&#039;: Anzahl der Taktzyklen seit Beginn der Simulation&lt;br /&gt;
* &#039;&#039;Time Elapsed&#039;&#039;: Zeit, die seit dem Beginn der Simulation vergangen ist &lt;br /&gt;
&lt;br /&gt;
Im Fenster &#039;&#039;&#039;Memory&#039;&#039;&#039; wird der Inhalt des RAMs angezeigt. &lt;br /&gt;
&lt;br /&gt;
Sind alle 3 Fenster gut auf einmal sichtbar, kann man anfangen, das Programm (in diesem Fall &amp;quot;stack.asm&amp;quot;) mit der Taste F11 langsam Befehl für Befehl zu simulieren. &lt;br /&gt;
&lt;br /&gt;
Wenn der gelbe Pfeil in der Zeile &#039;&#039;&#039;out SPL, temp&#039;&#039;&#039; vorbeikommt, kann man im Prozessor-Fenster sehen, wie der Stackpointer auf 0xDF (&#039;&#039;ATmega8&#039;&#039;: 0x45F) gesetzt wird. Wie man im Memory-Fenster sieht, ist das die letzte RAM-Adresse. &lt;br /&gt;
&lt;br /&gt;
Wenn der Pfeil auf dem Befehl &#039;&#039;&#039;rcall sub1&#039;&#039;&#039; steht, sollte man sich den Program Counter anschauen: Er steht auf 0x02 (&#039;&#039;ATmega8&#039;&#039;: 0x04). &lt;br /&gt;
&lt;br /&gt;
Drückt man jetzt nochmal auf F11, springt der Pfeil zum Unterprogramm sub1. Im RAM erscheint an der Stelle, auf die der Stackpointer vorher zeigte, die Zahl 0x03 (&#039;&#039;ATmega8&#039;&#039;: 0x05). Das ist die Adresse im ROM, an der das Hauptprogramm nach dem Abarbeiten des Unterprogramms fortgesetzt wird. Doch warum wurde der Stackpointer um 2 verkleinert? Das liegt daran, dass eine Programmspeicheradresse bis zu 2 Byte breit sein kann, und somit auch 2 Byte auf dem Stack benötigt werden, um die Adresse zu speichern. &lt;br /&gt;
&lt;br /&gt;
Das gleiche passiert beim Aufruf von sub2. &lt;br /&gt;
&lt;br /&gt;
Zur Rückkehr aus dem mit rcall aufgerufenen Unterprogramm gibt es den Befehl &#039;&#039;&#039;ret&#039;&#039;&#039;. Dieser Befehl sorgt dafür, dass der Stackpointer wieder um 2 erhöht wird und die dabei eingelesene Adresse in den &amp;quot;Program Counter&amp;quot; kopiert wird, so dass das Programm dort fortgesetzt wird. &lt;br /&gt;
&lt;br /&gt;
Apropos Program Counter: Wer sehen will, wie so ein Programm aussieht, wenn es assembliert ist, sollte mal die Datei mit der Endung &amp;quot;.lst&amp;quot; im Projektverzeichnis öffnen. Die Datei sollte ungefähr so aussehen: &lt;br /&gt;
&lt;br /&gt;
http://www.mikrocontroller.net/images/listfile.gif&lt;br /&gt;
&lt;br /&gt;
Im blau umrahmten Bereich steht die Adresse des Befehls im Programmspeicher. Das ist auch die Zahl, die im Program Counter angezeigt wird, und die beim Aufruf eines Unterprogramms auf den Stack gelegt wird. Der grüne Bereich rechts daneben ist der OP-Code des Befehls, so wie er in den Programmspeicher des Controllers programmiert wird, und im roten Kasten stehen die &amp;quot;mnemonics&amp;quot;: Das sind die Befehle, die man im Assembler eingibt.&lt;br /&gt;
Der nicht eingerahmte Rest besteht aus Assemblerdirektiven, Labels (Sprungmarkierungen) und Kommentaren, die nicht direkt in OP-Code umgewandelt werden.&lt;br /&gt;
Der grün eingerahmte Bereich ist das eigentliche Programm, so wie es der µC versteht. Die jeweils erste Zahl im grünen Bereich steht für einen Befehl, den sog. OP-Code (OP = Operation). Die zweite Zahl codiert Argumente für diesen Befehl.&lt;br /&gt;
&lt;br /&gt;
== Sichern von Registern ==&lt;br /&gt;
Eine weitere Anwendung des Stacks ist das &amp;quot;Sichern&amp;quot; von Registern. Wenn man z.&amp;amp;nbsp;B. im Hauptprogramm die Register R16, R17 und R18 verwendet, dann ist es i.d.R. erwünscht, dass diese Register durch aufgerufene Unterprogramme nicht beeinflusst werden. Man muss also nun entweder auf die Verwendung dieser Register innerhalb von Unterprogrammen verzichten, oder man sorgt dafür, dass am Ende jedes Unterprogramms der ursprüngliche Zustand der Register wiederhergestellt wird. Wie man sich leicht vorstellen kann ist ein &amp;quot;Stapelspeicher&amp;quot; dafür ideal: Zu Beginn des Unterprogramms legt man die Daten aus den zu sichernden Registern oben auf den Stapel, und am Ende holt man sie wieder (in der umgekehrten Reihenfolge) in die entsprechenden Register zurück. Das Hauptprogramm bekommt also wenn es fortgesetzt wird überhaupt nichts davon mit, dass die Register inzwischen anderweitig verwendet wurden. &lt;br /&gt;
&lt;br /&gt;
[http://www.mikrocontroller.net/sourcecode/tutorial/stack-saveregs.asm Download stack-saveregs.asm]&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt;  &lt;br /&gt;
.include &amp;quot;4433def.inc&amp;quot;            ; bzw. 2333def.inc&lt;br /&gt;
&lt;br /&gt;
.def temp = R16&lt;br /&gt;
&lt;br /&gt;
         ldi temp, RAMEND         ; Stackpointer initialisieren&lt;br /&gt;
         out SP, temp&lt;br /&gt;
&lt;br /&gt;
         ldi temp, 0xFF&lt;br /&gt;
         out DDRB, temp           ; Port B = Ausgang&lt;br /&gt;
&lt;br /&gt;
         ldi R17, 0b10101010      ; einen Wert ins Register R17 laden&lt;br /&gt;
&lt;br /&gt;
         rcall sub1                ; Unterprogramm &amp;quot;sub1&amp;quot; aufrufen&lt;br /&gt;
 &lt;br /&gt;
         out PORTB, R17           ; Wert von R17 an den Port B ausgeben&lt;br /&gt;
&lt;br /&gt;
loop:    rjmp loop                ; Endlosschleife&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sub1:&lt;br /&gt;
         push R17                 ; Inhalt von R17 auf dem Stack speichern&lt;br /&gt;
&lt;br /&gt;
         ; hier kann nach belieben mit R17 gearbeitet werden,&lt;br /&gt;
         ; als Beispiel wird es hier auf 0 gesetzt&lt;br /&gt;
&lt;br /&gt;
         ldi R17, 0&lt;br /&gt;
&lt;br /&gt;
         pop R17                  ; R17 zurückholen&lt;br /&gt;
         ret                      ; wieder zurück zum Hauptprogramm&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wenn man dieses Programm assembliert und in den Controller lädt, dann wird man feststellen, dass jede zweite LED an Port B leuchtet. Der ursprüngliche Wert von R17 blieb also erhalten, obwohl dazwischen ein Unterprogramm aufgerufen wurde, das R17 geändert hat. &lt;br /&gt;
&lt;br /&gt;
Auch in diesem Fall kann man bei der Simulation des Programms im AVR-Studio die Beeinflussung des Stacks durch die Befehle &#039;&#039;&#039;push&#039;&#039;&#039; und &#039;&#039;&#039;pop&#039;&#039;&#039; genau nachvollziehen.&lt;br /&gt;
&lt;br /&gt;
== Sprung zu beliebiger Adresse ==&lt;br /&gt;
&#039;&#039;Dieser Abschnitt ist veraltet, da nahezu alle ATmega/ATtiny Typen IJMP/ICALL unterstützen.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Kleinere AVR besitzen keinen Befehl, um direkt zu einer Adresse zu springen, die in einem Registerpaar gespeichert ist. Man kann dies aber mit etwas Stack-Akrobatik erreichen. Dazu einfach zuerst den niederen Teil der Adresse, dann den höheren Teil der Adresse mit &#039;&#039;&#039;push&#039;&#039;&#039; auf den Stack legen und ein &#039;&#039;&#039;ret&#039;&#039;&#039; ausführen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
	ldi ZH, high(testRoutine)&lt;br /&gt;
	ldi ZL, low(testRoutine)&lt;br /&gt;
	&lt;br /&gt;
	push ZL&lt;br /&gt;
	push ZH&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
testRoutine:&lt;br /&gt;
	rjmp testRoutine&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Auf diese Art und Weise kann man auch Unterprogrammaufrufe durchführen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
	ldi ZH, high(testRoutine)&lt;br /&gt;
	ldi ZL, low(testRoutine)&lt;br /&gt;
	rcall indirectZCall&lt;br /&gt;
	...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
indirectZCall:&lt;br /&gt;
	push ZL&lt;br /&gt;
	push ZH&lt;br /&gt;
	ret&lt;br /&gt;
&lt;br /&gt;
testRoutine:&lt;br /&gt;
	...&lt;br /&gt;
	ret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Größere AVR haben dafür die Befehle &amp;lt;code&amp;gt;ijmp&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;icall&amp;lt;/code&amp;gt;.&lt;br /&gt;
Bei diesen Befehlen muss das Sprungziel in ZH:ZL stehen.&lt;br /&gt;
&lt;br /&gt;
== Weitere Informationen (von Lothar Müller): ==&lt;br /&gt;
* [http://www.mikrocontroller.net/attachment/301/Der-Stack-1.pdf Der Stack - Funktion und Nutzen (pdf)]&lt;br /&gt;
* [http://www.mikrocontroller.net/attachment/299/Der-Stack-2.pdf Der Stack - Parameterübergabe an Unterprogramme (pdf)]&lt;br /&gt;
* [http://www.mikrocontroller.net/attachment.php/676/Der-Stack-3.pdf Der Stack - Unterprogramme mit variabler Parameteranzahl (pdf) ]&lt;br /&gt;
&lt;br /&gt;
(Der in dieser Abhandlung angegebene Befehl &#039;&#039;MOV ZLow, SPL&#039;&#039; muss &#039;&#039;IN ZL, SPL&#039;&#039; heißen, da SPL und SPH I/O-Register sind. Ggf ist auch SPH zu berücksichtigen --&amp;gt; 2byte Stack-Pointer)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
{{Navigation_zurückhochvor|&lt;br /&gt;
zurücktext=logische Operatoren|&lt;br /&gt;
zurücklink=AVR-Tutorial: Logik|&lt;br /&gt;
hochtext=Inhaltsverzeichnis|&lt;br /&gt;
hochlink=AVR-Tutorial|&lt;br /&gt;
vortext=LCD|&lt;br /&gt;
vorlink=AVR-Tutorial: LCD}}&lt;br /&gt;
&lt;br /&gt;
[[Category:AVR-Tutorial|Stack]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Transistor&amp;diff=87256</id>
		<title>Transistor</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Transistor&amp;diff=87256"/>
		<updated>2015-02-11T09:16:02Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Änderung 87248 von 84.136.7.7 (Diskussion) rückgängig gemacht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Kunstwort aus &amp;quot;transfer resistor&amp;quot;, was etwa so viel bedeutet wie &amp;quot;übertragener [[Widerstand]]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
In den 1950-ern als praktische Anwendung des [[Halbleiter]]-Effekts erfundenes &amp;quot;solid state&amp;quot; Schalt- und Verstärkerelement, welches sehr klein ist, ohne bewegte Teile auskommt (anders als ein klassisches Relais) und keine energiefressende Heizung benötigt (anders als eine Röhre).&lt;br /&gt;
&lt;br /&gt;
Vom &amp;quot;bipolaren Transistor&amp;quot; (PNP, NPN) weiterentwickelt zum &amp;quot;Feldeffekt-Transistor&amp;quot; ([[FET]]), der heute - gefertigt mit einem preiswerten Verfahren unter Verwendung von Metall-Oxid-Schichten (MOS) - ein wesentliches Element integrierter Schaltkreise (ICs, integrated circuits) darstellt, und damit natürlich auch von [[Mikrocontroller]]n, um die es in diesem Wiki hauptsächlich geht (bzw. gehen sollte).&lt;br /&gt;
&lt;br /&gt;
== Schaltzeichen ==&lt;br /&gt;
http://electronicsclub.info/images/transbce.gif&lt;br /&gt;
&lt;br /&gt;
* E: Emitter&lt;br /&gt;
* B: Basis&lt;br /&gt;
* C: Collector    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In ASCII Schaltplänen sehen Transistoren so aus:&lt;br /&gt;
&amp;lt;pre&amp;gt; &lt;br /&gt;
                       |&amp;gt;                 |/&lt;br /&gt;
NPN      |&amp;gt;   oder    -|       oder      -|&lt;br /&gt;
                       |\                 |&amp;gt;&lt;br /&gt;
&lt;br /&gt;
                       |&amp;lt;                 |/&lt;br /&gt;
PNP:     |&amp;lt;   oder    -|       oder      -|&lt;br /&gt;
                       |\                 |&amp;lt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um zu erkennen, ob ein NPN oder PNP Transistor im Schaltplan verwendet wird, gibt es Eselsbrücken:&lt;br /&gt;
*Für Dichter: &#039;&#039;&#039;Tut der Pfeil der Basis weh, handelt&#039;s sich um PNP.&#039;&#039;&#039;&lt;br /&gt;
*Für Praktiker: &#039;&#039;&#039;PNP heisst &amp;quot;Pfeil Nach Platte&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
*Mit Dialekt: &#039;&#039;&#039;NPN &amp;quot;&#039;naus, Pfeil, &#039;naus&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
*..und für Gleichberechtigungsverfechter: &#039;&#039;&#039;NPN means &amp;quot;Not Pointing iN&amp;quot;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
JFET: [[Bild:Transistor_JFET.png]]&lt;br /&gt;
&lt;br /&gt;
MOSFET: [[Bild:Transistor_MOSFET.png]]&lt;br /&gt;
&lt;br /&gt;
* S: Source&lt;br /&gt;
* G: Gate&lt;br /&gt;
* D: Drain&lt;br /&gt;
&lt;br /&gt;
Eigentlich haben MOSFETs noch einen vierten Anschluss namens Bulk. Der ist aber nur bei Spezialtypen als Pin herausgeführt. Im Normalfall kann man ihn vergessen, da er nicht gesondert beschaltet werden muss, er ist praktisch und auch im Symbol mit Source verbunden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achtung:&#039;&#039;&#039; Die NPN/PNP Eselsbrücken funktionieren bei FETs nicht, denn bei einem P-Kanal FET zeigt der Pfeil weg vom FET!&lt;br /&gt;
Ein Bipolartransistor, im Englischen als bipolar junction transistor (BJT) bezeichnet, ist ein Transistor, bei dem Ladungsträger – negativ geladene Elektronen und positiv geladene Defektelektronen – zum Stromtransport durch den Bipolartransistor beitragen. Der BJT wird mittels eines elektrischen Stroms gesteuert und wird zum Schalten und Verstärken von Signalen ohne mechanisch bewegte Teile eingesetzt.&lt;br /&gt;
&lt;br /&gt;
Bipolare Leistungstransistoren sind für das Schalten und Verstärken von Signalen höherer Stromstärken und Spannungen ausgelegt.&lt;br /&gt;
&lt;br /&gt;
== Typbezeichnungen == &lt;br /&gt;
&lt;br /&gt;
Neben den Typbezeichnungen wie 2Nxxxx, TIPxxx, MJxxx, MJExx gibt es noch die in Europa geläufigere  Kennzeichnung bestehend aus zwei Buchstaben und drei Ziffern. Die diversen Kennzeichnungsmöglichkeiten sind in einem eigenen Artikel ([[Kennzeichnung von Halbleitern]]) zusammengefasst.&lt;br /&gt;
&lt;br /&gt;
== Kenndaten/Parameter ==&lt;br /&gt;
&lt;br /&gt;
Im [http://www.mikrocontroller.net/topic/197676#1938546 Beitrag: Transistorparameter Erklärung] sind Links zu Erläuterungen spezieller Kürzel.&lt;br /&gt;
&lt;br /&gt;
== Transistor Grundschaltungen ==&lt;br /&gt;
&lt;br /&gt;
Generell gilt, dass Strom vom Kollektor zum Emitter nur dann fließen kann, wenn die Basis positiver (NPN) bzw. negativer (PNP) wird als der Emitter. Dabei darf die Basis nicht direkt mit Vcc (NPN) oder GND (PNP) verbunden werden, da der Basisstrom sonst zu gross wird. Es muss jeweils ein geeigneter Basiswiderstand (R_Basis) gewählt werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Weitere Links:&#039;&#039;&#039;&lt;br /&gt;
* Artikel [[Basiswiderstand]]&lt;br /&gt;
* [http://www.elektronik-kompendium.de/sites/slt/0203111.htm Transistor Grundschaltungen im ElKo]&lt;br /&gt;
* [http://www.roboternetz.de/wissen/index.php/Transistor Transistor bei RoboterNetz.de]&lt;br /&gt;
&lt;br /&gt;
Es gibt drei Grundschaltungen. Der Name beschreibt den Anschluss, welcher sich auf einem festen Potential (Spannung) befindet. Die beiden anderen Anschlüsse haben bedingt durch die Schaltung ein veränderliches Potential.&lt;br /&gt;
&lt;br /&gt;
=== Kollektorschaltung (Emitterfolger)===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Anwendung:&#039;&#039;&#039;&lt;br /&gt;
* Impedanzwandler&lt;br /&gt;
* Darlington-Schaltung&lt;br /&gt;
* Schalter&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Eigenschaften:&#039;&#039;&#039;&lt;br /&gt;
* Keine Phasendrehung&lt;br /&gt;
* Hohe Stromverstärkung&lt;br /&gt;
* Keine Spannungsverstärkung&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beispiel: Transistor als Schalter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* NPN: Kollektor mit Vcc verbinden, Last an Emitter&lt;br /&gt;
* PNP: Kollektor mit GND verbinden, Last an Emitter&lt;br /&gt;
&lt;br /&gt;
In diesem Fall regelt der Transistor die Spannungen am Emitter, daher wird die Last am Emitter angeschlossen. Die Spannung am Emitter entspricht immer der an der Basis minus 0,6V, sie folgt der Basisspannung, deswegen auch der Name Emitterfolger. Daher ist diese Schaltung nicht geeignet, um 12V mit 5V zu schalten. &lt;br /&gt;
&lt;br /&gt;
[[Bild:NPN_Collector.gif | framed | center | NPN Transistor in Kollektorschaltung]]&lt;br /&gt;
&lt;br /&gt;
Wird &amp;lt;math&amp;gt;R_{Poti}&amp;lt;/math&amp;gt; (Spannungsteiler) erhöht, steigt die Spannung &amp;lt;math&amp;gt;U_{Last}&amp;lt;/math&amp;gt; letztlich bis auf Vcc-0,6V (Basis-Emitter-Übergang). &lt;br /&gt;
&lt;br /&gt;
[[Bild:PNP_Collector.gif | framed | center | PNP Transistor in Kollektorschaltung]]     &lt;br /&gt;
&lt;br /&gt;
Wird &amp;lt;math&amp;gt;R_{Poti}&amp;lt;/math&amp;gt; (Spannungsteiler) erhöht, sinkt Spannung an &amp;lt;math&amp;gt;U_{Last}&amp;lt;/math&amp;gt; letztlich bis auf 0,6V (Basis-Emitter-Übergang).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Weitere Links:&#039;&#039;&#039;&lt;br /&gt;
* [http://www.elektronik-kompendium.de/sites/slt/0204133.htm Kollektorschaltung im ElKo]&lt;br /&gt;
&lt;br /&gt;
=== Emitterschaltung ===&lt;br /&gt;
&lt;br /&gt;
Die Emitterschaltung bietet hohe Spannungs- und Stromverstärkung.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Anwendung:&#039;&#039;&#039;&lt;br /&gt;
* NF- und HF-Verstärker&lt;br /&gt;
* Leistungsverstärker&lt;br /&gt;
* Transistor als Schalter&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Eigenschaften:&#039;&#039;&#039;&lt;br /&gt;
* Phasendrehung 180°&lt;br /&gt;
* Hohe Spannungsverstärkung&lt;br /&gt;
* Hohe Stromverstärkung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beispiel: Transistor als Schalter&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Die Last liegt am Kollektor. Der Strom durch den Schalter oder an U_Schalt steuert den Strom zwischen Kollektor und Emitter. Wird der Schalter geschlossen, fließt ein Strom.&lt;br /&gt;
&lt;br /&gt;
[[Bild:NPN_Schalter.gif | framed | center | NPN Transistor als Schalter]]&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                   ___                                          ___&lt;br /&gt;
Vcc/+ o-----------------------+          Vcc/+ o-----------------------+&lt;br /&gt;
                              |                                        |&lt;br /&gt;
                     ___    |&amp;lt;            U_schalt (-)       ___     |&amp;lt;  PNP             &lt;br /&gt;
             +------|___|---|  PNP             o------------|___|----|&lt;br /&gt;
             |     R_Basis  |\                             R_Basis   |\&lt;br /&gt;
    Schalter \                |                                        |&lt;br /&gt;
             |       ___      |                               ___      |&lt;br /&gt;
GND/- o------+------|___|-----+          GND/- o-------------|___|-----+&lt;br /&gt;
                   R_Last                                    R_Last     &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Weitere Links:&#039;&#039;&#039;&lt;br /&gt;
* [http://www.elektronik-kompendium.de/sites/slt/0204302.htm Emitterschaltung im ElKo]&lt;br /&gt;
&lt;br /&gt;
=== Basisschaltung ===&lt;br /&gt;
&lt;br /&gt;
Die Basisschaltung findet sich vor allem in Eingangsstufen in der HF-Technik. Im Schaltbetrieb wird sie praktisch nur zur [[Pegelwandler#STEP-UP: 5V -&amp;gt; 9..15V | Pegelwandlung]] für nachfolgende Stufen verwendet.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Eigenschaften:&#039;&#039;&#039;&lt;br /&gt;
* Geringe Eingangsimpedanz&lt;br /&gt;
* Keine Phasenverschiebung&lt;br /&gt;
* Hohe Bandbreite&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Weitere Links:&#039;&#039;&#039;&lt;br /&gt;
* [http://www.elektronik-kompendium.de/sites/slt/0205081.htm Basisschaltung im ElKo&lt;br /&gt;
&lt;br /&gt;
== FAQ aus dem Forum ==&lt;br /&gt;
&lt;br /&gt;
=== PNP/NPN als Schalter, wohin mit der Last? === &lt;br /&gt;
Für viele einfache Anwendungen kann man sich merken: &#039;&#039;&#039;Bei Schaltanwendungen darf der Basisstrom nicht durch die Last fließen&#039;&#039;&#039;. Normalerweise kommt dabei die Emitterschaltung zum Einsatz, die Last kommt also an den Kollektor.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Vcc o-------------+                  Vcc o-----------+&lt;br /&gt;
                   |                                  |&lt;br /&gt;
                  .-.               An: GND   ___   |&amp;lt;&lt;br /&gt;
                  | | R_Last             o---|___|--|   PNP&lt;br /&gt;
                  &#039;-&#039;               Aus: Vcc        |\&lt;br /&gt;
                   |                                  |&lt;br /&gt;
An: Vcc  ___     |/                                  .-.&lt;br /&gt;
    o---|___|----|   NPN                      3&amp;gt;       | | R_Last&lt;br /&gt;
Aus: GND         |&amp;gt;                                  &#039;-&#039;&lt;br /&gt;
                   |                                  |&lt;br /&gt;
 GND o-------------+                  GND o-----------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Siehe [[Basiswiderstand]] zur Berechnung des notwendigen Basiswiderstandes bei gegebener Last R_Last für einen Transistor als Schalter.&lt;br /&gt;
&lt;br /&gt;
Siehe auch Threads im Forum: &lt;br /&gt;
* http://www.mikrocontroller.net/topic/58567 &lt;br /&gt;
* http://www.mikrocontroller.net/topic/119841&lt;br /&gt;
* oder im [http://www.elektronik-kompendium.de/sites/slt/0208031.htm Elektronik-Kompendium-Forum]&lt;br /&gt;
&lt;br /&gt;
=== Wie kann ich mit 5V vom Mikrocontroller 12V und mehr schalten? === &lt;br /&gt;
Schau mal hier:&lt;br /&gt;
* Wikiartikel [[Pegelwandler]]&lt;br /&gt;
* [http://www.elektronik-kompendium.de/sites/praxis/bausatz_pegelwandler-mit-transistoren.htm Pegelwandler im ElKo]&lt;br /&gt;
* [http://dl6gl.de/grundlagen/schalten-mit-transistoren schalten-mit-transistoren]&lt;br /&gt;
&lt;br /&gt;
oder in diesen Threads:&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/17899 Transistor als Schalter]&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/14437 Vcc schalten mit MOSFET]&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/29830 Schalten mit PNP-Transistor]&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/104027 Transistorschalter für Versorgungsspannung]&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/104951#921417 7-50V strombegrenzt schalten]&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/103116#900247 P-Kanal MOSFET ansteuern]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bei der Kollektor-Schaltung entspricht die Spannung am Emitter immer der an der Basis, daher ist sie nur bedingt geeignet. Zum Schalten können die folgenden Emitter-Schaltungen verwendet werden. Achtung: In der zweiten davon arbeitet T1 in Basisschaltung.&lt;br /&gt;
&lt;br /&gt;
Schalten gegen GND&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 +12V o------------------------+&lt;br /&gt;
                               |&lt;br /&gt;
                              .-. &lt;br /&gt;
                             ( X )  &lt;br /&gt;
                              &#039;-&#039;&lt;br /&gt;
                               |&lt;br /&gt;
                    ___      |/ T1,NPN   &lt;br /&gt;
        uC PIN o---|___|-----| BC547     &lt;br /&gt;
                   R2,4K7    |&amp;gt;&lt;br /&gt;
                               |&lt;br /&gt;
  GND o---------o--------------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Schalten gegen +12V&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 +12V o--------------+----------------------+&lt;br /&gt;
                     |                      |&lt;br /&gt;
                     |   ____              |&amp;lt; T2, PNP&lt;br /&gt;
                     +--|____|----+--------|  BC557&lt;br /&gt;
                        R1,4K7    |        |\&lt;br /&gt;
                                |/T1,NPN    |&lt;br /&gt;
         Vcc/+5V o--------------| BC547     |&lt;br /&gt;
                                |&amp;gt;          |&lt;br /&gt;
                        ___       |        .-. &lt;br /&gt;
          uC PIN o-----|___|------+       ( X )  &lt;br /&gt;
                       R2,4K7              &#039;-&#039;&lt;br /&gt;
                                            |&lt;br /&gt;
  GND o----------o--------------------------+&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Transistor an µC ohne Vorwiderstand === &lt;br /&gt;
&lt;br /&gt;
Normalerweise sind IO Pins vom µC nicht in der Lage, große Ströme zu treiben, beim AVR maximal ~20mA. Für einen kleinen Transistor ist das immer noch zu viel und es wäre auch Stromverschwendung.&lt;br /&gt;
&lt;br /&gt;
Deshalb kann man den IO-Pin des AVRs einfach als Tristate Eingang einstellen (Portpin als Eingang und Pullup deaktivieren), damit kein Basisstrom fließt.&lt;br /&gt;
&lt;br /&gt;
Aktiviert man nun den internen Pullup-Widerstand des AVRs, agiert dieser als Basisvorwiderstand, und es fließt nur ein geringer Basisstrom (die Pullups eines AVRs liegen irgendwo bei 50k bis 100k Ohm - siehe Datenblatt).&lt;br /&gt;
&lt;br /&gt;
Nur sollte man bei kleinen Transistoren aufpassen, dass man den Portpin in der Software nie als aktiven Ausgang schaltet. &lt;br /&gt;
&lt;br /&gt;
Wenn der verwendete µC zuschaltbare Pulldown-Widerstände an seinen Pins besitzt, kann man das gleiche auch mit einem PNP-Transistor machen (natürlich nur den Pulldown aktivieren).&lt;br /&gt;
&lt;br /&gt;
Eine Anwendung wären z.&amp;amp;nbsp;B. Nixie-Röhren-Kathodentreiber (geringe Stromverstärkung nötig).&lt;br /&gt;
&lt;br /&gt;
=== Wann bipolare (NPN/PNP) und wann FETs (insbesonders, wenn LEDs im Spiel sind)?=== &lt;br /&gt;
Oft sind bipolare Transistoren (NPN/PNP) schon ausreichend, vor allem wenn &amp;quot;normale&amp;quot; LEDs (20mA) verwendet werden. FETs sind u.a. dann gut, wenn mit geringen Eingangsströmen hohe Ausgangsströme (über 300 mA) geschaltet werden sollen, also bei den Power-LEDs (Luxeon...).&lt;br /&gt;
&lt;br /&gt;
Ein Grenzfall: 500mA/5V schalten, siehe http://www.mikrocontroller.net/topic/62327.&lt;br /&gt;
&lt;br /&gt;
=== Wieso gehen bei einer Multiplex-Anzeige mit Schieberegister 74HC595 und (Darlington-)Transistor als Zeilentreiber die LED nicht ganz aus?  ===&lt;br /&gt;
Das liegt an der &#039;&#039;&#039;Miller-Kapazität&#039;&#039;&#039; des übersteuerten (Darlington-)Transistors. Der braucht erst mal einige 10µs, um zu sperren. Du mußt also erstmal beide Zeilen ausschalten, dann etwas warten und dann die nächste Zeile an. Oder Du ersetzt die Darlington durch P-FETs. [http://www.mikrocontroller.net/topic/132545]&lt;br /&gt;
&lt;br /&gt;
=== Wie steuert man ein Relais? ===&lt;br /&gt;
Normalerweise verwendet man zur Ansteuerung von Relais NPN-Transistoren in Emitterschaltung. Freilaufdiode nicht vergessen! &lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* [[Relais mit Logik ansteuern]]&lt;br /&gt;
* [http://www.mikrocontroller.net/attachment/22023/Relaisanteuerung.png Schaltbilder aus dem Forum]&lt;br /&gt;
&lt;br /&gt;
=== Was ist die Spannung &amp;lt;math&amp;gt;U_{BE\_sat}&amp;lt;/math&amp;gt; (lt. Datenblatt max. 1,2V)? ===&lt;br /&gt;
Bekanntlich verhält sich die Basis-Emitter Strecke eines Transistors wie eine Diode und &amp;lt;math&amp;gt;U_{BE\_sat}&amp;lt;/math&amp;gt; ist die bei maximal zulässigem Basisstrom anliegende Vorwärtsspannung.&lt;br /&gt;
&lt;br /&gt;
=== Was bewirkt ein Kondensator (100µF-1nF) parallel zur Basis-Emitter-Strecke nach Masse? === &lt;br /&gt;
Er wirkt mit dem Basisvorwiderstand als RC-Tiefpass. Damit wird der Transistor eigentlich nicht mehr als Schalter, sondern als Linearregler betrieben. Manche Verstärker-Schaltungen sind, gerade bei hohen Lasten, sehr schwingfreudig. Deswegen ist bei PWM so ein C nicht sinnvoll.&lt;br /&gt;
&lt;br /&gt;
=== Gibt es einen IC, der wie mehrere Transistoren funktioniert? ===&lt;br /&gt;
&lt;br /&gt;
Gibt es! Beispielsweise der &#039;&#039;&#039;ULN2803&#039;&#039;&#039; ist ein 8-fach Darlington Transistor Array mit [[Ausgangsstufen_Logik-ICs#Open_Collector|Open-Collector Ausgang]]. Damit lässt sich z.&amp;amp;nbsp;B. ein Leistungstreiber zur Ansteuerung von Schrittmotoren, Relais und anderen induktiven Lasten aufbauen.&lt;br /&gt;
&lt;br /&gt;
=== Gibt es ein Transistor-Array wie ULN28xx, das gegen Vcc schaltet? ===&lt;br /&gt;
&lt;br /&gt;
Such mal nach UDN29xx, z.&amp;amp;nbsp;B. UDN2981, UDN2987 ...&lt;br /&gt;
&lt;br /&gt;
=== Wann setzt man einen MOSFET, Bipolartransistor, IGBT oder Thyristor ein ? ===&lt;br /&gt;
siehe [[Leistungselektronik]]&lt;br /&gt;
&lt;br /&gt;
Die Summe allen Übels ist konstant. Man muss wissen, welches Bauteil sich wofür besonders eignet.&lt;br /&gt;
&lt;br /&gt;
====[[FET | MOSFET]]====&lt;br /&gt;
&lt;br /&gt;
Vorteile&lt;br /&gt;
* Bei niedrigen Spannungen &amp;lt;100V sehr gut geeignet, &amp;lt;200V gut geeignet, sehr geringe R_DS-ON Widerstände möglich (einstelliger mOhm-Bereich)&lt;br /&gt;
* Hohe Schaltgeschwindigkeiten möglich&lt;br /&gt;
* Geringe An- und Ausschaltverluste&lt;br /&gt;
* Statisch praktisch leistungslos steuerbar&lt;br /&gt;
* Bodydiode kann als Freilaufdiode in H-Brücken verwendet werden&lt;br /&gt;
* 2. Durchbruch bei Überschreiten der max. Drain-Source Sperrspannung zerstört das Bauteil nicht, wenn der Strom sowie die Energie begrenzt werden. (Verhalten wie [[Diode | Z-Diode]])&lt;br /&gt;
   &lt;br /&gt;
Nachteile&lt;br /&gt;
*Antiparallele Diode (Bodydiode) ist in nahezu allen MOSFETs unvermeidlich, daduch Sperren nur in einer Polarität möglich, Stromfluss über den MOSFET aber in beiden Richtungen möglich (Inversbetrieb, Synchrongleichrichter)&lt;br /&gt;
* Bei Sperrspannungen &amp;gt;100V deutlich steigende Einschaltwiderstände (R_DS-ON)&lt;br /&gt;
* Schnelles Umschalten erfordert hohe Lade-und Entladeströme ([[MOSFET-Übersicht#Mosfet-Treiber|MOSFET-Treiber]])&lt;br /&gt;
* Leitverluste quadratisch proportional zum Strom, Pv = I²*R_DS-ON&lt;br /&gt;
&lt;br /&gt;
====[[Transistor | Bipolartransistor]]====&lt;br /&gt;
&lt;br /&gt;
Vorteile&lt;br /&gt;
* Hohe Spannungsfestigkeiten möglich, bis zu 2000V&lt;br /&gt;
* Sehr hohe Schaltgeschwindigkeiten möglich&lt;br /&gt;
* Leitverluste linear proportional zum Strom und Kollektor-Emitter-Sättigungsspannung, Pv = I * Uce-sat, U_CEC-sat typ 0,1..1V&lt;br /&gt;
&lt;br /&gt;
Nachteile&lt;br /&gt;
* Stromgesteuert, damit wird immer eine gewisse Ansteuerleistung benötigt&lt;br /&gt;
* Bei grossen Kollektorströmen nimmt die Stromverstärkung deutlich ab, dann wird ein großer Basisstrom benötigt&lt;br /&gt;
* 2. Durchbruch bei Überschreiten der max. Kollektor-Emitter Sperrspannung zerstört das Bauteil&lt;br /&gt;
&lt;br /&gt;
====[[IGBT]]====&lt;br /&gt;
&lt;br /&gt;
Vorteile&lt;br /&gt;
* Hohe Spannungsfestigkeiten möglich, bis zu 6600V, in üblichen Bauformen bis ca 1700V gut verfügbar&lt;br /&gt;
* Statisch praktisch leistungslos steuerbar&lt;br /&gt;
* Mit oder ohne antiparallele Diode zur Kollektor-Emitter-Strecke verfügbar&lt;br /&gt;
* Leitverluste linear proportional zum Strom und Kollektor-Emitter-Sättigungsspannung, Pv = I * Uce-sat, U_CE-sat typ. 2V&lt;br /&gt;
&lt;br /&gt;
Nachteile&lt;br /&gt;
* Nur mäßige Schaltfrequenzen möglich (typ. &amp;lt;30..50kHz)&lt;br /&gt;
* Schnelles Umschalten erfordert hohe Lade-und Entladeströme ([[MOSFET-Übersicht#Mosfet-Treiber|MOSFET-Treiber]])&lt;br /&gt;
* 2. Durchbruch bei Überschreiten der max. Kollektor-Emitter Sperrspannung zerstört das Bauteil&lt;br /&gt;
&lt;br /&gt;
====[[TRIAC]]/Thyristor====&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* Sehr hohe Spannungsfestigkeiten möglich (800V...mehrere kV, Thyristoren bis 12kV)&lt;br /&gt;
* Mit kurzen Pulsen einschaltbar, danach Selbsthaltung des Stromflusses&lt;br /&gt;
* Leitverluste linear proportional zum Strom, Pv = I * Uak, Uak typ. 0,8..1V &lt;br /&gt;
&lt;br /&gt;
Nachteile&lt;br /&gt;
* Auf niedrige Schaltfrequenzen beschränkt (kHz-Bereich, Schaltzeit im Bereich von µs)&lt;br /&gt;
* Anstiegsgeschwindigkeit des Stromes muss begrenzt werden, sonst kommt es zu Bauteilschäden&lt;br /&gt;
* Anstiegsgeschwindigkeit der Spannung muss begrenzt werden, sonst kommt es zum ungewollten Zünden&lt;br /&gt;
* Stromfluss kann nicht ausgeschaltet werden, damit meist nur Einsatz an Wechselspannung&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|- &lt;br /&gt;
! Bauteil               || optimales Einsatzgebiet || Kommentar&lt;br /&gt;
|-&lt;br /&gt;
| MOSFET                || 0..200V, 0..500A || im Kleinspannungsbereich meist die beste Wahl als Schalter&lt;br /&gt;
|-&lt;br /&gt;
| Bipolartransistor     || 0..1000V, 0..10A || wird mehr und mehr von MOSFETs verdrängt&lt;br /&gt;
|-&lt;br /&gt;
| IGBT                  || 200..1700V, 0..500A || optimal für hohe Spannungen und hohe Ströme&lt;br /&gt;
|-&lt;br /&gt;
| Triac/Thyristor       || 230V, 400V, 680V, bis mehrere kV, 0..100A || meist für Wechselspannung, im Pulsbetrieb einige kA. Thyristoren bis 1000A im Dauerbetrieb (Scheibenzelle)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Wie finde ich den richtigen Transistor für eine LED-Ansteuerung? ===&lt;br /&gt;
&lt;br /&gt;
Quelle: Beiträge [http://www.mikrocontroller.net/topic/157763#1493623] und [http://www.mikrocontroller.net/topic/157763#1494972] von yalu&lt;br /&gt;
&lt;br /&gt;
Um am Anfang wenigstens ein bisschen den Durchblick im Transistordschungel zu behalten, kannst du folgendermaßen vorgehen:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nomenklatur&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Nach der amerikanischen Nomenklatur beginnen die Transistornamen meist mit 2N (z.&amp;amp;nbsp;B. 2N2222 oder 2N3055) und nach der japanischen mit 2S (z.&amp;amp;nbsp;B. 2SC1815). Für den Anfang kann man sich auf europäische Transistoren beschränken, da es diese in ausreichender Auswahl gibt und die Bezeichnungen relativ gut den Transistortyp wiedergeben:&lt;br /&gt;
&lt;br /&gt;
Der erste Buchstabe bezeichnet das Halbleitermaterial (A=Germanium, B=Silizium). Germaniumtransistoren werden heute nur noch selten verwendet.&lt;br /&gt;
&lt;br /&gt;
Der zweite Buchstabe steht für den Einsatzzweck (C=Universal, D=hohe Leistung, F=Hochfrequenz, U=hohe Spannung).&lt;br /&gt;
&lt;br /&gt;
So ist also ein ACxxx ein Germaniumuniversaltransistor und ein BDxxx ein Siliziumleistungstransistor.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Auswahl&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Wenn du dich für einen Grundtyp entschieden hast (für die LED ist ein BC-Typ das Richtige), gehst du auf die Webseite eines Elektronikhändlers (Reichelt, Kessler usw.), schlägst die Seite mit den BC-Transistoren auf. Da gibt es natürlich sehr viele  davon, und du brauchst jetzt eine&lt;br /&gt;
Suchreihenfolge. Als erstes Auswahlkriterium nimmst du den Preis, denn:&lt;br /&gt;
&lt;br /&gt;
* Zuviel Geld hast wahrscheinlich nicht einmal du.&lt;br /&gt;
* Billig ist meist das, was in großen Stückzahlen hergestellt wird. Was für die Masse gut ist, ist (zumindest in diesem Fall) meist auch für dich gut.&lt;br /&gt;
* Was billig und damit in Massen verkauft wird, bekommst du auch bei anderen Händlern und auch noch in 10 Jahren. Das ist wichtig, wenn deine Schaltung irgendwann einmal in Serie gefertigt werden soll.&lt;br /&gt;
&lt;br /&gt;
Gleich als nächstes überlegst du, ob du einen NPN- oder einen PNP-Typ brauchst. Das ergibt sich aus der Anordnung der Bauteile in deiner Schaltung. Hast du die Möglichkeit, die Schaltung wahlweise für einen NPN- oder einen PNP-Typ auszulegen, wählst du die Variante mit dem NPN-Typ. Um einfach eine LED über einen Mikrocontroller einzuschalten, ist i.Allg. ein NPN-Typ in Emitterschaltung richtig.&lt;br /&gt;
&lt;br /&gt;
Ein weiteres wichtiges Kriterium ist die Befestigungstechnik: Wenn dir die SMD-Löterei etwas suspekt ist, lässt du die entsprechenden Modelle erst einmal alle außen vor. Ein typisches Nicht-SMD-Gehäuse für Universaltransistoren ist TO-92. Es gibt im Internet bebilderte Listen mit den einzelnen Gehäuseformen ([[IC-Gehäuseformen#Weblinks]])&lt;br /&gt;
&lt;br /&gt;
Wenn du jetzt also bei Reichelt  die BC-Transistoren nach Preis aufsteigend sortiert hast, siehst du erst einen Schwung SMD-Tranistoren. Dann kommen ein paar Transistoren im TO-92-Gehäuse, die sind aber PNP. Etwas weiter unten kommt der erste NPN-Transistor in TO-92, nämlich der BC547C. Netterweise stehen gleich ein paar Eckdaten dabei:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
BC547C  45V  0,1A  0,5W&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die 45V sind die maximale Kollektor-Emitter-Spannung, in deinem Fall also die Spannung, die du maximal schalten kannst. Da die LED bei Weitem keine 45V braucht und deine Versorgungsspannung eher in der Gegend von 5V liegt, bist du auf jeden Fall auf der sicheren Seite.&lt;br /&gt;
&lt;br /&gt;
Deine LED wird typisch mit 20mA (max. 30mA) betrieben. Der BC547C kann 100mA, also ist auch hier noch Luft.&lt;br /&gt;
&lt;br /&gt;
Zur maximalen Verlustleistung (0,5W): Wenn deine LED eingeschaltet ist, fließen bspw. 20mA. Ist der Transistor voll durchgesteuert (in Sättigung) beträgt die Kollektor-Emitter-Spannung bei diesem geringen Strom typischerweise zwischen 0,1V und 0,2V (Genaueres steht im Datenblatt). Am Transistor wird also maximal die Leistung 20mA·0,2V=4mW in Wärme umgesetzt. Bis zu 500mW dürfen es sein, also ebenfalls ok.&lt;br /&gt;
&lt;br /&gt;
Nachdem du den Transistor in engere Auswahl gezogen hast, lohnt sich auf jeden Fall ein Blick ins Datenblatt. Aus den Tabellen und Diagrammen erfährst du bspw., wie hoch der Basisstrom sein muss, um den Kollektorstrom von mindestens 20mA bei ausreichend geringer CE-Spannung bereitzustellen. Dort ist auch erklärt warum es einen BC547A, BC547B und BC547C gibt. Der letzte Buchstabe gibt nämlich die Stromverstärkungsklasse an. Da eine hohe Stromverstärkung meist wünschenswert ist und in diesem Fall keinen Aufpreis kostet, ziehst du den BC547C den anderen beiden vor.&lt;br /&gt;
&lt;br /&gt;
Da in deiner Anwendung HF- und Rauschverhalten keine Rolle spielen, bist du schon am Ziel angelangt.&lt;br /&gt;
&lt;br /&gt;
Würde deine LED 100mA statt 20mA benötigen, wären die max. 100mA des BC547 etwas knapp bemessen. Du blätterst also in der Reichelt-Liste weiter und stößt auf den BC337-40 mit 45V, 0,5A und 0,525W. Das ist genau das, wonach du suchst. Bei diesem Transistor sind die Stromverstärkungsklassen durch die Endungen -16, -25 und -40 gekennzeichnet. Es wäre ja auch&lt;br /&gt;
zu einfach, wenn immer nur A, B und C verwendet würde ;-)&lt;br /&gt;
&lt;br /&gt;
Bei Strömen ab etwa 500mA kommt man an die Grenze der Leistungsfähigkeit der BC-Typen. Dann geht es weiter mit BD. Der BD135 geht bspw. schon bis 1,5A. Das Problem bei solchen größeren Transistoren: Die Stromverstärkung ist nicht besonders hoch, so dass irgendwann der Mikrocontroller nicht mehr den benötigten Basisstrom liefern kann. Dann muss dem großen Transistor ein kleiner vorangeschaltet werden, um den erhöhten Basisstrom bereitszustellen. Man kann diese Kombination von zwei Transistoren auch fertig als Darlington-Transistor kaufen, von denen ebenfalls einige in der BD-Reihe zu finden sind (z.&amp;amp;nbsp;B. BD647). Ein Transistortyp, der sich sehr gut zum Schalten höherer Ströme eignet, ist der [[FET | MOSFET]].&lt;br /&gt;
&lt;br /&gt;
Wie schon oben angedeutet: Wenn die 30-80V die die meisten BC- und BD-Transistoren abkönnen, nicht ausreichen, suchst du weiter bei BU.&lt;br /&gt;
&lt;br /&gt;
Steigst du in die HF-Technik ein, sind BF-Transistoren eher das Richtige, wobei bei HF-Anwendungen die Auswahl der Transistoren nicht mehr das Schwierigste ist ;-)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Und wie geht&#039;s weiter?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Man könnte natürlich noch viel mehr zu diesem Thema schreiben. Ich hoffe aber, dass das Geschriebene dir wenigstens grob zeigt, wie man bei nicht allzu speziellem Anforderungen relativ schnell zu einem gewünschten Transistortyp kommt, der nicht nur die technischen Anforderungen erfüllt, sondern auch leicht beschaffbar ist.&lt;br /&gt;
&lt;br /&gt;
Werden die Anforderungen spezieller, helfen oft die Selektionstabellen auf den Webseiten der einschlägigen  Hersteller weiter. Auch Händler wie Farnell haben teilweise ganz gute Auswahlwerkzeuge. &lt;br /&gt;
&lt;br /&gt;
Wenn du dich intensiv mit Elektronik beschäftigst, wirst du wahrscheinlich noch viele  Schaltungen von Leuten zu Gesicht bekommen, die vielleicht schon etwas weiter fortgeschritten sind. Dabei wirst du immer wieder auf bestimmte Standardtypen von Transistoren (und auch anderen Bauteilen wie Operationsverstärker u.ä.) stoßen und sehen, welche [[Standardbauelemente]] &amp;quot;man&amp;quot; üblicherweise für bestimmte Anwendungen einsetzt. Mit der Zeit setzt sich dann eine Auswahl von bspw. 10 oder 20 verschiedenen Transistoren und 5 bis 10 verschiedenen OpAmps im Kopf fest, von denen man die wesentlichen Parameter auswendig kennt, so dass man ohne aufwendige Suche eine schnelle Auswahl treffen kann. Auch hier in der Artikelsammlung gibt es eine solche [[Transistor-Übersicht]].&lt;br /&gt;
&lt;br /&gt;
=== Wo ist die Antwort auf meine Frage? ===&lt;br /&gt;
&lt;br /&gt;
Vielleicht im Forum? Falls du sie da findest, dann pack das ganze doch hier rein.&lt;br /&gt;
&lt;br /&gt;
[http://www.mikrocontroller.net/topic/165580 Gegen Vcc oder GND schalten]&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [[Basiswiderstand]]&lt;br /&gt;
* [[Transistor-Übersicht]]&lt;br /&gt;
* [[AVR-Transistortester]]&lt;br /&gt;
* [[Leistungselektronik]]&lt;br /&gt;
&lt;br /&gt;
== Gehäusebauformen von Transistoren ==&lt;br /&gt;
&lt;br /&gt;
=== TO-92 ===&lt;br /&gt;
Ein kleiner Aufsatz über TO-92 Transistorgehäuse und Footprints findet sich unter: [[Media:TO-92-Gehaeuse_RevB2.pdf]]. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://de.wikipedia.org/wiki/transistor &amp;quot;Transistor&amp;quot; bei Wikipedia]&lt;br /&gt;
* [http://www.elektronik-kompendium.de www.elektronik-kompendium.de]&lt;br /&gt;
** [http://www.elektronik-kompendium.de/sites/bau/0201291.htm Elko/Transistor]&lt;br /&gt;
* http://www.elektronikinfo.de/strom/bipolartransistoren.htm&lt;br /&gt;
* http://www.ferromel.de/tronic_1870.htm&lt;br /&gt;
* [http://www.DieElektronikerseite.de Die Elektronikerseite] Lehrgang: Der Transistor - Ein Tausendsassa&lt;br /&gt;
&lt;br /&gt;
[[Category:Bauteile]]&lt;br /&gt;
[[Category:Grundlagen]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Arduino&amp;diff=86929</id>
		<title>Arduino</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Arduino&amp;diff=86929"/>
		<updated>2015-01-29T09:03:37Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Schrott&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das Arduino-Projekt ist ein 2006 gestartetes Projekt aus Italien. Arduino ist eine Zusammenstellung aus verschiedenen Boards und einer IDE. Die Boards basieren auf der Atmel-AVR Serie. Die einzige Ausnahme bildet der Arduino Due, dieser basiert auf einem ARM-Chip von Atmel. Das Gesamt Projekt ist quelloffen, also Open-Source. Was nicht nur die Entwicklungsumgebung betrifft, sondern auch die Projektdateien für die Platinen. Die Unterschiede zu anderen Atmel-Boards sind der Bootloader und die IDE. Der Bootloader wird durch das Arduino-Projekt entwickelt und ist für die einzelnen Boards spezifisch.&lt;br /&gt;
&lt;br /&gt;
== Zielgruppe ==&lt;br /&gt;
Arduinos richten sich an Mikrocontroller-Einsteiger und kleinere bis mittlere Projekte. Es sind fertig aufgebaute Boards mit zahlreichen Anschlüssen und aufgelöteten Buchsenleisten. Die Programmierung ist zuverlässig und die Kompatibilität mit Shields und die Portabilität zwischen den einzelnen Boards wird weitestgehend gewährleistet. Eine obere Grenze für die verfügbare Rechenleistung sind Ausgaben auf große Anzeigen wie XVGA-Monitore. Ein PAL-Signal für Fernseher ist möglich. Die meisten Boards verfügen über relativ wenig Speicher, womit sie schon mit Bibliotheken für Ein-/ Ausgabe auf SD-Karten (16kByte) ausgereizt sind. Eine LED blinken zu lassen wird im u.a. Tutorial gezeigt.&lt;br /&gt;
&lt;br /&gt;
Projekte aus den Startpaketen benutzen bspw. 3 lichtempfindliche Widerstände um eine 3-farbige LED anzusteuern. Eine Lichtschranke oder ein Mikrofon regeln die Stellung eines Servomotor. Dem offiziellen Arduino Starterkit liegen sogar Optokoppler bei, um die Tasten anderer Geräte zu &#039;&#039;hacken&#039;&#039; und per Arduino fernzusteuern. Der sog. &#039;&#039;Playground&#039;&#039; &amp;lt;ref name=&amp;quot;playground&amp;quot;&amp;gt;[http://playground.arduino.cc/] Arduino Playground Wiki&amp;lt;/ref&amp;gt; ist ein Wiki, in dem eine Vielzahl von Ideen mit Schaltungsbeispielen die Möglichkeiten eines Mikrocontrollers aufzeigen.&lt;br /&gt;
&lt;br /&gt;
Wer dem Arduino dann entwachsen ist, muss ihn nicht zum alten Eisen legen. Einige Boards haben einen ISP-Port (In System Programming=Programmierung in der Schaltung) vorgesehen und sogar mit einem 6pol. Steckverbinder bestückt. Damit sind diese Arduinos über einen passenden Programmieradapter gemäß Chip-Datenblatt vollständig programmierbar – auch was für Profis, die das teure Atmel-Board scheuen.&lt;br /&gt;
&lt;br /&gt;
==Die IDE und Schaltpläne==&lt;br /&gt;
[[Datei:Arduino ide.png|miniatur|links|Bildschirmfoto Arduino-IDE]] Die Arduino-IDE ist eine in JAVA programmierte grafische Oberfläche. Dadurch ist sie plattfomunabhägig, folglich mit gleichem Erscheinungsbild auf Windows, Linux, MacOS X und Solaris verfügbar. Der Funktionsumfang ist deutlich geringer als etwa das [[Atmel Studio]] oder [[AVR Eclipse|Eclipse]]-basierte Entwicklungsumgebungen. So gibt es keine gesonderte Verwaltung von Bibliotheken (libraries/ Header-Dateien). Jedes Projekt ist abgeschlossen und enthält alle notwendigen Abhängigkeiten, statt sie aus einer gemeinsamen Ablage zu beziehen. Diese Arbeitsweise entspricht eher dem ad-hoc-Charakter des Arduino. Es sollen schnell Ergebnisse sichtbar sein, ohne allzu tief in die Materie eintauchen zu müssen.&lt;br /&gt;
&lt;br /&gt;
Die Grafische Oberfläche compiliert die Sketche (engl. für Skizze, so heißt ein Arduino-Programm offiziel) nicht, sondern ruft verschiedene Programme auf. Dies sind in der Regel der Compiler avr-g++ (und zugehörige Programme, z.B. ein Linker) und avrdude, ein Programm zum übertragen des compilierten Sketch als *.hex File auf den Flashspeicher des Arduino. Die IDE basiert auf der Processing IDE und Wiring.&lt;br /&gt;
&lt;br /&gt;
Für die Einsteiger-freundliche virtuelle Verkabelung kann [[Schaltplaneditoren#Fritzing|Fritzing]] benutzt werden. Wie für die Arduino IDE zählt auch hier nicht die technische Genauigkeit. Wer aber sein Arduino-Projekt schnell zeichnen möchte, so dass andere es schnell nachbauen können, ist damit bestens beraten.&lt;br /&gt;
&lt;br /&gt;
==Die Boards==&lt;br /&gt;
Die Arduino-Boards sind Atmel AVR/ARM Chips basierende Mikrocontrollerplatinen,&lt;br /&gt;
welche zur Steuerung von I/O-Pins gedacht sind. Im Gegensatz zu anderen Boards sind die Arduino-Boards nicht gedacht um als &amp;quot;Computer&amp;quot; mit Betriebssystem zu dienen, wie etwa der Raspberry Pi, sondern um die I/O Pins zu steuern. Es gibt mehr als 10 echte Arduino Boards mit 13 - 70 I/O Pins. Die Platinen besitzen meistens einen USB-Aschluß (USB-B bzw. USB-Mini) oder eine Schnittstelle für einen USB-Serial-Konverterchip. Die Platinen mit USB-Anschluß haben einen solchen Chip integriert. Ältere Boards nutzen dafür einen FTDI-Chip, oder einen 8U2/16U2 bei neueren Boards. Eine Ausnahme bildet hier der Arduino Leonardo: Dieser besitzt einen Atmel-AVR 32U4 Mikrocontroller, welcher auch die Funktionen eines FTDI-Chips besitzt. Es ist also kein weiterer Konverter nötig.&lt;br /&gt;
Neben den von Arduino selbst hergestellten Boards gibt es eine Vielzahl von Sprösslingen, die von anderen Firmen auf der Arduino-Architektur aufgesetzt werden. Dieser Artikel beschäftigt sich der Einfachheit wegen nur mit den echten Arduinos. Es lohnt sich aber auch die anderen Boards zu studieren, um noch kleinere, noch sparsamere oder noch leistungsfähigere zu finden.&lt;br /&gt;
&lt;br /&gt;
Wer wenig Erfahrung mit Elektronik hat muss darauf achten, einen Arduino mit einem austauschbaren Chip zu kaufen. Dazu gehört der Uno (mittlerweile R3). Alle anderen Boards haben fest verlötete Prozessoren und ein Fehler im eigenen Projekt mit anschließendem Kurzschluss, Spannungs- oder Stromspitzen entwertet so die gesamte Platine. Da die anderen Varianten zudem oft in Oberflächenmontage und mit vielen Beinchen gelötet werden, ist ein Austausch für den Anfänger ausgeschlossen. Einen neuen ATMega328P (PDIP/ Plastikinsekt mit 32 Beinen) gibt es im Elektronikhandel für ca. 3 Euro im Gegensatz zu 25 Euro für ein komplettes Board. (Den blanken Chip kann man aus der IDE mit dem Bootloader &#039;&#039;flashen&#039;&#039;.)&lt;br /&gt;
&lt;br /&gt;
Es ist generell ratsam mit einem kleinen Arduino einzusteigen. Wer noch keine Bastelkiste mit Elektronikteilen hat, dem seien die Startpakete ans Herz gelegt. Neben den wichtigsten Bauteilen enthalten sie ein kleines Steckbrett, ein paar Drahtbrücken und ein Buch mit ca. 10 Projekten. Wenn man dann dem Speicher des Uno entwachsen ist und die Anschlüsse nicht mehr reichen, lohnt sich der Umstieg auf die größeren Varianten. Wer es dann elektronischer haben möchte, der schaut sich die gesamte Atmel-Palette an, in die Kataloge der anderen Hersteller oder rüstet gleich auf einen vollwertigen Mini-PC um.&lt;br /&gt;
&lt;br /&gt;
===Arduino Uno===&lt;br /&gt;
Der Arduino Uno R3 ist der Standard-Arduino. In den meisten Anfänger-Bücher und Tutorials wird dieser Arduino verwendet. Auch sind die meisten Libaries für ihn geschrieben. Er ist der neuste der am längsten weiterentwickleten Arduino-Reihe.&lt;br /&gt;
So ist eine frühere Version des Arduino Uno (Arduino USB) das Board gewesen, welches als erstes &#039;&#039;Arduino&#039;&#039; gennant wurde. In der aktuellen Revision (Version) 3 besitzt der Uno 14 Digitale I/O Pins sowie 6 analoge Eingänge. Er besitzt eine Spannungsregelung und darf mit 12V über einen Hohlstecker versorgt werden, kann aber auch an bereits geregelte 5V angeschlossen werden und besitzt folgende Speicherkapazitäten:&lt;br /&gt;
* 32K Flash(0,5 werden vom Bootloader verwendet.)&lt;br /&gt;
* 2K SRAM&lt;br /&gt;
* 1K EEPROM&lt;br /&gt;
* 16 MHz (Prozessortakt)&lt;br /&gt;
Neben dem USB-B Anschluß verfügt der Uno noch über folgende Anschlüsse:&lt;br /&gt;
* Hohlstecker-Buchse (2.1mm , 6-20 V möglich)&lt;br /&gt;
* SPI&lt;br /&gt;
* I²C&lt;br /&gt;
* ICSP&lt;br /&gt;
&lt;br /&gt;
==== Arduino Mega ====&lt;br /&gt;
Hinsichtlich der Ein- und Ausgänge sowie dem verfügbaren Speicher ist der Mega der große Bruder von allen AVR-basierten Arduinos. Die aktuellen Versionen sind der Mega 2560 und der Mega ADK. Neben 16 analogen Eingängen gibt es 54 digitale Kanäle von denen 15 mit PWM steuern können. Zur seriellen Kommunikation, sog. UARTs, können 4 Kanäle genutzt werden. Der Flash-Speicher ist mit 256kByte 8mal größer als der des Uno. So passen eine Menge Bibliotheken in eigene Programme.&lt;br /&gt;
&lt;br /&gt;
==== Arduino Due ====&lt;br /&gt;
Im Gegensatz zu den übrigen Boards wird für den Due ein ARM Cortex-M3-Chip (Atmel SAM3X8E) verbaut. Das bringt den größten Flash-Speicher mit 512kByte und zum Mega vergleichbare Ein- und Ausgänge. Die drei wichtigsten Unterscheidungsmerkmale sind die deutlich höhere Taktfrequenz von 84MHz (statt 16MHz), 32bit-Verarbeitung (statt 8bit) und 2 analoge Ausgänge. Zudem darf der Due nur mit 3.3V betrieben und angesteuert werden, d.h. alle I/O-Pins müssen an 5V-Logik angepasst werden, sollen sie mit 5V genutzt werden.&lt;br /&gt;
&lt;br /&gt;
==== Andere Boards ====&lt;br /&gt;
Der Arduino Duemilanove ist der Vorgänger des Arduino Uno. Er besitzt den&lt;br /&gt;
ATmega168 (seit 2009 328p) statt dem 328 wie beim Uno. Als Konverter verwendet der Duemilianove eine FTDI-Chip anstelle eines 16U2. Sonst ist von der Pin anzahlen und den Maßen des Boards identisch mit denen des Uno. Das Board des &#039;&#039;Ethernet&#039;&#039; verfügt über einen RJ45-Anschluss sowie einen microSD-Karten-Slot. Wenn man einen Arduino als USB-Gerät benutzen möchte, dann bietet sich der &#039;&#039;Leonardo&#039;&#039; an. Der verbaute Mikrocontroller (ATmega32u4) besitzt eine in Hardware implementierte USB-Schnittstelle. Den übrigen Boards fehlt dafür der Programmieranschluss für den separaten USB-Controller oder es muss ein Programmieradapter statt des USB-Kabels benutzt werden, die Firmware entsprechend zu aktualisieren.&lt;br /&gt;
&lt;br /&gt;
Alle o.a. Boards sind groß und so gibt es etwa die &#039;&#039;Lilipads&#039;&#039;, deren runde Platine und niedrige Bauhöhe den Einsatz in Textilien erleichtert. Sie sind nicht mehr kompatibel zu den Shields. Wer es dennoch niedrig und Shield-kompatibel wünscht, der kann die &#039;&#039;Pro&#039;&#039;-Modelle nutzen. Sie haben eine feste Spannungsreglung und müssen mit 3.3V oder 5V betrieben werden. Die Buchsenleisten sind nicht vorgelötet. Die kleinsten Boards sind die &#039;&#039;Pro Mini&#039;&#039;-Varianten. Sie haben nur noch die Größe eines Kaugummistreifens. Diese Miniaturisierung fordert auch ihren Tribut und die höchstzulässige Verlustleistung des verbauten Chips ist geringer als bei den großen Boards.&lt;br /&gt;
&lt;br /&gt;
==Tutorial==&lt;br /&gt;
===Ein erster Sketch: Blinkende LED===&lt;br /&gt;
Die meisten aktuellen Arduino-Boards habe einen fest verlötete&lt;br /&gt;
SMD-LED, welche an Pin 13 angeschloßen ist. Diese LED kann von jedem&lt;br /&gt;
Sketch angesteuert werden. Da diese LED meistens vorhanden ist und immer an Pin 13 ageschloßen ist, ist dieses Programm auf den meisten Boards gleich.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
//Blinkende LED&lt;br /&gt;
void setup() {&lt;br /&gt;
    pinMode(13,OUTPUT);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    digitalWrite(13,HIGH);&lt;br /&gt;
    delay(1000);&lt;br /&gt;
    digitalWrite(13,LOW);&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Shields(Erweiterungsplatinen)==&lt;br /&gt;
Sogennante Shields sind Erweiterungsplatinen, die die Funktionen eines Arduino-Boards um neue Funktionen erweitern. So gibt es z.B. Shields die den Arduino um eine Ethernet-Schnittstelle erweitern, einen VGA-Aschluß besitzen oder einfach leere Platinen sind, auf die eine Chip eingesetzt werden kann, ohne zu Löten. Für das letztere Bsp. wäre eine solche Platine die XBEE-Antenne. Es gibt eine eigene Datenbank &amp;lt;ref name=&amp;quot;shieldlist&amp;quot;&amp;gt;[http://shieldlist.org/] Shieldlist für Arduino&amp;lt;/ref&amp;gt; nur für Shields.&lt;br /&gt;
&lt;br /&gt;
===8-bit LCD-Shield mit Touch-Controller ohne IRQ-Pin===&lt;br /&gt;
&lt;br /&gt;
Seit ca. Herbst 2012 werden einige LCD-Shields mit Touch-Controller angeboten, die den IRQ-Pin nicht mehr durchschleifen.&lt;br /&gt;
&lt;br /&gt;
Damit läuft auch die U-Touch Bibliothek von Henning Carlsen nicht mehr. Alle Sample-Codes im Web funktionieren auch nicht. Das Problem besteht darin herauszufinden, mit welchem Arduino-Pin das CS-Signal verbunden ist. Hier hilft nur: Sheets studieren.&lt;br /&gt;
&lt;br /&gt;
Beim Austesten des Touch-Shields ergab sich bei mir zusätzlich ein y-Basiswert des Touchcontrollers von 4095 (&#039;kein Touch&#039;)  und eine Differenz der Widerstandswerte zwischen &#039;Touch&#039; und &#039;keine Touch&#039; von 180 (x) bzw. 240 (y), siehe Code-Kommentare.   &lt;br /&gt;
&lt;br /&gt;
Bei mir lief schließlich folgender Code (das CS-Signal lag auf Pin 10):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define LCD_RS   19         &lt;br /&gt;
#define LCD_WR   18     &lt;br /&gt;
#define LCD_CS   17       &lt;br /&gt;
#define LCD_REST 16&lt;br /&gt;
&lt;br /&gt;
#define DCLK     15&lt;br /&gt;
#define DIN      14 &lt;br /&gt;
#define CS       10  &lt;br /&gt;
#define DOUT     8&lt;br /&gt;
&lt;br /&gt;
//#define IRQ      7    &lt;br /&gt;
 &lt;br /&gt;
unsigned int TP_X,TP_Y,x0,y0;    &lt;br /&gt;
unsigned int l3=0;&lt;br /&gt;
int lx,ly, l2, ry,rx,x3=65,y3=318;&lt;br /&gt;
int  k=3, vh2=0x84,vl2=0xFF;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
void spistar()                                     //SPI Start&lt;br /&gt;
{&lt;br /&gt;
  digitalWrite(CS,LOW);&lt;br /&gt;
  digitalWrite(DCLK,HIGH);&lt;br /&gt;
  digitalWrite(DIN,HIGH);&lt;br /&gt;
  digitalWrite(DCLK,HIGH);&lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
//**********************************************************&lt;br /&gt;
void WriteCharTo7843(unsigned char num)          //SPI Write Data&lt;br /&gt;
{&lt;br /&gt;
  unsigned char count=0;&lt;br /&gt;
  unsigned char temp;&lt;br /&gt;
  unsigned nop;&lt;br /&gt;
  temp=num;&lt;br /&gt;
  digitalWrite(DCLK,LOW);&lt;br /&gt;
  for(count=0;count&amp;lt;8;count++)&lt;br /&gt;
  {&lt;br /&gt;
    if(temp&amp;amp;0x80)&lt;br /&gt;
      digitalWrite(DIN,HIGH);&lt;br /&gt;
    else&lt;br /&gt;
      digitalWrite(DIN,LOW);&lt;br /&gt;
 &lt;br /&gt;
    temp=temp&amp;lt;&amp;lt;1; &lt;br /&gt;
 &lt;br /&gt;
    digitalWrite(DCLK,LOW);                &lt;br /&gt;
    nop++;&lt;br /&gt;
    nop++;&lt;br /&gt;
    digitalWrite(DCLK,HIGH);&lt;br /&gt;
    nop++;&lt;br /&gt;
    nop++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
//**********************************************************&lt;br /&gt;
unsigned int ReadFromCharFrom7843()             //SPI Read Data&lt;br /&gt;
{ &lt;br /&gt;
  unsigned nop;&lt;br /&gt;
  unsigned char count=0;&lt;br /&gt;
  unsigned int Num=0;&lt;br /&gt;
  for(count=0;count&amp;lt;12;count++)&lt;br /&gt;
  {&lt;br /&gt;
    Num&amp;lt;&amp;lt;=1;&lt;br /&gt;
    digitalWrite(DCLK,HIGH);//DCLK=1; _nop_();_nop_();_nop_();                &lt;br /&gt;
    nop++;&lt;br /&gt;
    digitalWrite(DCLK,LOW);//DCLK=0; _nop_();_nop_();_nop_();&lt;br /&gt;
    nop++;&lt;br /&gt;
    if(digitalRead(DOUT)) Num++;&lt;br /&gt;
  }&lt;br /&gt;
  return(Num);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
void LCD_Writ_Bus(char VH,char VL)   &lt;br /&gt;
{   &lt;br /&gt;
  PORTD = VH;&lt;br /&gt;
  digitalWrite(LCD_WR,LOW);&lt;br /&gt;
  digitalWrite(LCD_WR,HIGH);&lt;br /&gt;
  PORTD = VL;&lt;br /&gt;
  digitalWrite(LCD_WR,LOW);&lt;br /&gt;
  digitalWrite(LCD_WR,HIGH);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
void LCD_Write_COM(char VH,char VL)  &lt;br /&gt;
{   &lt;br /&gt;
  digitalWrite(LCD_RS,LOW);&lt;br /&gt;
  LCD_Writ_Bus(VH,VL);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
void LCD_Write_DATA(char VH,char VL)    &lt;br /&gt;
{&lt;br /&gt;
  digitalWrite(LCD_RS,HIGH);&lt;br /&gt;
  LCD_Writ_Bus(VH,VL);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Lcd_Write_Com_Data(int com,int val)&lt;br /&gt;
{&lt;br /&gt;
    LCD_Write_COM(com&amp;gt;&amp;gt;8,com);&lt;br /&gt;
    LCD_Write_DATA(val&amp;gt;&amp;gt;8,val);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)&lt;br /&gt;
{&lt;br /&gt;
  LCD_Write_COM(0x00,0x46);LCD_Write_DATA(x2,x1);	  &lt;br /&gt;
  LCD_Write_COM(0x00,0x47);LCD_Write_DATA(y2&amp;gt;&amp;gt;8,y2);  &lt;br /&gt;
  LCD_Write_COM(0x00,0x48);LCD_Write_DATA(y1&amp;gt;&amp;gt;8,y1);&lt;br /&gt;
  LCD_Write_COM(0x00,0x20);LCD_Write_DATA(x1&amp;gt;&amp;gt;8,x1);	  &lt;br /&gt;
  LCD_Write_COM(0x00,0x21);LCD_Write_DATA(y1&amp;gt;&amp;gt;8,y1); &lt;br /&gt;
  LCD_Write_COM(0x00,0x22);		         				 &lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void LCD_Init(void)&lt;br /&gt;
{&lt;br /&gt;
 &lt;br /&gt;
  digitalWrite(LCD_REST,HIGH);&lt;br /&gt;
  delay(5); &lt;br /&gt;
  digitalWrite(LCD_REST,LOW);&lt;br /&gt;
  delay(5);&lt;br /&gt;
  digitalWrite(LCD_REST,HIGH);&lt;br /&gt;
  delay(5);&lt;br /&gt;
 &lt;br /&gt;
  digitalWrite(LCD_CS,LOW);  &lt;br /&gt;
        Lcd_Write_Com_Data(0x11,0x2004);		&lt;br /&gt;
        Lcd_Write_Com_Data(0x13,0xCC00);		&lt;br /&gt;
        Lcd_Write_Com_Data(0x15,0x2600);	&lt;br /&gt;
	Lcd_Write_Com_Data(0x14,0x252A);			&lt;br /&gt;
	Lcd_Write_Com_Data(0x12,0x0033);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x13,0xCC04);		&lt;br /&gt;
	delay(1); &lt;br /&gt;
	Lcd_Write_Com_Data(0x13,0xCC06);		&lt;br /&gt;
	delay(1); &lt;br /&gt;
	Lcd_Write_Com_Data(0x13,0xCC4F);		&lt;br /&gt;
	delay(1); &lt;br /&gt;
	Lcd_Write_Com_Data(0x13,0x674F);&lt;br /&gt;
	Lcd_Write_Com_Data(0x11,0x2003);&lt;br /&gt;
	delay(1); 	&lt;br /&gt;
	Lcd_Write_Com_Data(0x30,0x2609);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x31,0x242C);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x32,0x1F23);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x33,0x2425);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x34,0x2226);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x35,0x2523);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x36,0x1C1A);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x37,0x131D);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x38,0x0B11);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x39,0x1210);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x3A,0x1315);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x3B,0x3619);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x3C,0x0D00);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x3D,0x000D);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x16,0x0007);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x02,0x0013);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x03,0x0003);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x01,0x0127);		&lt;br /&gt;
	delay(1); &lt;br /&gt;
	Lcd_Write_Com_Data(0x08,0x0303);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x0A,0x000B);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x0B,0x0003);   &lt;br /&gt;
	Lcd_Write_Com_Data(0x0C,0x0000);   &lt;br /&gt;
	Lcd_Write_Com_Data(0x41,0x0000);    &lt;br /&gt;
	Lcd_Write_Com_Data(0x50,0x0000);   &lt;br /&gt;
	Lcd_Write_Com_Data(0x60,0x0005);    &lt;br /&gt;
        Lcd_Write_Com_Data(0x70,0x000B);    &lt;br /&gt;
	Lcd_Write_Com_Data(0x71,0x0000);    &lt;br /&gt;
	Lcd_Write_Com_Data(0x78,0x0000);    &lt;br /&gt;
	Lcd_Write_Com_Data(0x7A,0x0000);   &lt;br /&gt;
	Lcd_Write_Com_Data(0x79,0x0007);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x07,0x0051);   &lt;br /&gt;
	delay(1); 	&lt;br /&gt;
	Lcd_Write_Com_Data(0x07,0x0053);		&lt;br /&gt;
	Lcd_Write_Com_Data(0x79,0x0000);&lt;br /&gt;
 &lt;br /&gt;
	LCD_Write_COM(0x00,0x22);&lt;br /&gt;
  digitalWrite(LCD_CS,HIGH);  &lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void Pant(char VH,char VL)&lt;br /&gt;
{&lt;br /&gt;
  int i,j;&lt;br /&gt;
  Address_set(0,0,240,320);&lt;br /&gt;
  for(i=0;i&amp;lt;=320;i++)&lt;br /&gt;
  {&lt;br /&gt;
    for (j=0;j&amp;lt;=240;j++)&lt;br /&gt;
    {&lt;br /&gt;
      LCD_Write_DATA(VH,VL);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void digi(int z3)&lt;br /&gt;
{&lt;br /&gt;
  unsigned char p;&lt;br /&gt;
  int x2, y2, z2, i,h2=1000;&lt;br /&gt;
  digitalWrite(LCD_CS,LOW); &lt;br /&gt;
  for(i=0;i&amp;lt;3;i++)&lt;br /&gt;
  {&lt;br /&gt;
  y2=y3;&lt;br /&gt;
  x2=x3+(10*i);&lt;br /&gt;
  Address_set(x2+6,y2-15,x2+7,y2);&lt;br /&gt;
  for(p=0; p&amp;lt;32; p++)  LCD_Write_DATA(0xFF,0xFF);&lt;br /&gt;
  Address_set(x2,y2-15,x2+7,y2-14);&lt;br /&gt;
  for(p=0; p&amp;lt;16; p++)  LCD_Write_DATA(0xFF,0xFF);&lt;br /&gt;
  Address_set(x2,y2-1,x2+7,y2);&lt;br /&gt;
  for(p=0; p&amp;lt;16; p++)  LCD_Write_DATA(0xFF,0xFF);&lt;br /&gt;
  Address_set(x2,y2-8,x2+7,y2-7);&lt;br /&gt;
  for(p=0; p&amp;lt;16; p++)  LCD_Write_DATA(0xFF,0xFF);&lt;br /&gt;
  Address_set(x2,y2-15,x2+1,y2);&lt;br /&gt;
  for(p=0; p&amp;lt;32; p++)  LCD_Write_DATA(0xFF,0xFF);&lt;br /&gt;
 &lt;br /&gt;
    h2=h2/10;&lt;br /&gt;
    z2=z3/h2; &lt;br /&gt;
    z3=z3-z2*h2;&lt;br /&gt;
    if (z2==0)  {&lt;br /&gt;
      Address_set(x2+2,y2-8,x2+5,y2-7);&lt;br /&gt;
      for(p=0; p&amp;lt;8; p++)  LCD_Write_DATA(0x00,0x00);&lt;br /&gt;
    }&lt;br /&gt;
    if (z2==1)  {&lt;br /&gt;
      Address_set(x2,y2-15,x2+5,y2);&lt;br /&gt;
      for(p=0; p&amp;lt;96; p++)  LCD_Write_DATA(0x00,0x00);&lt;br /&gt;
    }&lt;br /&gt;
   if (z2==2)  {&lt;br /&gt;
      Address_set(x2,y2-13,x2+1,y2-9);&lt;br /&gt;
      for(p=0; p&amp;lt;10; p++)  LCD_Write_DATA(0x00,0x00);&lt;br /&gt;
      Address_set(x2+6,y2-6,x2+7,y2-2);&lt;br /&gt;
      for(p=0; p&amp;lt;10; p++)  LCD_Write_DATA(0x00,0x00);&lt;br /&gt;
    }&lt;br /&gt;
   if (z2==3)  {&lt;br /&gt;
      Address_set(x2,y2-13,x2+1,y2-9);&lt;br /&gt;
      for(p=0; p&amp;lt;10; p++)  LCD_Write_DATA(0x00,0x00);&lt;br /&gt;
      Address_set(x2,y2-6,x2+1,y2-2);&lt;br /&gt;
      for(p=0; p&amp;lt;10; p++)  LCD_Write_DATA(0x00,0x00);&lt;br /&gt;
    }&lt;br /&gt;
   if (z2==4)  {&lt;br /&gt;
      Address_set(x2,y2-6,x2+5,y2);&lt;br /&gt;
      for(p=0; p&amp;lt;42; p++)  LCD_Write_DATA(0x00,0x00);&lt;br /&gt;
      Address_set(x2+2,y2-15,x2+5,y2-14);&lt;br /&gt;
      for(p=0; p&amp;lt;8; p++)  LCD_Write_DATA(0x00,0x00);&lt;br /&gt;
    }&lt;br /&gt;
   if (z2==5)  {&lt;br /&gt;
      Address_set(x2+6,y2-13,x2+7,y2-9);&lt;br /&gt;
      for(p=0; p&amp;lt;10; p++)  LCD_Write_DATA(0x00,0x00);&lt;br /&gt;
     Address_set(x2,y2-6,x2+1,y2-2);&lt;br /&gt;
      for(p=0; p&amp;lt;10; p++)  LCD_Write_DATA(0x00,0x00);&lt;br /&gt;
    }&lt;br /&gt;
   if (z2==6)  {&lt;br /&gt;
      Address_set(x2+6,y2-13,x2+7,y2-9);&lt;br /&gt;
      for(p=0; p&amp;lt;10; p++)  LCD_Write_DATA(0x00,0x00);&lt;br /&gt;
    }&lt;br /&gt;
   if (z2==7)  {&lt;br /&gt;
      Address_set(x2,y2-13,x2+5,y2);&lt;br /&gt;
      for(p=0; p&amp;lt;84; p++)  LCD_Write_DATA(0x00,0x00);&lt;br /&gt;
    }&lt;br /&gt;
   if (z2==9)  {&lt;br /&gt;
      Address_set(x2,y2-6,x2+1,y2-2);&lt;br /&gt;
      for(p=0; p&amp;lt;10; p++)  LCD_Write_DATA(0x00,0x00);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  digitalWrite(LCD_CS,HIGH); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void newpa(void)&lt;br /&gt;
{&lt;br /&gt;
  unsigned char p;&lt;br /&gt;
  digitalWrite(LCD_CS,LOW); &lt;br /&gt;
  Pant(0x00,0x00);   &lt;br /&gt;
&lt;br /&gt;
  Address_set(0,319,240,319);&lt;br /&gt;
  for(p=0; p&amp;lt;240; p++)  LCD_Write_DATA(0xF8,0x00);&lt;br /&gt;
  Address_set(0,0,240,0);&lt;br /&gt;
  for(p=0; p&amp;lt;240; p++)  LCD_Write_DATA(0xFF,0xFF);&lt;br /&gt;
  Address_set(0,300,240,300);&lt;br /&gt;
  for(p=0; p&amp;lt;240; p++)  LCD_Write_DATA(0xFF,0xFF);&lt;br /&gt;
  Address_set(0,0,0,255);&lt;br /&gt;
  for(p=0; p&amp;lt;255; p++)  LCD_Write_DATA(0xF8,0x00);&lt;br /&gt;
  Address_set(0,255,0,300);&lt;br /&gt;
  for(p=0; p&amp;lt;45; p++)  LCD_Write_DATA(0xF8,0x00);&lt;br /&gt;
  Address_set(239,0,239,255);&lt;br /&gt;
  for(p=0; p&amp;lt;255; p++)  LCD_Write_DATA(0xF8,0x00);&lt;br /&gt;
  Address_set(239,255,239,300);&lt;br /&gt;
  for(p=0; p&amp;lt;45; p++)  LCD_Write_DATA(0xF8,0x00);&lt;br /&gt;
Address_set(50,308,59,311);&lt;br /&gt;
  for(p=0; p&amp;lt;40; p++)  LCD_Write_DATA(0x07,0xE0);&lt;br /&gt;
Address_set(53,305,56,314);&lt;br /&gt;
  for(p=0; p&amp;lt;40; p++)  LCD_Write_DATA(0x07,0xE0);&lt;br /&gt;
Address_set(215,305,239,314);&lt;br /&gt;
  for(p=0; p&amp;lt;250; p++)  LCD_Write_DATA(0xF8,0x00);&lt;br /&gt;
 digitalWrite(LCD_CS,HIGH); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
 void recan(void)&lt;br /&gt;
{&lt;br /&gt;
  int i,j;&lt;br /&gt;
//  unsigned int m;&lt;br /&gt;
 digitalWrite(LCD_CS,LOW); &lt;br /&gt;
  for(i=0;i&amp;lt;7;i++)&lt;br /&gt;
  {&lt;br /&gt;
//    m=i*3;&lt;br /&gt;
    Address_set(i*5,305,i*5+3,314);&lt;br /&gt;
    for(j=0; j&amp;lt;40; j++)&lt;br /&gt;
    {&lt;br /&gt;
      if (1+i*2&amp;lt;= k) LCD_Write_DATA(0xFF,0xE0); else LCD_Write_DATA(0x00,0x00);&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
Address_set(100,305,124,314);&lt;br /&gt;
  for(i=0; i&amp;lt;250; i++)  LCD_Write_DATA(vh2,vl2);&lt;br /&gt;
Address_set(125,305,149,314);&lt;br /&gt;
  for(i=0; i&amp;lt;250; i++)  LCD_Write_DATA(vh2,vl2);&lt;br /&gt;
 digitalWrite(LCD_CS,HIGH); &lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
void AD7843(void)              &lt;br /&gt;
{&lt;br /&gt;
  digitalWrite(CS,LOW);                    &lt;br /&gt;
  WriteCharTo7843(0x90);        &lt;br /&gt;
  digitalWrite(DCLK,HIGH);&lt;br /&gt;
  digitalWrite(DCLK,LOW); &lt;br /&gt;
  TP_Y=ReadFromCharFrom7843();&lt;br /&gt;
  WriteCharTo7843(0xD0);      &lt;br /&gt;
  digitalWrite(DCLK,HIGH);&lt;br /&gt;
  digitalWrite(DCLK,LOW);&lt;br /&gt;
  TP_X=ReadFromCharFrom7843();&lt;br /&gt;
  digitalWrite(CS,HIGH);&lt;br /&gt;
 &lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void setup()&lt;br /&gt;
{&lt;br /&gt;
 &lt;br /&gt;
  unsigned char p;&lt;br /&gt;
&lt;br /&gt;
  for(p=0;p&amp;lt;20;p++)&lt;br /&gt;
  {&lt;br /&gt;
    pinMode(p,OUTPUT);&lt;br /&gt;
  }&lt;br /&gt;
  pinMode(DOUT,INPUT);&lt;br /&gt;
      x0=1;&lt;br /&gt;
      y0=1;&lt;br /&gt;
 &lt;br /&gt;
  LCD_Init();  &lt;br /&gt;
  newpa();&lt;br /&gt;
  recan();&lt;br /&gt;
  digi(vh2);&lt;br /&gt;
  x3=x3+90;&lt;br /&gt;
  digi(vl2);&lt;br /&gt;
  spistar();  &lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
void loop()&lt;br /&gt;
{  &lt;br /&gt;
  rx=0;&lt;br /&gt;
  ry=0;&lt;br /&gt;
   &lt;br /&gt;
  for(l3=0;l3&amp;lt;8;l3++)&lt;br /&gt;
    {&lt;br /&gt;
      AD7843();&lt;br /&gt;
&lt;br /&gt;
      lx=0;&lt;br /&gt;
      ly=-1*TP_Y;&lt;br /&gt;
      ly=4095+ly;              //4095=Basiswert y-Signal&lt;br /&gt;
      if(ly &amp;gt; 0) lx=1*TP_X; else {lx=0;ly=0;rx=0;ry=0;l3=9; }&lt;br /&gt;
      rx=rx+lx;&lt;br /&gt;
      ry=ry+ly;&lt;br /&gt;
    }&lt;br /&gt;
      lx=(rx/8-180)/15;        //180=Minimaler x-Wert bei &#039;Touch&#039;&lt;br /&gt;
      ly=(ry/8-240)/11;        //240=Minimaler (über 4095) y-Wert bei &#039;Touch&#039;&lt;br /&gt;
      if(ly &amp;lt; 1) {lx=0;ly=0; }&lt;br /&gt;
      if(lx &amp;lt; 1) lx=0;&lt;br /&gt;
 &lt;br /&gt;
      if(ly &amp;gt; 309-k)&lt;br /&gt;
      {&lt;br /&gt;
        ly=0;&lt;br /&gt;
        if(lx &amp;gt; 200) k=k-2; else if (lx &amp;gt; 160) k=k+2;else&lt;br /&gt;
            if (lx &amp;gt; 100) vh2++; else if (lx &amp;gt; 40) vl2++; else newpa();&lt;br /&gt;
        lx=0;&lt;br /&gt;
        if (k&amp;lt;1) k=1;&lt;br /&gt;
        if (k&amp;gt;13) k=13;&lt;br /&gt;
        if (vh2&amp;gt;255) vh2=0;&lt;br /&gt;
        if (vl2&amp;gt;255) vl2=0;&lt;br /&gt;
        x3=65;&lt;br /&gt;
        digi(vh2);&lt;br /&gt;
        x3=x3+90;&lt;br /&gt;
        digi(vl2);&lt;br /&gt;
        recan();&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      if(ly &amp;gt; 299-k) ly=299-k;&lt;br /&gt;
      if(ly &amp;gt; 0)&lt;br /&gt;
      {&lt;br /&gt;
        x0=240-lx;&lt;br /&gt;
        if(x0 &amp;gt; 240-k) x0=240-k;&lt;br /&gt;
        y0=ly;&lt;br /&gt;
        l2=(k+1)*(k+1);&lt;br /&gt;
        digitalWrite(LCD_CS,LOW); &lt;br /&gt;
        Address_set(x0,y0,x0+k,y0+k);&lt;br /&gt;
        for (l3=0; l3&amp;lt;l2; l3++) LCD_Write_DATA(vh2,vl2);&lt;br /&gt;
        digitalWrite(LCD_CS,HIGH); &lt;br /&gt;
    }&lt;br /&gt;
    delay (50);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Downloads ==&lt;br /&gt;
* [http://www.arduino.cc/en/Main/Software Download der IDE] &lt;br /&gt;
* [http://www.mikrocontroller.net/articles/AVR Artikel zur AVR Prozessor-Serie]&lt;br /&gt;
* [http://sourceforge.net/projects/arduinosources/ Quelltexte zu Arduino - Hard- und Software Open Source Plattform (ISBN 978-3-907857-16-8)]&lt;br /&gt;
* [http://sourceforge.net/projects/arduinoynsnippets/ Programmbeispiele zu beiden Prozessoren des Arduino Yún: Atheros AR9331 mit Linino (openWRT) &amp;amp; ATmega32u4]&lt;br /&gt;
&lt;br /&gt;
==Literatur==&lt;br /&gt;
* Günter Spanner: &#039;&#039;Arduino: Schaltungsprojekte für Profis&#039;&#039;, Elektor Verlag, 2012, ISBN 978-3-89576-257-4&lt;br /&gt;
* Erik Bartmann: &#039;&#039;Die elektronische Welt mit Arduino entdecken&#039;&#039;, O&#039;Reilly Verlag, 2011, ISBN 978-3-89721-319-7&lt;br /&gt;
* Thomas Brühlmann: &#039;&#039;Arduino: Praxiseinstieg&#039;&#039;, mitp Verlag, 2010, ISBN 978-3-8266-5605-7&lt;br /&gt;
* Claus Kühnel: &#039;&#039;Arduino Yún - Arduino für die Cloud&#039;&#039;, Skript Verlag Kühnel 2014, ISBN 978-3-907857-20-5&lt;br /&gt;
* Claus Kühnel: &#039;&#039;Arduino für die Cloud - Arduino Yún &amp;amp; Dragino Yún Shield&#039;&#039;, 2. Aufl., Skript Verlag Kühnel 2014, ISBN 978-3-907857-25-0&lt;br /&gt;
&lt;br /&gt;
==Bezugsquellen(Auswahl)==&lt;br /&gt;
&lt;br /&gt;
===Offiziele Boards===&lt;br /&gt;
* [http://www.watterott.com/de/Boards-Kits/Arduino Watterott.com] &lt;br /&gt;
* [http://www.reichelt.de/ Reichelt.de]&lt;br /&gt;
* [http://www.conrad.de/ Conrad.de]&lt;br /&gt;
* [http://www.tigal.com/ TIGAL.com]&lt;br /&gt;
&lt;br /&gt;
===Lernpakete===&lt;br /&gt;
* [http://www.franzis.de/ Franzis Verlag(Lernpakete)]&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [http://www.arduino.cc/ Website des Arduino-Projekt] &lt;br /&gt;
* [http://arduino.cc/forum/index.php/board,31.0.html Deutsches Arduino-Forum(offiziel)]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
[[Kategorie:AVR-Boards]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR_In_System_Programmer&amp;diff=86760</id>
		<title>AVR In System Programmer</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR_In_System_Programmer&amp;diff=86760"/>
		<updated>2015-01-21T22:50:17Z</updated>

		<summary type="html">&lt;p&gt;Maybee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einführung ==&lt;br /&gt;
&lt;br /&gt;
In-System-Programming (ISP) bedeutet, einen Mikrocontroller oder anderen programmierbaren Baustein im eingebauten Zustand zu programmieren. Dazu muss der Mikrocontroller entsprechend beschaltet sein. Das bedeutet, die benötigten Anschlüsse am Mikrocontroller müssen zugänglich und nicht ohne weitere Vorkehrungen anderweitig benutzt sein - siehe [http://www.atmel.com/images/atmel-2521-avr-hardware-design-considerations_application-note_avr042.pdf Atmel Application Note AVR042].&lt;br /&gt;
&lt;br /&gt;
Atmel verwendet für ihre 8-Bit RISC Mikrocontroller zum Teil unterschiedliche ISP-Protokolle. Das bekannteste davon wird einfach als ISP bezeichnet. Insgesamt findet man:&lt;br /&gt;
&lt;br /&gt;
;ISP:Der Normalfall. Bei vielen, aber nicht allen AVRs teilen sich [[SPI]]- und ISP-Schnittstelle die Pins. Je nach AVR gibt es leichte Unterschiede im Protokoll. Das Protokoll für einen Typ ist im Datenblatt unter &#039;&#039;Memory Programming -&amp;gt; Serial Downloading&#039;&#039; beschrieben.&lt;br /&gt;
;TPI:Tiny Programming Interface. Einige AVRs der Tiny-Serie, besonders die 6-Pin Tinys.&lt;br /&gt;
;PDI:Programming and Debugging Interface. Die XMEGAs.&lt;br /&gt;
;JTAG:AVRs mit [[JTAG]] Debugging-Schnittstelle lassen sich auch über JTAG in-system-programmieren.&lt;br /&gt;
;Bootloader:Einige wenige AVRs kommen bereits mit einem einprogrammierten [[Bootloader]]. Bei diesen kann man ein zum Bootloader passendes Programm nutzen um den AVR über eine im Bootloader definierte Schnittstelle programmieren. Auf Bootloadern basierende Systeme haben ansonsten ein Henne-Ei Problem. Irgendwie muss der Bootloader einmal konventionell in den AVR programmiert werden, zum Beispiel mit ISP.&lt;br /&gt;
&lt;br /&gt;
Atmels [[debugWire]] ist keine Programmierschnittstelle, sondern eine reines Debugging-Interface. Zum Programmieren verwendet man bei AVRs mit debugWire daher normalerweise ISP.&lt;br /&gt;
&lt;br /&gt;
Atmel hat für die AVR 8-Bit RISC Mikrocontroller mehrere Application Notes herausgegeben, auf deren Basis eine Vielzahl von Programmiergeräten (&#039;&#039;programmer&#039;&#039;) entwickelt wurden. &lt;br /&gt;
&lt;br /&gt;
Natürlich liefert Atmel auch eigene, fertige Programmiergeräte (AVRISP (mk I), AVRISP mk II, [[AVR-Dragon]], ...), Programmiersoftware (AVRProg, AVR Studio) und Entwicklungsboards mit integriertem Programmiergerät (z.&amp;amp;nbsp;B. [[STK500]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p style=&amp;quot;color:darkred;&amp;quot;&amp;gt;&amp;lt;big&amp;gt;FAQ/Tipp: &#039;&#039;&#039;&amp;quot;Welchen ISP-Adapter sollte man sich zulegen oder bauen?&amp;quot;&#039;&#039;&#039;&amp;lt;/big&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Man sollte sich einen fertigen, original Atmel (keinen Clone) ISP-Adapter kaufen. Zum Beispiel für ISP (und PDI) Programmierung &#039;&#039;&#039;Atmels original [[AVR_In_System_Programmer#Atmel_AVRISP_MKII|AVRISP mkII]] für rund 36,- Euro&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Das ist eine Investition, die viel Zeit und Ärger spart, denn es geht nichts über zuverlässiges Werkzeug. Beim Umgang mit µCs ist es sehr frustrierend an drei Fronten gleichzeitig zu kämpfen:&lt;br /&gt;
# Bugs in der Software, &lt;br /&gt;
# Bugs in der Schaltung und &lt;br /&gt;
# Bugs/Probleme beim ISP-Adapter-/PC-Gespann.&lt;br /&gt;
&lt;br /&gt;
Wenigstens Probleme mit dem ISP-Adapter lassen sich durch den Kauf eines zuverlässigen ISP-Adapters eliminieren. Siehe auch diverse Forenbeiträge u.a. [http://www.mikrocontroller.net/topic/91042#778908] und [http://www.mikrocontroller.net/topic/153841#1447882].&lt;br /&gt;
&lt;br /&gt;
Sehr unzuverlässig sind häufig billige oder selbstgebaute Programmierkabel mit nichts außer ein paar Widerständen. Unzuverlässig sind häufig auch billige oder selbstgebaute Programmierkabel mit einem einfachen Bustreiber. Nur weil sie bei manchen funktionieren heißt das nicht, dass sie überall problemlos funktionieren.&lt;br /&gt;
&lt;br /&gt;
Parallelport- (Druckerport-) ISP-Adapter funktionieren gar nicht, wenn man sie mit einem USB &amp;lt;-&amp;gt; Druckerport Adapter an einen USB-Port am PC anschließt. Einfach (unintelligente) ISP-Adapter für die serielle Schnittstelle funktionieren gar nicht oder extrem langsam, wenn man sie mit einem USB &amp;lt;-&amp;gt; Seriell Adapter am PC anschließt. Gute intelligente serielle Programmieradapter, wie der in Atmels STK500 eingebaute, funktionieren normalerweise mit einem USB-Adapter.&lt;br /&gt;
&lt;br /&gt;
Bei allen Programmieradaptern mit eigener Firmware, einschließlich der Original-Adapter von Atmel, ist man darauf angewiesen, dass der Hersteller wenn nötig Firmware-Updates bereitstellt. Bei Clones ist die Versorgung mit Firmware manchmal fraglich. &lt;br /&gt;
&lt;br /&gt;
Oftmals funktionieren auch die Treiber der Clones unter 64-Bit Betriebssystem nicht richtig oder nur mit Tricks, die leider wichtige Sicherheitsfunktionen des Betriebssystem abschalten. Der [[AVR_In_System_Programmer#Atmel_AVRISP_MKII|AVRISP mkII]] funktioniert dagegen auch unter Windows 7 (64-Bit).&lt;br /&gt;
&lt;br /&gt;
== Application Notes ==&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/DOC0943.PDF AVR910] (PDF) &amp;quot;&#039;&#039;Low-cost&#039;&#039;&amp;quot; &#039;&#039;In-system programming&#039;&#039; (&#039;&#039;&#039;AVRISP&#039;&#039;&#039;) beschreibt einen einfachen, kostengünstigen Programmieradapter zur Übertragung von Programmen in den Mikrocontroller. Auf dem Programmer befindet sich ein Mikrocontroller (natürlich von Atmel ;-), der serielle Steuerkommandos und Daten vom PC in Programmiersignale für den Mikrocontroller umsetzt.&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2568.pdf AVR911] (PDF) &#039;&#039;Open source serial programmer&#039;&#039; (&#039;&#039;&#039;AVROSP&#039;&#039;&#039;) beschreibt eine &#039;&#039;open source&#039;&#039; Programmiersoftware zur Übertragung von Programmen in den Mikrocontroller. &lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc1644.pdf AVR109] (PDF) &#039;&#039;Self-Programming&#039;&#039; mit Hilfe eines [[Bootloader|Bootloaders]]. Hier wird im Mikrocontroller zunächst ein mikrocontroller-spezifisches Bootloader-Programm abgelegt. Dieses Programm empfängt das eigentliche Benutzerprogramm oder Daten z.&amp;amp;nbsp;B. über einen seriellen Anschluss ([[UART]]), legt es ggf. im Speicher (Flash-ROM, EEPROM) ab und führt ggf. anschliessend das Benutzerprogramm aus.&lt;br /&gt;
&lt;br /&gt;
== Pinbelegung ==&lt;br /&gt;
===ISP===&lt;br /&gt;
Die Standard-Pinbelegung des ISP-Steckers zum Anschluss des Mikrocontrollers sieht nach obigen Application Notes und der [http://www.atmel.com/images/atmel-2521-avr-hardware-design-considerations_application-note_avr042.pdf AVR042] (PDF) folgendermaßen aus (Anschluss auf der Platine, Ansicht von oben). Atmel bevorzugt dabei bereits seit Jahren den 6-poligen Anschluss.&lt;br /&gt;
&lt;br /&gt;
[[Bild:avr-isp-pinout.png|right]]&lt;br /&gt;
  &lt;br /&gt;
  10-poliger       6-poliger&lt;br /&gt;
  Anschluss        Anschluss&lt;br /&gt;
  &lt;br /&gt;
  1 MOSI           1 MISO&lt;br /&gt;
  2 VCC            2 VCC&lt;br /&gt;
  3 - (*)          3 SCK&lt;br /&gt;
  4,6,8,10 GND     4 MOSI&lt;br /&gt;
  5 RESET          5 RESET&lt;br /&gt;
  7 SCK            6 GND&lt;br /&gt;
  9 MISO&lt;br /&gt;
&lt;br /&gt;
Pin 1 ist am Pfostenstecker mit einem kleinen Pfeil gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Um Verwechslungen zu vermeiden, empfiehlt es sich, für die einzelnen Leitungen unterschiedliche Farben zu verwenden. Atmel hat dafür keine Festlegung getroffen, so dass es keinen festen Standard gibt. Üblich ist jedoch eine Farbzuordnung wie beim [https://guloshop.de/shop/Mikrocontroller-Programmierung/guloboard-G6::5.html guloboard]:&lt;br /&gt;
&lt;br /&gt;
  1 MISO  weiß&lt;br /&gt;
  2 VCC   rot&lt;br /&gt;
  3 SCK   blau&lt;br /&gt;
  4 MOSI  grün&lt;br /&gt;
  5 RESET gelb&lt;br /&gt;
  6 GND   schwarz&lt;br /&gt;
&lt;br /&gt;
(*) Einige Programmieradapter (Ponyprog-Adapter nach Lancos-Schaltplan) unterstützen an Pin 3 des 10-poligen Steckers eine LED (Kathode an Pin), die &amp;quot;Programmierzugriff&amp;quot; signalisieren soll. Dies ist aber kaum nützlich, daher wird der Pin auch von Atmel als N/C (not connected) definiert und beim original Atmel AVRISP mit GND verbunden.&lt;br /&gt;
&lt;br /&gt;
Der 10-polige Anschluss wurde von der Firma Kanda beim STK200 verwendet und ist deshalb auch als &amp;quot;Kanda-Standard&amp;quot; bekannt und war zur Zeit der STK200 Programmieradapter relativ weit verbreitet. Die Anschlussbelegung über einen 6-poligen Stecker stammt von Atmel selbst und ist platzsparender auf der Platine.&lt;br /&gt;
&lt;br /&gt;
Am besten kauft oder fertigt man sich einen Adapter 6 &amp;lt;-&amp;gt; 10 (siehe [http://www.shop.robotikhardware.de/shop/catalog/product_info.php?products_id=190], [http://www.watterott.com/de/AVR-ISP-Programmieradapter], [http://www.watterott.com/de/AVR-Programmier-Kabel], [https://guloshop.de/shop/Adapterkabel/Programmieradapterkabel-6-polig-10-polig-lang::9.html]), dann lassen sich praktisch alle Boards mit jedem Programmer programmieren.&lt;br /&gt;
&lt;br /&gt;
[[Datei:Kabeloben.jpg]]&lt;br /&gt;
[[Datei:Kabelunten.jpg]]&lt;br /&gt;
[[Datei:isp_kab.jpg]]&lt;br /&gt;
&lt;br /&gt;
Zehnpolige Messerleisten (Wannenstecker) zur Montage auf einer µC Platine zum verpolungssicheren Anschluss des Programmieradapters sind fast &amp;quot;überall&amp;quot; verfügbar, nach den sechspoligen muss man häufig etwas suchen. Mittlerweile sind sie endlich bei Reichelt erhältlich (WSL 6G).&amp;lt;br/&amp;gt;&lt;br /&gt;
Alternativ bleibt nur der Griff zu den nicht verpolungssicheren 2xN Stiftleisten (z.&amp;amp;nbsp;B. 2x40), wobei man eine Stiftleiste auf 2x3 Pole kürzt.&lt;br /&gt;
&lt;br /&gt;
Sechspolige Federleisten (Pfostenbuchsen) zum Anquetschen an ein Programmierkabel sind dagegen zumindest bei den großen Versendern und Distributoren erhältlich (z.&amp;amp;nbsp;B. von Bürklin  Art.53F3500; Conrad Art.701980-62; Farnell Art.1097021; Reichelt PFL 6). Kleine lokale Elektronikläden führen diese jedoch häufig nicht. Zu den sechpoligen Pfostenbuchsen gibt es keine Alternative, wenn man ein sechpoliges Programmierkabel bauen möchte. Zehnpolige Pfostenbuchsen lassen sich nicht auf sechs Pole kürzen. Korrektur: Man kann die äußeren pins  ( 2 rechts, 2 links) einfach rausdrücken, dann passt der 6pol in die Buchse. Verpolungsschutz besteht weiterhin.&lt;br /&gt;
&lt;br /&gt;
Je nach Programmieradapter hat der VCC-Anschluss unterschiedliche Funktionen:&lt;br /&gt;
&lt;br /&gt;
1. Versorgung des Programmieradapters mit Strom aus der Schaltung, wie es bei vielen Parallelport-Adaptern der Fall ist.&lt;br /&gt;
&lt;br /&gt;
2. Versorgung der Schaltung mit Strom aus dem Programmieradapter. Dies ist insbesondere beim STK500 möglich und dank dessen programmierbarer Versorgungsspannung manchmal ganz praktisch. &lt;br /&gt;
&lt;br /&gt;
3. Messung der Betriebsspannung der Schaltung, so dass der Programmieradapter sich auf diese Spannung einstellen kann und so ein 3,3 V Board mit 3,3 V und ein 5 V Board mit 5 V programmiert. So wie zum Beispiel beim AVRISP mkII. Daher wird VCC auf neueren Schaltbildern auch als Vtg oder VTref bezeichnet (Atmel kann sich da nicht auf eine Bezeichnung einigen).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Je nach verwendetem Programmer muss man daher sorgfältig auf die Beschaltung von VCC/Vtg/VTref und auf die Stromversorgung von Board und Programmer achten.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/301971#3234822 Forumsbeitrag]: Extrem kleiner ISP Header, wie?&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/145711#1352516 Forumsbeitrag]: Kleinserie: ISP Programmierung mögl. ohne Stecker&lt;br /&gt;
&lt;br /&gt;
===TPI===&lt;br /&gt;
&lt;br /&gt;
Die TPI-Programmierung setzt sich aus mehreren Schichten zusammen: Hardware (Ansteuerung der IO-Pins), Speicher-Management (stellt Funktionen zum Flashen bereit) und der Speicher selbst.&lt;br /&gt;
&lt;br /&gt;
  Data  1 2 VCC&lt;br /&gt;
  Clock 3 4 N.C.&lt;br /&gt;
  Reset 5 6 GND&lt;br /&gt;
&lt;br /&gt;
Standard TPI connector used on e.g. STK600 and AVRISP mkII.&lt;br /&gt;
&lt;br /&gt;
===PDI===&lt;br /&gt;
====Atmel Board-Schnittstelle &amp;amp; AVRISP MkII ====&lt;br /&gt;
Für Mikrocontroller-Boards schlägt Atmel einen 6-Pin Header, 2,54 mm Raster, mit folgender Pinbelegung vor (Ansicht von Oben):&lt;br /&gt;
&lt;br /&gt;
 DATA  1 2  VCC&lt;br /&gt;
 N.C.  3 4  N.C.&lt;br /&gt;
  CLK  5 6  GND&lt;br /&gt;
&lt;br /&gt;
(N.C.: Not Connected, nicht verbunden). Diese Belegung wird auch von Atmels AVRISP MkII im PDI-Modus verwendet.&lt;br /&gt;
&lt;br /&gt;
Bei Atmels eigenem XPlain Eval-Kit und anderen Programmieradaptern geht es zur Zeit jedoch noch fröhlich durcheinander. Folgenden Pinbelegungen lassen sich finden.&lt;br /&gt;
&lt;br /&gt;
====Atmel XPlain Eval-Board====&lt;br /&gt;
&lt;br /&gt;
Hier hat Atmel die Xmega PDI- und JTAG-Schnittstelle gemeinsam auf den Header J100 gelegt. Die PDI-Belegung ist wie folgt:&lt;br /&gt;
&lt;br /&gt;
       1  2  GND&lt;br /&gt;
       3  4  VCC&lt;br /&gt;
       5  6  CLK&lt;br /&gt;
  VCC  7  &#039;&#039;&#039;8  DATA&#039;&#039;&#039;&lt;br /&gt;
       9 10  GND&lt;br /&gt;
&lt;br /&gt;
Nur jeweils ein VCC- und ein GND-Anschluss muss verwendet werden. Es bieten sich die Pins 2 und 4 an.&lt;br /&gt;
&lt;br /&gt;
Man beachte die Position von DATA auf Pin 8 bei dieser Belegung von PDI auf dem XPlain JTAG-Header.&lt;br /&gt;
&lt;br /&gt;
====Atmel JTAGICE MkII====&lt;br /&gt;
&lt;br /&gt;
Einige sehr alte JTAGICE MkII unterstützen kein PDI. Alle neueren, in den letzten Jahren hergestellte tun es. Eventuell ist ein Firmware-Upgrade über AVR-Studio nötig.&lt;br /&gt;
&lt;br /&gt;
Laut [http://support.atmel.no/knowledgebase/avrstudiohelp/mergedProjects/JTAGICEmkII/mkII/Html/Connecting_to_target_through_the_PDI_interface.htm] und der eingebauten Hilfe von [[AVR Studio]] 4.18 SP 1 verwendet ein JTAGICE MkII im PDI-Modus folgende Pinbelegung:&lt;br /&gt;
&lt;br /&gt;
       1  2  GND&lt;br /&gt;
       3  4  VTref&lt;br /&gt;
       5  6  CLK&lt;br /&gt;
       7  8&lt;br /&gt;
 &#039;&#039;&#039;DATA  9&#039;&#039;&#039; 10  GND&lt;br /&gt;
&lt;br /&gt;
Man beachte, dass DATA hier angeblich auf Pin 9 liegt. (VTref dürfte VCC entsprechen). In der Hilfe zu AVR Studio 4.18 SP 1 ist der Pin CLK mit PDI_CLK, und der Pin DATA mit PDI_DATA bezeichnet.&lt;br /&gt;
&lt;br /&gt;
====Atmel AVR Dragon====&lt;br /&gt;
&lt;br /&gt;
Erst mit der Dragon-Firmware im SP 1 für AVR Studio 4.18 soll der PDI-Support des [[AVR Dragon]] funktionieren. Angekündigt war PDI-Support bereits für AVR Studio 4.18. &lt;br /&gt;
&lt;br /&gt;
Leider hat Atmel es versäumt in der Dragon-Dokumentation die Pinbelegung für PDI auf der Seite des Dragon anzugeben. In der Studio-Dokumentation ist von einem ominösen Dragon PDI Adapter die Rede, der Teil des &amp;quot;Dragon Kit&amp;quot; sein soll. Allerdings wird der Dragon &#039;nackt&#039; ausgeliefert und bisher gibt es keine Berichte darüber, dass jemand diesen ominösen Adapter gesehen hat. Von neueren Versionen des JTAGICE mkII ist hingegen bekannt, dass sie mit einem &#039;&#039;XMEGA PDI adapter kit&#039;&#039; geliefert werden.&lt;br /&gt;
&lt;br /&gt;
Angeblich ist es nötig, beim Dragon jeweils einen 330Ω Widerstand in die CLK und DATA Leitung zu legen, um Probleme mit dem Überschwingen der Signale zu vermeiden.&lt;br /&gt;
&lt;br /&gt;
== Programmer-Varianten ==&lt;br /&gt;
&lt;br /&gt;
Mittlerweile existiert eine fast unüberschaubare Zahl von Programmer-Varianten und Untervarianten. Hier sollen nur die wichtigsten Varianten mit Bauanleitungen aufgelistet werden, geordnet nach der Art des Anschlusses an den PC.&lt;br /&gt;
&lt;br /&gt;
Zur Zeit (März 2012) gibt es vermehrt Probleme, mit den neuen Varianten 5.x des AVR Studios, kompatible Programmer, die nicht von Atmel selbst hergestellt wurden, anzusteuern. Es sollte beim Erwerb/Nachbau auf die Zusicherung der Komptibilität zum gewünschen AVR Studio geachtet werden.&lt;br /&gt;
&lt;br /&gt;
=== Parallelport ===&lt;br /&gt;
&lt;br /&gt;
==== STK200-kompatibel ====&lt;br /&gt;
&lt;br /&gt;
Fast alle erhältlichen Parallelport-Programmieradapter, u.a. auch der hier im [http://shop.mikrocontroller.net/ Shop] angebotene, sind kompatibel zum Programmer des [[STK200]] / STK300.&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/STK200 Schaltbilder für STK200 und kompatible]&lt;br /&gt;
* Bauanleitung für einen [http://rumil.de/hardware/avrisp.html STK200-kompatiblen Programmieradapter] von Rolf Milde&lt;br /&gt;
* Universelles Programmiergerät mit 74HC244 und Schutzwiderständen http://www.aplomb.nl/TechStuff/PPPD/PPPD%20English.html&lt;br /&gt;
&lt;br /&gt;
==== Paralleles Interface für AVR und PonyProg ====&lt;br /&gt;
&lt;br /&gt;
Schaltplan und Erläuterungen bei [http://s-huehn.de/elektronik/avr-prog/avr-prog-alt.htm Scott-Falk Hühn]&lt;br /&gt;
&lt;br /&gt;
==== SP12 Programmer ====&lt;br /&gt;
&lt;br /&gt;
Schaltplan, Erläuterungen und Software für mehrere Plattformen, darunter auch MSDOS, gibt es bei [http://www.xs4all.nl/~sbolt/e-spider_prog.html#programmer Steven Bolt]. [http://www.xs4all.nl/~sbolt/e-spider_prog.html#programmer Ken&#039;s Dongle] ist ein spezieller Kabeladapter für SP12 zur Verbesserung der Signalqualität. Anpassung an neue Typen erfolgt durch leicht selbst erstellbare Beschreibungsdateien.&lt;br /&gt;
&lt;br /&gt;
=== Serieller Port ([[RS-232]]) ===&lt;br /&gt;
&lt;br /&gt;
==== Atmel AVRISP, STK500, AVR910 ====&lt;br /&gt;
&lt;br /&gt;
Der original AVRISP von Atmel, das [[STK500]] und der Programmer aus der Application Note AVR910 enthalten einen Mikrocontroller, der die Umsetzung der seriellen Daten auf das ISP- und TPI-Programmierinterface vornimmt. Sie lassen sich direkt mit dem AVR-Studio programmieren und sind auch problemlos mit einem USB-seriell-Adapter verwendbar.&lt;br /&gt;
&lt;br /&gt;
Ein Layout mit Schaltplan und erweitertem Sourcecode findet sich in diesem Thread in der Codesammlung [http://www.mikrocontroller.net/topic/88295#749553 AVR910 Programmer, Schaltplan, Layout, Firmware].&lt;br /&gt;
&lt;br /&gt;
Das AVR910 Design ist u.a. auf der Seite von [http://www.serasidis.gr/circuits/avr_isp/avr_isp.htm Serasidis Vasilis] im Detail beschrieben.&lt;br /&gt;
&lt;br /&gt;
Eine weitere, auführliche Anleitung zum AVR910 gibt es in deutsch auf der Seite von [http://www.klaus-leidinger.de/mp/Mikrocontroller/AVR-Prog/AVR-Programmer.html Klaus Leidinger].&lt;br /&gt;
* [https://www.ssl-id.de/b-redemann.de AVR910-USB-Prog: Bausatz incl. USB-seriell Wandler]&lt;br /&gt;
* [http://www.avr-projekte.de/isp.htm AVR910-USB: Bauanleitung incl. USB-seriell Wandler]&lt;br /&gt;
&lt;br /&gt;
==== SI-Prog ====&lt;br /&gt;
&lt;br /&gt;
Daneben gibt es noch weitere Programmieradapter für den seriellen Port, die auf den eigenen Mikrocontroller im Programmieradapter verzichten und das ISP-Programmierprotokoll über die Steuerleitungen des RS-232-Port nachbilden. Das Programmierprogramm auf dem PC sendet jetzt keine Steuerkommandos und Daten mehr, sondern gibt direkt die Programmiersignale an der seriellen Schnittstelle aus (&amp;quot;Pinwackeln an den Statuspins&amp;quot;). Der Nachteil dieser Adapter ist, dass sie meistens relativ langsam sind und nur unter wenigen Betriebssystemen funktionieren. Ein Beispiel dafür ist SI-Prog.&lt;br /&gt;
&lt;br /&gt;
* [http://www.lancos.com/siprogsch.html SI-Prog Originalversion]&lt;br /&gt;
* [http://s-huehn.de/elektronik/avr-prog/avr-prog.htm Schaltplan und Erläuterungen]&lt;br /&gt;
&lt;br /&gt;
==== Sercon2 ====&lt;br /&gt;
&lt;br /&gt;
Mit einer etwas anderen Steckerbelegung als der SI-Prog arbeitet die Sercon Familie an Adaptern. Nähere Unterlagen dazu finden sich &lt;br /&gt;
[http://www.speedy-bl.com/adapter.htm hier]&lt;br /&gt;
&lt;br /&gt;
==== Selbstbau-Programmer, basierend auf dem FTDI chip (via avrdude) ====&lt;br /&gt;
http://irq5.wordpress.com/2010/07/15/programming-the-attiny10/&lt;br /&gt;
&lt;br /&gt;
=== USB ===&lt;br /&gt;
&lt;br /&gt;
Die meisten USB-Programmieradapter verwenden einen USB-seriell-Wandler und ein STK500/AVRPROG-kompatibles Protokoll und können damit direkt aus dem AVR-Studio programmiert werden.&lt;br /&gt;
&lt;br /&gt;
Eine Quick-and-Dirty Programmierlösung bietet der [[#USB-Hub-ISP]], der außer einem USB-Hub nur Standard-Bauteile voraussetzt.&lt;br /&gt;
&lt;br /&gt;
==== Atmel AVRISP MKII ====&lt;br /&gt;
&lt;br /&gt;
Nachfolger des Atmel AVRISP &amp;quot;MKI&amp;quot;. Mit USB-Schnittstelle, leistungsfähigerem Programmiercontroller und erweitertem Hardwareschutz. Programmiersoftware: [[AVR-Studio]] und [[AVRDUDE]]. Herstellerinformation bei [http://www.atmel.com/dyn/products/tools_card.asp?family_id=607&amp;amp;family_name=AVR+8%2DBit+RISC+&amp;amp;tool_id=3808 atmel.com]&lt;br /&gt;
&lt;br /&gt;
Der AVRISP MKII führt ca. 1s nach dem Einschalten der Versorgungsspannung einen Reset aus. Lässt man den Programmer beim Testen der Schaltung gesteckt und startet diese durch Einschalten von Vcc, kann dies zu unangenehmen Nebeneffekten führen. Z.B. wird eine gerade angelaufene Datenübertragung nach 1s abrupt abgebrochen, startet neu und läuft danach fehlerfrei. &lt;br /&gt;
&lt;br /&gt;
Dave Jones hat im EEVblog #158 ein [http://www.eevblog.com/2011/03/25/eevblog-158-avr-isp-mk2-lm317-regulator-tutorial/ Videotutorial] erstellt, wie man beim Atmel AVRISP &amp;quot;MKI&amp;quot; mit dem LM317 Spannungsregler 3.3V oder 5V Versorgungsspannungen für das Targetboard nachrüstet. Im Video schlägt Dave als bessere Lösung die Verwendung eines Low-Drop-Spannungsreglers vor. Dafür eignet sich z.B. der [http://www.mikrocontroller.net/part/LM1117 LM1117]&lt;br /&gt;
&lt;br /&gt;
Weiter unten auf dieser Seite wird auch ein einfacher, kompatibler Nachbau namens [http://www.mikrocontroller.net/articles/AVR_In_System_Programmer#usbprog usbprog] vorgestellt.&lt;br /&gt;
&lt;br /&gt;
==== Atmel AT90USBKEY ====&lt;br /&gt;
Mit hilfe des [http://www.fourwalledcubicle.com/AVRISP.php AVRISP-MKII Clone] Projekts aus dem [http://www.fourwalledcubicle.com/LUFA.php LUFA] Paket wird aus dem [http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3879 AT90USBKEY] recht einfach ein Programmer, der mit [[AVR-Studio]] und [[AVRDUDE]] genutzt werden kann.&lt;br /&gt;
&lt;br /&gt;
==== AVRISP mkII Klon mit dem Teensy-Board und der Lufa-Bibliothek ====&lt;br /&gt;
Mit der [http://www.fourwalledcubicle.com/LUFA.php LUFA-Bibliothek] und dem [http://www.pjrc.com/teensy TEENSY 2.0 Board] kann schnell ein AVRISP mk2 Klon gebaut werden, der auch mit [[AVR-Studio]] in Windows einwandfrei  zusammenarbeitet. Weitere Infos auf [http://www.weigu.lu/b/avrispmk2 weigu.lu].&lt;br /&gt;
&lt;br /&gt;
==== AVRISP mkII Klon mit dem Atmega32U2-Breakout-Board und der Lufa-Bibliothek ====&lt;br /&gt;
Mit der [http://www.fourwalledcubicle.com/LUFA.php LUFA-Bibliothek] ([http://dokuwiki.ehajo.de/artikel:atmega_u-howto:avrisp-mkii Eine Anleitung gibt es hier]) und dem [http://www.ehajo.de/Bausaetze/Atmega32u2-Breakout-Board Atmega32U2-Breakout-Board] kann problemlos ein AVRISP mkII-Klon programmiert werden. Um praktisch auf die Programmierpins zugreifen zu können gibt es [http://www.ehajo.de/Bausaetze/ISP-Addon-Atmega%2AU2-Breakout dieses Addon-Board] für das Breakout-Board. Der Programmer läuft problemlos mit [[AVR-Studio]] unter Windows.&lt;br /&gt;
&lt;br /&gt;
==== Bascom USB ISP ====&lt;br /&gt;
Beliebter USB programmer der speziell für den Bascom Compiler entwickelt wurde. &lt;br /&gt;
Unterstützt Bascom einen neuen AVR-Controller, so kann dies automatisch auch dieser USB Programmer, eine neue Firmware ist nicht erforderlich. Ein weiterer Vorteil ist, dass er speziell für Bascom entwickelt wurde und in der IDE unterstützt wird. Er unterstützt alle Features von Bascom, auch die automatische Fusebit-Einstellung per Direktive im Quellcode.&lt;br /&gt;
&lt;br /&gt;
Angenehm ist auch, dass er keine 5V benötigt. Im Gegenteil, er kann sogar Boards über das übliche ISP-Programmierkabel mit 5V versorgen, so dass viele Boards auch ohne weitere Spannungsquelle programmiert werden können. &lt;br /&gt;
Ein wirklich empfehlenswerter Qualitätsprogrammer für alle Programmierer, die ausschließlich mit Bascom arbeiten wollen&lt;br /&gt;
* [http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=73&amp;amp;products_id=161 Vertrieb in Deutschland bei robotikhardware.de]&lt;br /&gt;
&lt;br /&gt;
Im Online- / Auktionshandel werden auch Alternativen angeboten, teils recht schick im Plexiglasgehäuse für ca. 20 Euro. Angeboten z.&amp;amp;nbsp;B. als &amp;quot;USB 2.0 Full Speed low cost Programmer für ATMEGA Chips&amp;quot; oder &amp;quot;AVR USB ISP Programmer ATMEL ATMEGA STK500&amp;quot;. Die Adapter funktionieren auch mit BasCom (aber auch mit AVR Studio), z.&amp;amp;nbsp;B. mit der Einstellung &amp;quot;STK500 native driver&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Man kann die Targetspannungsversorgung per USB zwischen 3,3 und 5V umschalten oder ganz abschalten (per DIP-Schalter). Sie sind per USB an den PC angeschlossen und arbeiten über einen virtuellen COM-Port. Achtung: In BasCom funktioniert das nur bis COM9. Wenn sich das Gerät z.&amp;amp;nbsp;B. auf COM15 installiert, wird es im BasCom evtl. nicht gefunden. Dann in der Systemsteuerung entsprechend umstellen.&lt;br /&gt;
&lt;br /&gt;
==== Atmel AVR Dragon ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Hauptartikel [[AVR-Dragon]]&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Der [http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3891 AVR Dragon] ist ein preiswerter ISP (und ICE) von Atmel, der aufgrund Preis/Leistungs-Verhältnisses schnell populär wurde. Atmel wurde von dieser Popularität überrascht, da der Dragon wohl ursprünglich nur als ein &amp;quot;Gimmick&amp;quot; zur Verbreitung von AVRs in Asien gedacht war.&lt;br /&gt;
&lt;br /&gt;
Die großen Vorteile des Dragons sind, dass er alle Programmiermodi beherrscht, inklusive High-Voltage Parallel Programming (&amp;quot;verfuste&amp;quot; AVRs retten), dass er ein natives USB-Interface hat, von AVR-Studio unterstützt wird, und sogar [[JTAG]] und [[debugWIRE]] ICE / Debugging unterstützt (bei den AVRs die dies können). &lt;br /&gt;
&lt;br /&gt;
Zu den größten bekannten Nachteilen gehören, dass der Dragon völlig &amp;quot;nackt&amp;quot; kommt. Kein USB-Kabel, kein Gehäuse, nicht einmal Abstandsbolzen unter der Platine, keine Patchkabel und nicht einmal die Fassungen zum Einstecken von AVRs sind bestückt. Eine gedruckte Anleitung gibt es auch nicht. Daneben wird aufgrund des Stromverbrauchs des Dragon ein USB-Hub mit Netzteil benötigt.&lt;br /&gt;
&lt;br /&gt;
Weiter ist der Dragon dafür bekannt, empfindlich auf statische Aufladungen zu reagieren. Ein Spannungsregler und ein Ausgangstreiber gehen dabei besonders gerne kaputt. Ein gerne von Anfängern gemachter Fehler ist es, den Dragon im Betrieb auf dem mitgelieferten &amp;quot;Schaumstoff&amp;quot; aus der Verpackung liegen zu lassen. Das ist jedoch kein Schaumstoff, sondern leitendes Moosgummi.&lt;br /&gt;
&lt;br /&gt;
Weitere Schutzmaßnahmen für gefährdete AVR Dragons findet man auf der Dragonlair-Seite von [http://www.aplomb.nl/TechStuff/Dragon/Dragon.html Nard Awater].&lt;br /&gt;
&lt;br /&gt;
Der Dragon wird unter Linux z.&amp;amp;nbsp;B. von der avrdude-Programmiersoftware unterstützt. Unerklärlicherweise stellt Atmel die Dokumentation und Beschreibung des Dragon nur als Teil der Online-Hilfe der AVR-Studio Software unter Windows zur Verfügung. Weiterhin lassen sich Firmware-Updates auch nur mittels eine proprietären Atmel-Software unter Windows einspielen. Daher ist der Dragon für Linux-Benutzer nur dann zu empfehlen, wenn man zusätzlich noch Zugriff auf eine Windows-Installation hat.&lt;br /&gt;
&lt;br /&gt;
==== USBisp ====&lt;br /&gt;
&lt;br /&gt;
AVR Programmierdongle mit USB Anschluss und kompatibel zum STK500-Protokoll. Unter anderem programmierbar mit [[AVR-Studio]], [[AVRDUDE]] und [[uisp]]. Schaltplan (PDF), Layout (PDF), Erläuterungen und Firmware gibt es vom Entwickler [http://www.matwei.de Matthias Weißer].&lt;br /&gt;
&lt;br /&gt;
==== USB avrisp ====&lt;br /&gt;
&lt;br /&gt;
USB AVR Programmer auf Basis des AVR 910 Designs. Den Schaltplan, Layout und Erläuterungen (englisch) gibt es von [http://www.e.kth.se/~joakimar/hardware.html Joakim Arfvidsson].&lt;br /&gt;
&lt;br /&gt;
==== Evertool ====&lt;br /&gt;
&lt;br /&gt;
Mit USB-seriell-Wandler. Getestet mit Adapterkabeln/ICs von FTDI, SiLabs und Prolific (Adapterkabel z.&amp;amp;nbsp;B. für ca. 10EUR bei Reichelt).&lt;br /&gt;
&lt;br /&gt;
* [http://www.siwawi.arubi.uni-kl.de/avr_projects/evertool/ Evertool-&amp;quot;Homepage&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
==== USBasp ====&lt;br /&gt;
&lt;br /&gt;
Thomas Fischls [http://www.fischl.de/usbasp/ USBasp] ist ein&lt;br /&gt;
Openhardware-/Openfirmware-USB-ISP-Adapter. Er basiert auf einem&lt;br /&gt;
ATmega8, ATmega8L, ATmega88 oder ATtiny85, der mittels einer rein auf Firmware&lt;br /&gt;
basierenden USB-Implementierung von&lt;br /&gt;
[http://www.obdev.at/products/avrusb/index.html Objective Development]&lt;br /&gt;
arbeitet. &lt;br /&gt;
&lt;br /&gt;
Bezugsquellen:&lt;br /&gt;
* Ein [http://www.FundF.net/usbasp/ offizieller USBasp Bausatz] ist erhältlich.&lt;br /&gt;
* Alternative Bausätze inkl. Dokumentation gibt es bei [http://www.b-redemann.de/produkte-programmer.shtml www.b-redemann.de], [http://shop.ulrichradig.de/Bausaetze/USB-ASP-Bausatz.html shop.ulrichradig.de] und [https://guloshop.de/shop/index.php guloshop.de].&lt;br /&gt;
* Eine MacOS X Anpassung stammt von [http://www.macsven.de/usbasp.html Sven Schwiecker]. Man kann aber auch das Komplettpaket Crosspack-AVR, in dem AVRDUDE für Mac OS X bereits enthalten ist, von [http://www.obdev.at/products/crosspack/index-de.html obdev.at] benutzen&lt;br /&gt;
* Chinesische Clones von [http://www.ebay.de/sch/i.html?_from=R40&amp;amp;_sacat=0&amp;amp;_nkw=usbasp&amp;amp;rt=nc&amp;amp;LH_BIN=1 Ebay].&lt;br /&gt;
&lt;br /&gt;
Zum Ansteuern des USBasp wird [[AVRDUDE]] in einem speziellen Modus benötigt, der ab Version 5.2 standardmäßig vorhanden ist (vorher waren&lt;br /&gt;
Patches nötig).&lt;br /&gt;
&lt;br /&gt;
Zum Programmieren von neuen ATtinys muss der Jumper Slow SCK gesetzt werden.&lt;br /&gt;
Alternativ ist es möglich mit der zusätzlichen Option von avrdude &amp;quot;-B100&amp;quot; die Periodendauer von SCK auf etwa 100 µs oder noch länger zu vergrößern (funktioniert nur, wenn die Firmware des USBasp vom Mai 2011 oder neuer ist).&lt;br /&gt;
&lt;br /&gt;
Der originale USBasp hat den Nachteil, dass er nicht die Targetspannung zum Programmieren benutzt, sondern immer seine 5V. Deshalb kann es Probleme geben, wenn das Target mit einer niedrigen Spannung versorgt wird, da der USBasp die Target-Highpegel eventuell nicht mehr als High erkennt. Abhilfe kann ein kleiner Hack schaffen, mit dem der µC wahlweise mit 5V oder mit ~3.6V betrieben wird:&lt;br /&gt;
http://www.mikrocontroller.net/topic/109648?goto=2031524#2031524&lt;br /&gt;
&lt;br /&gt;
Der [http://diy.elektroda.eu/usbasp-z-optoizolacja-do-25kv-18v-6v/?lang=en Optoisolated USBASP 1.8V to 6V] ist eine Hardwareänderung ebenfalls mit breitem Targetspannungsbereich und zusätzlich galvanischer Isolation über die [[Optokoppler]] 6N317 (schnelle Datenleitungen) und PC817 (langsame Resetleitung).&lt;br /&gt;
&lt;br /&gt;
Manche USBasp sind umschaltbar zwischen 5 V und 3,3 V. Falls man später darüber eine Schaltung mit 3,3 Volt betreiben will – etwa zum direkten Ansprechen einer SD-Karte – lohnt gezieltes Nachfragen vor dem Kauf.&lt;br /&gt;
&lt;br /&gt;
==== AvrUsb500 ====&lt;br /&gt;
&lt;br /&gt;
* [http://www.tuxgraphics.org/electronics/200510/article05101.shtml AvrUsb500] - an open source Atmel AVR Programmer, stk500 V2 compatible, with USB interface&lt;br /&gt;
* [http://www.mechaos.de/avr_progusb.php meCHAOS] - Nachbau mit neuem Platinenlayout und weiteren Funktionen.&lt;br /&gt;
&lt;br /&gt;
==== usbprog ====&lt;br /&gt;
&lt;br /&gt;
[http://www.usbprog.org/ usbprog] von Benedikt Sauter ist ein USB Programmieradapter, der fast alle Atmel-Mikrocontroller unterstützt (ATiny, ATMega, AT89, AT90,&amp;amp;nbsp;...) und daneben auch für ARM7/9 und MSP universell einsetzbar ist. Unterstützung für Xmega gibt es nicht.&lt;br /&gt;
&lt;br /&gt;
Der Programmer wurde so entwickelt, dass man die Firmware auf dem Adapter über die USB-Verbindung austauschen kann. Dadurch sollte der Adapter lange attraktiv bleiben, da alles rund um das Projekt als open Source veröffentlicht ist und daher neue Controller einfach in die usbprog-Firmware integriert werden können.&lt;br /&gt;
Es ensteht gerade eine Firmware für einen einfachen JTAG-Adapter. Damit kann man dann ganz einfach debuggen (voraussichtlich auch aus dem AVR Studio aus).&lt;br /&gt;
&lt;br /&gt;
Man kann den Adapter auch als 1:1 AVRISP-mkII-kompatibles Gerät betreiben. Dafür muss man eine andere Firmware einspielen, die ebenfalls Teil des Projektes ist. Der Vorteil ist der, dass man so auf jede bestehende Programmiersoftware zurückgreifen kann, die das originale AVRISP mkII unterstützt. Getestet wurde usbprog bis jetzt mit avrdude (Linux und Windows) und dem AVR Studio 4 (Windows).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Damit der Programmer mit AVR Studio 5.x zusammen arbeitet, muss die Firmware aktualisiert werden: http://www.usbprog.org/index.php/Firmwares (siehe Update-Hinweis)&lt;br /&gt;
&lt;br /&gt;
Derzeit kann man bei der embedded projects GmbH die Versionen 3.3 und 4.0 bestellen. Näheres im [http://www.usbprog.org/index.php/Hardware Projekt-Wiki].&lt;br /&gt;
&lt;br /&gt;
==== AVR-Doper ====&lt;br /&gt;
&lt;br /&gt;
[http://www.obdev.at/products/avrusb/avrdoper.html AVR-Doper] kann neben ISP auch im High-Voltage Serial Mode als [[AVR HV-Programmer]] programmieren. Rein auf Firmware basierende USB-Implementierung. BUS-Powered. Einseitige Platine und damit auch für Selbstbauer geeignet. Verwendet einen Mega8 zur Steuerung des Programmers. Ist kompatibel zu AVR-Studio durch STK500-Protokoll.&lt;br /&gt;
&lt;br /&gt;
==== USB AVR-Lab ====&lt;br /&gt;
&lt;br /&gt;
[http://www.ullihome.de/index.php/Hauptseite#USB_AVR-Lab USB AVR-Lab] besteht aus einer sehr einfachen Hardware, usb wird in Software gemacht. Mit einem Bootloader nebst Applikation kann die Funktion des Lab´s zwischen &lt;br /&gt;
&lt;br /&gt;
*AVRISPmkII kompatiblem Programmer (AVR Studio, Linux, MacOS)&lt;br /&gt;
*JTAGICEmkII kompatibler AVR Programmer (AVR Studio, Linux, MacOS) (keine AVR32, kein Xmega)&lt;br /&gt;
*OpenOCD Interface (sehr viel ARM Controller, PLD´s, FPGA´s)&lt;br /&gt;
*STK500v2 kompatiblem Programmer (AVR Studio)&lt;br /&gt;
*USBasp kompatiblem Programmer (Linux, MacOS)&lt;br /&gt;
*JTAG Boundary Scan Interface + Software&lt;br /&gt;
*RS232/RS485 Wandler&lt;br /&gt;
*I2C Logger&lt;br /&gt;
*I2C Interface (zur benutzung aus eigenen Programmen)&lt;br /&gt;
*Oszi&lt;br /&gt;
*6-Kanal Logik Analyzer (in Entwicklung)&lt;br /&gt;
*Labornetzteil (in Entwicklung)&lt;br /&gt;
&lt;br /&gt;
getauscht werden. Mit der STK500v2 kompatiblen Firmware kann der Programmer direkt aus dem AVR Studio heraus voll kompatibel zum AVR-ISP mkII arbeiten.&lt;br /&gt;
Zusätzlich bietet der Programmer den virtuellen Com Port als Debug Port an solange nicht geflasht wird. Man kann also direkt mit dem Terminalprogramm auf seinen AVR zugreifen über den ISP Adapter.&lt;br /&gt;
Dieser Modus wird von jeder ISP Firmware unterstützt.&lt;br /&gt;
Statusanzeige des Targets (angeschlossen, falsch angeschlossen, nicht angeschlossen), max. 3 Mhz ISP Freq. Das Ganze ist sehr günstig in der Beschaffung (10 Eur Bauteile bei Reichelt + 3,5 Eur Platine von ullihome.de, oder 15 Eur bestückt von ullihome.de)&lt;br /&gt;
&lt;br /&gt;
==== USBtinyISP ====&lt;br /&gt;
&lt;br /&gt;
[http://www.ladyada.net/make/usbtinyisp/ USBtinyISP] ist ein preiswerter (ca. 16$ für die Bauteile) AVR ISP Programmer und SPI Interface auf open-source Basis. Als Software kann z.B. AVRDUDE oder AVRStudio verwendet werden. Der Programmer wurde auf Windows, MacOS X und Ubuntu (ab 9.04) getestet. Bei Adafruit sind auch Selbstbaukits erhältlich.&lt;br /&gt;
Eine miniaturisierte Version findet sich hier [http://www.mikrocontroller.net/articles/AVR-ISP-Stick www.mikrocontroller.net/articles/AVR-ISP-Stick]. Diese ist ab 6,90€ als Bausatz bei [http://www.ehajo.de/Bausaetze/AVR-ISP-Stick eHaJo.de] erhältlich.&lt;br /&gt;
&lt;br /&gt;
==== UCOM-IR ====&lt;br /&gt;
Der [http://www.nibo-roboter.de/wiki/UCOM-IR UCOM-IR] Programmieradapter ist ein kommerzieller Bausatz (ca. 25 €), der auf einem AT90USB162 basiert. Durch die Verwendung des STK500v2 Protokolls kann zur Programmierung sowohl das [[AVR-Studio]] wie auch [[AVRDUDE]] verwendet werden. Zusätzlich hat der Adapter einen IR-Empfänger und zwei Sendedioden, die zur Kommunikation und zur Fernsteuerung verwendet werden können.&lt;br /&gt;
&lt;br /&gt;
==== Selbstbau-Programmer, basierend auf dem vUSB stack ====&lt;br /&gt;
http://www.avrfreaks.net/index.php?name=PNphpBB2&amp;amp;file=viewtopic&amp;amp;t=90498&lt;br /&gt;
&lt;br /&gt;
==== USB-Hub-ISP ====&lt;br /&gt;
HUB ISP - Solving the USB-Only &amp;quot;Chicken or Egg&amp;quot; Problem:&amp;lt;br&amp;gt;&lt;br /&gt;
HUB ISP can write an AVR chip using only a USB hub, one cheap/common logic chip, and a few resistors.&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.pjrc.com/hub_isp/&lt;br /&gt;
&lt;br /&gt;
==== Launchprog ====&lt;br /&gt;
Der [[Launchprog]] ist ein AVR-ISP-Programmer nach der Atmel AVR910-Appnote, der auf einem [http://processors.wiki.ti.com/index.php?title=MSP430_LaunchPad_%28MSP-EXP430G2%29 TI Launchpad 1.4] mit dem beiliegenden [http://www.ti.com/product/msp430g2211 MSP430G2211] und dem beiliegenden Uhrenquarz läuft. Nach außen hin ist der [[Launchprog]] wie ein AVR910 zu verwenden. Allerdings muss die Geschwindigkeit der seriellen Schnittstelle auf 9600 Baud eingestelllt werden.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel der avrdude-Kommandozeile: &amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;avrdude -c avr910 -b 9600 -P &amp;lt;PORT&amp;gt; -p &amp;lt;PART&amp;gt; -U &amp;lt;KOMMANDO&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== mySmartUSB ====&lt;br /&gt;
Der mySmartUSB Programmer von myAVR ist ein kompakter ISP Programmer mit USB Anschluss (der Preis liegt bei 28€). Lt. Hersteller kann er auch für die Kommunikation via UART, TWI, SPI verwendet werden (hab ich noch nicht probiert).&lt;br /&gt;
&lt;br /&gt;
ich aber: Beim Schreiben der Fuse Bits musste ich das Tool myAVR_ProgTool.exe verwenden &lt;br /&gt;
&lt;br /&gt;
Mit avrdude ist das Schreiben der Fuse-Bits mit dem AVR910-Modus möglich.&lt;br /&gt;
 &lt;br /&gt;
avrdude-Kommandozeile :&lt;br /&gt;
&#039;&#039;avrdude -c avr910 -P PORT -p PART -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achtung:&#039;&#039;&#039; Die neuere Version (mySmartUSB MK3) scheint mit der aktuellen Firmwareversion noch große Probleme mit ISP zu haben (siehe Postings im Supportforum: http://myavr.info/myForum/viewforum.php?f=8). Solange diese Probleme nicht ausgemerzt sind, sollte man auf die ältere Version (mySmartUSB MK2) oder ein anderes Produkt ausweichen.&lt;br /&gt;
&lt;br /&gt;
==== mySmartUSB light ====&lt;br /&gt;
&lt;br /&gt;
Preiswerter (ca. 15 €) Programmer im USB-Stick Design von myAVR. Der mySmartUSB light verfügt über eine Auto-Speed Funktion die die Frequenz des Programmers automatisch an die Taktfrequenz des Controllers anpasst.&lt;br /&gt;
Der Programmer kann 5V und 3.3V Systeme programmieren, Treiber gibt es für Windows, Linux und MacOS X und unterstützt wird je nach Firmware-Version das STK500v2 oder AVR910/911 Protokoll.&lt;br /&gt;
&lt;br /&gt;
==== Amadeus-USB ====&lt;br /&gt;
&lt;br /&gt;
[http://home.arcor.de/bernhard.michelis Amadeus-USB] ist ein ISP-Programmer zum Selberbauen. Er unterstützt eine Vielzahl von AVRs und verfügt über ein eigenes User-Interface. Der Programmer enthält einen einfach zu bedienenden Fuse-Editor. Sollte man einmal die falschen Clock-Einstellungen vorgenommen haben, ist das kein Problem, da der Programmer über eine Takterzeugung verfügt, mit der man den AVR wiederbeleben kann.&lt;br /&gt;
Auch wer mit niedrigen Taktraten arbeitet (z.&amp;amp;nbsp;B. 32kHz), kann einen ATmega64 in ca. 4,8 Sekunden programmieren und vergleichen. Darüber hinaus kann mit geeigneten Makros die Programmausführung getracet werden. Die maximale Programmierdauer beträgt bei einem ATmega64 mit 16MHz Quarz 3,1 Sekunden, wenn der gesamte Speicher geschrieben und verglichen werden muss. Ist das Programm kleiner, geht es natürlich schneller ;-) Für einen ATTiny2313 oder ATTiny24 braucht er weniger als eine Sekunde.&lt;br /&gt;
&lt;br /&gt;
==== AVR-ISP-Stick ====&lt;br /&gt;
&lt;br /&gt;
Der [http://www.ehajo.de/Bausaetze/AVR-ISP-Stick AVR-ISP-Stick] ist ein OpenSource/CC-Projekt und eine sehr günstige (6,90€!) Alternative zu den restlichen Programmieradaptern auf dem Markt. Er ist als Bausatz erhältlich und bereits über 100 mal im produktiven Einsatz.&lt;br /&gt;
&lt;br /&gt;
==== µISP-Stick ====&lt;br /&gt;
&lt;br /&gt;
Der [http://www.ehajo.de/Bausaetze/µISP-Stick µISP-Stick] ist die Weiterentwicklung des AVR-ISP-Sticks. Für 9,90€ bekommt man hier einen vorbestückten Bausatz an dem nur noch die bedrahteten Stecker angelötet werden müssen.&lt;br /&gt;
&lt;br /&gt;
==== Arduino ISP Shield ====&lt;br /&gt;
&lt;br /&gt;
Ein Arduino-Board kann mit dem entsprechenden Sketch und einfachen Jumperwires oder einem komfortablen Shield benutzt werden, um AVRs ohne [[Bootloader]] zu flashen. Eine Anleitung dazu wird bei [http://www.open-electronics.org/arduino-isp-in-system-programming-and-stand-alone-circuits/ www.open-electronics.org] und [http://hlt.media.mit.edu/?p=1229 hlt.media.mit.edu] (via [http://www.mikrocontroller.net/topic/252620#2598960]) gegeben.&lt;br /&gt;
&lt;br /&gt;
==== aTeVaL-Board ====&lt;br /&gt;
&lt;br /&gt;
Das [http://www.ehajo.de/Bausaetze/aTeVaL aTeVaL-Board] ist die Weiterentwicklung des Atmel Evalboards von Pollin. Damit lassen sich problemlos alle bedrahteten AVR-Controller programmieren. Der Programmer ist ein AVR-ISP-mkii-Clon und somit 100% kompatibel mit dem Atmelstudio. Für eigene Platinen ist ein 6- und 10-poliger ISP-Stecker vorhanden.&lt;br /&gt;
&lt;br /&gt;
==== USP-Stick ====&lt;br /&gt;
&lt;br /&gt;
Der [http://www.ehajo.de/Bausaetze/USP-Stick USP-Stick] ist ein sehr kleiner Programmieradapter, der in ein USB-A-Gehäuse passt. Er beruht auf der bewährten Hardware des AVR-ISP-Sticks (attiny2313 + quarz) und ist für 4,90€ erhältlich.&lt;br /&gt;
&lt;br /&gt;
==== guloprog USB-Programmer und Signalwandler ====&lt;br /&gt;
&lt;br /&gt;
Unter dem Namen [https://guloshop.de/shop/Mikrocontroller-Programmierung/guloprog-der-Programmer-von-guloshop-de::70.html guloprog] wird eine kleine Platine angeboten, die einen USB-Programmer und einen [https://guloshop.de/shop/USB-TTL-ADC-PWM-Signalwandler:::10.html Signalwandler] vereint. Der Programmer wird per USB angeschlossen und meldet sich als Fischl-kompatibler usbasp.&lt;br /&gt;
&lt;br /&gt;
Die Signalwandlerfunktion bietet voneinander unabhängige einfache Schalt- und Abfragemöglichkeiten für die vier sonst zum Programmieren verwendeten Anschlüsse. Jede Leitung kann per Tastatur-Kommando einen Ausgang auf 0 Volt oder auf 5 Volt setzen oder &amp;quot;dimmen&amp;quot; (PWM in Schritten von 0 bis 100%). Alle Anschlüsse können als Digital-Eingang verwendet werden, drei davon wahlweise als Analog-Eingang. Die gemessenen Werte lassen sich ebenfalls per Kommandozeile abfragen und auf diese Weise leicht in andere PC-Programme einbinden (Linux, Mac, Windows).&lt;br /&gt;
&lt;br /&gt;
Herzstück ist ein ATtiny85, der im Gegensatz zu allen ATmegas und fast allen ATtinys auch über den internen RC-Oszillator mit 16 MHz betrieben werden kann. Ein Quarz ist daher nicht erforderlich. Die für V-USB erforderliche Genauigkeit erreicht der Programmer über einen Synchronisationsschritt, der bei jedem Start automatischen durchlaufen wird. Die Firmware steht unter einer freien Lizenz, es werden nur sehr wenige Bauteile benötigt, so dass sich dieser Programmer auch recht gut für den Nachbau eignet. Schaltungs- und softwaretechnisch besteht praktisch Baugleichheit zum [[Bierdeckel-Programmer]].&lt;br /&gt;
&lt;br /&gt;
=== Standalone ===&lt;br /&gt;
&lt;br /&gt;
Die folgenden Geräte verfügen über interne Speicher, auf denen der zu programmierende Maschinencode abgelegt werden kann. Zum &amp;quot;flashen&amp;quot; selbst ist keine Verbindung zwischen Arbeitsplatzrechner bzw. Notebook und Programmiergerät erforderlich. &lt;br /&gt;
&lt;br /&gt;
==== roloFlash (kommerziell) ====&lt;br /&gt;
[http://www.halec.de/roloFlash/?ref=wiki_isp.mikrocontroller.net roloFlash] wird mit einer microSD-Karte bestückt, die die zu flashenden Daten enthält. Dadurch können unabhängig von einem PC an jedem beliebigen Ort AVR-Controller geflasht werden.&lt;br /&gt;
&lt;br /&gt;
In einem ersten Schritt wird die microSD-Karte vorbereitet. Durch die auf dem roloFlash eingebaute Scriptsprache roloBasic lässt sich der gewünschte Ablauf sehr flexibel festlegen.&lt;br /&gt;
&lt;br /&gt;
Nun kann roloFlash irgendwo anders ohne PC AVR-Controller flashen. Dabei geben 5 zweifarbigen LEDs Auskunft über den Fortschritt bzw. das Ergebnis des Flash-Prozesses. Fehlbedienungen sind unmöglich, da es keine Bedienelemente gibt.&lt;br /&gt;
&lt;br /&gt;
Einsatzgebiete:&lt;br /&gt;
* Produktion&lt;br /&gt;
* Fehlbedienungssichere Updates beim Kunden&lt;br /&gt;
&lt;br /&gt;
==== TheCableAVR-SD (kommerziell) ====&lt;br /&gt;
[http://www.priio.com/productcart/pc/viewPrd.asp?idcategory=6&amp;amp;idproduct=88 TheCableAVR-SD]  works by saving the &amp;quot;ISP&amp;quot;, &amp;quot;HEX&amp;quot; and &amp;quot;EEP&amp;quot; files required for part programming from the PC application onto an SD-Card and inserting it into TheCableAVR-SD. This programmer is stand alone, making it very handy for field software updates and production programming. &lt;br /&gt;
&lt;br /&gt;
Wird 4/2012 scheinbar nicht mehr verkauft ([http://www.mikrocontroller.net/topic/257278#2657606 Forumsbeitrag Priio AVR Programmer?]).&lt;br /&gt;
&lt;br /&gt;
==== ButtLoad ====&lt;br /&gt;
[http://www.fourwalledcubicle.com/ButtLoad.php ButtLoad] is based on the Atmel [[AVR Butterfly]] development board. ButtLoad is specially written firmware which converts a low-cost official Atmel Butterfly evaluation board into a smart ISP programmer for other members of the Atmel AVR family. It supports the entire AVR range, and allows for a complete program (including EEP, HEX, Fuse and Lock Bytes) to be stored and later programmed into a device from the Butterfly&#039;s on board non-volatile memory.&lt;br /&gt;
&lt;br /&gt;
[http://www.fourwalledcubicle.com/ButtLoad.php ButtLoad] basiert auf dem Atmel-[[AVR Butterfly]]-development board und ist eine spezielle Firmware, die ein (billiges) Atmel-Butterfly-Board in einen vollwertigen ISP-Programmierer für andere Controller der Atmel-AVR-Familie verwandelt. Es unterstützt den gesamten AVR-Bereich und erlaubt, ein Programm komplett mit EEP, HEX, Sicherungs- und Lock-Bytes im nichtflüchtigen on-board-Speicher des Butterflys abzulegen und dann von dort heraus die Controller zu programmieren.&lt;br /&gt;
&lt;br /&gt;
==== PalmAVR ====&lt;br /&gt;
* siehe [http://www.mikrocontroller.net/topic/77870#648376 Forenbeitrag]&lt;br /&gt;
&lt;br /&gt;
==== ISPnub (Open Source) ====&lt;br /&gt;
[http://www.fischl.de/ispnub/ ISPnub - Stand-alone AVR In-System-Programmer Module] besteht aus einem AVR in dessen Flash ein Programmierskript geladen wird. Der eigentliche Programmiervorgang wird über einen Tastendruck ausgelöst. Die Zahl der Programmierzyklen kann beschränkt werden (z.B. auf ein Fertigungslos beschränkt).&lt;br /&gt;
&lt;br /&gt;
==== AVR-ISP500, AVR-ISP500 tiny ====&lt;br /&gt;
von Olimex, siehe&lt;br /&gt;
* [http://www.olimex.com/dev/avr-isp500-iso.html Herstellerseite zum ISP500] &lt;br /&gt;
* [http://www.olimex.com/dev/avr-isp500-tiny.html Herstellerseite zum ISP500-TINY]&lt;br /&gt;
&lt;br /&gt;
=== Geschwindigkeitsvergleich ===&lt;br /&gt;
&lt;br /&gt;
Im Rahmen einer Forendiskussion entstand die folgende Messung, die&lt;br /&gt;
einige der möglichen Programmer in ihrer Geschwindigkeit vergleicht.&lt;br /&gt;
Mit einbezogen in den Vergleich wurde neben originalen&lt;br /&gt;
Atmel-ISP-Werkzeugen noch Werkzeuge für [[JTAG#AVR_JTAG|JTAG]].&lt;br /&gt;
&lt;br /&gt;
Die Testdatei war 29704 Bytes groß.  Target ist ein ATmega6490, der&lt;br /&gt;
mit 8 MHz vom RC-Oszillator getaktet wird.  Das alles wurde mit einem&lt;br /&gt;
AVRDUDE 5.5 getestet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Programmer     Parameter         Zeit fürs&lt;br /&gt;
                              Schreiben  Lesen&lt;br /&gt;
-----------------------------------------------&lt;br /&gt;
JTAG ICE mkII  default        2,58 s     3,27 s&lt;br /&gt;
JTAG           (4 MHz)&lt;br /&gt;
-----------------------------------------------&lt;br /&gt;
JTAG ICE mkII  1 MHz          8,34 s     8,51 s   (**)&lt;br /&gt;
ISP&lt;br /&gt;
-----------------------------------------------&lt;br /&gt;
AVRISP mkII    250 kHz        5,37 s     5,46 s&lt;br /&gt;
               1 MHz          2,45 s     2,45 s&lt;br /&gt;
               2 MHz          1,89 s     1,99 s&lt;br /&gt;
-----------------------------------------------&lt;br /&gt;
STK500         900 kHz        5,84 s     3,49 s&lt;br /&gt;
               (schnellstes)&lt;br /&gt;
-----------------------------------------------&lt;br /&gt;
AVR Dragon     default        2,81 s     3,49 s&lt;br /&gt;
JTAG           (4 MHz)&lt;br /&gt;
-----------------------------------------------&lt;br /&gt;
AVR Dragon     1 MHz          8,34 s     8,64 s&lt;br /&gt;
ISP            2 MHz          -          -        (*)&lt;br /&gt;
-----------------------------------------------&lt;br /&gt;
Parallelport-  keine Delay   13,20 s    12,45 s   (**)&lt;br /&gt;
Dongle &amp;quot;alf&amp;quot;   CPU 900 MHz&lt;br /&gt;
-----------------------------------------------&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(*) Benutzung unmöglich, weder Fuses noch Signature zuverlässig&lt;br /&gt;
lesbar.&lt;br /&gt;
&lt;br /&gt;
(**) Fuses und Signature OK, aber das programmierte Ergebnis ist&lt;br /&gt;
fehlerhaft (verify errors)&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.myplace.nu/avr/yaap/ yaap] (Windows, diverse Parallelport-Programmer, GUI)&lt;br /&gt;
* [[Pony-Prog Tutorial|PonyProg]] (Linux, Windows, diverse Programmer für den parallelen und seriellen Port, GUI, am seriellen Port nur &amp;quot;Statuspinwackler&amp;quot; nach dem Schaltplan auf der lancos-Seite)&lt;br /&gt;
* [http://www.soft-land.de/index.php?page=avrburner AVRBurner] Ponyprog ähnliche Oberfläche für AVRDUDE.&lt;br /&gt;
* [http://www.nongnu.org/avrdude AVRDUDE] (Unix, Linux, Windows, praktisch alle Programmer, leicht erweiterbar auf andere Parallelportadapter-Anschlussbelegungen, Kommandozeile, auch für AVR Butterfly über dessen vorinstallierten Bootloader/Firmware-Uploader) siehe im Wiki [[AVRDUDE]]&lt;br /&gt;
* [http://savannah.nongnu.org/projects/uisp uisp] (Unix, Linux, Windows, praktisch alle Programmer, Kommandozeile, nicht mehr gepflegt).&lt;br /&gt;
* AVR-Studio (nur Programmieradapter mit integriertem Controller für den seriellen Port, z.&amp;amp;nbsp;B. AVR910, ATMEL AVRISP und STK500)&lt;br /&gt;
* [http://www.mcselec.com Eingebauter Programmer im Bascom-Basic Compiler]&lt;br /&gt;
* [http://esnips.com/web/AtmelAVR AvrOspII] - GUI Open Source programmer based on Atmels Application note AVR911.&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/60817 Forumsbeitrag] - Wie man Ponyprog aus dem AVR-Studio heraus nutzt&lt;br /&gt;
* [http://www.cadmaniac.org/projectMain.php?projectName=kontrollerlab Kontrollerlab] - (Linux), Grafische Oberfläche zu avr-gcc, uisp, avrdude und kate mit built-in debugger und serial terminal. Einfach verständlich und aufgeräumt (im KDE-Stil)&lt;br /&gt;
* [http://shop.myavr.de/index.php?sp=download.sp.php&amp;amp;suchwort=dl112 myAVRProgTool] - Freies Programmiertool und zusätzlich auch als DUDE-GUI geeignet, einfach zu bedienen&lt;br /&gt;
* [http://dybkowski.net/isp ISP Programmer] von Adam Dybkowski (Opensource, Windows 95, 98, Me, NT 4.0, 2000, XP, 2003, Vista and Windows 7 (32-bit and 64-bit versions))&lt;br /&gt;
* [http://andreas-weschenfelder.de.vu/Homepage/Version_3/index.php?section=PC_Delphi_FT2232_AtmelISP.html FT2232 ISP Flasher] von Andreas Weschenfelder (Windows 95, 98, Me, NT 4.0, 2000, XP, 2003, Vista and Windows 7 (32-bit and 64-bit versions)), verwendet das MPSSE Protokoll der FTDI Chips zur ISP Programmierung&lt;br /&gt;
* [http://andreas-weschenfelder.de.vu/Homepage/Version_3/index.php?section=Android_FTDI_AVR_Programmer.html Atmel ISP Flasher for Android] von Andreas Weschenfelder (Android 4.1.1), verwendet das MPSSE Protokoll der FTDI Chips zur ISP Programmierung, KEINE root-Rechte erforderlich&lt;br /&gt;
&lt;br /&gt;
== ISP-Pins am AVR auch für andere Zwecke nutzen ==&lt;br /&gt;
&lt;br /&gt;
Bei einem Programmer mit eingebautem [[Ausgangsstufen_Logik-ICs#Tristate|Tristate]]-Treiber (z.&amp;amp;nbsp;B. 74HC(T)244) werden die Leitungen MISO, MOSI und SCK hochohmig geschaltet wenn die Programmierung beendet ist, d.h. sie beeinflussen die Schaltung nicht. Man kann die betreffenden Pins am AVR also relativ problemlos als Ausgänge verwenden, wenn man darauf achtet, dass die daran angeschlossene Peripherie durch die Programmierimpulse keinen Schaden nehmen kann. Als Eingänge sollte man die Pins allerdings nicht verwenden, da ein angeschlossener Taster zum Beispiel die Programmierimpulse kurzschließen würde, wenn er gedrückt ist.&lt;br /&gt;
&lt;br /&gt;
Atmel empfiehlt in der Application Note [http://www.atmel.com/images/atmel-2521-avr-hardware-design-considerations_applicationnote_avr042.pdf AVR042: AVR Hardware Design Considerations (PDF)] Peripherie an der SPI-Schnittstelle, bei gleichzeitiger Verwendung der Schnittstelle als In-System-Programmieranschluss, über Widerstände anzuschliessen.&lt;br /&gt;
&lt;br /&gt;
Ein Widerstand in SCK ist in diesem Zusammenhang aber nur dann sinnvoll, wenn am AVR ein externer SPI-Master hängt, denn nur dann kann ein Konflikt zwischen diesem SCK treibenden Master und dem ebenfalls SCK treibenden ISP auftreten. Ist der AVR hingegen wie üblich selbst der Master, dann ist ein Konflikt ausgeschlossen. Das gleiche gilt für MOSI.&lt;br /&gt;
&lt;br /&gt;
Bei MISO kann ein Konflikt nur auftreten, wenn diese Leitung vom Slave in der ISP-Phase aktiv treibend sein kann. Das ist beispielsweise bei Porterweiterungen (Inputs) mit Schieberegistern der Fall, wenn der&lt;br /&gt;
Datenausgang des Schieberegisters nicht passivierbar ist (tristate, Z-state). Dann ist ein Serienwiderstand in MISO sinnvoll.&lt;br /&gt;
&lt;br /&gt;
Normale SPI-Slaves mit CS-Leitung, wie ADCs, passivieren jedoch ihren Datenausgang wenn CS inaktiv ist. In diesem Fall ist ein Serienwiderstand in MISO unnötig, es muss nur über schwache Pullup-Widerstände an allen relevanten CS Leitungen sichergestellt sein, dass sie während Reset hochgezogen werden. Manche SPI-Slaves haben die bereits an Bord. Die internen Pullups im AVR sind keine Hilfe, da sie während Reset abgeschaltet sind.&lt;br /&gt;
&lt;br /&gt;
siehe auch [http://www.mikrocontroller.net/articles/AVR_HV-Programmer AVR HV-Programmer]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Programmer und -Bootloader| ]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR-GCC-Tutorial/LCD-Ansteuerung&amp;diff=86429</id>
		<title>AVR-GCC-Tutorial/LCD-Ansteuerung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR-GCC-Tutorial/LCD-Ansteuerung&amp;diff=86429"/>
		<updated>2015-01-03T10:36:54Z</updated>

		<summary type="html">&lt;p&gt;Maybee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Das LCD und sein Controller==&lt;br /&gt;
&lt;br /&gt;
Die meisten Text-LCDs verwenden den Controller [[HD44780]] oder einen kompatiblen (z.&amp;amp;nbsp;B. KS0070) und haben 14 oder 16 Pins. Hier ist die häufigste Anschluss-Belegung angegeben. &lt;br /&gt;
&lt;br /&gt;
;Achtung: Es gibt Displays mit abweichender Anschluss-Belegung, z.B. TC1602E (Pollin 120420). Falscher Anschluss kann zur Zerstörung führen! Daher immer das zugehörige Datenblatt zu Rate ziehen. Einzelheiten unter Artikel zum Controller [[HD44780]].&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Pin # || Bezeichnung || Funktion&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| Vss  || GND (beim TC1602E Vdd=Vcc)&lt;br /&gt;
|-&lt;br /&gt;
! 2&lt;br /&gt;
| Vdd/Vcc  || 5V  (beim TC1602E Vss=Gnd)&lt;br /&gt;
|-&lt;br /&gt;
! 3&lt;br /&gt;
| Vee  || Kontrastspannung (0V bis 5V)&lt;br /&gt;
|-&lt;br /&gt;
! 4&lt;br /&gt;
| RS   || Register Select (Befehle/Daten)&lt;br /&gt;
|-&lt;br /&gt;
! 5&lt;br /&gt;
| RW   || Read/Write&lt;br /&gt;
|-&lt;br /&gt;
! 6&lt;br /&gt;
| E&lt;br /&gt;
| Enable&lt;br /&gt;
|-&lt;br /&gt;
! 7&lt;br /&gt;
| DB0  ||rowspan=&amp;quot;8&amp;quot;| Datenbits 0&amp;amp;minus;7&lt;br /&gt;
|-&lt;br /&gt;
! 8&lt;br /&gt;
| DB1&lt;br /&gt;
|-&lt;br /&gt;
! 9&lt;br /&gt;
| DB2&lt;br /&gt;
|-&lt;br /&gt;
! 10&lt;br /&gt;
| DB3&lt;br /&gt;
|-&lt;br /&gt;
! 11&lt;br /&gt;
| DB4&lt;br /&gt;
|-&lt;br /&gt;
! 12&lt;br /&gt;
| DB5&lt;br /&gt;
|-&lt;br /&gt;
! 13&lt;br /&gt;
| DB6&lt;br /&gt;
|-&lt;br /&gt;
! 14&lt;br /&gt;
| DB7&lt;br /&gt;
|-&lt;br /&gt;
! 15&lt;br /&gt;
| A   || LED-Beleuchtung, Anode&lt;br /&gt;
|-&lt;br /&gt;
! 16&lt;br /&gt;
| K   || LED-Beleuchtung, Kathode&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Warnung|&lt;br /&gt;
;Achtung: Unbedingt von der richtigen Seite zu zählen anfangen! Meistens ist neben Pin 1 eine kleine 1 auf der LCD-Platine. Ansonsten im Datenblatt nachschauen! Oft ist Pin 1 auch durch ein rechteckiges statt rundes Pad gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
:Bei LCDs mit 16-poligem Anschluss sind die beiden letzten Pins für die Hintergrundbeleuchtung reserviert. Hier unbedingt das Datenblatt zu Rate ziehen, die beiden Anschlüsse sind je nach Hersteller oft anders beschaltet. Falls kein Datenblatt vorliegt, kann man mit einem Durchgangsprüfer feststellen, welcher Anschluss mit Masse (GND) verbunden ist.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Vss wird ganz einfach an GND angeschlossen und Vcc an 5V. Vee kann man testweise auch an GND legen. Wenn das LCD dann zu dunkel sein sollte muss man ein 10k-Potentiometer zwischen GND und 5V schalten, mit dem Schleifer an Vee: &lt;br /&gt;
&lt;br /&gt;
[[Bild:LCD_Vee.gif]]&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei verschiedene Möglichkeiten zur Ansteuerung eines solchen Displays: den &#039;&#039;&#039;8-bit-&#039;&#039;&#039; und den &#039;&#039;&#039;4-bit-&#039;&#039;&#039;Modus.&lt;br /&gt;
* Für den &#039;&#039;&#039;8-bit-Modus&#039;&#039;&#039; werden (wie der Name schon sagt) alle acht Datenleitungen zur Ansteuerung verwendet, somit kann durch einen Zugriff immer ein ganzes Byte übertragen werden.&lt;br /&gt;
* Der &#039;&#039;&#039;4-bit-Modus&#039;&#039;&#039; verwendet nur die oberen vier Datenleitungen (&#039;&#039;&#039;DB4-DB7&#039;&#039;&#039;). Um ein Byte zu übertragen braucht man somit zwei Zugriffe, wobei zuerst das höherwertige &#039;&#039;&#039;&amp;quot;Nibble&amp;quot;&#039;&#039;&#039; (= 4 Bits), also Bit 4 bis Bit 7 übertragen wird und dann das niederwertige, also Bit 0 bis Bit 3. Die unteren Datenleitungen des LCDs, die beim Lesezyklus Ausgänge sind, lässt man offen (siehe Datasheets, z.&amp;amp;nbsp;B. vom KS0070).&lt;br /&gt;
&lt;br /&gt;
Der 4-bit-Modus hat den Vorteil, dass man 4 IO-Pins weniger benötigt als beim 8-bit-Modus, weshalb ich mich hier für eine Ansteuerung mit 4bit entschieden habe. &lt;br /&gt;
&lt;br /&gt;
Neben den vier Datenleitungen (DB4, DB5, DB6 und DB7) werden noch die Anschlüsse &#039;&#039;&#039;RS&#039;&#039;&#039;, &#039;&#039;&#039;RW&#039;&#039;&#039; und &#039;&#039;&#039;E&#039;&#039;&#039; (ist in manchen Unterlagen auch &#039;&#039;&#039;EN&#039;&#039;&#039;  für &#039;&#039;Enable&#039;&#039; abgekürzt) benötigt. &lt;br /&gt;
&lt;br /&gt;
* Über &#039;&#039;&#039;RS&#039;&#039;&#039; wird ausgewählt, ob man einen Befehl oder ein Datenbyte an das LCD schicken möchte. Ist RS Low, dann wird das ankommende Byte als Befehl interpretiert, ist RS high, dann wird das Byte auf dem LCD angezeigt. &lt;br /&gt;
* &#039;&#039;&#039;RW&#039;&#039;&#039; legt fest, ob geschrieben oder gelesen werden soll. High bedeutet lesen, low bedeutet schreiben. Wenn man RW auf lesen einstellt und RS auf Befehl, dann kann man das &#039;&#039;&#039;Busy-Flag&#039;&#039;&#039; an DB7 lesen, das anzeigt, ob das LCD den vorhergehenden Befehl fertig verarbeitetet hat (diese Methode u.a. in der LCD-Library von Peter Fleury verwendet). Ist RS auf Daten eingestellt, dann kann man z.&amp;amp;nbsp;B. den Inhalt des Displays lesen - was jedoch nur in den wenigsten Fällen Sinn macht. Deshalb kann man RW dauerhaft auf low lassen (= an GND anschließen), so dass man noch ein IO-Pin am Controller einspart. Der Nachteil ist, dass man dann das Busy-Flag nicht lesen kann, weswegen man nach jedem Befehl vorsichtshalber ein paar Mikrosekunden warten sollte, um dem LCD Zeit zum Ausführen des Befehls zu geben. Dummerweise schwankt die Ausführungszeit von Display zu Display und ist auch von der Betriebsspannung abhängig. Für professionellere Sachen also lieber den IO-Pin opfern und Busy abfragen.&lt;br /&gt;
* Der &#039;&#039;&#039;E&#039;&#039;&#039; Anschluss schließlich signalisiert dem LCD, dass die übrigen Datenleitungen jetzt korrekte Pegel angenommen haben und es die gewünschten Daten von den Datenleitungen bzw. Kommandos von den Datenleitungen übernehmen kann.&lt;br /&gt;
&lt;br /&gt;
== Anschluss an den Controller ==&lt;br /&gt;
&lt;br /&gt;
Jetzt da wir wissen, welche Anschlüsse das LCDs benötigt, können wir das LCD mit dem Mikrocontroller verbinden: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;ACHTUNG: Es gibt Displays mit abweichender Anschluss-Belegung, falscher Anschluss kann zur Zerstörung führen! Daher immer das zugehörige Datenblatt zu Rate ziehen.&amp;lt;/span&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Einzelheiten unter [http://www.mikrocontroller.net/articles/HD44780 Artikel zum Controller HD44780]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Pin #-LCD  || Bezeichnung-LCD || Pin-µC&lt;br /&gt;
|-&lt;br /&gt;
!1&lt;br /&gt;
| Vss || GND&lt;br /&gt;
|-&lt;br /&gt;
!2&lt;br /&gt;
| Vcc || 5V&lt;br /&gt;
|-&lt;br /&gt;
!3&lt;br /&gt;
| Vee || GND oder Poti (siehe oben)&lt;br /&gt;
|-&lt;br /&gt;
!4&lt;br /&gt;
| RS  || PD4 am AVR&lt;br /&gt;
|-&lt;br /&gt;
!5&lt;br /&gt;
| RW  || GND&lt;br /&gt;
|-&lt;br /&gt;
!6&lt;br /&gt;
| E   || PD5 am AVR&lt;br /&gt;
|-&lt;br /&gt;
!7&lt;br /&gt;
| DB0 ||rowspan=&amp;quot;4&amp;quot;| offen (unbenutzt)&lt;br /&gt;
|-&lt;br /&gt;
!8&lt;br /&gt;
| DB1&lt;br /&gt;
|-&lt;br /&gt;
!9&lt;br /&gt;
| DB2&lt;br /&gt;
|-&lt;br /&gt;
!10&lt;br /&gt;
| DB3&lt;br /&gt;
|-&lt;br /&gt;
!11&lt;br /&gt;
| DB4 || PD0 am AVR&lt;br /&gt;
|-&lt;br /&gt;
!12&lt;br /&gt;
| DB5 || PD1 am AVR&lt;br /&gt;
|-&lt;br /&gt;
!13&lt;br /&gt;
| DB6 || PD2 am AVR&lt;br /&gt;
|-&lt;br /&gt;
!14&lt;br /&gt;
| DB7 || PD3 am AVR&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Wenn man die Steuerleitungen EN und RS auf Pins an einem anderen Port legen möchte, kann man so wie in diesem [http://www.mikrocontroller.net/topic/88543#751982 Forumsbeitrag] oder wie im Artikel [[Erweiterte LCD-Ansteuerung]] vorgehen.&lt;br /&gt;
&lt;br /&gt;
Ok, alles ist verbunden, wenn man jetzt den Strom einschaltet sollten ein oder zwei schwarze Balken auf dem Display angezeigt werden. Erscheint trotz korrektem Anschluss nichts auf dem Display, so kann das auch am Kontrast des LCDs liegen. Die Balken werden dann zwar theoretisch angezeigt, sind aber nicht sichtbar, weil die Kontrastspannung zu hoch ist. Abhilfe schafft es hier, wenn man die Spannung am Schleifer des Potis nachmisst und in Richtung 0V verstellt. Zwischen 1V und 0V treten die Balken dann meist hervor.&lt;br /&gt;
Doch wie bekommt man jetzt die Befehle und Daten in das Display?&lt;br /&gt;
&lt;br /&gt;
== Programmierung ==&lt;br /&gt;
&lt;br /&gt;
=== Die LCD Routinen ===&lt;br /&gt;
&lt;br /&gt;
Der folgende Satz von Ansteuerroutinen für ein Text-LCD ist in der Datei &#039;&#039;&#039;lcd-routines.c&#039;&#039;&#039; zusammengefasst. Diese Datei muss man beim Einrichten zusätzlich zum eigenen Hauptprogramm in sein Projekt aufnehmen. Dies geschieht beim AVR Studio unter Source Files im Fenster AVR GCC oder bei WinAVR im Makefile (z.&amp;amp;nbsp;B. durch SRC += lcd-routines.c). &lt;br /&gt;
&lt;br /&gt;
Wichtig ist außerdem, dass die Optimierung bei der Compilierung eingeschaltet ist, sonst stimmen die Zeiten der Funktionen _delay_us() und _delay_ms() nicht und der Code wird wesentlich länger (Siehe Dokumentation der libc im WinAVR).&lt;br /&gt;
&lt;br /&gt;
Als weitere Datei ist die Includedatei &#039;&#039;&#039;lcd-routines.h&#039;&#039;&#039; notwendig, die im Hauptprogramm und in &#039;&#039;&#039;lcd-routines.c&#039;&#039;&#039; eingebunden wird. Die Anpassung der Pinbelegung etc. macht man in dieser Datei.&lt;br /&gt;
&lt;br /&gt;
==== Datei &#039;&#039;&#039;lcd-routines.h&#039;&#039;&#039; ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus&lt;br /&gt;
// http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung&lt;br /&gt;
//&lt;br /&gt;
 &lt;br /&gt;
#ifndef LCD_ROUTINES_H&lt;br /&gt;
#define LCD_ROUTINES_H&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Hier die verwendete Taktfrequenz in Hz eintragen, wichtig!&lt;br /&gt;
 &lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
#define F_CPU 8000000&lt;br /&gt;
#endif&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Pinbelegung für das LCD, an verwendete Pins anpassen&lt;br /&gt;
// Alle LCD Pins müssen an einem Port angeschlossen sein und die 4&lt;br /&gt;
// Datenleitungen müssen auf aufeinanderfolgenden Pins liegen&lt;br /&gt;
 &lt;br /&gt;
//  LCD DB4-DB7 &amp;lt;--&amp;gt;  PORTD Bit PD0-PD3&lt;br /&gt;
#define LCD_PORT      PORTD&lt;br /&gt;
#define LCD_DDR       DDRD&lt;br /&gt;
#define LCD_DB        PD0&lt;br /&gt;
 &lt;br /&gt;
//  LCD RS      &amp;lt;--&amp;gt;  PORTD Bit PD4     (RS: 1=Data, 0=Command)&lt;br /&gt;
#define LCD_RS        PD4&lt;br /&gt;
 &lt;br /&gt;
//  LCD EN      &amp;lt;--&amp;gt;  PORTD Bit PD5     (EN: 1-Impuls für Daten)&lt;br /&gt;
#define LCD_EN        PD5&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// LCD Ausführungszeiten (MS=Millisekunden, US=Mikrosekunden)&lt;br /&gt;
 &lt;br /&gt;
#define LCD_BOOTUP_MS           15&lt;br /&gt;
#define LCD_ENABLE_US           20&lt;br /&gt;
#define LCD_WRITEDATA_US        46&lt;br /&gt;
#define LCD_COMMAND_US          42&lt;br /&gt;
 &lt;br /&gt;
#define LCD_SOFT_RESET_MS1      5&lt;br /&gt;
#define LCD_SOFT_RESET_MS2      1&lt;br /&gt;
#define LCD_SOFT_RESET_MS3      1&lt;br /&gt;
#define LCD_SET_4BITMODE_MS     5&lt;br /&gt;
 &lt;br /&gt;
#define LCD_CLEAR_DISPLAY_MS    2&lt;br /&gt;
#define LCD_CURSOR_HOME_MS      2&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Zeilendefinitionen des verwendeten LCD&lt;br /&gt;
// Die Einträge hier sollten für ein LCD mit einer Zeilenlänge von 16 Zeichen passen&lt;br /&gt;
// Bei anderen Zeilenlängen müssen diese Einträge angepasst werden&lt;br /&gt;
 &lt;br /&gt;
#define LCD_DDADR_LINE1         0x00&lt;br /&gt;
#define LCD_DDADR_LINE2         0x40&lt;br /&gt;
#define LCD_DDADR_LINE3         0x10&lt;br /&gt;
#define LCD_DDADR_LINE4         0x50&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Initialisierung: muss ganz am Anfang des Programms aufgerufen werden.&lt;br /&gt;
void lcd_init( void );&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// LCD löschen&lt;br /&gt;
void lcd_clear( void );&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Cursor in die 1. Zeile, 0-te Spalte&lt;br /&gt;
void lcd_home( void );&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Cursor an eine beliebige Position &lt;br /&gt;
void lcd_setcursor( uint8_t spalte, uint8_t zeile );&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Ausgabe eines einzelnen Zeichens an der aktuellen Cursorposition &lt;br /&gt;
void lcd_data( uint8_t data );&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Ausgabe eines Strings an der aktuellen Cursorposition &lt;br /&gt;
void lcd_string( const char *data );&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Definition eines benutzerdefinierten Sonderzeichens.&lt;br /&gt;
// data muss auf ein Array[8] mit den Zeilencodes des zu definierenden Zeichens&lt;br /&gt;
// zeigen&lt;br /&gt;
void lcd_generatechar( uint8_t code, const uint8_t *data );&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Ausgabe eines Kommandos an das LCD.&lt;br /&gt;
void lcd_command( uint8_t data );&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// LCD Befehle und Argumente.&lt;br /&gt;
// Zur Verwendung in lcd_command&lt;br /&gt;
 &lt;br /&gt;
// Clear Display -------------- 0b00000001&lt;br /&gt;
#define LCD_CLEAR_DISPLAY       0x01&lt;br /&gt;
 &lt;br /&gt;
// Cursor Home ---------------- 0b0000001x&lt;br /&gt;
#define LCD_CURSOR_HOME         0x02&lt;br /&gt;
 &lt;br /&gt;
// Set Entry Mode ------------- 0b000001xx&lt;br /&gt;
#define LCD_SET_ENTRY           0x04&lt;br /&gt;
 &lt;br /&gt;
#define LCD_ENTRY_DECREASE      0x00&lt;br /&gt;
#define LCD_ENTRY_INCREASE      0x02&lt;br /&gt;
#define LCD_ENTRY_NOSHIFT       0x00&lt;br /&gt;
#define LCD_ENTRY_SHIFT         0x01&lt;br /&gt;
 &lt;br /&gt;
// Set Display ---------------- 0b00001xxx&lt;br /&gt;
#define LCD_SET_DISPLAY         0x08&lt;br /&gt;
 &lt;br /&gt;
#define LCD_DISPLAY_OFF         0x00&lt;br /&gt;
#define LCD_DISPLAY_ON          0x04&lt;br /&gt;
#define LCD_CURSOR_OFF          0x00&lt;br /&gt;
#define LCD_CURSOR_ON           0x02&lt;br /&gt;
#define LCD_BLINKING_OFF        0x00&lt;br /&gt;
#define LCD_BLINKING_ON         0x01&lt;br /&gt;
 &lt;br /&gt;
// Set Shift ------------------ 0b0001xxxx&lt;br /&gt;
#define LCD_SET_SHIFT           0x10&lt;br /&gt;
 &lt;br /&gt;
#define LCD_CURSOR_MOVE         0x00&lt;br /&gt;
#define LCD_DISPLAY_SHIFT       0x08&lt;br /&gt;
#define LCD_SHIFT_LEFT          0x00&lt;br /&gt;
#define LCD_SHIFT_RIGHT         0x04&lt;br /&gt;
 &lt;br /&gt;
// Set Function --------------- 0b001xxxxx&lt;br /&gt;
#define LCD_SET_FUNCTION        0x20&lt;br /&gt;
 &lt;br /&gt;
#define LCD_FUNCTION_4BIT       0x00&lt;br /&gt;
#define LCD_FUNCTION_8BIT       0x10&lt;br /&gt;
#define LCD_FUNCTION_1LINE      0x00&lt;br /&gt;
#define LCD_FUNCTION_2LINE      0x08&lt;br /&gt;
#define LCD_FUNCTION_5X7        0x00&lt;br /&gt;
#define LCD_FUNCTION_5X10       0x04&lt;br /&gt;
 &lt;br /&gt;
#define LCD_SOFT_RESET          0x30&lt;br /&gt;
 &lt;br /&gt;
// Set CG RAM Address --------- 0b01xxxxxx  (Character Generator RAM)&lt;br /&gt;
#define LCD_SET_CGADR           0x40&lt;br /&gt;
 &lt;br /&gt;
#define LCD_GC_CHAR0            0&lt;br /&gt;
#define LCD_GC_CHAR1            1&lt;br /&gt;
#define LCD_GC_CHAR2            2&lt;br /&gt;
#define LCD_GC_CHAR3            3&lt;br /&gt;
#define LCD_GC_CHAR4            4&lt;br /&gt;
#define LCD_GC_CHAR5            5&lt;br /&gt;
#define LCD_GC_CHAR6            6&lt;br /&gt;
#define LCD_GC_CHAR7            7&lt;br /&gt;
 &lt;br /&gt;
// Set DD RAM Address --------- 0b1xxxxxxx  (Display Data RAM)&lt;br /&gt;
#define LCD_SET_DDADR           0x80&lt;br /&gt;
 &lt;br /&gt;
#endif &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Datei &#039;&#039;&#039;lcd-routines.c&#039;&#039;&#039;: ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus&lt;br /&gt;
// http://www.mikrocontroller.net/articles/HD44780&lt;br /&gt;
// http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung&lt;br /&gt;
//&lt;br /&gt;
// Die Pinbelegung ist über defines in lcd-routines.h einstellbar&lt;br /&gt;
 &lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;quot;lcd-routines.h&amp;quot;&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Erzeugt einen Enable-Puls&lt;br /&gt;
static void lcd_enable( void )&lt;br /&gt;
{&lt;br /&gt;
    LCD_PORT |= (1&amp;lt;&amp;lt;LCD_EN);     // Enable auf 1 setzen&lt;br /&gt;
    _delay_us( LCD_ENABLE_US );  // kurze Pause&lt;br /&gt;
    LCD_PORT &amp;amp;= ~(1&amp;lt;&amp;lt;LCD_EN);    // Enable auf 0 setzen&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Sendet eine 4-bit Ausgabeoperation an das LCD&lt;br /&gt;
static void lcd_out( uint8_t data )&lt;br /&gt;
{&lt;br /&gt;
    data &amp;amp;= 0xF0;                       // obere 4 Bit maskieren&lt;br /&gt;
 &lt;br /&gt;
    LCD_PORT &amp;amp;= ~(0xF0&amp;gt;&amp;gt;(4-LCD_DB));    // Maske löschen&lt;br /&gt;
    LCD_PORT |= (data&amp;gt;&amp;gt;(4-LCD_DB));     // Bits setzen&lt;br /&gt;
    lcd_enable();&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Initialisierung: muss ganz am Anfang des Programms aufgerufen werden.&lt;br /&gt;
void lcd_init( void )&lt;br /&gt;
{&lt;br /&gt;
    // verwendete Pins auf Ausgang schalten&lt;br /&gt;
    uint8_t pins = (0x0F &amp;lt;&amp;lt; LCD_DB) |           // 4 Datenleitungen&lt;br /&gt;
                   (1&amp;lt;&amp;lt;LCD_RS) |                // R/S Leitung&lt;br /&gt;
                   (1&amp;lt;&amp;lt;LCD_EN);                 // Enable Leitung&lt;br /&gt;
    LCD_DDR |= pins;&lt;br /&gt;
 &lt;br /&gt;
    // initial alle Ausgänge auf Null&lt;br /&gt;
    LCD_PORT &amp;amp;= ~pins;&lt;br /&gt;
 &lt;br /&gt;
    // warten auf die Bereitschaft des LCD&lt;br /&gt;
    _delay_ms( LCD_BOOTUP_MS );&lt;br /&gt;
    &lt;br /&gt;
    // Soft-Reset muss 3mal hintereinander gesendet werden zur Initialisierung&lt;br /&gt;
    lcd_out( LCD_SOFT_RESET );&lt;br /&gt;
    _delay_ms( LCD_SOFT_RESET_MS1 );&lt;br /&gt;
 &lt;br /&gt;
    lcd_enable();&lt;br /&gt;
    _delay_ms( LCD_SOFT_RESET_MS2 );&lt;br /&gt;
 &lt;br /&gt;
    lcd_enable();&lt;br /&gt;
    _delay_ms( LCD_SOFT_RESET_MS3 );&lt;br /&gt;
 &lt;br /&gt;
    // 4-bit Modus aktivieren &lt;br /&gt;
    lcd_out( LCD_SET_FUNCTION |&lt;br /&gt;
             LCD_FUNCTION_4BIT );&lt;br /&gt;
    _delay_ms( LCD_SET_4BITMODE_MS );&lt;br /&gt;
 &lt;br /&gt;
    // 4-bit Modus / 2 Zeilen / 5x7&lt;br /&gt;
    lcd_command( LCD_SET_FUNCTION |&lt;br /&gt;
                 LCD_FUNCTION_4BIT |&lt;br /&gt;
                 LCD_FUNCTION_2LINE |&lt;br /&gt;
                 LCD_FUNCTION_5X7 );&lt;br /&gt;
 &lt;br /&gt;
    // Display ein / Cursor aus / Blinken aus&lt;br /&gt;
    lcd_command( LCD_SET_DISPLAY |&lt;br /&gt;
                 LCD_DISPLAY_ON |&lt;br /&gt;
                 LCD_CURSOR_OFF |&lt;br /&gt;
                 LCD_BLINKING_OFF); &lt;br /&gt;
 &lt;br /&gt;
    // Cursor inkrement / kein Scrollen&lt;br /&gt;
    lcd_command( LCD_SET_ENTRY |&lt;br /&gt;
                 LCD_ENTRY_INCREASE |&lt;br /&gt;
                 LCD_ENTRY_NOSHIFT );&lt;br /&gt;
 &lt;br /&gt;
    lcd_clear();&lt;br /&gt;
}&lt;br /&gt;
  &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Sendet ein Datenbyte an das LCD&lt;br /&gt;
void lcd_data( uint8_t data )&lt;br /&gt;
{&lt;br /&gt;
    LCD_PORT |= (1&amp;lt;&amp;lt;LCD_RS);    // RS auf 1 setzen&lt;br /&gt;
 &lt;br /&gt;
    lcd_out( data );            // zuerst die oberen, &lt;br /&gt;
    lcd_out( data&amp;lt;&amp;lt;4 );         // dann die unteren 4 Bit senden&lt;br /&gt;
 &lt;br /&gt;
    _delay_us( LCD_WRITEDATA_US );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Sendet einen Befehl an das LCD&lt;br /&gt;
void lcd_command( uint8_t data )&lt;br /&gt;
{&lt;br /&gt;
    LCD_PORT &amp;amp;= ~(1&amp;lt;&amp;lt;LCD_RS);    // RS auf 0 setzen&lt;br /&gt;
 &lt;br /&gt;
    lcd_out( data );             // zuerst die oberen, &lt;br /&gt;
    lcd_out( data&amp;lt;&amp;lt;4 );           // dann die unteren 4 Bit senden&lt;br /&gt;
 &lt;br /&gt;
    _delay_us( LCD_COMMAND_US );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Sendet den Befehl zur Löschung des Displays&lt;br /&gt;
void lcd_clear( void )&lt;br /&gt;
{&lt;br /&gt;
    lcd_command( LCD_CLEAR_DISPLAY );&lt;br /&gt;
    _delay_ms( LCD_CLEAR_DISPLAY_MS );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Sendet den Befehl: Cursor Home&lt;br /&gt;
void lcd_home( void )&lt;br /&gt;
{&lt;br /&gt;
    lcd_command( LCD_CURSOR_HOME );&lt;br /&gt;
    _delay_ms( LCD_CURSOR_HOME_MS );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Setzt den Cursor in Spalte x (0..15) Zeile y (1..4) &lt;br /&gt;
 &lt;br /&gt;
void lcd_setcursor( uint8_t x, uint8_t y )&lt;br /&gt;
{&lt;br /&gt;
    uint8_t data;&lt;br /&gt;
 &lt;br /&gt;
    switch (y)&lt;br /&gt;
    {&lt;br /&gt;
        case 1:    // 1. Zeile&lt;br /&gt;
            data = LCD_SET_DDADR + LCD_DDADR_LINE1 + x;&lt;br /&gt;
            break;&lt;br /&gt;
 &lt;br /&gt;
        case 2:    // 2. Zeile&lt;br /&gt;
            data = LCD_SET_DDADR + LCD_DDADR_LINE2 + x;&lt;br /&gt;
            break;&lt;br /&gt;
 &lt;br /&gt;
        case 3:    // 3. Zeile&lt;br /&gt;
            data = LCD_SET_DDADR + LCD_DDADR_LINE3 + x;&lt;br /&gt;
            break;&lt;br /&gt;
 &lt;br /&gt;
        case 4:    // 4. Zeile&lt;br /&gt;
            data = LCD_SET_DDADR + LCD_DDADR_LINE4 + x;&lt;br /&gt;
            break;&lt;br /&gt;
 &lt;br /&gt;
        default:&lt;br /&gt;
            return;                                   // für den Fall einer falschen Zeile&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    lcd_command( data );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Schreibt einen String auf das LCD&lt;br /&gt;
 &lt;br /&gt;
void lcd_string( const char *data )&lt;br /&gt;
{&lt;br /&gt;
    while( *data != &#039;\0&#039; )&lt;br /&gt;
        lcd_data( *data++ );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Schreibt ein Zeichen in den Character Generator RAM&lt;br /&gt;
 &lt;br /&gt;
void lcd_generatechar( uint8_t code, const uint8_t *data )&lt;br /&gt;
{&lt;br /&gt;
    // Startposition des Zeichens einstellen&lt;br /&gt;
    lcd_command( LCD_SET_CGADR | (code&amp;lt;&amp;lt;3) );&lt;br /&gt;
 &lt;br /&gt;
    // Bitmuster übertragen&lt;br /&gt;
    for ( uint8_t i=0; i&amp;lt;8; i++ )&lt;br /&gt;
    {&lt;br /&gt;
        lcd_data( data[i] );&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LCD Beispiel 1 ===&lt;br /&gt;
Ein Hauptprogramm, welches die LCD Funktionen benutzt, sieht zb. so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// &lt;br /&gt;
// Anpassungen im makefile:&lt;br /&gt;
//    ATMega8 =&amp;gt; MCU=atmega8 im makefile einstellen&lt;br /&gt;
//    lcd-routines.c in SRC = ... Zeile anhängen&lt;br /&gt;
// &lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;quot;lcd-routines.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  // Initialisierung des LCD&lt;br /&gt;
  // Nach der Initialisierung müssen auf dem LCD vorhandene schwarze Balken&lt;br /&gt;
  // verschwunden sein&lt;br /&gt;
  lcd_init();&lt;br /&gt;
&lt;br /&gt;
  // Text in einzelnen Zeichen ausgeben&lt;br /&gt;
  lcd_data( &#039;T&#039; );&lt;br /&gt;
  lcd_data( &#039;e&#039; );&lt;br /&gt;
  lcd_data( &#039;s&#039; );&lt;br /&gt;
  lcd_data( &#039;t&#039; );&lt;br /&gt;
&lt;br /&gt;
  // Die Ausgabemarke in die 2te Zeile setzen&lt;br /&gt;
  lcd_setcursor( 0, 2 );&lt;br /&gt;
&lt;br /&gt;
  // erneut Text ausgeben, aber diesmal komfortabler als String&lt;br /&gt;
  lcd_string(&amp;quot;Hello World!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  while(1)&lt;br /&gt;
  {&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LCD Beispiel 2 ===&lt;br /&gt;
Ein Hauptprogramm, welches eine Variable ausgibt, sieht zb. so aus.&lt;br /&gt;
Mittels der itoa() Funktion (itoa = &amp;lt;b&amp;gt;I&amp;lt;/b&amp;gt;nteger &amp;lt;b&amp;gt;To&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;A&amp;lt;/b&amp;gt;scii ) wird von einem Zahlenwert eine textuelle Repräsentierung ermittelt (sprich: ein String erzeugt) und dieser String mit der bereits vorhandenen Funktion lcd_string ausgegeben. Das Einrichten des Projekts ist wie in Beispiel 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// &lt;br /&gt;
// Anpassungen im makefile:&lt;br /&gt;
//    ATMega8 =&amp;gt; MCU=atmega8 im makefile einstellen&lt;br /&gt;
//    lcd-routines.c in SRC = ... Zeile anhängen &lt;br /&gt;
// &lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;lcd-routines.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Beispiel&lt;br /&gt;
int variable = 42;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  lcd_init();&lt;br /&gt;
&lt;br /&gt;
  // Ausgabe des Zeichens dessen ASCII-Code gleich dem Variablenwert ist&lt;br /&gt;
  // (Im Beispiel entspricht der ASCII-Code 42 dem Zeichen *)&lt;br /&gt;
  // http://www.code-knacker.de/ascii.htm&lt;br /&gt;
  lcd_data( variable );&lt;br /&gt;
&lt;br /&gt;
  lcd_setcursor( 0, 2 );&lt;br /&gt;
 &lt;br /&gt;
  // Ausgabe der Variable als Text in dezimaler Schreibweise&lt;br /&gt;
  {&lt;br /&gt;
     // ... umwandeln siehe FAQ Artikel bei http://www.mikrocontroller.net/articles/FAQ&lt;br /&gt;
     // WinAVR hat eine itoa()-Funktion, das erfordert obiges #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
     char Buffer[20]; // in diesem {} lokal&lt;br /&gt;
     itoa( variable, Buffer, 10 ); &lt;br /&gt;
&lt;br /&gt;
     // ... ausgeben  &lt;br /&gt;
     lcd_string( Buffer );&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  while(1)&lt;br /&gt;
  {&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Erweiterte LCD-Ansteuerung]]&lt;br /&gt;
* [[Pseudo-Graphische LCD-Ansteuerung]]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/316826#3431235 Ermittlung der Startadresse der einzelnen Zeilen]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/350554#3899961 LCD-Ansteuerung mit freier Wahl von Pins und Portregistern am Controller]&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
* [http://homepage.hispeed.ch/peterfleury/avr-software.html#libs Lib zur HD44780 Ansteuerung (AVR)]&lt;br /&gt;
* [http://pic-projekte.de/wordpress/?p=908 Lib zur HD44780 Ansteuerung (PIC)]&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/group__stdiodemo.html Using the standard IO facilities] - Demoprojekt zur Text-LCD Ansteuerung (HD44780 komp.) in der avr-libc&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Avr-gcc Tutorial]]&lt;br /&gt;
[[Kategorie:LCD]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Remote_IRMP&amp;diff=86305</id>
		<title>Remote IRMP</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Remote_IRMP&amp;diff=86305"/>
		<updated>2014-12-20T09:55:10Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Konsistenz&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Von &#039;&#039;&#039;Frank M. ([http://www.mikrocontroller.net/user/show/ukw ukw])&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Datei:Remote-IRMP-Screenshot1.png|thumb|Frei gestaltbare Tasten zum Senden von IR-Befehlen]]&lt;br /&gt;
&lt;br /&gt;
Dieser Artikel ist eine konkrete Anwendung des [[IRMP]]-Projekts (IRMP-Dekoder = Infrarot-Multiprotokoll-Dekoder). Wir verschaffen unserem Mikrocontroller nicht nur einen IR-Sender und Empfänger, sondern auch noch einen Netzwerkanschluss. Damit wird es möglich, mit einer Android-App eine anlernbare IR-Fernbedienung zu realisieren. Der Anwender kann dann mehrere Geräte, die irgendwo im Haushalt verteilt sind, über das Handy steuern. Dabei sendet die App über WLAN zuvor gespeicherte [[IRMP]]-Codes an den gewünschten µC. Dieser strahlt dann die Signale über den IR-Sender aus, um damit unsere Geräte aus der Unterhaltungsindustrie zu schalten.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist eine Erweiterung von [[IRMP]] um Funksender geplant, damit zukünftig auch Funksteckdosen bequem vom Handy aus geschaltet werden können.&lt;br /&gt;
&lt;br /&gt;
== Merkmale ==&lt;br /&gt;
&lt;br /&gt;
Folgende Funktionalitäten sind bereits umgesetzt:&lt;br /&gt;
&lt;br /&gt;
* Anbindung des µC an einen Wiznet W5100 Ethernet-Controller&lt;br /&gt;
* Protokollschnittstelle über TCP/IP und UDP&lt;br /&gt;
* Testprogramme der Kommunikation für Unix, Linux und Windows&lt;br /&gt;
* Android-App mit frei konfigurierbaren Bedienertasten/Bildschirmseiten&lt;br /&gt;
* Anlernen von IR-Codes mit Speicherung unter Android&lt;br /&gt;
* Senden der IR-Codes über WLAN an den Remote-IRMP Controller&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:Remote-irmp-schaltung-arduino.png|thumb|Schaltbild des Prototyps als Shield für Arduino Ethernet]]&lt;br /&gt;
&lt;br /&gt;
Der stabil laufende Prototyp wurde mit dem Arduino Ethernet Board (erhältlich z.B. bei [http://www.pollin.de/shop/dt/MTA4OTgxOTk-/Bausaetze_Module/Entwicklerboards/ARDUINO_Ethernet.html Pollin]) realisiert - jedoch ohne die Verwendung der Arduino-Bibliotheken bzw. Arduino-Software. Die Verwendung des fertigen Boards hatte den Vorteil, dass der Lötaufwand sich auf ein Minimum reduziert: Es muss lediglich je ein IR-Sender- und ein Empfänger-Modul angeschlossen werden. Diese Module bestehen lediglich aus ein paar Bauteilen, welche hier auf eine Lochraster-Platine gelötet werden. Die Lochraster-Platine wird dann einfach als Shield auf das Arduino-Board aufgesteckt. Das Schaltbild dazu ist rechts zu sehen.&lt;br /&gt;
&lt;br /&gt;
Dabei ist:&lt;br /&gt;
&lt;br /&gt;
  * 0C0A = PD6 oder in der Arduino-Nomenklatur: Digital Pin 6&lt;br /&gt;
  * PC0 in der Arduino-Schreibweise: Analog Input 0.&lt;br /&gt;
&lt;br /&gt;
Die für den Prototyp entwickelte Software funktioniert aber auch mit einem WIZnet WIZ812MJ-Modul, welches man zum Beispiel bei [http://www.watterott.com/de/WIZnet-WIZ812MJ-Ethernet-Modul Watterott] erstehen kann. Dieses Modul wird dann auf eine eigens zu entwickelnde Platine aufgesteckt.&lt;br /&gt;
&lt;br /&gt;
Die dafür notwendige Hauptplatine als endgültige Version mit ATmega, Infrarot-Sender/Empfänger und Funksteckdosen-Sendermodul ist noch nicht ganz fertig - dazu später mehr. Der Prototyp mit dem Arduino Ethernet Board ist aber durchaus jetzt schon einsatzfähig.&lt;br /&gt;
&lt;br /&gt;
== Protokoll ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:Remote-IRMP-Screenshot3.png|thumb|Beispiel für einen DVD-Player]]&lt;br /&gt;
&lt;br /&gt;
Das Kommunikationsprotokoll für die Remote-IRMP-Satelliten wurde bewusst einfach gehalten. Dabei kann sowohl TCP/IP als auch UDP verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=== Senden eines IRMP-Codes ===&lt;br /&gt;
&lt;br /&gt;
In diesem Fall sind 7 Bytes zu übertragen:&lt;br /&gt;
&lt;br /&gt;
* Byte 1: &#039;S&#039; als Kommmando &amp;quot;Send&amp;quot;&lt;br /&gt;
* Byte 2: [[IRMP]]-Protokollnummer&lt;br /&gt;
* Byte 3: Upper Byte der [[IRMP]]-Adresse&lt;br /&gt;
* Byte 4: Lower Byte der [[IRMP]]-Adresse&lt;br /&gt;
* Byte 5: Upper Byte des [[IRMP]]-Kommandos&lt;br /&gt;
* Byte 6: Lower Byte des [[IRMP]]-Kommandos&lt;br /&gt;
* Byte 7: [[IRMP]]-Flag&lt;br /&gt;
&lt;br /&gt;
Antwort:&lt;br /&gt;
&lt;br /&gt;
* Byte 1: &#039;S&#039;&lt;br /&gt;
* Byte 2: &#039;+&#039; im Erfolgsfall&lt;br /&gt;
&lt;br /&gt;
oder:&lt;br /&gt;
&lt;br /&gt;
* Byte 1: &#039;S&#039;&lt;br /&gt;
* Byte 2: &#039;-&#039; als Fehlercode, wenn das Protokoll unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
=== Empfangen eines IRMP-Codes (Anlernen) ===&lt;br /&gt;
&lt;br /&gt;
Es wird lediglich 1 Byte gesandt:&lt;br /&gt;
&lt;br /&gt;
* Byte 1: &#039;R&#039; als Kommmando &amp;quot;Receive&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Wenn man als Anwender innerhalb von 5 Sekunden nun eine Fernbedienung betätigt, wird der angelernte Code als Antwort zurückgeschickt, nämlich:&lt;br /&gt;
&lt;br /&gt;
* Byte 1: &#039;R&#039; als Bestätigung&lt;br /&gt;
* Byte 2: &#039;+&#039; als Erfolgscode&lt;br /&gt;
* Byte 3: [[IRMP]]-Protokollnummer&lt;br /&gt;
* Byte 4: Upper Byte der [[IRMP]]-Adresse&lt;br /&gt;
* Byte 5: Lower Byte der [[IRMP]]-Adresse&lt;br /&gt;
* Byte 6: Upper Byte des [[IRMP]]-Kommandos&lt;br /&gt;
* Byte 7: Lower Byte des [[IRMP]]-Kommandos&lt;br /&gt;
* Byte 8: [[IRMP]]-Flag&lt;br /&gt;
&lt;br /&gt;
Sollte keine Fernbedienungstaste betätigt oder das verwendete IR-Protokoll von [[IRMP]] nicht verstanden werden, werden als Antwort auch 8 Bytes zurückgesandt, aber:&lt;br /&gt;
&lt;br /&gt;
* Byte 1: &#039;R&#039; als Bestätigung&lt;br /&gt;
* Byte 2: &#039;-&#039; als Fehlercode&lt;br /&gt;
* Byte 3-8: 0x00&lt;br /&gt;
&lt;br /&gt;
=== Weitere Netzwerkbefehle ===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Remote-IRMP-Screenshot4.png|thumb|Bis zu 8 Remote-IRMP Server sind ansprechbar]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Außerdem wurde noch ein Kommando eingebaut, um die Kommunikation über IP selbst zu testen:&lt;br /&gt;
&lt;br /&gt;
* Byte 1: &#039;P&#039; als &amp;quot;Ping&amp;quot;-Kommando&lt;br /&gt;
&lt;br /&gt;
Antwort:&lt;br /&gt;
&lt;br /&gt;
* Byte 1: &#039;P&#039; als Bestätigung&lt;br /&gt;
* Byte 2: &#039;+&#039; als Erfolgscode&lt;br /&gt;
&lt;br /&gt;
Es gibt noch ein weiteres Kommando - dieses jedoch nur für TCP/IP, nicht für UDP:&lt;br /&gt;
&lt;br /&gt;
* Byte 1: &#039;B&#039; als Bootloader-Sprungkommando&lt;br /&gt;
&lt;br /&gt;
Es kommt keine Antwort zurück, sondern der ATmega328 springt dann direkt in den Ethernet-Bootloader, damit man ein Update flashen kann, ohne extra die RESET-Taste drücken zu müssen. Siehe dazu auch das Kapitel [http://www.mikrocontroller.net/articles/Remote_IRMP#Bootloader_-_Flashen_.C3.BCbers_Netzwerk Bootloader - Flashen übers Netzwerk].&lt;br /&gt;
&lt;br /&gt;
== IRMP-Software mit LAN-Anbindung ==&lt;br /&gt;
&lt;br /&gt;
Der Source-Code lässt sich einfach für AVR-µCs übersetzen, indem man unter Windows die Projekt-Datei ipserver.aps in das AVR Studio 4 lädt. Jedoch sollte der avr-gcc schon ein neuerer sein, als ursprünglich mal 2010 mit dem AVR Studio 4 ausgeliefert wurde. Ich persönlich nutze avr-gcc 4.7.2.&lt;br /&gt;
&lt;br /&gt;
Bei neueren Entwicklungsumgebungen bzw. Linux ist es auch kein Problem, ein eigenes Projekt bzw. Makefile zu erstellen. Folgende Sources müssen dafür ins Projekt übernommen werden:&lt;br /&gt;
&lt;br /&gt;
* ipserver.c - das main-Modul&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irmp.c?view=markup irmp.c] - der IR-Multiprotokoll-Decoder&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irsnd.c?view=markup irsnd.c] - der IR-Encoder&lt;br /&gt;
* w5100.c - der Wiznet W5100 Treiber&lt;br /&gt;
&lt;br /&gt;
Zum Projekt gehören dann noch folgende Includes:&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irmp.h?view=markup irmp.h]&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irmpconfig.h?view=markup irmpconfig.h]&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irmpextlog.h?view=markup irmpextlog.h]&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irmpprotocols.h?view=markup irmpprotocols.h]&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irmpsystem.h?view=markup irmpsystem.h]&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irsnd.h?view=markup irsnd.h]&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irsndconfig.h?view=markup irsndconfig.h]&lt;br /&gt;
* w5100.h&lt;br /&gt;
* w5100config.h&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bitte KEINE weiteren C-Module (wie z.B. ipbootloader.c) im Projekt angeben!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Zusatzlich zu den Standard-Compiler-Optionen (Prozessor-Typ etc.) sollten dem Projekt für alle C-Dateien folgende Optionen hinzugefügt werden:&lt;br /&gt;
&lt;br /&gt;
  -DF_CPU=16000000UL&lt;br /&gt;
  -Os&lt;br /&gt;
  -flto&lt;br /&gt;
  -ffunction-sections&lt;br /&gt;
  -fdata-sections&lt;br /&gt;
&lt;br /&gt;
Als Linker-Optionen:&lt;br /&gt;
&lt;br /&gt;
  -Os&lt;br /&gt;
  -flto&lt;br /&gt;
  -ffunction-sections&lt;br /&gt;
  -fdata-sections&lt;br /&gt;
  -Wl,--gc-sections&lt;br /&gt;
&lt;br /&gt;
=== Fuses ===&lt;br /&gt;
Wichtig sind auch die Fuses. Wenn das Arduino Ethernet Board verwendet wird, muss auf jeden Fall der standardmäßig installierte Bootloader deaktiviert werden. Aber auch für eine eigene Platine müssen die Fuses angepasst werden, nämlich auf:&lt;br /&gt;
&lt;br /&gt;
* lfuse: 0xFF&lt;br /&gt;
* hfuse: 0xD1&lt;br /&gt;
* efuse: 0xFD&lt;br /&gt;
&lt;br /&gt;
Nur wenn der eigene IP-Bootloader auch verwendet werden soll, ist die hfuse nochmals zu ändern. Das ist dann im [http://www.mikrocontroller.net/articles/Remote_IRMP#Bootloader_-_Flashen_.C3.BCbers_Netzwerk Bootloader-Kapitel] weiter unten nachzulesen.&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration ===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Remote-IRMP-Screenshot5.png|thumb|Konfiguration und Test eines Remote-IRMP Servers]]&lt;br /&gt;
&lt;br /&gt;
Es können etliche Parameter angepasst werden. Hier die wichtigsten Einstellungen:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ipserver.c&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define DEBUG                       1&lt;br /&gt;
&lt;br /&gt;
#define MAC_ADDRESS                 {0x90,0xA2,0xDA,0x00,0xF4,0x65}         // mac address&lt;br /&gt;
#define IP_ADDRESS                  {192,168,10,233}                        // ip address&lt;br /&gt;
#define IP_NETMASK                  {255,255,255,0}                         // netmask&lt;br /&gt;
#define IP_GATEWAY                  {192,168,10,1}                          // gateway address&lt;br /&gt;
&lt;br /&gt;
#define DBG_PORT                    10000                                   // debug tcp listen port&lt;br /&gt;
#define TCP_PORT                    10001                                   // normal tcp listen port&lt;br /&gt;
#define UDP_PORT                    10001                                   // udp port&lt;br /&gt;
&lt;br /&gt;
#define LED_DDR                     DDRB&lt;br /&gt;
#define LED_PORT                    PORTB&lt;br /&gt;
#define LED_BIT                     PB1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Als MAC-Adresse (MAC_ADDRESS) wählt man beim Arduino Ethernet Board am besten die aufgeklebte MAC-Adresse. Dann kann es nicht zu Konflikten kommen. Die IP-Adresse (IP_ADDRESS) sollte an das lokale Netzwerk angepasst werden. Ebenso die Netzwerkmaske (IP_NETMASK), wenn sie im lokalen Netz abweicht. Die Angabe eines Gateways (IP_GATEWAY) ist nicht unbedingt notwendig, wenn die [[IRMP]]-Server nur im lokalen Netz erreichbar sein sollen. In diesem Fall kann {0,0,0,0} angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Normalerweise horchen die [[IRMP]]-Server auf dem TCP- und UDP-Port 10001. Wenn gewünscht, können die Ports sowohl für TCP (TCP_PORT) als auch für UDP (UDP_PORT) geändert werden. Sie können auch verschieden sein. Normalerweise ist aber eine Änderung nicht notwendig.&lt;br /&gt;
&lt;br /&gt;
Bleibt noch der Debug-Port (DBG_PORT). Nur wenn die Präprozessor-Konstante DEBUG auf 1 steht, spielt dieser eine Rolle. Dann protokolliert der [[IRMP]]-Server nämlich alle eingehenden [[IRMP]]-Befehle, wenn man eine telnet-Session für die konfigurierte IP-Adresse und den Debug-Port öffnet. Unter Windows eignet sich dafür hervorragend PuTTY, welches man aus dem Internet herunterladen kann. Bei unixoiden Systemen ist telnet sowieso verfügbar - meist schon standardmäßig installiert.&lt;br /&gt;
&lt;br /&gt;
Wird Debugging nicht gewünscht, kann man DEBUG auf 0 setzen und der Wert des DBG_PORTs wird irrelevant.&lt;br /&gt;
&lt;br /&gt;
Außerdem gibt es noch die Definitionen für eine am ATmega angeschlossene LED (Konstanten LED_xxx). Hier werden dann ausgesandte IR-Signale parallel auf der LED visualisiert. Außerdem leuchtet diese LED, solange man einen IR-Code anlernt.&lt;br /&gt;
&lt;br /&gt;
Die obigen Werte dafür entsprechen der bereits vorhandenen LED auf dem Arduino-Board. Sie können natürlich für andere Hardware (z.B. eigene Platine mit WIZ812MJ-Modul) angepasst werden. Besser: Man wählt beim Entwurf einer eigenen Hauptplatine einfach denselben Port.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;w5100config.h&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define CHIP_SELECT_AVAILABLE       0            // set to 1 if CS will be controlled by other pin than SS of the µC &lt;br /&gt;
#define CHIP_RESET_AVAILABLE        0            // set to 1 if RESET can be controlled by µC&lt;br /&gt;
&lt;br /&gt;
#if CHIP_SELECT_AVAILABLE == 1                   // if CS can be controlled , enter port/pin of µC&lt;br /&gt;
#  define CS_DDR                    DDRD&lt;br /&gt;
#  define CS_PORT                   PORTD&lt;br /&gt;
#  define CS_BIT                    4&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if CHIP_RESET_AVAILABLE == 1                    // if RESET can be controlled by µC, enter port/pin of µC&lt;br /&gt;
#  define RESET_DDR                 DDRD&lt;br /&gt;
#  define RESET_PORT                PORTD&lt;br /&gt;
#  define RESET_BIT                 5&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die obigen Konstanten beschreiben, wie der W5100-Controller an den ATmega angebunden ist.&lt;br /&gt;
&lt;br /&gt;
Ist CS (Chip-Select) des W5100 &#039;&#039;&#039;nicht&#039;&#039;&#039; an SS des ATmegas angeschlossen, muss CHIP_SELECT_AVAILABE auf 1 gesetzt werden und mittels CS_xxx-Konstanten der für CS verwendete Port-Pin des ATmegas angegeben werden, damit der ATmega softwaremäßig den Ethernet-Controller aktivieren kann. Beim Arduino Ethernet Board ist CS mit SS fest verbunden, so dass CHIP_SELECT_AVAILABLE auf 0 stehen bleibt und die CS_xxx-Konstanten nicht weiter beachtet werden.&lt;br /&gt;
&lt;br /&gt;
Muss der W5100-Controller explizit über den RESET-Pin softwaremäßig zurückgesetzt werden, dann sollte dies über den ATmega geschehen. In diesem Fall setzt man CHIP_RESET_AVAILABLE auf 1 und definiert weiter unten den Portpin (RESET_xxx), an welchem ATmega-Portpin der RESET-Pin des W51000 angeschlossen ist. Beim Arduino Ethernet Board hängt der W5100 an einer eigenen Hardware-Reset-Schaltung, so dass CHIP_SELECT_AVAILABLE auf 0 stehenbleiben kann und damit die RESET_xxx-Konstanten irrelevant werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;irmpconfig.h&#039;&#039;&#039; und &#039;&#039;&#039;irsndconfig.h&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Die Konstanten in den [[IRMP]]-Konfigurationsdateien sind ausführlich im [[IRMP]]-Artikel erklärt. Daher wird hier auf weitere Erläuterungen verzichtet. Im wesentlichen wird hier definiert, welche Pins am ATmega für den IR-Empfänger und für den IR-Sender verwendet werden. Die Port-Einstellungen sind hier vorgewählt auf das oben bereits erwähnte Lochraster-Arduino-Ethernet-Shield - siehe Schaltbild. Ausserdem kann man hier die IR-Protokolle auswählen, die [[IRMP]]/IRSND mit einbinden soll. Insgsamt sind 36 Protokolle wählbar. Die häufigsten 6 Protokolle sind bereits aktiviert.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Erster Start&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Der erste Start mit dem Arduino Ethernet Board kann durchaus auch ohne selbstgebautes &amp;quot;Shield&amp;quot; auf Lochrasterplatine gewagt werden. Hierzu wird die vom Compiler erzeugte Hex-Datei über den 6-poligen ISP-Stecker des Boards eingespielt. [http://www.mikrocontroller.net/articles/Remote_IRMP#Fuses Fuses] nicht vergessen! Anschließend sollte man vom PC aus das Modul per ping-Befehl ansprechen können. Wenn das funktioniert, ist man schon fast am Ziel. Nun sollte man das Board von der Stromversorgung trennen und die Platine mit IR-Empfänger und Sender als Shield aufstecken. Nach Neustart kann man nun entweder direkt die Funktionen mit der [http://www.mikrocontroller.net/articles/Remote_IRMP#Android-Software Android-App] testen oder erstmal mit einem [http://www.mikrocontroller.net/articles/Remote_IRMP#Andere_Betriebssysteme_als_Clients PC-Testprogramm], siehe weiter unten.&lt;br /&gt;
&lt;br /&gt;
Ganz Mutige lassen das aber mit dem Programmieren der Remote-IRMP-Software über den ISP, sondern installieren direkt den [http://www.mikrocontroller.net/articles/Remote_IRMP#Bootloader_-_Flashen_.C3.BCbers_Netzwerk Bootloader], siehe weiter [http://www.mikrocontroller.net/articles/Remote_IRMP#Bootloader_-_Flashen_.C3.BCbers_Netzwerk unten]. Anschließend kann man beliebig oft die IRMP-Software oder Updates davon direkt übers Netzwerk installieren.&lt;br /&gt;
&lt;br /&gt;
== Bootloader - Flashen übers Netzwerk ==&lt;br /&gt;
&lt;br /&gt;
Wenn man schon einen netzwerkfähigen ATmega hat, dann möchte man Updates auch über das angesteckte Netzwerkkabel einspielen. Dafür wurde ein Bootloader entwickelt, welcher mit 1,6 KB Größe leicht in den oberen Flash-Bereich des ATmega328 passt. Das eigentliche Flash-Programm sendet dann per TCP/IP die Daten an den Bootloader. Das Flash-Programm ist für Unix, Linux und Windows verfügbar.&lt;br /&gt;
&lt;br /&gt;
=== Bootloader-Kommunikationsprotokoll ===&lt;br /&gt;
&lt;br /&gt;
* Bootloader (BL) horcht auf TCP/Port 22222 und wartet für 3 Sekunden auf das Zeichen &#039;$&#039; (1 Byte)&lt;br /&gt;
* Falls dieses eintrifft, antwortet BL ebenfalls mit dem &#039;$&#039;-Zeichen (1 Byte), anderenfalls hier Ende&lt;br /&gt;
* BL sendet die µC-spezifische &amp;quot;Page-Size&amp;quot; des Flashs zum Programmieren an den PC (1 Byte)&lt;br /&gt;
* PC sendet erste Page-Nummer des zu schreibenden Programms (2 Bytes, LSB, i.d.R. 0x00 0x00)&lt;br /&gt;
* PC sendet die Anzahl der zu übertragenden Pages (2 Bytes, LSB)&lt;br /&gt;
* PC sendet die Daten für eine Page - gefolgt von einem Prüfsummen-Byte&lt;br /&gt;
* BL antwortet mit &#039;1&#039;, wenn das Prüfsummen-Byte passt, anderenfalls mit &#039;0&#039; und bricht ab&lt;br /&gt;
* Weiter gehts mit der nächsten Page, also 2 Schritte höher...&lt;br /&gt;
&lt;br /&gt;
=== Bootloader-Software ===&lt;br /&gt;
&lt;br /&gt;
Der Source-Code lässt sich einfach für AVR-µCs übersetzen, indem man unter Windows die Projekt-Datei ipbootloader.aps in das AVR Studio 4 lädt. Der avr-gcc muss jedoch neuer sein als der, welcher ursprünglich im Jahre 2010 mit dem AVR Studio 4 ausgeliefert wurde. Empfehlung: avr-gcc 4.7.2 oder neuer.&lt;br /&gt;
&lt;br /&gt;
Bei neueren AVR-Entwicklungsumgebungen bzw. Linux ist es auch kein Problem, ein eigenes Projekt bzw. Makefile zu erstellen. Folgende Sources müssen dafür ins Projekt übernommen werden:&lt;br /&gt;
&lt;br /&gt;
* ipbootloader.c - der Bootloader&lt;br /&gt;
* w5100.c - der Wiznet W5100 Treiber&lt;br /&gt;
&lt;br /&gt;
Zum IP-Bootloader-Projekt gehören dann noch folgende Includes:&lt;br /&gt;
&lt;br /&gt;
* w5100.h&lt;br /&gt;
* w5100config.h&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bitte KEINE weiteren C-Module (wie z.B. ipserver.c o.ä.) im Projekt angeben!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Zusatzlich zu den Standard-Compiler-Optionen (Prozessor-Typ etc.) müssen dem Projekt für alle C-Dateien folgende Optionen hinzugefügt werden:&lt;br /&gt;
&lt;br /&gt;
  -DF_CPU=16000000UL&lt;br /&gt;
  -Os&lt;br /&gt;
  -flto&lt;br /&gt;
  -ffunction-sections&lt;br /&gt;
  -fdata-sections&lt;br /&gt;
&lt;br /&gt;
Als Linker-Optionen:&lt;br /&gt;
&lt;br /&gt;
  -Os&lt;br /&gt;
  -flto&lt;br /&gt;
  -ffunction-sections&lt;br /&gt;
  -fdata-sections&lt;br /&gt;
  -Wl,--gc-sections&lt;br /&gt;
  -Wl,--section-start=.text=0x7800&lt;br /&gt;
&lt;br /&gt;
Mit der letzten Linker-Option wird das Programm derart übersetzt, dass es ab Adresse 0x7800 lauffähig ist. Damit liegt es in den letzten 2KB des ATmega328-Flash-Speichers. Beim Übersetzen ist dringendst darauf zu achten, dass das Compilat eine &amp;quot;Program Size&amp;quot; von ca. 1,6KB hat. Wird es größer als 2KB, dann sind offensichtlich die obigen Compiler- und Linker-Optionen nicht korrekt eingetragen und das Programm ist als Bootloader unbrauchbar.&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration des Bootloaders ===&lt;br /&gt;
&lt;br /&gt;
Hier gelten im wesentlichen dieselben Konfigurationsparameter für w5100config.h wie [http://www.mikrocontroller.net/articles/Remote_IRMP#Konfiguration oben]. Wichtig ist die Anpassung der IP-Adresse, siehe dafür ipbootloader.c:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define MAC_ADDRESS     {0x90,0xA2,0xDA,0x00,0xF4,0x65}             // mac address&lt;br /&gt;
#define IP_ADDRESS      {192,168,10,233}                            // ip address&lt;br /&gt;
#define IP_NETMASK      {255,255,255,0}                             // netmask&lt;br /&gt;
#define IP_GATEWAY      {192,168,10,1}                              // gateway address&lt;br /&gt;
&lt;br /&gt;
#define TCP_PORT        22222                                       // listen port&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Fuses für den Bootloader ===&lt;br /&gt;
&lt;br /&gt;
Die Fuses sind in diesem Fall auf folgende Werte zu ändern:&lt;br /&gt;
&lt;br /&gt;
* lfuse: 0xFF&lt;br /&gt;
* hfuse: 0xD2&lt;br /&gt;
* efuse: 0xFD&lt;br /&gt;
&lt;br /&gt;
Damit werden die letzten 2KB im Flash für den Bootloader reserviert. Dieser kann dann über den ISP-Stecker installiert werden. Updates der Remote-IRMP-Software können anschließend bequem über das Netzwerk eingespielt werden. Der Anschluss eines ISP-Programmers ist dann nicht mehr notwendig.&lt;br /&gt;
&lt;br /&gt;
=== Flashprogramm ===&lt;br /&gt;
&lt;br /&gt;
Das Flashprogramm ist unter Unix, Linux und Windows verfügbar. Als Executable für Windows benutzt man einfach ipflash.exe, unter unixoiden System kompiliert man sich das Programm selbst mit:&lt;br /&gt;
&lt;br /&gt;
  cc -O win32/ipflash/ipflash.c -o ipflash&lt;br /&gt;
&lt;br /&gt;
Der Aufruf ist dann allgemein:&lt;br /&gt;
&lt;br /&gt;
  ipflash [-b ipserver-tcp-port] ip-address tcp-port hex-file&lt;br /&gt;
&lt;br /&gt;
oder konkret für die Windows-Eingabeaufforderung:&lt;br /&gt;
&lt;br /&gt;
  ipflash.exe 192.168.10.233 22222 ipserver.hex&lt;br /&gt;
&lt;br /&gt;
bzw. linux:&lt;br /&gt;
&lt;br /&gt;
  ./ipflash 192.168.10.233 22222 ipserver.hex&lt;br /&gt;
&lt;br /&gt;
Wichtig ist dabei, kurz vorher den RESET-Button auf dem Board zu drücken und dann innerhalb von 3 Sekunden das Flash-Programm zu starten.&lt;br /&gt;
&lt;br /&gt;
Ist einmal das ipserver-Programm installiert, kann man sich das Drücken des RESET-Buttons zukünftig auch sparen. Dann kann das Flash-Programm den ATmega auch über das Netzwerk resetten. Hierbei ist zusätzlich der TCP-Port des ipserver-Programms anzugeben, also:&lt;br /&gt;
&lt;br /&gt;
  ipflash.exe -b 10001 192.168.10.233 22222 ipserver.hex&lt;br /&gt;
&lt;br /&gt;
bzw.&lt;br /&gt;
&lt;br /&gt;
  ./ipflash -b 10001 192.168.10.233 22222 ipserver.hex&lt;br /&gt;
&lt;br /&gt;
In diesem Fall schickt das Flash-Programm zunächst den Boot-Befehl auf Port 10001, wartet dann ein paar Sekunden und führt dann erst den eigentlichen Flash-Prozess aus. So kann man dann bequem vom Arbeitsplatz aus alle [[IRMP]]-Netzwerkserver im Haushalt aktualisieren, ohne direkt &amp;quot;vor Ort&amp;quot; zu sein.&lt;br /&gt;
&lt;br /&gt;
== Android-Software ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:Remote-IRMP-Screenshot2.png|thumb|Anlernen eines IR-Befehls]]&lt;br /&gt;
&lt;br /&gt;
=== Merkmale ===&lt;br /&gt;
&lt;br /&gt;
* Ansteuerung von mehreren im Haushalt verteilten IRMP-Satelliten&lt;br /&gt;
* Erstellung von mehreren Bildschirmseiten&lt;br /&gt;
* Frei definierbares Tastenfeld pro Bildschirmseite&lt;br /&gt;
* Anlernen von IR-Codes&lt;br /&gt;
* Senden von IR-Codes&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration ===&lt;br /&gt;
&lt;br /&gt;
Nach dem ersten Start der App sollte zunächst mindestens ein Remote-IRMP-Satellit konfiguriert werden. Dazu wählt man unter dem Menü den Punkt &amp;quot;Server&amp;quot; an und wählt den ersten Server aus. Hier kann man einen Namen wählen, z.B. &amp;quot;Wohnzimmer&amp;quot;. Nach Eingabe der IP-Adresse und des UDP-Ports (i.d.R. 10001) kann man zunächst die Verbindung testen. War diese erfolgreich, speichert man die Serverkonfiguration mit &amp;quot;OK&amp;quot; ab.&lt;br /&gt;
&lt;br /&gt;
=== Bearbeiten ===&lt;br /&gt;
&lt;br /&gt;
In der App sind bereits einige Geräte und ein paar Tasten als Beispiel gespeichert. Die verschiedenen Bildschirmseiten kann man durch Wischen nach links oder rechts anwählen.&lt;br /&gt;
&lt;br /&gt;
Mit der Anwahl des Menüpunktes &amp;quot;Bearbeiten&amp;quot; kann man nun eine (oder direkt mehrere) Seiten ändern. Oben erscheint dann eine zusätzliche Schaltfläche zum Speichern. Unmittelbar darunter kann die Bezeichnung der Seite geändert werden.&lt;br /&gt;
&lt;br /&gt;
Die bisherigen Tasten werden nun etwas nach unten hin &amp;quot;gestreckt&amp;quot; gezeigt. Das ist Absicht: Die Leerzeilen repräsentieren nämlich später jeweils einen kleinen Abstand zwischen Tastenzeilen. Tippt man nun auf eine leere Fläche, erscheint dort eine neue Taste. Durch erneutes Antippen wird die Konfiguration der Taste geöffnet. Nach Eingabe einer Bezeichnung (Bitte keine Smilies o.ä. eingeben, das kann beim Speichern im Moment noch die Konfiguration zerschiessen!) kann man nun die Taste anlernen. Dafür tippt man die Anlernen-Schaltfläche an. Nun hat man 5 Sekunden Zeit, die gewünschte Taste anzulernen, indem man sie auf der Fernbedienung drückt und dabei auf den IR-Empfänger zielt. Nun sollte das Protokoll, die Adresse und das Kommando erscheinen. Man kann diese Parameter zwar auch manuell eingeben, jedoch ist die Übernahme durch Anlernen doch um einiges einfacher.&lt;br /&gt;
&lt;br /&gt;
Nach dem Speichern sollte ein kurzes Antippen der konfigurierten Tasten den Remote-IRMP-Sender dazu bewegen, den vorher angelernten IR-Code wieder auszusenden.&lt;br /&gt;
&lt;br /&gt;
Eine Taste kann durch langes Drücken im Bearbeitungsmodus gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
(Beschreibung wird fortgesetzt)&lt;br /&gt;
&lt;br /&gt;
=== Weitere Planung ===&lt;br /&gt;
&lt;br /&gt;
* Erweiterung um Graphiksymbole für die Tasten&lt;br /&gt;
* Makros, um mehrere nachfolgende Befehle über eine Taste zu senden&lt;br /&gt;
* Anlernen von Funksteckdosen-Fernbedienungen&lt;br /&gt;
&lt;br /&gt;
== Andere Betriebssysteme als Clients ==&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, für andere Betriebssysteme einen Remote-IRMP-Client zu entwickeln. Ein entsprechendes C-Programm inkl. Quelltext, welches [[IRMP]]-Codes an einen [[IRMP]]-Satelliten schickt bzw. die angelernten Codes empfängt, habe ich beigefügt. Der C-Quelltext ist unter Unix, Linux und Windows compilierbar. Dieses Testprogramm ist als Vorlage für ambitionierte Anwender gedacht, die selbst ein eigenes PC-Projekt für Remote-IRMP realisieren möchten.&lt;br /&gt;
&lt;br /&gt;
Als Executable für Windows kann man auch einfach ipclient.exe benutzen, unter Unix bzw. Linux kompiliert man das Programm selbst mit:&lt;br /&gt;
&lt;br /&gt;
    cc -O win32/ipclient/ipclient.c -o ipclient&lt;br /&gt;
&lt;br /&gt;
=== Aufruf des Testprogramms ===&lt;br /&gt;
&lt;br /&gt;
Allgemeiner Aufruf:&lt;br /&gt;
&lt;br /&gt;
IR-Code senden über UDP:&lt;br /&gt;
&lt;br /&gt;
    ipclient udpsend ipaddress udp-port ir-protocol ir-addr-in-hex ir-command-in-hex flag-in-hex&lt;br /&gt;
&lt;br /&gt;
IR-Code senden über TCP:&lt;br /&gt;
&lt;br /&gt;
    ipclient send ipaddress tcp-port ir-protocol ir-addr-in-hex ir-command-in-hex flag-in-hex&lt;br /&gt;
&lt;br /&gt;
IR-Code empfangen über UDP:&lt;br /&gt;
&lt;br /&gt;
    ipclient udprec ipaddress udp-port&lt;br /&gt;
&lt;br /&gt;
IR-Code empfangen über TCP:&lt;br /&gt;
&lt;br /&gt;
    ipclient rec ipaddress tcp-port&lt;br /&gt;
&lt;br /&gt;
=== Beispiel: Senden eines IRMP-Codes ===&lt;br /&gt;
&lt;br /&gt;
IR-Code senden über UDP, z.B. NEC-Protokoll (Nr. 2), Adresse 0xFF00, Kommando: 0x0020, Flag: 0x00&lt;br /&gt;
&lt;br /&gt;
Der Aufruf ist dann in der Windows-Eingabeaufforderung:&lt;br /&gt;
&lt;br /&gt;
    ipclient.exe udpsend 192.168.10.233 10001 2 FF00 0020 0&lt;br /&gt;
&lt;br /&gt;
bzw. unter Linux:&lt;br /&gt;
&lt;br /&gt;
    ./ipclient udpsend 192.168.10.233 10001 2 FF00 0020 0&lt;br /&gt;
&lt;br /&gt;
Wichtig ist dabei, dass die Protokollnummer in dezimal, alle anderen IR-Parameter in hexadezimal angegeben werden. Eine Liste der IR-Protokollnummern findet man hier: [http://www.mikrocontroller.net/svnbrowser/irmp/irmpprotocols.h?view=markup irmpprotocols.h]&lt;br /&gt;
&lt;br /&gt;
=== Beispiel: Empfangen eines IRMP-Codes ===&lt;br /&gt;
&lt;br /&gt;
Man kann natürlich auch IR-Telegramme empfangen, z.B. über TCP mit dem folgenden Befehl:&lt;br /&gt;
&lt;br /&gt;
Windows-Eingabeaufforderung:&lt;br /&gt;
&lt;br /&gt;
    ipclient.exe rec 192.168.10.233 10001&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
&lt;br /&gt;
    ./ipclient rec 192.168.10.233 10001&lt;br /&gt;
&lt;br /&gt;
Sendet man nun innerhalb von 5 Sekunden mit irgendeiner Fernbedienung ein Signal an den IR-Empfänger, wird dieses dann als [[IRMP]]-Code (Protokoll, Adresse, Kommando, Flag) auf dem PC ausgegeben.&lt;br /&gt;
&lt;br /&gt;
== Downloads ==&lt;br /&gt;
&lt;br /&gt;
==== Remote-IRMP für AVR, Unix, Linux, Windows ====&lt;br /&gt;
&lt;br /&gt;
Version 1.0: [[Datei:Remote-irmp.zip]]&lt;br /&gt;
&lt;br /&gt;
==== Remote-Butler als Client für Android ====&lt;br /&gt;
&lt;br /&gt;
Version 1.0: [[Datei:RemoteButler.apk]]&lt;br /&gt;
&lt;br /&gt;
Das einfachste, um die App unter Android zu installieren, ist es, den obigen Download-Link direkt auf dem Handy anzuklicken.&lt;br /&gt;
&lt;br /&gt;
Java-Sources für Interessierte:  [[Datei:Remotebutler.zip]]&lt;br /&gt;
&lt;br /&gt;
==== Dateiliste ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Dateiname || Erläuterung&lt;br /&gt;
|-&lt;br /&gt;
| ipbootloader.aps || AVR Studio4 Projektdatei des Bootloaders&lt;br /&gt;
|- &lt;br /&gt;
| ipbootloader.c || main-Modul des Bootloaders&lt;br /&gt;
|- &lt;br /&gt;
| &lt;br /&gt;
|- &lt;br /&gt;
| ipserver.aps || AVR Studio4 Projektdatei des IP-Servers&lt;br /&gt;
|- &lt;br /&gt;
| ipserver.c || main-Modul des IP-Servers&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/svnbrowser/irmp/irmp.c?view=markup irmp.c] || Der eigentliche IR-Decoder&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/svnbrowser/irmp/irmp.h?view=markup irmp.h] || Include-Datei für IRMP-Projekte&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/svnbrowser/irmp/irmpconfig.h?view=markup irmpconfig.h] || Konfiguration für IRMP&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/svnbrowser/irmp/irmpextlog.c?view=markup irmpextlog.c] || IRMP-Logging für Nicht-AVR-µCs&lt;br /&gt;
|- &lt;br /&gt;
| irmpextlog.h || IRMP-Interne Include-Datei&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/svnbrowser/irmp/irmpprotocols.h?view=markup irmpprotocols.h] || Sämtliche Definitionen zu den IR-Protokollen&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/svnbrowser/irmp/irmpsystem.h?view=markup irmpsystem.h] || Vom Zielsystem abhängige Definitionen für AVR/PIC/STM32&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/svnbrowser/irmp/irsnd.c?view=markup irsnd.c] || Der eigentliche IR-Encoder&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/svnbrowser/irmp/irsnd.h?view=markup irsnd.h] || Include-Datei für die Applikation&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/svnbrowser/irmp/irsndconfig.h?view=markup irsndconfig.h] || Anzupassende Konfigurationsdatei&lt;br /&gt;
|- &lt;br /&gt;
| &lt;br /&gt;
|- &lt;br /&gt;
| w5100.c || Treiber-Modul für WIZnet W5100 Netzwerk-Controller&lt;br /&gt;
|- &lt;br /&gt;
| w5100.h || Include-Datei für W5100-Treiber&lt;br /&gt;
|- &lt;br /&gt;
| w5100config.h|| Konfigurationsdatei für W5100-Treiber&lt;br /&gt;
|- &lt;br /&gt;
| &lt;br /&gt;
|- &lt;br /&gt;
| ipclient.exe || ipclient-Executable für Windows&lt;br /&gt;
|- &lt;br /&gt;
| ipflash.exe || ipflash-Executable für Windows&lt;br /&gt;
|- &lt;br /&gt;
|&lt;br /&gt;
|- &lt;br /&gt;
| win32/ipclient/ipclient.c || Beispiel Client in C - übersetzbar unter Unix, Linux und Windows&lt;br /&gt;
|- &lt;br /&gt;
| win32/ipclient/ipclient.sln || gehört zu ipclient - für Microsoft Visual C++ 2010 Express&lt;br /&gt;
|- &lt;br /&gt;
| win32/ipclient/ipclient.suo || gehört zu ipclient - für Microsoft Visual C++ 2010 Express&lt;br /&gt;
|- &lt;br /&gt;
| win32/ipclient/ipclient.vcxproj || Projekt-Datei für Microsoft Visual C++ 2010 Express&lt;br /&gt;
|- &lt;br /&gt;
| &lt;br /&gt;
|- &lt;br /&gt;
| win32/ipflash/ipflash.c || Flash-Programm in C - übersetzbar unter Unix, Linux und Windows&lt;br /&gt;
|- &lt;br /&gt;
| win32/ipflash/ipflash.sln || gehört zu ipflash - für Microsoft Visual C++ 2010 Express&lt;br /&gt;
|- &lt;br /&gt;
| win32/ipflash/ipflash.suo || gehört zu ipflash - für Microsoft Visual C++ 2010 Express&lt;br /&gt;
|- &lt;br /&gt;
| win32/ipflash/ipflash.vcxproj || Projekt-Datei für Microsoft Visual C++ 2010 Express&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/329407 Thread im Forum zu diesem Projekt]&lt;br /&gt;
* [[IRMP]]&lt;br /&gt;
* [http://ethersex.de/index.php/IRMP Portierung nach Ethersex]&lt;br /&gt;
&lt;br /&gt;
Viel Spaß mit Remote IRMP!&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Infrarot]]&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Remote_IRMP&amp;diff=86304</id>
		<title>Remote IRMP</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Remote_IRMP&amp;diff=86304"/>
		<updated>2014-12-20T09:51:32Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Von &#039;&#039;&#039;Frank M. ([http://www.mikrocontroller.net/user/show/ukw ukw])&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Datei:Remote-IRMP-Screenshot1.png|thumb|Frei gestaltbare Tasten zum Senden von IR-Befehlen]]&lt;br /&gt;
&lt;br /&gt;
Dieser Artikel ist eine konkrete Anwendung des [[IRMP]]-Projekts (IRMP-Dekoder = Infrarot-Multiprotokoll-Dekoder). Wir verschaffen unserem Mikrocontroller nicht nur einen IR-Sender und Empfänger, sondern auch noch einen Netzwerkanschluss. Damit wird es möglich, mit einer Android-App eine anlernbare IR-Fernbedienung zu realisieren. Der Anwender kann dann mehrere Geräte, die irgendwo im Haushalt verteilt sind, über das Handy steuern. Dabei sendet die App über WLAN zuvor gespeicherte [[IRMP]]-Codes an den gewünschten µC. Dieser strahlt dann die Signale über den IR-Sender aus, um damit unsere Geräte aus der Unterhaltungsindustrie zu schalten.&lt;br /&gt;
&lt;br /&gt;
Außerdem ist eine Erweiterung von [[IRMP]] um Funksender geplant, damit zukünftig auch Funksteckdosen bequem vom Handy aus geschaltet werden können.&lt;br /&gt;
&lt;br /&gt;
== Merkmale ==&lt;br /&gt;
&lt;br /&gt;
Folgende Funktionalitäten sind bereits umgesetzt:&lt;br /&gt;
&lt;br /&gt;
* Anbindung des µC an einen Wiznet W5100 Ethernet-Controller&lt;br /&gt;
* Protokollschnittstelle über TCP/IP und UDP&lt;br /&gt;
* Testprogramme der Kommunikation für Unix, Linux und Windows&lt;br /&gt;
* Android-App mit frei konfigurierbaren Bedienertasten/Bildschirmseiten&lt;br /&gt;
* Anlernen von IR-Codes mit Speicherung unter Android&lt;br /&gt;
* Senden der IR-Codes über WLAN an den Remote-IRMP Controller&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:Remote-irmp-schaltung-arduino.png|thumb|Schaltbild des Prototyps als Shield für Arduino Ethernet]]&lt;br /&gt;
&lt;br /&gt;
Der stabil laufende Prototyp wurde mit dem Arduino Ethernet Board (erhältlich z.B. bei [http://www.pollin.de/shop/dt/MTA4OTgxOTk-/Bausaetze_Module/Entwicklerboards/ARDUINO_Ethernet.html Pollin]) realisiert - jedoch ohne die Verwendung der Arduino-Bibliotheken bzw. Arduino-Software. Die Verwendung des fertigen Boards hatte den Vorteil, dass der Lötaufwand sich auf ein Minimum reduziert: Es muss lediglich je ein IR-Sender- und ein Empfänger-Modul angeschlossen werden. Diese Module bestehen lediglich aus ein paar Bauteilen, welche hier auf eine Lochraster-Platine gelötet werden. Die Lochraster-Platine wird dann einfach als Shield auf das Arduino-Board aufgesteckt. Das Schaltbild dazu ist rechts zu sehen.&lt;br /&gt;
&lt;br /&gt;
Dabei ist:&lt;br /&gt;
&lt;br /&gt;
  * 0C0A = PD6 oder in der Arduino-Nomenklatur: Digital Pin 6&lt;br /&gt;
  * PC0 in der Arduino-Schreibweise: Analog Input 0.&lt;br /&gt;
&lt;br /&gt;
Die für den Prototyp entwickelte Software funktioniert aber auch mit einem WIZnet WIZ812MJ-Modul, welches man zum Beispiel bei [http://www.watterott.com/de/WIZnet-WIZ812MJ-Ethernet-Modul Watterott] erstehen kann. Dieses Modul wird dann auf eine eigens zu entwickelnde Platine aufgesteckt.&lt;br /&gt;
&lt;br /&gt;
Die dafür notwendige Hauptplatine als endgültige Version mit ATmega, Infrarot-Sender/Empfänger und Funksteckdosen-Sendermodul ist noch nicht ganz fertig - dazu später mehr. Der Prototyp mit dem Arduino Ethernet Board ist aber durchaus jetzt schon einsatzfähig.&lt;br /&gt;
&lt;br /&gt;
== Protokoll ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:Remote-IRMP-Screenshot3.png|thumb|Beispiel für einen DVD-Player]]&lt;br /&gt;
&lt;br /&gt;
Das Kommunikationsprotokoll für die Remote-IRMP-Satelliten wurde bewusst einfach gehalten. Dabei kann sowohl TCP/IP als auch UDP verwendet werden.&lt;br /&gt;
&lt;br /&gt;
=== Senden eines IRMP-Codes ===&lt;br /&gt;
&lt;br /&gt;
In diesem Fall sind 7 Bytes zu übertragen:&lt;br /&gt;
&lt;br /&gt;
* Byte 1: &#039;S&#039; als Kommmando &amp;quot;Send&amp;quot;&lt;br /&gt;
* Byte 2: [[IRMP]]-Protokollnummer&lt;br /&gt;
* Byte 3: Upper Byte der [[IRMP]]-Adresse&lt;br /&gt;
* Byte 4: Lower Byte der [[IRMP]]-Adresse&lt;br /&gt;
* Byte 5: Upper Byte des [[IRMP]]-Kommandos&lt;br /&gt;
* Byte 6: Lower Byte des [[IRMP]]-Kommandos&lt;br /&gt;
* Byte 7: [[IRMP]]-Flag&lt;br /&gt;
&lt;br /&gt;
Antwort:&lt;br /&gt;
&lt;br /&gt;
* Byte 1: &#039;S&#039;&lt;br /&gt;
* Byte 2: &#039;+&#039; im Erfolgsfall&lt;br /&gt;
&lt;br /&gt;
oder:&lt;br /&gt;
&lt;br /&gt;
* Byte 1: &#039;S&#039;&lt;br /&gt;
* Byte 2: &#039;-&#039; als Fehlercode, wenn das Protokoll unbekannt ist.&lt;br /&gt;
&lt;br /&gt;
=== Empfangen eines IRMP-Codes (Anlernen) ===&lt;br /&gt;
&lt;br /&gt;
Es wird lediglich 1 Byte gesandt:&lt;br /&gt;
&lt;br /&gt;
* Byte 1: &#039;R&#039; als Kommmando &amp;quot;Receive&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Wenn man als Anwender innerhalb von 5 Sekunden nun eine Fernbedienung betätigt, wird der angelernte Code als Antwort zurückgeschickt, nämlich:&lt;br /&gt;
&lt;br /&gt;
* Byte 1: &#039;R&#039; als Bestätigung&lt;br /&gt;
* Byte 2: &#039;+&#039; als Erfolgscode&lt;br /&gt;
* Byte 3: [[IRMP]]-Protokollnummer&lt;br /&gt;
* Byte 4: Upper Byte der [[IRMP]]-Adresse&lt;br /&gt;
* Byte 5: Lower Byte der [[IRMP]]-Adresse&lt;br /&gt;
* Byte 6: Upper Byte des [[IRMP]]-Kommandos&lt;br /&gt;
* Byte 7: Lower Byte des [[IRMP]]-Kommandos&lt;br /&gt;
* Byte 8: [[IRMP]]-Flag&lt;br /&gt;
&lt;br /&gt;
Sollte keine Fernbedienungstaste betätigt oder das verwendete IR-Protokoll von [[IRMP]] nicht verstanden werden, werden als Antwort auch 8 Bytes zurückgesandt, aber:&lt;br /&gt;
&lt;br /&gt;
* Byte 1: &#039;R&#039; als Bestätigung&lt;br /&gt;
* Byte 2: &#039;-&#039; als Fehlercode&lt;br /&gt;
* Byte 3-8: 0x00&lt;br /&gt;
&lt;br /&gt;
=== Weitere Netzwerkbefehle ===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Remote-IRMP-Screenshot4.png|thumb|Bis zu 8 Remote-IRMP Server sind ansprechbar]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Außerdem wurde noch ein Kommando eingebaut, um die Kommunikation über IP selbst zu testen:&lt;br /&gt;
&lt;br /&gt;
* Byte 1: &#039;P&#039; als &amp;quot;Ping&amp;quot;-Kommando&lt;br /&gt;
&lt;br /&gt;
Antwort:&lt;br /&gt;
&lt;br /&gt;
* Byte 1: &#039;P&#039; als Bestätigung&lt;br /&gt;
* Byte 2: &#039;+&#039; als Erfolgscode&lt;br /&gt;
&lt;br /&gt;
Es gibt noch ein weiteres Kommando - dieses jedoch nur für TCP/IP, nicht für UDP:&lt;br /&gt;
&lt;br /&gt;
* Byte 1: &#039;B&#039; als Bootloader-Sprungkommando&lt;br /&gt;
&lt;br /&gt;
Es kommt keine Antwort zurück, sondern der ATmega328 springt dann direkt in den Ethernet-Bootloader, damit man ein Update flashen kann, ohne extra die RESET-Taste drücken zu müssen. Siehe dazu auch das Kapitel [http://www.mikrocontroller.net/articles/Remote_IRMP#Bootloader_-_Flashen_.C3.BCbers_Netzwerk Bootloader - Flashen übers Netzwerk].&lt;br /&gt;
&lt;br /&gt;
== IRMP-Software mit LAN-Anbindung ==&lt;br /&gt;
&lt;br /&gt;
Der Source-Code lässt sich einfach für AVR-µCs übersetzen, indem man unter Windows die Projekt-Datei ipserver.aps in das AVR Studio 4 lädt. Jedoch sollte der avr-gcc schon ein neuerer sein, als ursprünglich mal 2010 mit dem AVR Studio 4 ausgeliefert wurde. Ich persönlich nutze avr-gcc 4.7.2.&lt;br /&gt;
&lt;br /&gt;
Bei neueren Entwicklungsumgebungen bzw. Linux ist es auch kein Problem, ein eigenes Projekt bzw. Makefile zu erstellen. Folgende Sources müssen dafür ins Projekt übernommen werden:&lt;br /&gt;
&lt;br /&gt;
* ipserver.c - das main-Modul&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irmp.c?view=markup irmp.c] - der IR-Multiprotokoll-Decoder&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irsnd.c?view=markup irsnd.c] - der IR-Encoder&lt;br /&gt;
* w5100.c - der Wiznet W5100 Treiber&lt;br /&gt;
&lt;br /&gt;
Zum Projekt gehören dann noch folgende Includes:&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irmp.h?view=markup irmp.h]&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irmpconfig.h?view=markup irmpconfig.h]&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irmpextlog.h?view=markup irmpextlog.h]&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irmpprotocols.h?view=markup irmpprotocols.h]&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irmpsystem.h?view=markup irmpsystem.h]&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irsnd.h?view=markup irsnd.h]&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irsndconfig.h?view=markup irsndconfig.h]&lt;br /&gt;
* w5100.h&lt;br /&gt;
* w5100config.h&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bitte KEINE weiteren C-Module (wie z.B. ipbootloader.c) im Projekt angeben!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Zusatzlich zu den Standard-Compiler-Optionen (Prozessor-Typ etc.) sollten dem Projekt für alle C-Dateien folgende Optionen hinzugefügt werden:&lt;br /&gt;
&lt;br /&gt;
  -DF_CPU=16000000UL&lt;br /&gt;
  -Os&lt;br /&gt;
  -flto&lt;br /&gt;
  -ffunction-sections&lt;br /&gt;
  -fdata-sections&lt;br /&gt;
&lt;br /&gt;
Als Linker-Optionen:&lt;br /&gt;
&lt;br /&gt;
  -Os&lt;br /&gt;
  -flto&lt;br /&gt;
  -ffunction-sections&lt;br /&gt;
  -fdata-sections&lt;br /&gt;
  -Wl,--gc-sections&lt;br /&gt;
&lt;br /&gt;
=== Fuses ===&lt;br /&gt;
Wichtig sind auch die Fuses. Wenn das Arduino Ethernet Board verwendet wird, muss auf jeden Fall der standardmäßig installierte Bootloader deaktiviert werden. Aber auch für eine eigene Platine müssen die Fuses angepasst werden, nämlich auf:&lt;br /&gt;
&lt;br /&gt;
* lfuse: 0xFF&lt;br /&gt;
* hfuse: 0xD1&lt;br /&gt;
* efuse: 0xFD&lt;br /&gt;
&lt;br /&gt;
Nur wenn der eigene IP-Bootloader auch verwendet werden soll, ist die hfuse nochmals zu ändern. Das ist dann im [http://www.mikrocontroller.net/articles/Remote_IRMP#Bootloader_-_Flashen_.C3.BCbers_Netzwerk Bootloader-Kapitel] weiter unten nachzulesen.&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration ===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Remote-IRMP-Screenshot5.png|thumb|Konfiguration und Test eines Remote-IRMP Servers]]&lt;br /&gt;
&lt;br /&gt;
Es können etliche Parameter angepasst werden. Hier die wichtigsten Einstellungen:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ipserver.c&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define DEBUG                       1&lt;br /&gt;
&lt;br /&gt;
#define MAC_ADDRESS                 {0x90,0xA2,0xDA,0x00,0xF4,0x65}         // mac address&lt;br /&gt;
#define IP_ADDRESS                  {192,168,10,233}                        // ip address&lt;br /&gt;
#define IP_NETMASK                  {255,255,255,0}                         // netmask&lt;br /&gt;
#define IP_GATEWAY                  {192,168,10,1}                          // gateway address&lt;br /&gt;
&lt;br /&gt;
#define DBG_PORT                    10000                                   // debug tcp listen port&lt;br /&gt;
#define TCP_PORT                    10001                                   // normal tcp listen port&lt;br /&gt;
#define UDP_PORT                    10001                                   // udp port&lt;br /&gt;
&lt;br /&gt;
#define LED_DDR                     DDRB&lt;br /&gt;
#define LED_PORT                    PORTB&lt;br /&gt;
#define LED_BIT                     PB1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Als MAC-Adresse (MAC_ADDRESS) wählt man beim Arduino Ethernet Board am besten die aufgeklebte MAC-Adresse. Dann kann es nicht zu Konflikten kommen. Die IP-Adresse (IP_ADDRESS) sollte an das lokale Netzwerk angepasst werden. Ebenso die Netzwerkmaske (IP_NETMASK), wenn sie im lokalen Netz abweicht. Die Angabe eines Gateways (IP_GATEWAY) ist nicht unbedingt notwendig, wenn die [[IRMP]]-Server nur im lokalen Netz erreichbar sein sollen. In diesem Fall kann {0,0,0,0} angegeben werden.&lt;br /&gt;
&lt;br /&gt;
Normalerweise horchen die [[IRMP]]-Server auf dem TCP- und UDP-Port 10001. Wenn gewünscht, können die Ports sowohl für TCP (TCP_PORT) als auch für UDP (UDP_PORT) geändert werden. Sie können auch verschieden sein. Normalerweise ist aber eine Änderung nicht notwendig.&lt;br /&gt;
&lt;br /&gt;
Bleibt noch der Debug-Port (DBG_PORT). Nur wenn die Präprozessor-Konstante DEBUG auf 1 steht, spielt dieser eine Rolle. Dann protokolliert der [[IRMP]]-Server nämlich alle eingehenden [[IRMP]]-Befehle, wenn man eine telnet-Session für die konfigurierte IP-Adresse und den Debug-Port öffnet. Unter Windows eignet sich dafür hervorragend PuTTY, welches man aus dem Internet herunterladen kann. Bei unixoiden Systemen ist telnet sowieso verfügbar - meist schon standardmäßig installiert.&lt;br /&gt;
&lt;br /&gt;
Wird Debugging nicht gewünscht, kann man DEBUG auf 0 setzen und der Wert des DBG_PORTs wird irrelevant.&lt;br /&gt;
&lt;br /&gt;
Außerdem gibt es noch die Definitionen für eine am ATmega angeschlossene LED (Konstanten LED_xxx). Hier werden dann ausgesandte IR-Signale parallel auf der LED visualisiert. Außerdem leuchtet diese LED, solange man einen IR-Code anlernt.&lt;br /&gt;
&lt;br /&gt;
Die obigen Werte dafür entsprechen der bereits vorhandenen LED auf dem Arduino-Board. Sie können natürlich für andere Hardware (z.B. eigene Platine mit WIZ812MJ-Modul) angepasst werden. Besser: Man wählt beim Entwurf einer eigenen Hauptplatine einfach denselben Port.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;w5100config.h&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define CHIP_SELECT_AVAILABLE       0            // set to 1 if CS will be controlled by other pin than SS of the µC &lt;br /&gt;
#define CHIP_RESET_AVAILABLE        0            // set to 1 if RESET can be controlled by µC&lt;br /&gt;
&lt;br /&gt;
#if CHIP_SELECT_AVAILABLE == 1                   // if CS can be controlled , enter port/pin of µC&lt;br /&gt;
#  define CS_DDR                    DDRD&lt;br /&gt;
#  define CS_PORT                   PORTD&lt;br /&gt;
#  define CS_BIT                    4&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#if CHIP_RESET_AVAILABLE == 1                    // if RESET can be controlled by µC, enter port/pin of µC&lt;br /&gt;
#  define RESET_DDR                 DDRD&lt;br /&gt;
#  define RESET_PORT                PORTD&lt;br /&gt;
#  define RESET_BIT                 5&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die obigen Konstanten beschreiben, wie der W5100-Controller an den ATmega angebunden ist.&lt;br /&gt;
&lt;br /&gt;
Ist CS (Chip-Select) des W5100 &#039;&#039;&#039;nicht&#039;&#039;&#039; an SS des ATmegas angeschlossen, muss CHIP_SELECT_AVAILABE auf 1 gesetzt werden und mittels CS_xxx-Konstanten der für CS verwendete Port-Pin des ATmegas angegeben werden, damit der ATmega softwaremäßig den Ethernet-Controller aktivieren kann. Beim Arduino Ethernet Board ist CS mit SS fest verbunden, so dass CHIP_SELECT_AVAILABLE auf 0 stehen bleibt und die CS_xxx-Konstanten nicht weiter beachtet werden.&lt;br /&gt;
&lt;br /&gt;
Muss der W5100-Controller explizit über den RESET-Pin softwaremäßig zurückgesetzt werden, dann sollte dies über den ATmega geschehen. In diesem Fall setzt man CHIP_RESET_AVAILABLE auf 1 und definiert weiter unten den Portpin (RESET_xxx), an welchem ATmega-Portpin der RESET-Pin des W51000 angeschlossen ist. Beim Arduino Ethernet Board hängt der W5100 an einer eigenen Hardware-Reset-Schaltung, so dass CHIP_SELECT_AVAILABLE auf 0 stehenbleiben kann und damit die RESET_xxx-Konstanten irrelevant werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;irmpconfig.h&#039;&#039;&#039; und &#039;&#039;&#039;irsndconfig.h&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Die Konstanten in den [[IRMP]]-Konfigurationsdateien sind ausführlich im [[IRMP]]-Artikel erklärt. Daher wird hier auf weitere Erläuterungen verzichtet. Im wesentlichen wird hier definiert, welche Pins am ATmega für den IR-Empfänger und für den IR-Sender verwendet werden. Die Port-Einstellungen sind hier vorgewählt auf das oben bereits erwähnte Lochraster-Arduino-Ethernet-Shield - siehe Schaltbild. Ausserdem kann man hier die IR-Protokolle auswählen, die [[IRMP]]/IRSND mit einbinden soll. Insgsamt sind 36 Protokolle wählbar. Die häufigsten 6 Protokolle sind bereits aktiviert.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Erster Start&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Der erste Start mit dem Arduino Ethernet Board kann durchaus auch ohne selbstgebautes &amp;quot;Shield&amp;quot; auf Lochrasterplatine gewagt werden. Hierzu wird die vom Compiler erzeugte Hex-Datei über den 6-poligen ISP-Stecker des Boards eingespielt. [http://www.mikrocontroller.net/articles/Remote_IRMP#Fuses Fuses] nicht vergessen! Anschließend sollte man vom PC aus das Modul per ping-Befehl ansprechen können. Wenn das funktioniert, ist man schon fast am Ziel. Nun sollte man das Board von der Stromversorgung trennen und die Platine mit IR-Empfänger und Sender als Shield aufstecken. Nach Neustart kann man nun entweder direkt die Funktionen mit der [http://www.mikrocontroller.net/articles/Remote_IRMP#Android-Software Android-App] testen oder erstmal mit einem [http://www.mikrocontroller.net/articles/Remote_IRMP#Andere_Betriebssysteme_als_Clients PC-Testprogramm], siehe weiter unten.&lt;br /&gt;
&lt;br /&gt;
Ganz Mutige lassen das aber mit dem Programmieren der Remote-IRMP-Software über den ISP, sondern installieren direkt den [http://www.mikrocontroller.net/articles/Remote_IRMP#Bootloader_-_Flashen_.C3.BCbers_Netzwerk Bootloader], siehe weiter [http://www.mikrocontroller.net/articles/Remote_IRMP#Bootloader_-_Flashen_.C3.BCbers_Netzwerk unten]. Anschließend kann man beliebig oft die IRMP-Software oder Updates davon direkt übers Netzwerk installieren.&lt;br /&gt;
&lt;br /&gt;
== Bootloader - Flashen übers Netzwerk ==&lt;br /&gt;
&lt;br /&gt;
Wenn man schon einen netzwerkfähigen ATmega hat, dann möchte man Updates auch über das angesteckte Netzwerkkabel einspielen. Dafür wurde ein Bootloader entwickelt, welcher mit 1,6 KB Größe leicht in den oberen Flash-Bereich des ATmega328 passt. Das eigentliche Flash-Programm sendet dann per TCP/IP die Daten an den Bootloader. Das Flash-Programm ist für Unix, Linux und Windows verfügbar.&lt;br /&gt;
&lt;br /&gt;
=== Bootloader-Kommunikationsprotokoll ===&lt;br /&gt;
&lt;br /&gt;
* Bootloader (BL) horcht auf TCP/Port 22222 und wartet für 3 Sekunden auf das Zeichen &#039;$&#039; (1 Byte)&lt;br /&gt;
* Falls dieses eintrifft, antwortet BL ebenfalls mit dem &#039;$&#039;-Zeichen (1 Byte), anderenfalls hier Ende&lt;br /&gt;
* BL sendet die µC-spezifische &amp;quot;Page-Size&amp;quot; des Flashs zum Programmieren an den PC (1 Byte)&lt;br /&gt;
* PC sendet erste Page-Nummer des zu schreibenden Programms (2 Bytes, LSB, i.d.R. 0x00 0x00)&lt;br /&gt;
* PC sendet die Anzahl der zu übertragenden Pages (2 Bytes, LSB)&lt;br /&gt;
* PC sendet die Daten für eine Page - gefolgt von einem Prüfsummen-Byte&lt;br /&gt;
* BL antwortet mit &#039;1&#039;, wenn das Prüfsummen-Byte passt, anderenfalls mit &#039;0&#039; und bricht ab&lt;br /&gt;
* Weiter gehts mit der nächsten Page, also 2 Schritte höher...&lt;br /&gt;
&lt;br /&gt;
=== Bootloader-Software ===&lt;br /&gt;
&lt;br /&gt;
Der Source-Code lässt sich einfach für AVR-µCs übersetzen, indem man unter Windows die Projekt-Datei ipbootloader.aps in das AVR Studio 4 lädt. Der avr-gcc muss jedoch neuer sein als der, welcher ursprünglich im Jahre 2010 mit dem AVR Studio 4 ausgeliefert wurde. Empfehlung: avr-gcc 4.7.2 oder neuer.&lt;br /&gt;
&lt;br /&gt;
Bei neueren AVR-Entwicklungsumgebungen bzw. Linux ist es auch kein Problem, ein eigenes Projekt bzw. Makefile zu erstellen. Folgende Sources müssen dafür ins Projekt übernommen werden:&lt;br /&gt;
&lt;br /&gt;
* ipbootloader.c - der Bootloader&lt;br /&gt;
* w5100.c - der Wiznet W5100 Treiber&lt;br /&gt;
&lt;br /&gt;
Zum IP-Bootloader-Projekt gehören dann noch folgende Includes:&lt;br /&gt;
&lt;br /&gt;
* w5100.h&lt;br /&gt;
* w5100config.h&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bitte KEINE weiteren C-Module (wie z.B. ipserver.c o.ä.) im Projekt angeben!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Zusatzlich zu den Standard-Compiler-Optionen (Prozessor-Typ etc.) müssen dem Projekt für alle C-Dateien folgende Optionen hinzugefügt werden:&lt;br /&gt;
&lt;br /&gt;
  -DF_CPU=16000000UL&lt;br /&gt;
  -Os&lt;br /&gt;
  -flto&lt;br /&gt;
  -ffunction-sections&lt;br /&gt;
  -fdata-sections&lt;br /&gt;
&lt;br /&gt;
Als Linker-Optionen:&lt;br /&gt;
&lt;br /&gt;
  -Os&lt;br /&gt;
  -flto&lt;br /&gt;
  -ffunction-sections&lt;br /&gt;
  -fdata-sections&lt;br /&gt;
  -Wl,--gc-sections&lt;br /&gt;
  -Wl,--section-start=.text=0x7800&lt;br /&gt;
&lt;br /&gt;
Mit der letzten Linker-Option wird das Programm derart übersetzt, dass es ab Adresse 0x7800 lauffähig ist. Damit liegt es in den letzten 2KB des ATmega328-Flash-Speichers. Beim Übersetzen ist dringendst darauf zu achten, dass das Compilat eine &amp;quot;Program Size&amp;quot; von ca. 1,6KB hat. Wird es größer als 2KB, dann sind offensichtlich die obigen Compiler- und Linker-Optionen nicht korrekt eingetragen und das Programm ist als Bootloader unbrauchbar.&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration des Bootloaders ===&lt;br /&gt;
&lt;br /&gt;
Hier gelten im wesentlichen dieselben Konfigurationsparameter für w5100config.h wie [http://www.mikrocontroller.net/articles/Remote_IRMP#Konfiguration oben]. Wichtig ist die Anpassung der IP-Adresse, siehe dafür ipbootloader.c:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define MAC_ADDRESS     {0x90,0xA2,0xDA,0x00,0xF4,0x65}             // mac address&lt;br /&gt;
#define IP_ADDRESS      {192,168,10,233}                            // ip address&lt;br /&gt;
#define IP_NETMASK      {255,255,255,0}                             // netmask&lt;br /&gt;
#define IP_GATEWAY      {192,168,10,1}                              // gateway address&lt;br /&gt;
&lt;br /&gt;
#define TCP_PORT        22222                                       // listen port&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Fuses für den Bootloader ===&lt;br /&gt;
&lt;br /&gt;
Die Fuses sind in diesem Fall auf folgende Werte zu ändern:&lt;br /&gt;
&lt;br /&gt;
* lfuse: 0xFF&lt;br /&gt;
* hfuse: 0xD2&lt;br /&gt;
* efuse: 0xFD&lt;br /&gt;
&lt;br /&gt;
Damit werden die letzten 2KB im Flash für den Bootloader reserviert. Dieser kann dann über den ISP-Stecker installiert werden. Updates der Remote-IRMP-Software können anschließend bequem über das Netzwerk eingespielt werden. Der Anschluss eines ISP-Programmers ist dann nicht mehr notwendig.&lt;br /&gt;
&lt;br /&gt;
=== Flashprogramm ===&lt;br /&gt;
&lt;br /&gt;
Das Flashprogramm ist unter Unix, Linux und Windows verfügbar. Als Executable für Windows benutzt man einfach ipflash.exe, unter unixoiden System kompiliert man sich das Programm selbst mit:&lt;br /&gt;
&lt;br /&gt;
  cc -O win32/ipflash/ipflash.c -o ipflash&lt;br /&gt;
&lt;br /&gt;
Der Aufruf ist dann allgemein:&lt;br /&gt;
&lt;br /&gt;
  ipflash [-b ipserver-tcp-port] ip-address tcp-port hex-file&lt;br /&gt;
&lt;br /&gt;
oder konkret für die Windows-Eingabeaufforderung:&lt;br /&gt;
&lt;br /&gt;
  ipflash.exe 192.168.10.233 22222 ipserver.hex&lt;br /&gt;
&lt;br /&gt;
bzw. linux:&lt;br /&gt;
&lt;br /&gt;
  ./ipflash 192.168.10.233 22222 ipserver.hex&lt;br /&gt;
&lt;br /&gt;
Wichtig ist dabei, kurz vorher den RESET-Button auf dem Board zu drücken und dann innerhalb von 3 Sekunden das Flash-Programm zu starten.&lt;br /&gt;
&lt;br /&gt;
Ist einmal das ipserver-Programm installiert, kann man sich das Drücken des RESET-Buttons zukünftig auch sparen. Dann kann das Flash-Programm den ATmega auch über das Netzwerk resetten. Hierbei ist zusätzlich der TCP-Port des ipserver-Programms anzugeben, also:&lt;br /&gt;
&lt;br /&gt;
  ipflash.exe -b 10001 192.168.10.233 22222 ipserver.hex&lt;br /&gt;
&lt;br /&gt;
bzw.&lt;br /&gt;
&lt;br /&gt;
  ./ipflash -b 10001 192.168.10.233 22222 ipserver.hex&lt;br /&gt;
&lt;br /&gt;
In diesem Fall schickt das Flash-Programm zunächst den Boot-Befehl auf Port 10001, wartet dann ein paar Sekunden und führt dann erst den eigentlichen Flash-Prozess aus. So kann man dann bequem vom Arbeitsplatz aus alle [[IRMP]]-Netzwerkserver im Haushalt aktualisieren, ohne direkt &amp;quot;vor Ort&amp;quot; zu sein.&lt;br /&gt;
&lt;br /&gt;
== Android-Software ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:Remote-IRMP-Screenshot2.png|thumb|Anlernen eines IR-Befehls]]&lt;br /&gt;
&lt;br /&gt;
=== Merkmale ===&lt;br /&gt;
&lt;br /&gt;
* Ansteuerung von mehreren im Haushalt verteilten IRMP-Satelliten&lt;br /&gt;
* Erstellung von mehreren Bildschirmseiten&lt;br /&gt;
* Frei definierbares Tastenfeld pro Bildschirmseite&lt;br /&gt;
* Anlernen von IR-Codes&lt;br /&gt;
* Senden von IR-Codes&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration ===&lt;br /&gt;
&lt;br /&gt;
Nach dem ersten Start der App sollte zunächst mindestens ein Remote-IRMP-Satellit konfiguriert werden. Dazu wählt man unter dem Menü den Punkt &amp;quot;Server&amp;quot; an und wählt den ersten Server aus. Hier kann man einen Namen wählen, z.B. &amp;quot;Wohnzimmer&amp;quot;. Nach Eingabe der IP-Adresse und des UDP-Ports (i.d.R. 10001) kann man zunächst die Verbindung testen. War diese erfolgreich, speichert man die Serverkonfiguration mit &amp;quot;OK&amp;quot; ab.&lt;br /&gt;
&lt;br /&gt;
=== Bearbeiten ===&lt;br /&gt;
&lt;br /&gt;
In der App sind bereits einige Geräte und ein paar Tasten als Beispiel gespeichert. Die verschiedenen Bildschirmseiten kann man durch Wischen nach links oder rechts anwählen.&lt;br /&gt;
&lt;br /&gt;
Mit der Anwahl des Menüpunktes &amp;quot;Bearbeiten&amp;quot; kann man nun eine (oder direkt mehrere) Seiten ändern. Oben erscheint dann eine zusätzliche Schaltfläche zum Speichern. Unmittelbar darunter kann die Bezeichnung der Seite geändert werden.&lt;br /&gt;
&lt;br /&gt;
Die bisherigen Tasten werden nun etwas nach unten hin &amp;quot;gestreckt&amp;quot; gezeigt. Das ist Absicht: Die Leerzeilen repräsentieren nämlich später jeweils einen kleinen Abstand zwischen Tastenzeilen. Tippt man nun auf eine leere Fläche, erscheint dort eine neue Taste. Durch erneutes Antippen wird die Konfiguration der Taste geöffnet. Nach Eingabe einer Bezeichnung (Bitte keine Smilies o.ä. eingeben, das kann beim Speichern im Moment noch die Konfiguration zerschiessen!) kann man nun die Taste anlernen. Dafür tippt man die Anlernen-Schaltfläche an. Nun hat man 5 Sekunden Zeit, die gewünschte Taste anzulernen, indem man sie auf der Fernbedienung drückt und dabei auf den IR-Empfänger zielt. Nun sollte das Protokoll, die Adresse und das Kommando erscheinen. Man kann diese Parameter zwar auch manuell eingeben, jedoch ist die Übernahme durch Anlernen doch um einiges einfacher.&lt;br /&gt;
&lt;br /&gt;
Nach dem Speichern sollte ein kurzes Antippen der konfigurierten Tasten den Remote-IRMP-Sender dazu bewegen, den vorher angelernten IR-Code wieder auszusenden.&lt;br /&gt;
&lt;br /&gt;
Eine Taste kann durch langes Drücken im Bearbeitungsmodus gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
(Beschreibung wird fortgesetzt)&lt;br /&gt;
&lt;br /&gt;
=== Weitere Planung ===&lt;br /&gt;
&lt;br /&gt;
* Erweiterung um Graphiksymbole für die Tasten&lt;br /&gt;
* Makros, um mehrere nachfolgende Befehle über eine Taste zu senden&lt;br /&gt;
* Anlernen von Funksteckdosen-Fernbedienungen&lt;br /&gt;
&lt;br /&gt;
== Andere Betriebssysteme als Clients ==&lt;br /&gt;
&lt;br /&gt;
Es ist auch möglich, für andere Betriebssysteme einen Remote-IRMP-Client zu entwickeln. Ein entsprechendes C-Programm inkl. Quelltext, welches [[IRMP]]-Codes an einen [[IRMP]]-Satelliten schickt bzw. die angelernten Codes empfängt, habe ich beigefügt. Der C-Quelltext ist unter Unix, Linux und Windows compilierbar. Dieses Testprogramm ist als Vorlage für ambitionierte Anwender gedacht, die selbst ein eigenes PC-Projekt für Remote-IRMP realisieren möchten.&lt;br /&gt;
&lt;br /&gt;
Als Executable für Windows kann man auch einfach ipclient.exe benutzen, unter Unix bzw. Linux kompiliert man das Programm selbst mit:&lt;br /&gt;
&lt;br /&gt;
    cc -O win32/ipclient/ipclient.c -o ipclient&lt;br /&gt;
&lt;br /&gt;
=== Aufruf des Testprogramms ===&lt;br /&gt;
&lt;br /&gt;
Allgemeiner Aufruf:&lt;br /&gt;
&lt;br /&gt;
IR-Code senden über UDP:&lt;br /&gt;
&lt;br /&gt;
    ipclient udpsend ipaddress tcp-port ir-protocol ir-addr-in-hex ir-command-in-hex flag-in-hex&lt;br /&gt;
&lt;br /&gt;
IR-Code senden über TCP:&lt;br /&gt;
&lt;br /&gt;
    ipclient send ipaddress tcp-port ir-protocol ir-addr-in-hex ir-command-in-hex flag-in-hex&lt;br /&gt;
&lt;br /&gt;
IR-Code empfangen über UDP:&lt;br /&gt;
&lt;br /&gt;
    ipclient udprec ipaddress tcp-port&lt;br /&gt;
&lt;br /&gt;
IR-Code empfangen über TCP:&lt;br /&gt;
&lt;br /&gt;
    ipclient rec ipaddress tcp-port&lt;br /&gt;
&lt;br /&gt;
=== Beispiel: Senden eines IRMP-Codes ===&lt;br /&gt;
&lt;br /&gt;
IR-Code senden über UDP, z.B. NEC-Protokoll (Nr. 2), Adresse 0xFF00, Kommando: 0x0020, Flag: 0x00&lt;br /&gt;
&lt;br /&gt;
Der Aufruf ist dann in der Windows-Eingabeaufforderung:&lt;br /&gt;
&lt;br /&gt;
    ipclient.exe udpsend 192.168.10.233 10001 2 FF00 0020 0&lt;br /&gt;
&lt;br /&gt;
bzw. unter Linux:&lt;br /&gt;
&lt;br /&gt;
    ./ipclient udpsend 192.168.10.233 10001 2 FF00 0020 0&lt;br /&gt;
&lt;br /&gt;
Wichtig ist dabei, dass die Protokollnummer in dezimal, alle anderen IR-Parameter in hexadezimal angegeben werden. Eine Liste der IR-Protokollnummern findet man hier: [http://www.mikrocontroller.net/svnbrowser/irmp/irmpprotocols.h?view=markup irmpprotocols.h]&lt;br /&gt;
&lt;br /&gt;
=== Beispiel: Empfangen eines IRMP-Codes ===&lt;br /&gt;
&lt;br /&gt;
Man kann natürlich auch IR-Telegramme empfangen, z.B. über TCP mit dem folgenden Befehl:&lt;br /&gt;
&lt;br /&gt;
Windows-Eingabeaufforderung:&lt;br /&gt;
&lt;br /&gt;
    ipclient.exe rec 192.168.10.233 10001&lt;br /&gt;
&lt;br /&gt;
Linux:&lt;br /&gt;
&lt;br /&gt;
    ./ipclient rec 192.168.10.233 10001&lt;br /&gt;
&lt;br /&gt;
Sendet man nun innerhalb von 5 Sekunden mit irgendeiner Fernbedienung ein Signal an den IR-Empfänger, wird dieses dann als [[IRMP]]-Code (Protokoll, Adresse, Kommando, Flag) auf dem PC ausgegeben.&lt;br /&gt;
&lt;br /&gt;
== Downloads ==&lt;br /&gt;
&lt;br /&gt;
==== Remote-IRMP für AVR, Unix, Linux, Windows ====&lt;br /&gt;
&lt;br /&gt;
Version 1.0: [[Datei:Remote-irmp.zip]]&lt;br /&gt;
&lt;br /&gt;
==== Remote-Butler als Client für Android ====&lt;br /&gt;
&lt;br /&gt;
Version 1.0: [[Datei:RemoteButler.apk]]&lt;br /&gt;
&lt;br /&gt;
Das einfachste, um die App unter Android zu installieren, ist es, den obigen Download-Link direkt auf dem Handy anzuklicken.&lt;br /&gt;
&lt;br /&gt;
Java-Sources für Interessierte:  [[Datei:Remotebutler.zip]]&lt;br /&gt;
&lt;br /&gt;
==== Dateiliste ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Dateiname || Erläuterung&lt;br /&gt;
|-&lt;br /&gt;
| ipbootloader.aps || AVR Studio4 Projektdatei des Bootloaders&lt;br /&gt;
|- &lt;br /&gt;
| ipbootloader.c || main-Modul des Bootloaders&lt;br /&gt;
|- &lt;br /&gt;
| &lt;br /&gt;
|- &lt;br /&gt;
| ipserver.aps || AVR Studio4 Projektdatei des IP-Servers&lt;br /&gt;
|- &lt;br /&gt;
| ipserver.c || main-Modul des IP-Servers&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/svnbrowser/irmp/irmp.c?view=markup irmp.c] || Der eigentliche IR-Decoder&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/svnbrowser/irmp/irmp.h?view=markup irmp.h] || Include-Datei für IRMP-Projekte&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/svnbrowser/irmp/irmpconfig.h?view=markup irmpconfig.h] || Konfiguration für IRMP&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/svnbrowser/irmp/irmpextlog.c?view=markup irmpextlog.c] || IRMP-Logging für Nicht-AVR-µCs&lt;br /&gt;
|- &lt;br /&gt;
| irmpextlog.h || IRMP-Interne Include-Datei&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/svnbrowser/irmp/irmpprotocols.h?view=markup irmpprotocols.h] || Sämtliche Definitionen zu den IR-Protokollen&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/svnbrowser/irmp/irmpsystem.h?view=markup irmpsystem.h] || Vom Zielsystem abhängige Definitionen für AVR/PIC/STM32&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/svnbrowser/irmp/irsnd.c?view=markup irsnd.c] || Der eigentliche IR-Encoder&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/svnbrowser/irmp/irsnd.h?view=markup irsnd.h] || Include-Datei für die Applikation&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/svnbrowser/irmp/irsndconfig.h?view=markup irsndconfig.h] || Anzupassende Konfigurationsdatei&lt;br /&gt;
|- &lt;br /&gt;
| &lt;br /&gt;
|- &lt;br /&gt;
| w5100.c || Treiber-Modul für WIZnet W5100 Netzwerk-Controller&lt;br /&gt;
|- &lt;br /&gt;
| w5100.h || Include-Datei für W5100-Treiber&lt;br /&gt;
|- &lt;br /&gt;
| w5100config.h|| Konfigurationsdatei für W5100-Treiber&lt;br /&gt;
|- &lt;br /&gt;
| &lt;br /&gt;
|- &lt;br /&gt;
| ipclient.exe || ipclient-Executable für Windows&lt;br /&gt;
|- &lt;br /&gt;
| ipflash.exe || ipflash-Executable für Windows&lt;br /&gt;
|- &lt;br /&gt;
|&lt;br /&gt;
|- &lt;br /&gt;
| win32/ipclient/ipclient.c || Beispiel Client in C - übersetzbar unter Unix, Linux und Windows&lt;br /&gt;
|- &lt;br /&gt;
| win32/ipclient/ipclient.sln || gehört zu ipclient - für Microsoft Visual C++ 2010 Express&lt;br /&gt;
|- &lt;br /&gt;
| win32/ipclient/ipclient.suo || gehört zu ipclient - für Microsoft Visual C++ 2010 Express&lt;br /&gt;
|- &lt;br /&gt;
| win32/ipclient/ipclient.vcxproj || Projekt-Datei für Microsoft Visual C++ 2010 Express&lt;br /&gt;
|- &lt;br /&gt;
| &lt;br /&gt;
|- &lt;br /&gt;
| win32/ipflash/ipflash.c || Flash-Programm in C - übersetzbar unter Unix, Linux und Windows&lt;br /&gt;
|- &lt;br /&gt;
| win32/ipflash/ipflash.sln || gehört zu ipflash - für Microsoft Visual C++ 2010 Express&lt;br /&gt;
|- &lt;br /&gt;
| win32/ipflash/ipflash.suo || gehört zu ipflash - für Microsoft Visual C++ 2010 Express&lt;br /&gt;
|- &lt;br /&gt;
| win32/ipflash/ipflash.vcxproj || Projekt-Datei für Microsoft Visual C++ 2010 Express&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/329407 Thread im Forum zu diesem Projekt]&lt;br /&gt;
* [[IRMP]]&lt;br /&gt;
* [http://ethersex.de/index.php/IRMP Portierung nach Ethersex]&lt;br /&gt;
&lt;br /&gt;
Viel Spaß mit Remote IRMP!&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Infrarot]]&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Multitasking&amp;diff=85477</id>
		<title>Multitasking</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Multitasking&amp;diff=85477"/>
		<updated>2014-11-02T09:18:24Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Wiki-Syntax&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Multitasking bedeutet ein quasi paralleles Ausführen von mehreren Prozessen auf einem Prozessor.&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Da eine echte parallele Ausführung von mehreren Prozessen (Programmen, Funktionen) auf einer einzelnen CPU (genauer: einem CPU-Kern) nicht möglich ist, wird ein &amp;quot;Trick&amp;quot; angewendet. Er besteht darin, einzelne Prozesse jeweils nur für kurze Zeit (ungefähr 1...50 ms) zu bearbeiten und danach auf einen anderen Prozess umzuschalten. Man spricht auch von einer verschachtelten Bearbeitung (engl. interleaving).&lt;br /&gt;
&lt;br /&gt;
Das Herz jedes Multitasking-Systems ist der Scheduler. Dies ist ein Programm, das nach bestimmten Algorithmen überprüft, welcher Prozess als nächstes die CPU (also Rechenzeit) zugeteilt bekommt. Es gibt verschiedene Schedulingstrategien:&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;First come first served&amp;quot;: Prozesse bekommen Rechenzeit zugeteilt in der Reihenfolge, in der sie rechenbereit werden.&lt;br /&gt;
* &amp;quot;Shortest job first&amp;quot;: Der Prozess mit der kürzesten Rechenzeit wird als erstes bearbeitet. Dazu muss die Rechenzeit natürlich im Voraus bekannt sein.&lt;br /&gt;
* &amp;quot;Shortest remaining time next&amp;quot;: Der Prozess mit der kürzesten &#039;&#039;verbleibenden&#039;&#039; Rechenzeit wird jeweils als nächstes bearbeitet. Auch hier muss diese Zeit bekannt sein.&lt;br /&gt;
* Round robin: Alle Prozesse bekommen gleich viel Zeit zugeteilt. Der Scheduler lässt jeden Prozess für dieselbe Dauer rechnen und übergibt die CPU dann an den nächsten Prozess.&lt;br /&gt;
* Priority Scheduling: Die Prozesse sind nicht gleichwertig (wie beim Round-Robin-Verfahren), sondern haben Prioritäten. Der Scheduler sorgt dafür, dass höher priorisierte Prozesse bevorzugt behandelt werden.&lt;br /&gt;
&lt;br /&gt;
Soweit die &amp;quot;reine Lehre&amp;quot;. Scheduler in freier Wildbahn implementieren oftmals komplizierte Hybriden der genannten Techniken. Jene der &amp;quot;echten&amp;quot; Betriebsysteme (Windows, Linux, MacOS, *BSD) sind im Prinzip prioritäten-basierte Round-Robin-Scheduler. Generell hat ein Betriebssystem zwei Möglichkeiten, Multitasking zu realisieren: kooperativ oder präemptiv.&lt;br /&gt;
&lt;br /&gt;
== Kooperatives Multitasking ==&lt;br /&gt;
&lt;br /&gt;
Beim kooperativen Multitasking gibt der Scheduler die Kontrolle komplett an den Prozess ab. Als Konsequenz davon ist das Betriebssystem darauf angewiesen, dass der Prozess seinerseits die Kontrolle &amp;quot;freiwillig&amp;quot; wieder zurückgibt. Geschieht das nicht, wird der Scheduler nicht wieder aufgerufen und damit auch kein anderer Prozess mehr ausgeführt - das System &amp;quot;hängt&amp;quot;. Das Betriebssystem ist also auf die [http://de.wikipedia.org/wiki/Kooperation Kooperation] der Prozesse angewiesen. Bekannte Beispiele für Betriebssysteme mit kooperativem Multitasking sind Windows 3.x und MacOS vor Version 10.&lt;br /&gt;
&lt;br /&gt;
Dennoch ist kooperatives Multitasking keineswegs überholt oder schlecht. Gerade im Bereich der Mikrocontroller und Echtzeitanwendungen gibt es viele gute Argumente dafür: Kooperatives Multitasking ist deterministischer, also besser zeitlich und logisch vorhersagbar. Es ist besser simulierbar, d. h. für ein gegebenes System ist leichter nachweisbar, dass es funktioniert. Da es sich um geschlossene Systeme handelt, tritt das Problem, dass &amp;quot;irgendein&amp;quot; Prozess das System anhält, nicht auf. Es laufen ja im Gegensatz zum PC nicht &amp;quot;irgendwelche&amp;quot; Prozesse, sondern nur die, deren Korrektheit (im Idealfall) verifiziert und validiert wurde.&lt;br /&gt;
&lt;br /&gt;
=== Ein einfaches Beispiel für den AVR ===&lt;br /&gt;
&lt;br /&gt;
Hier soll ein einfaches Beispiel den Weg in die Programmierung von parallel bearbeiteten Aufgaben zeigen.&lt;br /&gt;
&lt;br /&gt;
Wichtigster Grundsatz ist die Herangehensweise! Viele Programmieranfänger haben damit Schwierigkeiten, was unter anderem an den schlecht vermittelten Grundlagen liegt. Oft sieht man Funktionen zum Warten in Form von&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
while(1) {&lt;br /&gt;
    PORTD ^= (1&amp;lt;&amp;lt;PD0);&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
um beispielsweise eine [[LED]] blinken zu lassen. Will man dann noch andere Dinge erledigen, wundert sich der Programmierer, warum der Mikrocontroller so langsam reagiert, trotz 16 MHz Taktfrequenz.&lt;br /&gt;
&lt;br /&gt;
==== Einfacher Ansatz ====&lt;br /&gt;
&lt;br /&gt;
Stellen wir uns vor, wir wollen drei Dinge gleichzeitig tun.&lt;br /&gt;
&lt;br /&gt;
* Eine Taste abfragen&lt;br /&gt;
* Eine LED blinken lassen, in Abhängigkeit der gedrückten Taste&lt;br /&gt;
* Daten vom UART empfangen und zum PC zurücksenden&lt;br /&gt;
&lt;br /&gt;
Ein einfacher Ansatz für die drei Dinge sieht etwa so aus. Die Beispiele wurden mit [[WinAVR]] Version 20081006 in der Optimierungsstufe -Os kompiliert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
&lt;br /&gt;
Multitasking Demo, erster Versuch&lt;br /&gt;
&lt;br /&gt;
ATmega32 @ 3,6864 MHz&lt;br /&gt;
&lt;br /&gt;
LED + 1KOhm Vorwiderstand an PB0&lt;br /&gt;
Taster nach GND an PA0&lt;br /&gt;
UART an RXD und TXD&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#define F_CPU 3686400&lt;br /&gt;
// Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!&lt;br /&gt;
#define BAUD 9600L          &lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;avr/io.h&amp;quot;&lt;br /&gt;
#include &amp;quot;util/delay.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
// Berechnungen&lt;br /&gt;
// clever runden&lt;br /&gt;
#define UBRR_VAL  ((F_CPU+BAUD*8)/(BAUD*16)-1)  &lt;br /&gt;
// Reale Baudrate&lt;br /&gt;
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     &lt;br /&gt;
// Fehler in Promille &lt;br /&gt;
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) &lt;br /&gt;
 &lt;br /&gt;
#if ((BAUD_ERROR&amp;gt;10) || (BAUD_ERROR&amp;lt;-10))&lt;br /&gt;
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! &lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
uint8_t taste_lesen(void) {&lt;br /&gt;
    if (PINA &amp;amp; (1&amp;lt;&amp;lt;PA0))&lt;br /&gt;
        return 1;&lt;br /&gt;
    else &lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void led_blinken(uint8_t taste) {&lt;br /&gt;
&lt;br /&gt;
    PORTB ^= (1&amp;lt;&amp;lt;PB0);&lt;br /&gt;
    if (taste) &lt;br /&gt;
        _delay_ms(1000);    // 1 s warten&lt;br /&gt;
    else&lt;br /&gt;
        _delay_ms(100);     // 0,1 s warten&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void uart_lesen(void) {&lt;br /&gt;
    uint8_t tmp;&lt;br /&gt;
    while (!(UCSRA &amp;amp; (1&amp;lt;&amp;lt;RXC)));            // Warte auf empfangenes Zeichen vom UART&lt;br /&gt;
    tmp = UDR;&lt;br /&gt;
    while (!(UCSRA &amp;amp; (1&amp;lt;&amp;lt;UDRE)));           // Warte auf freien Sendepuffer vom UART&lt;br /&gt;
    UDR = tmp;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
    int8_t taste;&lt;br /&gt;
&lt;br /&gt;
    // IOs initialisieren&lt;br /&gt;
    &lt;br /&gt;
    PORTA = 1;              // Pull Up für PA0&lt;br /&gt;
    DDRB  = 1;              // PC0 ist Ausgang&lt;br /&gt;
&lt;br /&gt;
    // UART initialisieren&lt;br /&gt;
    &lt;br /&gt;
    UBRRH = UBRR_VAL &amp;gt;&amp;gt; 8;&lt;br /&gt;
    UBRRL = UBRR_VAL &amp;amp; 0xFF;&lt;br /&gt;
    UCSRB = (1&amp;lt;&amp;lt;RXEN) | (1&amp;lt;&amp;lt;TXEN);&lt;br /&gt;
    &lt;br /&gt;
    // Endlose Hauptschleife&lt;br /&gt;
&lt;br /&gt;
    while (1) {&lt;br /&gt;
        taste = taste_lesen();&lt;br /&gt;
        led_blinken(taste);&lt;br /&gt;
        uart_lesen();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn man das Programm nun laufen lässt, wird man feststellen dass&lt;br /&gt;
&lt;br /&gt;
* das Hyperterminal sehr langsam reagiert und bisweilen Zeichen verschluckt&lt;br /&gt;
* die LED auf Tastendrücke nur dann reagiert, wenn man per Hyperterminal Zeichen eingibt&lt;br /&gt;
&lt;br /&gt;
Dieser Ansatz ist also untauglich. Egal wie schnell unser AVR auch ist, er reagiert sehr langsam.&lt;br /&gt;
&lt;br /&gt;
==== Verbesserter Ansatz ====&lt;br /&gt;
&lt;br /&gt;
Will man mehrere Dinge gleichzeitig bearbeiten, muss man die Aufgaben in kleinste Häppchen zerteilen. Diese kleinsten Häppchen werden dann verschachtelt abgearbeitet, also ein Häppchen von Aufgabe A, ein Häppchen von Aufgabe B, ein Häppchen von Aufgabe C.&lt;br /&gt;
&lt;br /&gt;
Das Auslesen der Taste geht immer sehr schnell, kein Ansatz zum optimieren. Das Blinken der LED dauer entweder 1s oder 100ms, eine Ewigkeit für einen Mikrocontroller! Hier muss man was ändern. Am schlimmsten ist die UART-Nutzung. Der AVR wartet solange, bis ein Zeichen empfangen wurde! Das kann ewig dauern! Unser Programm steht! Das darf nicht sein!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
&lt;br /&gt;
Multitasking Demo, zweiter Versuch&lt;br /&gt;
&lt;br /&gt;
ATmega32 @ 3,6468 MHz&lt;br /&gt;
&lt;br /&gt;
LED + 1KOhm Vorwiderstand an PB0&lt;br /&gt;
Taster nach GND an PA0&lt;br /&gt;
UART an RXD und TXD&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#define F_CPU 3686400&lt;br /&gt;
// Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!&lt;br /&gt;
#define BAUD 9600L          &lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;avr/io.h&amp;quot;&lt;br /&gt;
#include &amp;quot;util/delay.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
// Berechnungen&lt;br /&gt;
// clever runden&lt;br /&gt;
#define UBRR_VAL  ((F_CPU+BAUD*8)/(BAUD*16)-1)  &lt;br /&gt;
// Reale Baudrate&lt;br /&gt;
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     &lt;br /&gt;
// Fehler in Promille &lt;br /&gt;
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) &lt;br /&gt;
 &lt;br /&gt;
#if ((BAUD_ERROR&amp;gt;10) || (BAUD_ERROR&amp;lt;-10))&lt;br /&gt;
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! &lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
uint8_t taste_lesen(void) {&lt;br /&gt;
    if (PINA &amp;amp; (1&amp;lt;&amp;lt;PA0))&lt;br /&gt;
        return 1;&lt;br /&gt;
    else &lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void led_blinken(uint8_t taste) {&lt;br /&gt;
    static uint16_t zaehler=0;&lt;br /&gt;
&lt;br /&gt;
    if (taste) {&lt;br /&gt;
        if (zaehler&amp;gt;=999) {&lt;br /&gt;
            PORTB ^= (1&amp;lt;&amp;lt;PB0);&lt;br /&gt;
            zaehler=0;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
        if (zaehler&amp;gt;=99) {&lt;br /&gt;
            PORTB ^= (1&amp;lt;&amp;lt;PB0);&lt;br /&gt;
            zaehler=0;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    zaehler++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void uart_lesen(void) {&lt;br /&gt;
    uint8_t tmp;&lt;br /&gt;
    if((UCSRA &amp;amp; (1&amp;lt;&amp;lt;RXC))) {                // empfangenes Zeichen abholbereit im UART ?&lt;br /&gt;
        tmp = UDR;&lt;br /&gt;
        while (!(UCSRA &amp;amp; (1&amp;lt;&amp;lt;UDRE)));       // Warte auf freien Sendepuffer vom UART&lt;br /&gt;
        UDR = tmp;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void) {&lt;br /&gt;
    int8_t taste;&lt;br /&gt;
&lt;br /&gt;
    // IOs initialisieren&lt;br /&gt;
    &lt;br /&gt;
    PORTA = 1;              // Pull Up für PA0&lt;br /&gt;
    DDRB  = 1;              // PB0 ist Ausgang&lt;br /&gt;
&lt;br /&gt;
    // UART initialisieren&lt;br /&gt;
    &lt;br /&gt;
    UBRRH = UBRR_VAL &amp;gt;&amp;gt; 8;&lt;br /&gt;
    UBRRL = UBRR_VAL &amp;amp; 0xFF;&lt;br /&gt;
    UCSRB = (1&amp;lt;&amp;lt;RXEN) | (1&amp;lt;&amp;lt;TXEN);&lt;br /&gt;
    &lt;br /&gt;
    // Endlose Hauptschleife&lt;br /&gt;
&lt;br /&gt;
    while (1) {&lt;br /&gt;
        taste = taste_lesen();&lt;br /&gt;
        led_blinken(taste);&lt;br /&gt;
        uart_lesen();&lt;br /&gt;
        _delay_ms(1);       // 1 ms warten&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dieses Programm reagiert &#039;&#039;&#039;ganz&#039;&#039;&#039; anders! Schnell wie der Wind und vollkommen unabhängig von anderen, parallel laufenden Prozessen. Warum ist das so?&lt;br /&gt;
&lt;br /&gt;
Die einzelnen kleinen Häppchen sind verdaulicher als die großen. Die maximale Durchlaufzeit der einzelnen Funktionen ist drastisch reduziert. Anstatt in der LED-Ausgabe einmal 1000 ms zu warten wird nun 1000 mal 1 ms gewartet. Zwischendurch werden aber 1000 mal die anderen Prozesse bearbeitet. Echte Demokratie sozusagen. Noch viel besser ist die Handhabung des UARTs. Anstatt eine Ewigkeit auf ein ankommendes Zeichen zu warten, wird nur dann etwas bearbeitet, wenn auch wirklich etwas zur Bearbeitung vorliegt. Klingt eigentlich logisch. Also nur dann, wenn schon ein Zeichen empfangen wurde wird es auch bearbeitet, ansonsten geht es zurück zur Hauptschleife. Das ist praktisch der ganze &amp;quot;Trick&amp;quot; eines kooperativen Multitaskings. Auch wenn die Verwendung von _delay_ms(1) noch ein kleiner Schönheitsfehler ist, den die Profis lieber mit einem [[Timer]] erledigen, so wird das Prinzip klar.&lt;br /&gt;
&lt;br /&gt;
*Prozesse eines kooperativen Multitaskingsystems warten nicht (lies: niemals) auf das Eintreten von Ereignissen, sondern bearbeiten nur bereits eingetretene Ereignisse.&lt;br /&gt;
*Größere Aufgaben werden in kleine Teilaufgaben zerlegt, welche nur durch mehrfaches Aufrufen der Funktion abgearbeitet werden. Das erreicht man meist am besten mit einer [[statemachine |State machine]].&lt;br /&gt;
*Prozesse eines kooperativen Multitaskings haben eine garantierte, maximale Durchlaufzeit, welche möglichst klein ist.&lt;br /&gt;
&lt;br /&gt;
Damit ähneln die Prozesse einem [[Interrupt]], auch wenn sie als ganz normale Funktionen außerhalb eines Interrupts ausgeführt werden. An diesem Beispiel erkennt man die Vor- und Nachteile des kooperativen Multitaskings:&lt;br /&gt;
&lt;br /&gt;
Vorteile&lt;br /&gt;
* einfacher Scheduler mit geringster CPU Belastung&lt;br /&gt;
* Deterministische Arbeitsweise, damit einfach prüfbar und strenges Timing möglich&lt;br /&gt;
&lt;br /&gt;
Nachteile&lt;br /&gt;
* eine andere Programmierweise zur Zerlegung größerer Aufgaben in kleine Teilaufgaben muss manuell vorgenommen werden&lt;br /&gt;
&lt;br /&gt;
==== Verbesserter Ansatz mit Timer ====&lt;br /&gt;
&lt;br /&gt;
Zum Abschluss die noch bessere Version mit Timer. Diese hat mehrere Vorteile.&lt;br /&gt;
&lt;br /&gt;
* Das Zeitraster der Hauptschleife ist exakt, unabhängig von der Laufzeit der Aufgaben, weil der Timer unabhängig eine feste Interruptfrequenz generiert. Im vorherigen Beispiel war das Zeitraster die Summe aus Laufzeit aller Funktionen/Tasks und dem _delay_ms(1).&lt;br /&gt;
* CPU-Rechenleistung wird zu 100% in der Abarbeitung der Task verwendet und nicht für nutzlose Warteschleifen verschwendet.&lt;br /&gt;
* Es kann leicht im realen System geprüft werden, ob die Laufzeit der Tasks klein genug ist, um den Anforderungen des Timers zu genügen.&lt;br /&gt;
&lt;br /&gt;
Diese Überprüfung kann an zwei Stellen durchgeführt werden.&lt;br /&gt;
&lt;br /&gt;
* Am Ende der Hauptschleife nach Abarbeitung aller Ausgaben. Wenn hier die Variable flag_1ms schon wieder aktiv ist, dauerte die Abarbeitung länger als 1ms. Wenn man ein sehr strenges Timing sicherstellen möchte, ist das ein Fehler, der erkannt und signalisiert werden kann.&lt;br /&gt;
* In der ISR. Wenn hier die Variable immer noch aktiv ist, wurde sie von der Hauptschleife noch nicht erkannt und zurück gesetzt. Das ist definitiv ein Fehler, denn jetzt würde ohne Fehlererkennung ein Timerdurchlauf von der Hauptschleife verschluckt werden. Diese Prüfung ist etwas nachgiebiger, weil zwischenzeitlich ein Durchlauf der Hauptschleife mehr als 1ms, jedoch nicht länger als 2ms dauern darf. Siehe auch den Abschnitt [[Interrupt#Zeitverhalten_eines_Timerinterrupts]]. Sinnvollerweise nutzt man nur eine der beiden Prüfungen, nicht beide zusammen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
&lt;br /&gt;
Multitasking Demo, dritter Versuch&lt;br /&gt;
&lt;br /&gt;
ATmega32 @ 3,6468 MHz&lt;br /&gt;
&lt;br /&gt;
LED + 1KOhm Vorwiderstand an PB0 und PB1&lt;br /&gt;
Taster nach GND an PA0&lt;br /&gt;
UART an RXD und TXD&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#define F_CPU 3686400&lt;br /&gt;
// Baudrate, das L am Ende ist wichtig, NICHT UL verwenden!&lt;br /&gt;
#define BAUD 9600L          &lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;avr/io.h&amp;quot;&lt;br /&gt;
#include &amp;quot;util/delay.h&amp;quot;&lt;br /&gt;
#include &amp;quot;avr/interrupt.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
// Berechnungen&lt;br /&gt;
// clever runden&lt;br /&gt;
#define UBRR_VAL  ((F_CPU+BAUD*8)/(BAUD*16)-1)  &lt;br /&gt;
// Reale Baudrate&lt;br /&gt;
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     &lt;br /&gt;
// Fehler in Promille &lt;br /&gt;
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) &lt;br /&gt;
 &lt;br /&gt;
#if ((BAUD_ERROR&amp;gt;10) || (BAUD_ERROR&amp;lt;-10))&lt;br /&gt;
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! &lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
uint8_t taste_lesen(void) {&lt;br /&gt;
    if (PINA &amp;amp; (1&amp;lt;&amp;lt;PA0))&lt;br /&gt;
        return 1;&lt;br /&gt;
    else &lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void led_blinken(uint8_t taste) {&lt;br /&gt;
    static uint16_t zaehler=0;&lt;br /&gt;
&lt;br /&gt;
    if (taste) {&lt;br /&gt;
        if (zaehler&amp;gt;=999) {&lt;br /&gt;
            PORTB ^= (1&amp;lt;&amp;lt;PB0);&lt;br /&gt;
            zaehler=0;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
        if (zaehler&amp;gt;=99) {&lt;br /&gt;
            PORTB ^= (1&amp;lt;&amp;lt;PB0);&lt;br /&gt;
            zaehler=0;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    zaehler++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void uart_lesen(void) {&lt;br /&gt;
    uint8_t tmp;&lt;br /&gt;
    if((UCSRA &amp;amp; (1&amp;lt;&amp;lt;RXC))) {                // empfangenes Zeichen abholbereit im UART ?&lt;br /&gt;
        tmp = UDR;&lt;br /&gt;
        while (!(UCSRA &amp;amp; (1&amp;lt;&amp;lt;UDRE)));       // Warte auf freien Sendepuffer vom UART&lt;br /&gt;
        UDR = tmp;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
volatile uint8_t flag_1ms;&lt;br /&gt;
 &lt;br /&gt;
int main(void) {&lt;br /&gt;
    int8_t taste;&lt;br /&gt;
&lt;br /&gt;
    // IOs initialisieren&lt;br /&gt;
    &lt;br /&gt;
    PORTA = 1;              // Pull Up für PA0&lt;br /&gt;
    DDRB  = 3;              // PB0/1 sind Ausgang&lt;br /&gt;
&lt;br /&gt;
    // UART initialisieren&lt;br /&gt;
    &lt;br /&gt;
    UBRRH = UBRR_VAL &amp;gt;&amp;gt; 8;&lt;br /&gt;
    UBRRL = UBRR_VAL &amp;amp; 0xFF;&lt;br /&gt;
    UCSRB = (1&amp;lt;&amp;lt;RXEN) | (1&amp;lt;&amp;lt;TXEN);&lt;br /&gt;
&lt;br /&gt;
    // Timer 0 initialisieren, CTC, Presacler 64&lt;br /&gt;
&lt;br /&gt;
    TCCR0 = (1&amp;lt;&amp;lt;WGM01) | (1&amp;lt;&amp;lt;CS01) | (1&amp;lt;&amp;lt;CS00);&lt;br /&gt;
    OCR0  = 56;      // 1ms&lt;br /&gt;
    TIMSK |= (1&amp;lt;&amp;lt;OCIE0);&lt;br /&gt;
&lt;br /&gt;
    // Interrupts global freigeben&lt;br /&gt;
&lt;br /&gt;
    sei();&lt;br /&gt;
&lt;br /&gt;
    // Endlose Hauptschleife&lt;br /&gt;
&lt;br /&gt;
    while (1) {&lt;br /&gt;
        if (flag_1ms) {&lt;br /&gt;
            flag_1ms=0;&lt;br /&gt;
            taste = taste_lesen();&lt;br /&gt;
            led_blinken(taste);&lt;br /&gt;
            uart_lesen();&lt;br /&gt;
            if (flag_1ms) {&lt;br /&gt;
                // Laufzeit der Tasks &amp;gt;1ms, Fehlersignalisierung&lt;br /&gt;
                // PB1 auf HIGH, Programm stoppen&lt;br /&gt;
                PORTB |= (1&amp;lt;&amp;lt;PB1);&lt;br /&gt;
                while(1);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Interruptserviceroutine für Timer 0&lt;br /&gt;
// hier 1ms&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER0_COMP_vect) {&lt;br /&gt;
    if (flag_1ms) {&lt;br /&gt;
        // Laufzeit der Tasks &amp;gt;2ms, Fehlersignalisierung&lt;br /&gt;
        // PB1 auf HIGH, Programm stoppen&lt;br /&gt;
        PORTB |= (1&amp;lt;&amp;lt;PB1);&lt;br /&gt;
        while(1);&lt;br /&gt;
    }&lt;br /&gt;
    flag_1ms = 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Message passing Framework ====&lt;br /&gt;
&lt;br /&gt;
Im vorangegangenen Abschnitt wird erklärt, wie man die einzelnen Tasks in kleine &amp;quot;Häppchen&amp;quot; zerlegen kann und diese alle innerhalb der Main Loop aufruft.&lt;br /&gt;
Dieses kooperative System hat aber noch einige Nachteile:&lt;br /&gt;
&lt;br /&gt;
* Alle Häppchen werden gleich oft aufgerufen und nicht nur bei Bedarf&lt;br /&gt;
* Für die Timeouts gibt es noch keine befriedigende Lösung&lt;br /&gt;
&lt;br /&gt;
Wenn man diese beiden Nachteile auch noch beseitigen möchte, wird das ganze noch ein klein wenig komplizierter. Da man das Grundprinzip aber für viele Mikrocontroller-Projekte immer wieder verwenden kann, lohnt es sich und man kann die Entwicklung für diese Art des Multitasking in einem Framework zusammenfassen.&lt;br /&gt;
&lt;br /&gt;
Ein Framework, das sind einige Dateien, die den Rahmen (Frame=Rahmen) für ein Programm bilden und den Teil enthalten, den man immer wieder braucht.&lt;br /&gt;
&lt;br /&gt;
===== Message =====&lt;br /&gt;
&lt;br /&gt;
Die Basis des Frameworks bildet die &amp;quot;Message&amp;quot;. Immer wenn wir für einen unserer &amp;quot;Tasks&amp;quot; etwas zu tun haben, schicken wir eine &amp;quot;Message&amp;quot;. Die &amp;quot;Messages&amp;quot; werden in eine Warteschlange einsortiert und der Reihe nach abgearbeitet. Dadurch kommt ein Task der viel zu tun hat (viele Messages bekommt) öfter dran, als ein &amp;quot;Task&amp;quot; der nicht so viel zu tun hat. Außerdem kann eine Message noch Daten enthalten (z. B. ein empfangenes Zeichen). So können die einzelnen Tasks sogar Daten austauschen.&lt;br /&gt;
&lt;br /&gt;
===== Message Receiver =====&lt;br /&gt;
&lt;br /&gt;
Unsere &amp;quot;Tasks&amp;quot; werden immer dann aufgerufen, wenn Arbeit für sie da ist. Das wissen wir, weil sie eine Message empfangen sollen. Deshalb heißen die &amp;quot;Tasks&amp;quot; ab jetzt &amp;quot;Message Receiver&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===== Timeout =====&lt;br /&gt;
&lt;br /&gt;
In diesem System wird jeder Message Receiver aufgerufen, wenn jemand Arbeit für ihn hat und er deshalb eine Message bekommt. Was aber, wenn keine Message kommt, oder ein Message Receiver selbst aktiv werden soll?&lt;br /&gt;
&lt;br /&gt;
Aus diesem Grund braucht es die Timeouts. Mit Hilfe &amp;lt;u&amp;gt;eines&amp;lt;/u&amp;gt; Hardware Timers wird eine &amp;quot;Systemzeit&amp;quot; programmiert. Jeder Message Receiver kann die Zeit angeben, wann er wieder aufgerufen werden muss. Das Framework verwaltet alle Timer und sendet den Message Receivern eine &amp;quot;Timeout&amp;quot; message, wenn ihre Zeit gekommen ist.&lt;br /&gt;
&lt;br /&gt;
===== Beispiel =====&lt;br /&gt;
Hier der Sourcecode eines solchen Framework [[Datei:ACF.zip]]&lt;br /&gt;
Das Framework implementiert die Message Warteschlange und die Timer Warteschlange. Die Prozessor spezifischen Dinge sind in der Datei &amp;quot;ACF_Hal.c&amp;quot; zusammengefasst und für Linux Desktop und atMega128 implementiert.&lt;br /&gt;
In dieser Datei kann man das ganze auch auf andere Prozessoren anpassen.&lt;br /&gt;
&lt;br /&gt;
Ein &amp;quot;main&amp;quot; sieht dann z.B. so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;ACF.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char** argv)&lt;br /&gt;
{&lt;br /&gt;
    ACF_init();&lt;br /&gt;
    ACF_loop();&lt;br /&gt;
    return 0; // we will never arrive here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Tracing =====&lt;br /&gt;
Es gibt noch einen weiteren Grund, sich ein &amp;quot;Framework&amp;quot; zu erarbeiten, oder ein fertiges Framework zu verwenden. Da der Ablauf der Software und der Aufruf aller Teile vom Framework bestimmt wird, kann das Framework auch einen sehr detaillierten Trace über das Verhalten des Codes anfertigen. Das Framework aus vorstehendem Beispiel enthält bereits entsprechenden Code.&lt;br /&gt;
&lt;br /&gt;
Solche Traces von laufendem Code können gerade dann sehr hilfreich sein, wenn viele Dinge gleichzeitig ablaufen (und das war schließlich der Sinn des ganzen).&lt;br /&gt;
&lt;br /&gt;
Nachstehendes Bild zeigt den Trace eines Reglers, der mit dem Framework realisiert wurde.&lt;br /&gt;
[http://www.mikrocontroller.net/attachment/74409/ablauf.png Sequenzdiagramm]&lt;br /&gt;
&lt;br /&gt;
== Präemptives Multitasking ==&lt;br /&gt;
&lt;br /&gt;
Beim präemptiven Multitasking gibt das OS die Kontrolle zu keinem Zeitpunkt auf. Ein Prozess, der gerade die CPU nutzt, kann jederzeit wieder vom Betriebssystem unterbrochen werden. Daher muss bei der Entwicklung für ein präemptives System immer damit gerechnet werden, dass ein Prozess &#039;&#039;&#039;jederzeit&#039;&#039;&#039; unterbrochen werden kann. Das kann z.&amp;amp;nbsp;B. zu Problemen beim Zugriff auf limitierte Betriebsmittel führen. Beispiel:&lt;br /&gt;
&lt;br /&gt;
* Prozess A sucht freien Speicher und findet einen freien Block&lt;br /&gt;
* Prozess B wird vom Scheduler gestartet und sucht ebenfalls einen Speicherblock. Der gefundene Block wird von Prozess B reserviert und benutzt&lt;br /&gt;
* Der Scheduler teilt wieder Prozess A die CPU zu. Prozess A wird fortgeführt, d.h. er reserviert jetzt den im letzten Systemcall gefundenen Speicherblock&lt;br /&gt;
Jetzt haben also beide Prozesse den gleichen Speicherblock reserviert. Entweder arbeiten jetzt beide Prozesse mit dem gleichen Speicher, und überschreiben daher gegenseitig die Daten, oder das Betriebsystem hat etwas gemerkt und zieht die Notbremse. In jedem Fall passieren schreckliche Dinge. Sowas nennt man eine Race-Condition.&lt;br /&gt;
&lt;br /&gt;
Die Lösung nennt sich Semaphore: Dieser Mechanismus wird vom Betriebsystem bereitgestellt und erlaubt es einem Prozess eine bestimmte Ressource zu sperren. Wenn also Prozess A aus obigem Beispiel Speicher haben möchte, setzt er vor Beginn der sogenannten &amp;quot;Kritischen Sektion&amp;quot; einen Semaphor für &amp;quot;Speicher reservieren&amp;quot;. Dieser Semaphor wird erst wieder aufgehoben, sobald Prozess A den Speicher für sich reserviert hat. Wenn der Prozess B zwischendurch gestartet wird und ebenfalls versucht den Semaphor zu setzen, wird er solange warten müssen, bis Prozess A den Semaphor wieder freigibt. Speziell für derartige Locking Mechanismen bieten die meisten Prozessoren sogenannte TAS-Befehle (Test And Set), die in einem Prozessorbefehl eine Variable testen und je nach Ergebnis setzen können. Das ist nötig um das Setzen von Semaphoren unteilbar (atomar) zu machen. Könnte der Scheduler das Setzen eines Semaphors unterbrechen, wäre ja der ganze Aufwand umsonst.&lt;br /&gt;
&lt;br /&gt;
Präemptive Multitasking Systeme sind sehr flexibel und kommen mit einer Vielzahl an Tasks klar. Amok laufende Prozesse können das System bei korrekter Implementierung nicht blockieren. Damit aber das System crash-sicher ist, muss es Systemresourcen geben, die nur der Scheduler verteilen kann (z.&amp;amp;nbsp;B. kein anderer Prozess darf in den Speicherbereich des Schedulers schreiben; kein anderer Prozess darf den Timerinterrupt des Schedulers ändern). Diese Möglichkeiten sind in Mikrocontrollern normalerweise gar nicht vorhanden, wodurch dieser Vorteil des Präemptiven MT weniger ins Gewicht fällt. Beispiele für Systeme mit präemptivem Multitasking sind Linux, *BSD  und Windows XP.&lt;br /&gt;
&lt;br /&gt;
Vorteile&lt;br /&gt;
* sehr flexibel in der Verwaltung von dynamisch ausgeführten Prozessen&lt;br /&gt;
* einzelne Prozesse können einfach linear programmiert werden, ohne die Aufgabe in kleine Teile zerlegen zu müssen&lt;br /&gt;
&lt;br /&gt;
Nachteile&lt;br /&gt;
* Der Scheduler ist aufwändiger und benötigt mehr CPU-Zeit&lt;br /&gt;
* Höherer Resourcenbedarf zu Verwaltung des Systems und Bereitstellung der Semaphore etc.&lt;br /&gt;
* nicht streng deterministisch, somit kann kein festes Timing garantiert werden&lt;br /&gt;
* nicht explizit debug- und prüfbar, da die Prozesse nicht fest gekoppelt sind&lt;br /&gt;
&lt;br /&gt;
== Multithreading ==&lt;br /&gt;
&lt;br /&gt;
Multithreading ist eine meist softwarebasierende Möglichkeit moderner Betriebssysteme, innerhalb eines Prozesses mehrere Tasks (threads) parallel auszuführen. Der Vorteil dieser weiteren Unterteilung ist, dass sich die Threads eines Tasks den Speicherbereich teilen können und eine Aufteilung in logische nebeneinander laufende Teile möglich ist. Je nach Betriebssystem kann der Übergang von Multithreading zu Multiprocessing fliessend bis starr sein. &lt;br /&gt;
&lt;br /&gt;
Das Hyperthreading eines Intel Pentium 4 folgt dem Konzept des Multithreadings auf Hardwarebasis und teilt den CPU-Kern zeitlich in zwei logische Prozessoren ein.&lt;br /&gt;
&lt;br /&gt;
== Umsetzung auf Prozessoren ==&lt;br /&gt;
Unabhängig davon, ob Multitasking oder -threading auf einem Prozessor konkret unterstützt wird, lässt es sich immer in Form von Software realisieren. Dies wird in modernen Systemen durch das OS geleistet, das standardisierte Funktionen und Strukturen zur Verfügung stellt. Besonders C++ bietet ein stark abstrahiertes Programmiermodell und Methoden-Set an, um effektiv untereinander kompatible Programmmodule erstellen zu können. Nutzt man diese nicht, wie z.B. bei der Programmierung in C, müssen Strukturen manuell erzeugt und gehandhabt werden, was aufwändiger ist, aber auch geringeren overhead bewirkt. Das Programm ist dann fast immer erheblich kleiner, in den meisten Fällen strukturell einfacher, bezüglich komplizierter Änderungen jedoch auch unflexibler und träger. &lt;br /&gt;
&lt;br /&gt;
Bei Mikrocontrollern findet man je nach Komplexität und Struktur der Appliation praktisch alle denkbaren Kombinationen:&lt;br /&gt;
&lt;br /&gt;
=== System mit real-time OS und Entwicklung in C++ ===&lt;br /&gt;
* Programmentwicklung stark an abstrakte Interfaces und Standards gebunden&lt;br /&gt;
* Starke Abängigkeit an das OS im Bezug auf RT-Funktionalität&lt;br /&gt;
* Innerhalb gleicher OS-Landschaft gut portierbar&lt;br /&gt;
* Sehr geringe Abhängigkeit vom Prozessortyp&lt;br /&gt;
* Multitasking muss über OS-Schicht ausprogrammiert werden&lt;br /&gt;
* Multithreading muss/kann durch Programmierleistung optimiert werden&lt;br /&gt;
* Laufzeiteffizienz ist niedrig durch relativ hohen Anteil des OS-Bedarfs&lt;br /&gt;
* Datendurchsatz regelt sich selbst und ist gleichmässig am relativen Maximum&lt;br /&gt;
* Programmiereffizienz ist niedrig durch sehr viel Arbeit an Formalismen&lt;br /&gt;
* Planungsaufwand ist noch überschaubar&lt;br /&gt;
* Planungseffizienz ist relaiv hoch durch viele Standards&lt;br /&gt;
* Erweiterung um komplexe Module einfach möglich, Timing regelt sich selber&lt;br /&gt;
&lt;br /&gt;
=== System mit real-time OS und Entwicklung in C ===&lt;br /&gt;
* Programmentwicklung stark an Interfaces und weniger an Standards&lt;br /&gt;
* Starke Abängigkeit an das OS im Bezug auf RT-Funktionalität&lt;br /&gt;
* Innerhalb aber auch ausserhalb gleicher OS-Landschaft gut portierbar&lt;br /&gt;
* Geringe Abhängig von dem Prozessortyp&lt;br /&gt;
* Multitasking muss über OS-Schicht und eigene Strukturen programmiert werden&lt;br /&gt;
* Multithreading muss/kann durch Programmierleistung optimiert werden&lt;br /&gt;
* Laufzeiteffizienz ist höher durch geringeren Anteil des OS-Bedarfs&lt;br /&gt;
* Datendurchsatz regelt sich selbst und ist gleichmässig am relativen Maximum&lt;br /&gt;
* Programmiereffizienz ist höher durch weniger Arbeit mit Formalien&lt;br /&gt;
* Planungsaufwand ist etwas höher, je nach Applikation&lt;br /&gt;
* Planungseffizienz ist relaiv niedriger durch weniger Standards&lt;br /&gt;
* Erweiterung mit akzeptablem Aufwand möglich, Timing muss beachtet werden&lt;br /&gt;
&lt;br /&gt;
=== System ohne real-time OS und Entwicklung in C ===&lt;br /&gt;
* Programmentwicklung stark an Interfaces und kaum an Standards gebunden&lt;br /&gt;
* Ausprägung und Gestaltung der RT-Funktionalität absolut frei&lt;br /&gt;
* nur ausserhalb von OS-Landschaft portierbar, dafür prinziepiell sehr gut&lt;br /&gt;
* Stärkere Abhängig von dem Prozessortyp, kann die Portierbarkeit einschränken&lt;br /&gt;
* Multitasking muss auschlieslich durch eigene Strukturen programmiert werden&lt;br /&gt;
* Multithreading muss durch umständliche Programmierung ermöglicht werden werden&lt;br /&gt;
* Laufzeiteffizienz kann sehr hoch sein, ist aber stark von der Progr. abhängig&lt;br /&gt;
* Datendurchsatz muss selbst ins Maximum gesteuert werden, das aber höher liegt&lt;br /&gt;
* Programmiereffizienz ist hoch, dank Wegfall von Konventionen&lt;br /&gt;
* Planungsaufwand ist stark Applikations abhängig, gfs sehr viel grösser&lt;br /&gt;
* Planungseffizienz ist gering, da RT Konzept selber optmiert werden muss&lt;br /&gt;
* Erweiterung nur möglich, wenn Timing weitestgehend überarbeitet wird&lt;br /&gt;
&lt;br /&gt;
=== System ohne real-time OS und Entwicklung in ASM ===&lt;br /&gt;
* Programmentw. nur an physische Interfaces gebunden und frei von Standards&lt;br /&gt;
* Ausprägung und Gestaltung der RT-Funktionalität absolut frei&lt;br /&gt;
* nur innerhalb der Prozessorlandschaft gut portierbar&lt;br /&gt;
* Volle Abhängig vom Prozessortyp, Portierbarkeit auf andere aufwändig&lt;br /&gt;
* Multitasking muss auschlieslich durch eigene Strukturen programmiert werden&lt;br /&gt;
* Multithreading muss durch umständliche Programmierung ermöglicht werden werden&lt;br /&gt;
* Laufzeiteffizienz sehr hoch, jedoch stark von Programmierung abhängig&lt;br /&gt;
* Datendurchsatz muss selbst ins Maximum gesteuert werden, das aber höher liegt&lt;br /&gt;
* Programmiereffizienz ist hoch, dank Wegfall von Konventionen&lt;br /&gt;
* Planungsaufwand ist stark applikationsabhängig, ggfs. sehr viel grösser&lt;br /&gt;
* Planungseffizienz sehr gering, RT Konzept nur für einfache System machbar&lt;br /&gt;
* Erweiterung nur möglich, wenn Timing komplett überarbeitet wird&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Pr%E4emptives_Multitasking Präemptives Multitasking] bei [http://de.wikipedia.org Wikipedia]&lt;br /&gt;
* [http://www.femtoos.org/ Femto OS], ein ultrakompaktes Mulitaskingbetriebssystem für kleine Mikrocontroller&lt;br /&gt;
*[http://www.freertos.org/ FreeRTOS], ein freies Echtzeitbetriebssystem für Mikrocontroller&lt;br /&gt;
* [http://w3.ualg.pt/~rmarcel/Get%20by%20Without%20an%20RTOS.pdf Get by Without an RTOS] Ein schönes Beispiel wie man ohne ein RTOS auch Multitasking hinbekommt. &lt;br /&gt;
* [[TNKernel]], freier Multitasking-Kernel. &lt;br /&gt;
* [http://embeddedgurus.com/state-space/2010/04/i-hate-rtoses/ i-hate-rtoses] Blog zum Thema RTOS&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Betriebssysteme]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Stromversorgung_f%C3%BCr_FPGAs&amp;diff=85086</id>
		<title>Stromversorgung für FPGAs</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Stromversorgung_f%C3%BCr_FPGAs&amp;diff=85086"/>
		<updated>2014-10-04T16:51:55Z</updated>

		<summary type="html">&lt;p&gt;Maybee: /* Der klassische Ansatz */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In diesem Artikel soll eine kurze Erklärung zum Entwurfsproblem von Stromversorgungen für Hochleistungs-[[FPGA]]s gegeben werden. Ein neuer Ansatz zur Messung des Frequenzgangs wird dargestellt und praktische Messergebnisse werden gezeigt.&lt;br /&gt;
&lt;br /&gt;
FPGAs werden immer mehr Bestandteil moderner Elektronik. Die Bausteine werden größer, schneller und leistungsstärker mit jedem Tag. Und so steigt auch die Leistungsaufnahme. Obwohl die Leistung pro Gatter sich durch bessere Technologie und kleinere Geometrien verringert, steigt die Taktfrequenz und die Anzahl der Gatter pro Bauteil. Mit steigender Schaltgeschwindigkeit wird die Stromversorgung zu einem kritischen Teil im Systementwurf. Das Stromversorgungsnetz muss eine Quelle mit niedriger Impedanz über einen sehr weiten Frequenzbereich sein. Anderenfalls könnnen Überschwinger, Spannungsabfall oder Störpulse auf VCC/GND die Funktion des FPGAs stören, welche durch den schnell wechselnden Leistungsbedarf des FPGAs verursacht wird.&lt;br /&gt;
&lt;br /&gt;
== Breitbandentkopplung ist Teamwork ==&lt;br /&gt;
&lt;br /&gt;
Der Spannungsregler muss die Gleichstromkomponente für das Stromversorgungsnetzwerk liefern. Bei maximaler Leistung und Umgebungstemperatur muss er immer noch sauber funktionieren ohne zu überhitzen, Spannungseinbrüche etc. Seine Aufgabe ist es, auf niederfrequente Lastsprünge zu reagieren (ca. 0..30kHz).&lt;br /&gt;
&lt;br /&gt;
Im mittleren Frequenzbereich kann der Spannungsregler nicht mehr reagieren, er ist zu langsam. Der Strom muss dann von großen Elektrolytkondensatoren geliefert werden. Diese Kondensatoren können bis einige MHz Strom liefern, danach begrenzen der parasitäre Widerstand (ESR, engl. effective series resistance) bzw. die parasitäre Induktivität (ESL, engl. effective series inductance) die Stromlieferfähigkeit des Kondensators und machen ihn irgendwann bei höheren Frequenzen nutzlos.&lt;br /&gt;
&lt;br /&gt;
Jetzt kommt die Zeit der kleinen Keramikkondensatoren, typisch 10 oder 100nF. Sie gibt es in kleinen [[SMD]]-Gehäusen wie 0603 und kleiner mit sehr wenig parasitärer Induktivität. Sie können Strom bis einige hundert MHz liefern und sind damit eine niederohmige Quelle für Hochfrequenzströme.&lt;br /&gt;
&lt;br /&gt;
Aber für die &#039;&#039;&#039;wirklich&#039;&#039;&#039; schnell schaltenden ICs sind auch diese Keramikkondensatoren nicht ausreichend, um das Stromversorgungsnetzwerk ausreichend zu entkoppeln. Hier braucht man die Kapazität der Stromversorgungsflächen, welche duch VCC- und Masseflächen in mehrlagigen Platinen gebildet wird. Um ein Maximum an Kapazität zu erreichen sollte ein dünnes Dielektrikum mit einer hohen Dielektrizitätskonstante und niedrigen Verlusten benutzen. Außerdem sollte man ein VIA für jedes VCC/GND Pin benutzen, um die parasitären Induktivitäten zu minimieren, nicht ein VIA für mehrere Pins! [[IC-Gehäuseformen#BGA | BGA-Gehäuse]] bieten zusätzlich kürzere Verbindungen vom eigentlichen IC zur Platine, sie sind aber schwieriger zu handhaben (Layout und [[SMD Löten | Löten]]).&lt;br /&gt;
&lt;br /&gt;
== Der klassische Ansatz ==&lt;br /&gt;
&lt;br /&gt;
Es gibt viele Theorien und Application Notes zum Thema Entkopplung von Stromversorgungen. Einige nehmen einfach die Brechstange und bauen einen Friedhof für unzählige Kondensatoren, andere sind schlauer. Es gibt auch sehr viele Simulationen zu dem Thema. Aber am Ende sind die Eigenschaften des Stromversorgungsnetzes definiert duch das Zusammenspiel von&lt;br /&gt;
&lt;br /&gt;
* dem FPGA und dessen Leistungsaufnahme, welche von der Schaltfrequenz abhängt&lt;br /&gt;
* dem Layout der Platine mit der Platzierung der verschiedenen Kondensatoren&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit zur Messung der Qualität des Stromversorgungsnetzwerkes ist die Nutzung eines Netzwerkanalysators. Dafür benötigt man eine Platine, welche nur mit den passiven Komponenten bestückt ist. Dabei wird ein Testsignal in das Netzwerk eingespeist (meist an Stelle des Spannungsreglers) und an einer anderen Stelle gemessen (meist an Stelle der ICs). Der Netzwerkanalysator variiert dann die Frequenz und zeichnet eine Kurve des Widerstands über die Frequenz auf. Diese Methode hat einige Nachteile.&lt;br /&gt;
&lt;br /&gt;
*Man braucht einen teuren Netzwerkanalysator&lt;br /&gt;
*Man benötigt eine zusätzliches Board, welches nur mit den Kondensatoren bestückt ist, welches nicht immer verfügbar ist&lt;br /&gt;
*Die Messung spiegelt nicht die wahren Bedingungen wieder, weil alle ICs und aktiven Teile fehlen. Ausserdem sind nur Punkt zu Punkt Messungen möglich, welche das reale Verhalten nicht korrekt wiedergeben.&lt;br /&gt;
&lt;br /&gt;
Die Methode in diesem Artikel versucht, die meisten Nachteile zu vermeiden.&lt;br /&gt;
&lt;br /&gt;
== Ein direkter Ansatz ==&lt;br /&gt;
&lt;br /&gt;
Da wir hier über FPGAs reden, haben wir die Möglichkeit, &#039;&#039;&#039;jede&#039;&#039;&#039; beliebige digitale Funktion hineinzuprogrammieren. Also sollten wir eine digitale Funktion entwerfen, welche dem schlimmstmöglichen Fall der Belastung der Stromversorgung entspricht. Aus der Theorie der linearen Netzwerke wissen wir, dass der Frequenzgang eines linearen Systems aus der Sprungantwort am Eingang und der Reaktion am Ausgang gemessen werden kann. Für das Stromversorgungsnetzwerk funktioniert das sogar wenn es nicht vollständig linear ist, da wir ja die reale Reaktion auf konstante Last und Lastsprünge messen wollen. Was ist nun der schlimmste Belastungsfall für die Stromversorgung? Da fast alle ICs auf CMOS-Technologie beruhen, wird die meiste Leistung umgesetzt, wenn Signalnetze ihren Pegel wechseln. Bei einem FPGA heißt das, dass alle [[FlipFlop]]s ihren Pegel gleichzeitig wechseln und dabei große Signalnetze treiben (parasitäre Kapazität). Also entwerfen wir die folgende Schaltung. &lt;br /&gt;
&lt;br /&gt;
[[bild:Schematic.gif|thumb|left|600px|Logik für Lasttest]]&lt;br /&gt;
{{clear}}&lt;br /&gt;
&lt;br /&gt;
Der Kern besteht aus einer Matrix aus 30x50 FlipFlops, wobei jeweils 50 FlipFlops aus einem Puffer-FlipFlop gespeist werden, um die Ausgangslast relativ niedrig zu halten und damit eine hohe Taktfrequenz zu erreichen. Um etwas kombinatorische Logik zu erzeugen und um die HDL Compiler davon abzuhalten, die FlipFlops wegzuoptimieren, verbinden wir alle FlipFlops über ein gigantisches ODER-Gatter und leiten den Ausgang auf ein IO-Pad. Dieser Ausgang wird aber nicht weiter genutzt. Dann haben wir noch einen 16-Bit  Zähler und etwas Steuerlogik, welche das Toggle-FlipFlop gemäß folgender Tabelle steuert.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Steuerung der Testlogik&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! sel&amp;lt;1&amp;gt; || sel&amp;lt;0&amp;gt; || Modus&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 0 || inaktiv&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 1 || konstante Umschaltung&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 0 || Burstbetrieb&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== VHDL Code ==&lt;br /&gt;
&lt;br /&gt;
Wenn der Code synthetisiert wird, muss die Option &amp;quot;remove duplicate registers&amp;quot; in der Synthesesoftware ausgeschaltet werden. Es sollten zwei Dateien angelegt werden, top.vhd und row.vhd.&lt;br /&gt;
&lt;br /&gt;
Datei top.vhd&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;vhdl&amp;quot;&amp;gt;&lt;br /&gt;
library IEEE;&lt;br /&gt;
use IEEE.STD_LOGIC_1164.ALL;&lt;br /&gt;
use IEEE.STD_LOGIC_ARITH.ALL;&lt;br /&gt;
use IEEE.STD_LOGIC_UNSIGNED.ALL;&lt;br /&gt;
&lt;br /&gt;
entity power is&lt;br /&gt;
    Port ( clk_in  : in std_logic;                      -- clock input&lt;br /&gt;
           sel     : in std_logic_vector(1 downto 0);   -- select modulation ON/OFF&lt;br /&gt;
           gnd     : out std_logic_vector(5 downto 0);  -- artificial gnd&lt;br /&gt;
           mod_out : out std_logic;                     -- modulation signal&lt;br /&gt;
           reset   : in std_logic;                      -- reset for DLL&lt;br /&gt;
           dummy   : out std_logic);                    -- dummy out, to fool the synthesizer&lt;br /&gt;
           &lt;br /&gt;
end power;&lt;br /&gt;
&lt;br /&gt;
architecture Behavioral of power is&lt;br /&gt;
&lt;br /&gt;
COMPONENT row&lt;br /&gt;
    PORT(&lt;br /&gt;
        clk  : IN std_logic;&lt;br /&gt;
        data : IN std_logic;    &lt;br /&gt;
        dout : OUT std_logic&lt;br /&gt;
        );&lt;br /&gt;
END COMPONENT;&lt;br /&gt;
&lt;br /&gt;
-- DLL (Delay Locked Loop), a Virtex primitive&lt;br /&gt;
&lt;br /&gt;
component CLKDLL&lt;br /&gt;
    port (  &lt;br /&gt;
        CLKIN   : in    std_logic;&lt;br /&gt;
        CLKFB   : in    std_logic;&lt;br /&gt;
        RST     : in    std_logic;&lt;br /&gt;
        CLK0    : out   std_logic;&lt;br /&gt;
        CLK90   : out   std_logic;&lt;br /&gt;
        CLK180  : out   std_logic;&lt;br /&gt;
        CLK270  : out   std_logic;&lt;br /&gt;
        CLK2X   : out   std_logic;&lt;br /&gt;
        CLKDV   : out   std_logic;&lt;br /&gt;
        LOCKED  : out   std_logic);&lt;br /&gt;
end component;&lt;br /&gt;
&lt;br /&gt;
-- BUFG (Global Clock buffer), a Virtex  primitive&lt;br /&gt;
&lt;br /&gt;
component BUFG&lt;br /&gt;
    port (  I   : in    std_logic;&lt;br /&gt;
            O   : out   std_logic);&lt;br /&gt;
end component;&lt;br /&gt;
&lt;br /&gt;
-- IBUFG (Global Clock input buffer ), aa Virtex primitive&lt;br /&gt;
&lt;br /&gt;
component IBUFG&lt;br /&gt;
    port (  I   : in    std_logic;&lt;br /&gt;
            O   : out   std_logic);&lt;br /&gt;
end component;&lt;br /&gt;
&lt;br /&gt;
component SRL16     -- virtex primitive&lt;br /&gt;
  port (&lt;br /&gt;
        D    : in std_logic;        &lt;br /&gt;
        CLK  : in std_logic;&lt;br /&gt;
        A0   : in std_logic;&lt;br /&gt;
        A1   : in std_logic;&lt;br /&gt;
        A2   : in std_logic;&lt;br /&gt;
        A3   : in std_logic;        &lt;br /&gt;
        Q    : out std_logic&lt;br /&gt;
       ); &lt;br /&gt;
end component;&lt;br /&gt;
&lt;br /&gt;
constant rows: integer:=30;&lt;br /&gt;
&lt;br /&gt;
type flop_array is array (rows-1 downto 0) of std_logic_vector(49 downto 0);&lt;br /&gt;
&lt;br /&gt;
signal toggle   : std_logic;                            -- a toggle flipflop&lt;br /&gt;
signal ff_ar    : flop_array;&lt;br /&gt;
signal drive_ar : std_logic_vector (rows-1 downto 0);   -- driver array for toggeling rows&lt;br /&gt;
signal dout_ar  : std_logic_vector (rows-1 downto 0);   -- driver array for toggeling rows&lt;br /&gt;
signal or_ar    : std_logic_vector (rows-1 downto 0);   -- driver array for toggeling rows&lt;br /&gt;
signal cnt      : std_logic_vector (15 downto 0);       -- modulation divider&lt;br /&gt;
&lt;br /&gt;
signal CLKIN_w, RESET_w, CLK2X_dll, CLK2X_g, CLK4X_dll, CLK4X_g, CLK8X_dll, CLK8X_g: std_logic;&lt;br /&gt;
signal LOCKED2X, LOCKED2X_delay, RESET4X, RESET8X, LOCKED4X, LOCKED4X_delay, LOCKED8X : std_logic;&lt;br /&gt;
&lt;br /&gt;
signal logic1,clk : std_logic;&lt;br /&gt;
&lt;br /&gt;
signal clk2x,clk4x,clk8x, clkmux: std_logic;&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
-- use two DLL to get 147 MHz&lt;br /&gt;
&lt;br /&gt;
logic1&amp;lt;=&#039;1&#039;;&lt;br /&gt;
&lt;br /&gt;
clkpad : IBUFG  port map (I=&amp;gt;CLK_IN, O=&amp;gt;CLKIN_w);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
dll2x  : CLKDLL port map (CLKIN=&amp;gt;CLKIN_w,   CLKFB=&amp;gt;CLK2X_g, RST=&amp;gt;RESET,&lt;br /&gt;
                          CLK0=&amp;gt;open,   CLK90=&amp;gt;open, CLK180=&amp;gt;open, CLK270=&amp;gt;open,&lt;br /&gt;
                          CLK2X=&amp;gt;CLK2X_dll, CLKDV=&amp;gt;open, LOCKED=&amp;gt;LOCKED2X);&lt;br /&gt;
&lt;br /&gt;
clk2xg : BUFG   port map (I=&amp;gt;CLK2X_dll,   O=&amp;gt;CLK2X_g);&lt;br /&gt;
&lt;br /&gt;
rstsrl : SRL16  port map (D=&amp;gt;LOCKED2X, CLK=&amp;gt;CLK2X_g, Q=&amp;gt;LOCKED2X_delay,&lt;br /&gt;
                          A3=&amp;gt;logic1, A2=&amp;gt;logic1, A1=&amp;gt;logic1, A0=&amp;gt;logic1);&lt;br /&gt;
&lt;br /&gt;
RESET4X &amp;lt;= not LOCKED2X_delay;&lt;br /&gt;
&lt;br /&gt;
dll4x  : CLKDLL port map (CLKIN=&amp;gt;CLK2X_g,  CLKFB=&amp;gt;CLK4X_g, RST=&amp;gt;RESET4X,&lt;br /&gt;
                          CLK0=&amp;gt;open,   CLK90=&amp;gt;open, CLK180=&amp;gt;open, CLK270=&amp;gt;open,&lt;br /&gt;
                          CLK2X=&amp;gt;CLK4X_dll, CLKDV=&amp;gt;open, LOCKED=&amp;gt;LOCKED4X);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
clk4xg : BUFG   port map (I=&amp;gt;CLK4X_dll,  O=&amp;gt;CLK4X_g);&lt;br /&gt;
&lt;br /&gt;
clk&amp;lt;=clk4x_g;&lt;br /&gt;
&lt;br /&gt;
-- the toggeling array&lt;br /&gt;
&lt;br /&gt;
l_rows: for i in 0 to rows-1 generate&lt;br /&gt;
    Inst_row: row PORT MAP(&lt;br /&gt;
        clk  =&amp;gt; clk,&lt;br /&gt;
        data =&amp;gt; drive_ar(i),&lt;br /&gt;
        dout =&amp;gt; dout_ar(i)&lt;br /&gt;
    );&lt;br /&gt;
  end generate;&lt;br /&gt;
&lt;br /&gt;
-- combine all douts via a BIG or-gate&lt;br /&gt;
&lt;br /&gt;
  process(dout_ar)&lt;br /&gt;
  variable tmp: std_logic;&lt;br /&gt;
  begin&lt;br /&gt;
    tmp:=&#039;0&#039;;&lt;br /&gt;
    l_or: for i in 0 to rows-1 loop&lt;br /&gt;
      tmp:=tmp or dout_ar(i);&lt;br /&gt;
    end loop;&lt;br /&gt;
    dummy&amp;lt;=tmp;&lt;br /&gt;
  end process;&lt;br /&gt;
&lt;br /&gt;
-- prescaler&lt;br /&gt;
&lt;br /&gt;
  process(clk)&lt;br /&gt;
  begin&lt;br /&gt;
    if clk=&#039;1&#039; and clk&#039;event then&lt;br /&gt;
      cnt&amp;lt;=cnt+1;&lt;br /&gt;
    end if;&lt;br /&gt;
  end process;&lt;br /&gt;
&lt;br /&gt;
-- toggle fliplop and distribution&lt;br /&gt;
&lt;br /&gt;
  process(clk)&lt;br /&gt;
  begin&lt;br /&gt;
    if clk=&#039;1&#039; and clk&#039;event then&lt;br /&gt;
      case sel is&lt;br /&gt;
        when &amp;quot;00&amp;quot;       =&amp;gt; toggle &amp;lt;= &#039;0&#039;;&lt;br /&gt;
        when &amp;quot;01&amp;quot;       =&amp;gt; toggle &amp;lt;= not toggle;&lt;br /&gt;
        when &amp;quot;10&amp;quot;       =&amp;gt; if cnt(15)=&#039;1&#039; then toggle &amp;lt;= not toggle; else toggle&amp;lt;=&#039;0&#039;; end if;&lt;br /&gt;
        when others     =&amp;gt; null;&lt;br /&gt;
      end case;&lt;br /&gt;
      drive_ar&amp;lt;=(others=&amp;gt;toggle);&lt;br /&gt;
    end if;&lt;br /&gt;
  end process;&lt;br /&gt;
&lt;br /&gt;
gnd&amp;lt;=(others=&amp;gt;&#039;0&#039;);&lt;br /&gt;
mod_out&amp;lt;=cnt(15);&lt;br /&gt;
&lt;br /&gt;
end Behavioral;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Datei row.vhd&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;vhdl&amp;quot;&amp;gt;&lt;br /&gt;
library IEEE;&lt;br /&gt;
use IEEE.STD_LOGIC_1164.ALL;&lt;br /&gt;
use IEEE.STD_LOGIC_ARITH.ALL;&lt;br /&gt;
use IEEE.STD_LOGIC_UNSIGNED.ALL;&lt;br /&gt;
&lt;br /&gt;
entity row is&lt;br /&gt;
    Port ( clk  : in std_logic;&lt;br /&gt;
           data : in std_logic;&lt;br /&gt;
           dout : out std_logic);&lt;br /&gt;
end row;&lt;br /&gt;
&lt;br /&gt;
architecture Behavioral of row is&lt;br /&gt;
&lt;br /&gt;
signal my_array: std_logic_vector (49 downto 0);&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
-- generate 50 FFs with clock enable&lt;br /&gt;
&lt;br /&gt;
  process (clk)&lt;br /&gt;
  begin&lt;br /&gt;
    if clk=&#039;1&#039; and clK&#039;event then&lt;br /&gt;
      my_array&amp;lt;=(others=&amp;gt;data);     &lt;br /&gt;
    end if;&lt;br /&gt;
  end process;&lt;br /&gt;
&lt;br /&gt;
-- combine all into a BIG OR&lt;br /&gt;
&lt;br /&gt;
  process(my_array)&lt;br /&gt;
  variable tmp: std_logic;&lt;br /&gt;
  begin&lt;br /&gt;
    tmp:=&#039;0&#039;;&lt;br /&gt;
    l: for i in 0 to 49 loop&lt;br /&gt;
      tmp:=tmp or my_array(i);&lt;br /&gt;
    end loop;&lt;br /&gt;
    dout&amp;lt;=tmp;&lt;br /&gt;
  end process;&lt;br /&gt;
&lt;br /&gt;
end Behavioral;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Messungen ==&lt;br /&gt;
&lt;br /&gt;
[[bild:Term1.gif|thumb|right|220px|Terminierung 1: 50Ω vor dem Koppelkondensator, f&amp;lt;sub&amp;gt;g&amp;lt;/sub&amp;gt;&amp;amp;nbsp;=&amp;amp;nbsp;10&amp;amp;nbsp;Hz]]&lt;br /&gt;
[[bild:Term2.gif|thumb|right|220px|Terminierung 2: 50Ω nach dem Koppelkondensator, f&amp;lt;sub&amp;gt;g&amp;lt;/sub&amp;gt;&amp;amp;nbsp;=&amp;amp;nbsp;200&amp;amp;nbsp;kHz]]&lt;br /&gt;
&lt;br /&gt;
Die nachfolgenden Messungen wurden mit einem Spartan-II Demoboard von Insight Electronics durchgeführt. Es ist mit einem XC2S100-5 im PQ208 Gehäuse bestückt. Es nutzt eine Kernspannung von 2,5V und eine IO-Spannung von 3,3V. Beide Spannungen werden durch Linearregler geliefert. Ein 36.864 MHz Oszillator wurde hinzugefügt. Für die Messung wurde der Takt mittels DLL vervierfacht auf 147 MHz. Diese hohe Frequenz wurde gewählt, um die Effekte gut demonstrieren zu können. In einer praktischen Anwendung wird man diesen Test nur mit der normalen Frequenz betreiben, welche auch in der realen Anwendung genutzt wird. Das Board wird durch ein starkes Netzteil versorgt.&lt;br /&gt;
&lt;br /&gt;
Die Kernspannung wird mit einem Stück Koaxialkabel vom Typ RG 174 gemessen, welches direkt an ein VCC/GND-Pin des FPGAs angelötet ist. Das [[Oszilloskop]] ist auf 50Ω Eingangsimpedanz mit AC-Kopplung geschaltet. Wir sind nicht an der absoluten Größe der Versorgungsspannung interessiert sind, nur an Wechselanteilen, welche hoffentlich deutlich kleiner sind. Mit AC-Kopplung kann man einen deutlich kleineren Messbereich für die vertikale Auflösung verwenden. Dieser Aufbau hat eine gute Abschirmung gegen Störungen und eine sehr hohe Bandbreite zur Messung der hochfrequenten Störungen.&lt;br /&gt;
&lt;br /&gt;
Während der Messung wurde festgestellt, dass es zwei verschiedene [[Wellenwiderstand | Terminierungsmethoden]] in Oszilloskopen gibt. Das alte Tektronix CSA 404 mit einem 11A34 Verstärker nutzt Terminierung 1 am 50Ω Eingang. Daraus ergibt sich eine untere Grenzfrequenz des Hochpasses von ~10 Hz. Das zweite Oszilloskop, ein Tektronix TDS 3034, mit welchem die Screenshots gemacht wurden, nutz Terminierung 2, welche in einer unteren Grenzfrequenz von ~200 kHz resultiert. Das ist nicht akzeptabel für die Messung der Sprungantwort, weswegen die 1 M&amp;amp;Omega; Eingangsterminierung benutzt wurde. Das ist OK für die Messung niedriger Frequenzen (&amp;lt;10 MHz). Zur Messung der Hochfrequenzstörungen (Messung 4) ist die Grenzfrequenz von 200 kHz kein Problem.&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
== Messung 1 - FPGA unkonfiguriert ==&lt;br /&gt;
&lt;br /&gt;
Bei diesem Schritt können wir die Leistungsaufnahme in Ruhezustand messen, welche größtenteils durch Leckströme verursacht wird. Zu beachten ist auch, dass unser Oszilloskop mit Eingangsschaltung 1 viel Strom zieht (50Ω @ 2,5V = 50mA). Wir können mittles Multimeter messen, ob unsere Spannungsregler die korrekte Spannung liefern. Wir schreiben den aktuellen Stromverbrauch und Kernspannung auf. Dabei ist der Stromverbrauch der Eingangstermninierung nicht enthalten, weil für alle Messungen das zweite Oszilloskop mit Schaltung 2 verwendet wurde.&lt;br /&gt;
&lt;br /&gt;
== Messung 2 - FPGA mit leerer Logik == &lt;br /&gt;
&lt;br /&gt;
Ein Design mit einer einfachen Schleife von einem Eingang auf einen Ausgang ist jetzt in das FPGA geladen. Nach der Konfiguration &#039;&#039;&#039;sinkt&#039;&#039;&#039; der Stromverbrauch, weil die Konfigurationslogik im FPGA abgeschaltet wurde, welche permanant den Konfigurationsspeicher löscht. Die Leistungsaufnahme dieser Minimalschaltung wird als Kalibrierungspunkt für alle nachfolgenden Messungen verwendet.&lt;br /&gt;
&lt;br /&gt;
== Messung 3 - FPGA konfiguriert ohne schaltende Logik ==&lt;br /&gt;
&lt;br /&gt;
Jetzt steigt die Leistungsaufnahme deutlich. Auf den ersten Blick ist das unerwartet, denn im FPGA werden keinerlei Signale geschaltet , die FlipFlips laden immer den gleichen Wert. Aber das ist nicht ganz korrekt. Das Taktnetzwerk läuft auf voller Leistung. Daran erkennt man, dass die Taktverteilung signifikant Leistung benötigt. Darum nutzen [[Ultra low power | stromsparende ICs]] eine saubere Methode zur [[Taktung FPGA/CPLD | Taktabschaltung (clock gating)]], um die Leitungsaufnahme zu verringern. Aber das muss auf sichere Weise erfolgen.&lt;br /&gt;
&lt;br /&gt;
== Messung 4 - FPGA mit dauerhaft schaltenden Signalen ==&lt;br /&gt;
&lt;br /&gt;
Jetzt starten wir ein Feurwerk! Die Stromversorgung erfährt jetzt ihren schlimmsten Albtraum. 1500 FlipFlops die gleichzeitig mit 147 MHz umschalten (togglen)&lt;br /&gt;
ist kein Kindergeburtstag! Schau auf den Strommesser! Das FPGA wird schnell sehr heiß. Aber was sehen wir auf dem Oszilloskop? Da die Stromaufnahme konstant ist, können wir nur Hochfrequenzstörungen durch die schaltende Logik sehen, welche durch unzureichende Entkopplung der Keramikkondensatoren verursacht werden könnte. Mit einem schnellen Oszilloskop (1GHz++) und schlechten Versorgungslagen und Keramikkondensatoren, könnte man die &#039;&#039;&#039;wirklich&#039;&#039;&#039; hochfrequenten Störungen sehen. Mit dem 1 GHz-Oszilloskop sieht man in diesem Fall aber nichts, eben weil die Kondensatoren und Stromversorgungslagen gut funktionieren. Mit langsameren Oszilloskopen (300MHz oder weniger) sieht man nur den Effekt der Kondensatoren. Hier können wir auch die Kernspannung unter Volllast messen. Aber man muss sicherstellen, die Spannung zu messen, welche wirklich am FPGA ankommt, d.h. man muss &#039;&#039;&#039;direkt&#039;&#039;&#039; an den Pins des FPGA messen, nicht irgendwo auf dem Board! Denn das Stromversorgungsnetz hat einen endlichen Widerstand, welcher einen Spannungsabfall vom Spannungsregler bis zum FPGA verursacht. In einem guten Entwurf sollte der Spannungsabfall kleiner als 1% der Nennspannung sein.&lt;br /&gt;
&lt;br /&gt;
== Messung 5 - Burstbetrieb ==&lt;br /&gt;
&lt;br /&gt;
Zum Schluß erreichen wir den interessantesten Punkt. Mit dem 16-Bit Zähler wird das Umschalten des FlipFlop-Arrays mit einer niedrigen Frequenz moduliert, die Modulationsfrequenz ist 1/65356 der Taktfrequenz, hier ~2,2 kHz. Das ist die Sprungfunktion, welche in den Abschnitten weiter oben genannt wurde. Und wir sehen die Reaktion des Stromversorgungsnetzes. Wenn es ideal wäre, würden wir nur eine gerade Linie auf dem Oszilloskop sehen. Aber da es numal keine Idealfälle gibt, sehen wir Überschwinger und einen verbleibenden Offset. Das nachfolgende Bild zeigt das deutlich. Der blaue Kanal ist das Modulationssignal des 16-Bit Zählers (MSB), der gelbe Kanal die Kernspannung.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery widths=&amp;quot;140&amp;quot;&amp;gt;&lt;br /&gt;
bild:01.gif| Sprungantwort mit 10µF&lt;br /&gt;
bild:02.gif| Sprungantwort mit 110µF&lt;br /&gt;
bild:03.gif| Abschaltflanke 10µF&lt;br /&gt;
bild:04.gif| Abschaltflanke 110µF&lt;br /&gt;
bild:05.gif| Zoom, Abschaltflanke 110µF&lt;br /&gt;
bild:06.gif| Anschaltflanke 10µF&lt;br /&gt;
bild:07.gif| Anschaltflanke 110µF&lt;br /&gt;
bild:08.gif| Zoom, Anschaltflanke 110µF&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Erklärung ==&lt;br /&gt;
&lt;br /&gt;
Der Unterschwinger beim Einschalten wird verursacht durch unzureichende Entkopplung im mittleren Frequenzbereich. Der sprunghaft steigende Stromverbrauch kann nicht von den Mittelfrequenzkondensatoren geliefert werden (zu wenig Kapazität), auch nicht vom Spannungsregler (er ist zu langsam dafür). Das originale Demoboard ist nur mit einem 10µF Tantalkondensator hinter dem Spannungsregler bestückt, welcher für so eine große Last viel zu klein ist. Durch Ergänzung eines 100µF Kondensatores kann der Unterschwinger deutlich verkleinert werden.&lt;br /&gt;
&lt;br /&gt;
Der Überschwinger beim Abschalten ist ähnlich, aber hier ist der Spannungsregler ist zu langsam, den Ausgangsstrom herunterzuregeln. Der überschüssige Strom (Ladung) wird in den Mittelfrequenzkondensatoren gespeichert, aber da dieser nur 10µF hat, steigt die Spannung schnell an. Ein einfacher Vergleich. Es ist genauso wie wenn man mit einem kleinen Fass das Regenwasser von einem großen Dach auffangen will, das Faß füllt sich schnell.&lt;br /&gt;
&lt;br /&gt;
Was verursacht den verbliebenden Offset? Nun, das ist der Gleichstromwiderstand des Stromversorgungsnetzwerks vom Spannungsregler (wo dieser die Ausgangsspanung misst und regelt) bis zum VCC-Pin des FPGAs. Die Stromaufnahme des FPGAs schwankt zwischen Messung 3 (kein Umschalten) und Messung 4 (konstantes Umschalten). Auf dem Oszilloskop sehen wir eine Spannungsdifferenz von ~70mV bei einer Stromdifferenz von 912 mA, woraus ca. 76m&amp;amp;Omega; Widerstand resultieren. Die Schlußfolgerung daraus ist, dass die Verbindung zwischen dem Punkt der Spannungsmessung durch den Spannungsregler und den VCC-Pins einen möglichst niedrigen Widerstand haben muss. Das beste sind komplette Lagen für die Stromversorgung (Power Planes), aber kurze, dicke Leitungen sind meist auch OK. Es gibt auch Spannungsregler mit extra Messeingängen, welche den Spannungsabfall über der Zuleitung kompensieren können, weil sie direkt am Verbraucher die Spannung messen. Als weitere Möglichkeit werden heutzutage meist sog. Point of Load Module eingesetzt. Das sind Spannungsregler (Schaltregler), welche direkt am zu versorgenden FPGA sitzen und mit einer hohen Spannung von 5..48V über das Board versorgt werden.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Messergebnisse&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Messung || FPGA-Inhalt                || Icc [mA] || Vcc [V] || P [mW]&lt;br /&gt;
|-&lt;br /&gt;
| 1 || keine Konfiguration              || 80 || 2.501 || 200&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Minimallogik                     || 40 || 2.502 || 100&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Testlogik, inaktiv               || 235 || 2.487 || 584&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Testlogik, konstantes Umschalten || 1147 || 2.433 || 2790&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Testlogik, Burstbetrieb           || 690 || 2.464 || 1700&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Zusammenfassung ==&lt;br /&gt;
&lt;br /&gt;
In diesem Artikel wurde eine einfache aber leistungsfähige Methode zur Messung des Frequenzgangs des Stromversorgungsnetzwerks für FPGAs gezeigt. Die Messung kann deutlich einfacher und mit leicht verfügbaren Messgeräten unter realistischeren Bedingungen durchgeführt werden als eine klassische Messung mit einem Netzwerkanalysator. Es läßt viel Raum für Experimente mit der Entkopplung der Stromversorgung in Bezug auf die Platzierung und Werte der Kondensatoren.&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
*[http://processors.wiki.ti.com/index.php/General_hardware_design/BGA_PCB_design/BGA_decoupling General hardware design/BGA PCB design/BGA decoupling, Texas Instruments (engl.)]&lt;br /&gt;
*[http://www.signalintegrity.com/Pubs/pubsKeyword.htm#power%20system Signal integrity of power systems] by Howard Johnson (engl.)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Spannungsversorgung und Energiequellen]]&lt;br /&gt;
[[Kategorie:FPGA und Co]]&lt;br /&gt;
[[Kategorie:VHDL]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Bitmanipulation&amp;diff=85051</id>
		<title>Bitmanipulation</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Bitmanipulation&amp;diff=85051"/>
		<updated>2014-09-29T10:12:43Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Änderung 85050 von 2.244.37.200 (Diskussion) rückgängig gemacht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Bitoperatoren ==&lt;br /&gt;
&lt;br /&gt;
Bitoperatoren stammen ursprünglich aus dem Bereich des Maschinen-Codes und Assembler, existieren aber auch in den meisten Hochsprachen, wie C.&lt;br /&gt;
&lt;br /&gt;
* &amp;gt;&amp;gt; = Rechts schieben&lt;br /&gt;
* &amp;lt;&amp;lt; = Links schieben (Bsp: &#039;&#039;a&amp;lt;&amp;lt;b&#039;&#039; ist das gleiche wie &#039;&#039;a * 2^b&#039;&#039;; bzw. bei 1&amp;lt;&amp;lt;3 wird die 1 um drei Stellen nach links geschoben)&lt;br /&gt;
* |  = binäres ODER&lt;br /&gt;
* &amp;amp;  = binäres UND&lt;br /&gt;
* usw.&lt;br /&gt;
&lt;br /&gt;
Bitoperatoren in dieser Schreibweise können in Assemblercode für&lt;br /&gt;
konstante Ausdrücke benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, (1&amp;lt;&amp;lt;3) | (1&amp;lt;&amp;lt;1) | (1&amp;lt;&amp;lt;2) | (1&amp;lt;&amp;lt;0)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
wird zu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, 8 | 2 | 4 | 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
wird zu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, 15&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bitmaske ==&lt;br /&gt;
&lt;br /&gt;
Im Folgenden ist häufiger von dem Begriff &#039;&#039;Bitmaske&#039;&#039; die Rede. Damit wird eine Folge von einzelnen Bit bezeichnet, die den Zustand Null (&#039;0&#039;) oder Eins (&#039;1&#039;) darstellen können.&lt;br /&gt;
&lt;br /&gt;
Bitmasken werden im allgemeinen dazu verwendet, um unter Anwendung eines Operators (z.&amp;amp;nbsp;B. UND, ODER, XOR), eine Eingabe zu manipulieren. Das Ergebnis ist dann die Anwendung des Operators auf die Eingabe und der Bitmaske.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Operator eine Funktion mit zwei Argumenten ist, dann lässt sich dessen Anwendung wie folgt schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Ergebnis = Operator( Eingabe, Bitmaske )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Bitmaske ist häufig eine Konstante, da diese z.&amp;amp;nbsp;B. die Information über die Position einer Information in einem Register darstellt. Das kann z.&amp;amp;nbsp;B. ein Überlaufflag in einem Timer Statusregister sein.&lt;br /&gt;
&lt;br /&gt;
== Bits setzen ==&lt;br /&gt;
&lt;br /&gt;
Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] auf Eins gesetzt werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#ODER | ODER]]-Verknüpfung erreicht.  Alle Bits, welche in der Bitmaske &#039;1&#039; sind, werden auf &#039;1&#039; gesetzt. Alle Bits, die in der Maske auf &#039;0&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR-Assembler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
sbr r16, 0b11110000     ; setzt Bits 4-7 in r16, ist ein Pseudobefehl&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
ori r16, 0b11110000     ; setzt Bits 4-7 in r16, ori ist identisch mit sbr&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
sbi PORTB, 5            ; setzt Bit 5 in PortB&lt;br /&gt;
sbi PORTB, PB5          ; identisch, besser lesbar&lt;br /&gt;
                        ; funktioniert nur für die IO-Register 0..0x1F&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register mit I/O Adresse 0x20..0x3F muss&lt;br /&gt;
                        ; in/out verwendet werden&lt;br /&gt;
in  r16, TIMSK          ; setzt Bit TOIE1 in TIMSK&lt;br /&gt;
sbr r16, (1&amp;lt;&amp;lt;TOIE1)    &lt;br /&gt;
out TIMSK, r16&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register oberhalb der I/O Adresse 0x3F muss&lt;br /&gt;
                        ; lds/sts verwednet werden&lt;br /&gt;
                        ; setzt Bit RXCIE0 in UCSR0B&lt;br /&gt;
lds r16, UCSR0B &lt;br /&gt;
sbr r16, (1&amp;lt;&amp;lt;RXCIE0)    &lt;br /&gt;
sts UCSR0B, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Man beachte den Unterschied! Eine &amp;quot;5&amp;quot; würde von sbr als &amp;quot;setze Bit 2 und 0&amp;quot; gedeutet (=0b00000101), während sbi sie als &amp;quot;setze Bit 5&amp;quot; versteht. Der Befehl &#039;&#039;&#039;sbr&#039;&#039;&#039; erwartet ein Bit&#039;&#039;&#039;muster&#039;&#039;&#039; für eine ODER-Verknüpfung, während der Befehlt &#039;&#039;&#039;sbi&#039;&#039;&#039; die Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; benötigt. Darauf sind auch die Includefiles von Atmel im AVR-Studio (Assembler) als auch [[WinAVR]] (C) ausgelegt. Die Namen der Bits sind als Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; definiert. Das ist wichtig, wenn man Register von grossen AVRs manipuliert, z.&amp;amp;nbsp;B. ATmega48. Hier muss aus der Bitnummer über eine Schiebeoperation erst das Bit&#039;&#039;&#039;muster&#039;&#039;&#039; gemacht werden.&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB |= 0xF0;   // Kurzschreibweise, entspricht PORTB = PORTB | 0xF0; bitweises ODER&lt;br /&gt;
&lt;br /&gt;
/* übersichtlicher mittels Bit-Definitionen */&lt;br /&gt;
#define MEINBIT0 0&lt;br /&gt;
#define MEINBIT1 1&lt;br /&gt;
#define MEINBIT2 2&lt;br /&gt;
&lt;br /&gt;
PORTB |= ((1 &amp;lt;&amp;lt; MEINBIT0) | (1 &amp;lt;&amp;lt; MEINBIT2)); // setzt Bit 0 und 2 in PORTB auf &amp;quot;1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die letzte Zeile &amp;quot;entschlüsselt&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;(1 &amp;lt;&amp;lt; n)&#039;&#039;&#039; : Zuerst wird durch die &#039;&amp;lt;&amp;lt;&#039;-Ausdrücke eine &amp;quot;1&amp;quot; n-mal nach links geschoben.  Dies ergibt somit (in Binärschreibweise) 0b00000001 für (1 &amp;lt;&amp;lt; MEINBIT0) und 0b00000100 für (1 &amp;lt;&amp;lt; MEINBIT2).&lt;br /&gt;
# &#039;&#039;&#039;|&#039;&#039;&#039; : Das Ergebnis wird bitweise ODER-verknüpft, also 0b00000001 &#039;&#039;or&#039;&#039; 0b00000100 wird zu 0b00000101.&lt;br /&gt;
# &#039;&#039;&#039;|=&#039;&#039;&#039; : Diese Maske wird mit dem aktuellen Inhalt von PORTB bitweise ODER-verknüpft und das Ergebnis PORTB wieder zugewiesen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB |= variable;         // Kurzschreibweise&lt;br /&gt;
PORTB  = PORTB | variable; // lange Schreibweise&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Ist PORTB vorher z.&amp;amp;nbsp;B. 0b01111010, dann ist der Inhalt nach der Operation 0b01111010 &#039;&#039;or&#039;&#039; 0b00000101 = 0b01111111, die gewünschten Bits sind somit gesetzt!&lt;br /&gt;
&lt;br /&gt;
Anmerkung: Will man das gezeigte Beispiel der Bitmanipulation auf größere Datentypen anwenden, ist zu beachten, dass der Compiler in der Operation (1 &amp;lt;&amp;lt; MEINBIT1) stillschweigend gemäss, den C-Regeln, die 1 als Integer Typ ansieht. Beim AVR-GCC bedeutet das 16-Bit/signed und die folgende Operation bringt ggf. nicht das gewünschte Ergebnis. (Stichwort: &amp;quot;Integer Promotion&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Angenommen Bit 15 soll in einer 32-Bit weiten Variable gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define MEINBIT15 15&lt;br /&gt;
#define MEINBIT42 42&lt;br /&gt;
&lt;br /&gt;
uint32_t reg_32; /* uint32_t definiert per typedef z.&amp;amp;nbsp;B. in stdint.h */&lt;br /&gt;
uint64_t reg_64; /* uint64_t definiert per typedef z.&amp;amp;nbsp;B. in stdint.h */&lt;br /&gt;
&lt;br /&gt;
reg_32 |= (1 &amp;lt;&amp;lt; MEINBIT15);              /* FEHLER: Setzt die Bits 31 - 15, da ((int)1 &amp;lt;&amp;lt; 15) == 0xFFFF8000 */&lt;br /&gt;
&lt;br /&gt;
reg_32 |= ((uint32_t)1 &amp;lt;&amp;lt; MEINBIT15);    /* Hier wird nur Bit 15 gesetzt. */&lt;br /&gt;
reg_32 |= (1U &amp;lt;&amp;lt; MEINBIT15);             /* */&lt;br /&gt;
reg_32 |= (1L &amp;lt;&amp;lt; MEINBIT15);             /* andere Schreibweise. */&lt;br /&gt;
reg_64 |= (1LL &amp;lt;&amp;lt; MEINBIT42);            /* Hier wird nur Bit 42 gesetzt,&lt;br /&gt;
                                            andere Schreibweise für 64 Bit (long long). */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei Compilern für 32bit Controller (z.&amp;amp;nbsp;B. ARM7TDMI) sind Integers per default 32-bit und Konstanten sind somit implizit ebenfalls 32-bit. Man sollte aber dennoch die oben gezeigte Vorgehenweise verwenden, um Probleme zu vermeiden die entstehen könnten, wenn Code unter verschiedenen Plattformen/Compilern verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
== Bits löschen ==&lt;br /&gt;
&lt;br /&gt;
Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] auf Null gesetzt werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#UND | UND]]-Verknüpfung erreicht. Alle Bits, welche in der Bitmaske &#039;0&#039; sind, werden auf &#039;0&#039; gesetzt. Alle Bits, die in der Maske auf &#039;1&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR-Assembler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
cbr r16, 0b00001111     ; löscht Bits 0-3 in r16, ist ein Pseudobefehl &lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
andi r16, 0b11110000    ; löscht Bits 0-3 in r16, andi ist identisch mit cbr&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
andi r16, ~0b00001111   ; andere Schreibweise, hier wird die Bitmaske durch ~ invertiert&lt;br /&gt;
                        ; dadurch kann man einfach alle zu löschenden Bit als &#039;1&#039; angeben&lt;br /&gt;
                        ; so wie bei den Bitmasken für das setzen von Bits (positive Logik)&lt;br /&gt;
&lt;br /&gt;
cbi PORTB, 5            ; löscht Bit 5 in PortB&lt;br /&gt;
cbi PORTB, PB5          ; identisch, besser lesbar&lt;br /&gt;
                        ; funktioniert nur für die IO-Register 0..31&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register mit I/O Adresse 0x20..0x3F muss&lt;br /&gt;
                        ; in/out verwendet werden weil dieser Bereich nicht&lt;br /&gt;
                        ; bitadressierbar ist&lt;br /&gt;
in  r16, TIMSK          ; löscht Bit TOIE1 in TIMSK&lt;br /&gt;
cbr r16, 1&amp;lt;&amp;lt;TOIE1    &lt;br /&gt;
out TIMSK, r16&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register oberhalb der I/O Adresse 0x3F muss&lt;br /&gt;
                        ; lds/sts verwednet werden&lt;br /&gt;
                        ; löscht Bit RXCIE0 in UCSR0B&lt;br /&gt;
lds r16, UCSR0B &lt;br /&gt;
cbr r16, 1&amp;lt;&amp;lt;RXCIE0&lt;br /&gt;
sts UCSR0B, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier gilt: Man beachte den Unterschied! Eine &amp;quot;5&amp;quot; würde von cbr als &amp;quot;lösche Bit 2 und 0&amp;quot; gedeutet, während cbi sie als &amp;quot;lösche Bit 5&amp;quot; versteht. Der Befehl &#039;&#039;&#039;cbr&#039;&#039;&#039; erwartet ein Bit&#039;&#039;&#039;muster&#039;&#039;&#039; für eine UND-NOT-Verknüpfung (nicht zu verwechseln mit NAND), während der Befehl &#039;&#039;&#039;cbi&#039;&#039;&#039; die Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; benötigt. Darauf sind auch die Includefiles von Atmel im AVR-Studio (Assembler) als auch [[WinAVR]] ausgelegt. Die Namen der Bits sind als Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; definiert. Das ist wichtig, wenn man Register von grossen AVRs manipuliert, z.&amp;amp;nbsp;B. ATmega48. Hier muss aus der Bitnummer über eine Schiebeoperation &amp;lt;&amp;lt; erst das Bit&#039;&#039;&#039;muster&#039;&#039;&#039; gemacht werden.&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB &amp;amp;= 0xF0;   // entspricht PORTB = PORTB &amp;amp; 0xF0; bitweises UND&lt;br /&gt;
                 // Bits 0-3 (das &amp;quot;niederwertige&amp;quot; Nibble) werden geloescht &lt;br /&gt;
&lt;br /&gt;
/* übersichtlicher mittels Bit-Definitionen */ &lt;br /&gt;
#define MEINBIT0 0&lt;br /&gt;
#define MEINBIT1 1  &lt;br /&gt;
#define MEINBIT2 2  &lt;br /&gt;
&lt;br /&gt;
PORTB &amp;amp;= ~((1 &amp;lt;&amp;lt; MEINBIT0) | (1 &amp;lt;&amp;lt; MEINBIT2)); // löscht Bit 0 und 2 in PORTB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die letzte Zeile entschlüsselt:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;(1 &amp;lt;&amp;lt; n)&#039;&#039;&#039; : Zuerst wird durch die &#039;&amp;lt;&amp;lt;&#039;-Ausdrücke eine &amp;quot;1&amp;quot; n-mal nach links geschoben. Dies ergibt somit (in Binärschreibweise) 0b00000001 für (1 &amp;lt;&amp;lt; MEINBIT0) und 0b00000100 für (1 &amp;lt;&amp;lt; MEINBIT2).&lt;br /&gt;
# &#039;&#039;&#039;|&#039;&#039;&#039; : Das Ergebnis wird bitweise ODER-verknüpft also 0b00000001 &#039;&#039;or&#039;&#039; 0b00000100 wird zu 0b00000101.&lt;br /&gt;
# &#039;&#039;&#039;~&#039;&#039;&#039; : Der Wert in der Klammer wird bitweise invertiert, aus 0b00000101 wird 0b11111010.&lt;br /&gt;
# &#039;&#039;&#039;&amp;amp;=&#039;&#039;&#039; : PORTB wird mit der berechneten Maske UND-verknüpft und das Ergebnis wieder PORTB zugewiesen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB &amp;amp;= variable;          // Kurzschreibweise&lt;br /&gt;
PORTB  = PORTB &amp;amp; variable;  // lange Schreibweise&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Ist PORTB vorher z.&amp;amp;nbsp;B. 0b01111111, dann ist der Inhalt nach der Operation 0b011111111 &#039;&#039;and&#039;&#039; 0b11111010 = 0b01111010, die gewünschten Bits 0 und 2 sind somit gelöscht.&lt;br /&gt;
&lt;br /&gt;
Die C-Ausdrücke mittels Definitionen von Bitnummern und Schieboperator (&amp;lt;&amp;lt;) sehen auf den ersten Blick etwas &amp;quot;erschreckend&amp;quot; aus und sind mehr &amp;quot;Tipparbeit&amp;quot;, funktionieren aber universell und sind deutlicher und nachvollziehbarer als &amp;quot;handoptimierte&amp;quot; Konstanten. Bei eingeschalteter Optimierung löst der Compiler die Ausdücke mit konstanten Werten bereits zur Compilierungszeit auf und es entsteht kein zusätzlicher Maschinencode. Bei AVR sind die Definitionen meist Teil der Entwicklungsumgebungen (bei avr-libc z.&amp;amp;nbsp;B. implizit durch #include &amp;lt;avr/io.h&amp;gt;). Sie entsprechen den Angaben und Beispielen in den Datenblättern und sind damit de-facto ein Standard beim Zugriff auf Bits in Hardware-Registern.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Wichtiger Hinweis&#039;&#039;&#039;: Die ODER-Verknüpfung und die anschliessende Invertierung kann man nicht vertauschen! (Theorem von DeMorgan) Folgendes Beispiel soll die Richtigkeit der Aussage zeigen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 ~(0b0001 | 0b0010) == 0b1100&lt;br /&gt;
  ~0b0001 | ~0b0010 == 0b1111&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Noch ein wichtiger Hinweis&#039;&#039;&#039;: Der operator ~ mit einem Operanden vom Typ int negiert nur so viele bits, wie der Typ int hat.&lt;br /&gt;
Will man ein bit in einer breiteren Variablen löschen, dann sollte die nach links zu shiftende 1 den Typ dieser Variablen haben.&lt;br /&gt;
&lt;br /&gt;
Ein Programm, welches das verdeutlicht:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, const char* argv[])&lt;br /&gt;
{&lt;br /&gt;
    int bit = 60;&lt;br /&gt;
    uint64_t ui64;&lt;br /&gt;
    printf(&amp;quot;sizeof(int)=%d\n&amp;quot;, (int)sizeof(int));&lt;br /&gt;
    &lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;    &lt;br /&gt;
    ui64 &amp;amp;= ~(1&amp;lt;&amp;lt;60); /* Keine Wirkung bei sizeof(int) &amp;lt; 8 */&lt;br /&gt;
    /* gcc warnt sogar:    &lt;br /&gt;
     * gcc -Wall bit_clear.c -o bit_clear&lt;br /&gt;
     * bit_clear.c: In function ‘main’:&lt;br /&gt;
     * bit_clear.c:11:5: warning: left shift count &amp;gt;= width of type [enabled by default]&lt;br /&gt;
     */    &lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;    &lt;br /&gt;
    ui64 &amp;amp;= ~((uint64_t)1&amp;lt;&amp;lt;60); /* ok */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;&lt;br /&gt;
    ui64 &amp;amp;= ~(1LL&amp;lt;&amp;lt;60); /* auch ok, und kürzer. */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;&lt;br /&gt;
    ui64 &amp;amp;= ~(1&amp;lt;&amp;lt;bit); /* Ohne Warnung, und funktioniert manchmal, je nach Optimierung */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
/* Ausgabe auf meinem PC ohne Optimierung:&lt;br /&gt;
 * sizeof(int)=4&lt;br /&gt;
 * 0&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * Ausgabe auf meinem PC mit -O2&lt;br /&gt;
 * 0&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * 0&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Niederwertigstes gesetztes Bit löschen (Standard C) ===&lt;br /&gt;
&lt;br /&gt;
Folgender Code löscht von allen 1-Bits in einer Integer-Variable das niederwertigste, unabhängig von der Position desselben.&lt;br /&gt;
&lt;br /&gt;
Beispiel: 01101000 -&amp;gt; 01100000&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t byte;&lt;br /&gt;
&lt;br /&gt;
byte = irgendwas();&lt;br /&gt;
&lt;br /&gt;
byte = byte &amp;amp; (byte - 1); /* Diese seltsame Operation löscht das&lt;br /&gt;
                             niederwertigste 1-Bit */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Byte  :  01101000 &lt;br /&gt;
Byte-1:  01100111&lt;br /&gt;
Ergebnis:01100000&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Das funktioniert also mit jeder beliebigen Zahl.&lt;br /&gt;
&lt;br /&gt;
Dies kann bspw. zur schnellen Paritätsgenerierung eingesetzt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t pareven(uint8_t byte) {&lt;br /&gt;
  uint8_t par = 0;&lt;br /&gt;
&lt;br /&gt;
  while(byte) {&lt;br /&gt;
    byte = byte &amp;amp; (byte - 1);&lt;br /&gt;
    par = ~par;&lt;br /&gt;
  }&lt;br /&gt;
  return par;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das genannte gilt natürlich nicht nur für 8-Bit-Integers, sondern für beliebige, vom Compiler unterstützte Wortlängen.&lt;br /&gt;
&lt;br /&gt;
== Bits invertieren ==&lt;br /&gt;
&lt;br /&gt;
Im allgemeinen Sprachgebrauch oft Toggeln genannt (aus dem Englischen). Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] invertiert (getoggelt) werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#XOR_.28Exlusives_Oder.29 | XOR]]-Verknüpfung erreicht. Alle Bits, welche in der Bitmaske &#039;1&#039; sind, werden invertiert. Alle Bits, die in der Maske auf &#039;0&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR Assembler ===&lt;br /&gt;
&lt;br /&gt;
Bei [[AVR]]s erlaubt dies folgender Assemblercode. Hier wird ein Ausgangspin invertiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
  sbic  PortB, 0    ; Überspringe den nächsten Befehl, wenn das Bit 0 im Port gelöscht ist&lt;br /&gt;
  rjmp  ClrBitNow   ; Springe zu ClrBitNow   &lt;br /&gt;
  sbi   PortB, 0    ; Setze Bit 0 in PortB&lt;br /&gt;
  rjmp  BitReady    ; Springe BitReady&lt;br /&gt;
ClrBitNow:&lt;br /&gt;
   cbi  PortB, 0    ; Lösche Bit 0 in PortB&lt;br /&gt;
BitReady:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Noch kürzer gehts so:&amp;lt;br&amp;gt;&lt;br /&gt;
Die zweite Zeile mit dem Befehl &#039;&#039;&#039;ldi&#039;&#039;&#039; lädt die Bitmaske, in welcher die zu toggelnden Bits auf &#039;1&#039; gesetzt sind. In diesem Beispiel wird das dritte Bit invertiert. Der Vorteil dieser Methode ist neben der Kürze und Übersichtlichkeit auch die Möglichkeit, bis zu 8 Bit gleichzeitig zu toggeln. Diese Methode ist natürlich auch auf normale Daten anwendbar, nicht nur auf IO-Ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
 in     R24, PORTE   ; Daten lesen&lt;br /&gt;
 ldi    R25, 0x04    ; Bitmaske laden, hier Bit #2&lt;br /&gt;
 eor    R24, R25     ; Exklusiv ODER&lt;br /&gt;
 out    PORTE, R24   ; Daten zurückschreiben&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine andere Möglichkeit gibt es, wenn man nur das 8. Bit kippen will:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
 in      r16, PORTB&lt;br /&gt;
 subi    r16, 0x80&lt;br /&gt;
 out     PORTB, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 PORTB ^= (1&amp;lt;&amp;lt;PB0);    /* XOR, Kurzschreibweise, PORTB = PORTB ^ (1&amp;lt;&amp;lt;PB0) */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Neuere ATmegas ===&lt;br /&gt;
&lt;br /&gt;
Bei den neueren ATmegas (z.&amp;amp;nbsp;B. ATmega48) kann man IO-Pins direkt ohne den Umweg über Register togglen, indem man das entsprechende Bit im PINx-Register &#039;&#039;&#039;setzt&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
sbi PIND, 2       ; Bit 2 von Port D togglen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 8051er ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
cpl bitadresse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bits prüfen ==&lt;br /&gt;
&lt;br /&gt;
Will man prüfen ob ein oder mehrere Bits in einer Variable gesetzt oder gelöscht sind, muss man sie mit einer Bitmaske UND verknüpfen. Die Bitmaske muss an den Stellen der zu prüfenden Bits eine &#039;1&#039; haben, an allen anderen eine &#039;0&#039;.&lt;br /&gt;
&lt;br /&gt;
* Ist das Ergebnis gleich Null, sind alle geprüften Bits gelöscht.&lt;br /&gt;
* Ist das Ergebnis ungleich Null, ist mindestens ein geprüftes Bit gesetzt.&lt;br /&gt;
* Ist das Ergebnis gleich der Bitmaske, sind alle geprüften Bits gesetzt.&lt;br /&gt;
&lt;br /&gt;
=== AVR Assembler ===&lt;br /&gt;
&lt;br /&gt;
Der AVR hat spezielle Befehle um direkt einzelne Bits in den CPU-Registern r0..r31 sowie den IO-Registern 0..0x1F zu prüfen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
; Befehle zur Prüfung von einzelnen Bits&lt;br /&gt;
&lt;br /&gt;
    sbrs    r16,3       ; überspringe den nächsten Befehl, wenn in r16 Bit #3 gesetzt ist&lt;br /&gt;
    rjmp    bit_ist_nicht_gesetzt&lt;br /&gt;
&lt;br /&gt;
    sbrc    r16,5       ; überspringe den nächsten Befehl, wenn in r16 Bit #5 gelöscht ist&lt;br /&gt;
    rjmp    bit_ist_nicht_geloescht&lt;br /&gt;
&lt;br /&gt;
    sbis    timsk,3     ; überspringe den nächsten Befehl, wenn in timsk Bit #3 gesetzt ist&lt;br /&gt;
    rjmp    bit_ist_nicht_gesetzt&lt;br /&gt;
&lt;br /&gt;
    sbic    timsk,5     ; überspringe den nächsten Befehl, wenn in timsk Bit #5 gelöscht ist&lt;br /&gt;
    rjmp    bit_ist_nicht_geloescht&lt;br /&gt;
&lt;br /&gt;
; Befehle zur Prüfung von mehreren Bits&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    breq    alle_bits_sind_geloescht&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    brne    mind_ein_bit_ist_gesetzt&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    cpi     r16,0b1010&lt;br /&gt;
    breq    alle_bits_sind_gesetzt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    // prüfe ob Bit 4 in der Variable tmp gelöscht ist&lt;br /&gt;
    // die Klammer ist wichtig &lt;br /&gt;
    if (!(tmp &amp;amp; 0x10)) {        &lt;br /&gt;
       // hier die Anweisungen, wenn das Bit gelöscht ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 und Bit 4 in der Variable tmp gelöscht sind&lt;br /&gt;
    // die Klammer ist wichtig! &lt;br /&gt;
    if ((tmp &amp;amp; 0x11) == 0) {        &lt;br /&gt;
       // hier die Anweisungen, wenn beide Bits gelöscht sind&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 oder Bit 4 in der Variable tmp gesetzt ist&lt;br /&gt;
    if (tmp &amp;amp; 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn mindestens ein Bit gesetzt ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 oder Bit 4 in der Variable tmp gelöscht sind&lt;br /&gt;
    if (~tmp &amp;amp; 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn mindestens ein Bit gelöscht ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 4 in der Variable tmp gesetzt ist &lt;br /&gt;
    if (tmp &amp;amp; 0x10) {        &lt;br /&gt;
       // hier die Anweisungen, wenn das Bit gesetzt ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 und Bit 4 in der Variable tmp gesetzt sind&lt;br /&gt;
    // die Klammer ist wichtig! &lt;br /&gt;
    if ((tmp &amp;amp; 0x11) == 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn beide Bits gesetzt sind&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hilfsfunktionen zur Bitmanipulation in C/C++ ==&lt;br /&gt;
Um &amp;quot;einfacher&amp;quot; elementare Bitmanipulationen durchzuführen bietet es sich an einige Hilfsfunktionen zu definieren. Dabei gibt es zwei verschiedene Möglichkeiten diese zu realiseren:&lt;br /&gt;
* Als C-Makro [[C_Makros]]&lt;br /&gt;
* Als Inline-Funktion&lt;br /&gt;
In beiden Fällen wird bei eingeschalteter Optimierung letztendlich vom Compiler ein sehr kompakter (und identischer!) Code erzeugt, jedoch ist dringend von der Verwendung von Makros abzuraten (siehe [[Makro]] )!&lt;br /&gt;
Im Fehlerfall zeigt der Compiler bei der Verwendung vom Makros keine eindeutigen Fehlermeldungen an, da es sich um simple Ersetzungen handelt - bei der Verwendung von Inline-Funktionen hingegen gibt es eine &amp;quot;brauchbare&amp;quot; Fehlermeldung!&lt;br /&gt;
&lt;br /&gt;
=== Beispiele - Inline Variante ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Achtung: Zugriffe erfolgen über Pointer&lt;br /&gt;
// PORTA, PB2 setzen&lt;br /&gt;
BIT_SET(&amp;amp;PORTA, PB2);&lt;br /&gt;
&lt;br /&gt;
// PORTC, PB0 löschen&lt;br /&gt;
BIT_CLEAR(&amp;amp;PORTC, PB0);&lt;br /&gt;
&lt;br /&gt;
// PORTA, PB2 direkt setzen&lt;br /&gt;
// HIGH&lt;br /&gt;
BIT_BOOL_SET(&amp;amp;PORTA, PB2, 1);&lt;br /&gt;
&lt;br /&gt;
// LOW&lt;br /&gt;
BIT_BOOL_SET(&amp;amp;PORTA, PB2, 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beispiele - MakroVariante ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Achtung: Zugriffe erfolgen direkt über die Variablen/Portnamen&lt;br /&gt;
// PORTA, PB2 setzen&lt;br /&gt;
BIT_SET(PORTA, PB2);&lt;br /&gt;
&lt;br /&gt;
// PORTC, PB0 löschen&lt;br /&gt;
BIT_CLEAR(PORTC, PB0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um die Hilfsfunktionen verwenden zu können einfach folgenden Code in eine neue Header-Datei (z.B. BitIO.h) kopieren:&lt;br /&gt;
&lt;br /&gt;
=== Hilfsfunktionen als Inline-Methoden ===&lt;br /&gt;
Achtung: Wenn nur ein C Compiler verwendet wird, kennt dieser den Typ &amp;quot;bool&amp;quot; nicht, dieser muss dann vorher definiert werden!&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *  BitIO.h&lt;br /&gt;
 *	@author 	Andi Dittrich &amp;lt;http://andidittrich.de&amp;gt;&lt;br /&gt;
 *	@version	1.0&lt;br /&gt;
 *	@license	MIT Style X11 License&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;inttypes.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef BITIO_H_&lt;br /&gt;
#define BITIO_H_&lt;br /&gt;
&lt;br /&gt;
// set bit&lt;br /&gt;
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target |= (1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// set clear&lt;br /&gt;
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target &amp;amp;= ~(1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// bit toogle&lt;br /&gt;
static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target ^= (1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// set bit by boolean&lt;br /&gt;
static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable){&lt;br /&gt;
	if (enable){&lt;br /&gt;
		BIT_SET(target, bit);&lt;br /&gt;
	}else{&lt;br /&gt;
		BIT_CLEAR(target, bit);&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif /* BITIO_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hilfsfunktionen als C-Makro (nicht empfohlen) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* Bit setzen */&lt;br /&gt;
#define set_bit(var, bit) ((var) |= (1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
 &lt;br /&gt;
/* Bit löschen */&lt;br /&gt;
#define clear_bit(var, bit) ((var) &amp;amp;= (unsigned)~(1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
 &lt;br /&gt;
/* Bit togglen */&lt;br /&gt;
#define toggle_bit(var,bit) ((var) ^= (1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bitmanipulation beim MSP430 ==&lt;br /&gt;
&lt;br /&gt;
Beim MSP430 und dessen Compilern sind die Bitnamen meist anders definiert. Und zwar nicht als Bitnummer, sondern als Bitmuster. Darum schreibt man dort die Bitzugriffe in C anders. Das kann auch bei anderen Mikrocontrollern bzw. C-Compilern so sein. Wichtig ist, dass man seine eignen Definitionen in der gleichen Weise wie der Compiler anlegt, um Verwirrung zu vermeiden, siehe [[Strukturierte Programmierung auf Mikrocontrollern]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Definition von Bitnamen in den Headerfiles des Compilers&lt;br /&gt;
&lt;br /&gt;
#define PD4 4               // Definition im AVR GCC als Bitnummer&lt;br /&gt;
#define PD5 5&lt;br /&gt;
&lt;br /&gt;
#define P14 (1&amp;lt;&amp;lt;4)          // Definition im MSP430 GCC als Bitmuster&lt;br /&gt;
#define P15 (1&amp;lt;&amp;lt;5)&lt;br /&gt;
&lt;br /&gt;
// Bitmanipulation im Programm&lt;br /&gt;
 &lt;br /&gt;
   DDRD = (1&amp;lt;&amp;lt;PD5) | (1&amp;lt;&amp;lt;PD4);   // AVR GCC&lt;br /&gt;
   P1DIR = P15 | P14;            // MSP430 GCC&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/179566#1729219 Forumsbeitrag:] Bits aus einem Array extrahieren&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/169509#1631439 Forumsbeitrag:] Bits für ein Schieberegister zusammenstellen, TLC5941&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/15466?goto=107726#107720 Forumsbeitrag:] Bitreihenfolge ändern&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/23866?goto=new#177674 Forumsbeitrag:] Wie drehe ich eine Bitreihenfolge um?&lt;br /&gt;
* [http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/AVR-Built_002din-Functions.html AVR Build-in Functions], spezielle Funktion im avr-gcc zur schnellen Bitvertauschung, engl.&lt;br /&gt;
&lt;br /&gt;
[[Category:8051]]&lt;br /&gt;
[[Category:AVR-Arithmetik]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=GPIB-RS232-Schnittstelle&amp;diff=83620</id>
		<title>GPIB-RS232-Schnittstelle</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=GPIB-RS232-Schnittstelle&amp;diff=83620"/>
		<updated>2014-07-13T22:22:58Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Änderung 83589 von 84.21.100.54 (Diskussion) rückgängig gemacht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Achtung, Baustelle.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;von Sven Pauli&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Einfacher GPIB-Controller mit serieller Schnittstelle (RS232).&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
[[Datei:gpib-rs232.jpeg|miniatur|GPIB-RS232-Schnittstelle]]&lt;br /&gt;
Viele Messgeräte sind (auch heute immer noch) mit einer GPIB-Schnittstelle ausgerüstet. Zwar handelt es sich hierbei zwar um einen eher antiquierten, parallelen Datenbus, den Hewlett-Packard vor nunmehr vierzig Jahren in die Welt gesetzt hat, dennoch sind es vor allem die [http://www.ni.com/white-paper/3509/en/#vergleichsweise geringen Übertragungslatenzen], welche die GPIB-Schnittstelle auch weiterhin für zeitkritesche Aufgaben prädestinieren.&lt;br /&gt;
Mittlerweile wurde die GPIB-Schnittstelle vielfach genormt - unter anderem unter der Bezeichnung IEEE488 und IEC-625, daher auch die gängige Bezeichnung als &#039;&#039;IEC-BUS&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Der Bus ist acht Bit breit und beinhaltet neben einer Reihe von Steuerleitungen ein Drei-Leitungs-Handshake. Dieses ist in Wired-And-Methodik ausgeführt, d.h. der Bus wird terminiert und mit Pull-up versehen, welchen die Busteilnehmer dann aktiv nach Masse ziehen können. Das Handshake gewährleistet, dass der Bus nur so schnell betrieben wird, wie das langsamste Gerät am Bus Daten aufnehmen kann. Der genaue Ablauf des Bustransfers ist in [http://www.interfacebus.com/Design_Connector_GPIB.html#d dieser Grafik] recht anschaulich beschrieben.&lt;br /&gt;
&lt;br /&gt;
Funktionen:&lt;br /&gt;
* GPIB-Controller, also SH, AH, C,&lt;br /&gt;
* HP Universal Language Interface auf der seriellen,&lt;br /&gt;
* Zustandsanzeige über Blinkmuster...,&lt;br /&gt;
* Vernünftige Pegelwandler und keine Spannungsteiler,&lt;br /&gt;
* umfangreiche End-of-string-Behandlung.&lt;br /&gt;
&lt;br /&gt;
== Terminologie ==&lt;br /&gt;
Sämtliche Signale auf dem Bus sind Low-aktiv.&lt;br /&gt;
&lt;br /&gt;
Der Bus besteht aus den acht Datenleitungen des &#039;&#039;Datenbus&#039;&#039;, die das Datenbyte aufnehmen (invertiert, da Low-aktiv). Ein Byte kann &#039;&#039;auf den Bus gelegt&#039;&#039; werden, indem die Treiber eingeschaltet werden und die Datenleitungen entsprechend gesetzt werden. Um das Byte wieder &#039;&#039;vom Bus zu &#039;&#039;&#039;nehmen&#039;&#039;&#039;&#039;&#039;, werden die Treiber wieder abgeschaltet. Das ist etwas anderes, als ein Byte &#039;&#039;vom Bus zu &#039;&#039;&#039;lesen&#039;&#039;&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
Dazu kommt der &#039;&#039;Übergabebus&#039;&#039; mit den drei Handshakeleitungen DAV (data available), NDAC (no data accepted) und NRFD (not ready for data). Schließlich bilden ein paar Steuerleitungen den &#039;&#039;Steuerbus&#039;&#039;; die wichtigsten wären&lt;br /&gt;
* ATN (attention),&lt;br /&gt;
* REN (remote enable) und&lt;br /&gt;
* EOI (end or identify).&lt;br /&gt;
&lt;br /&gt;
Man spricht beim GPIB eigentlich immer von irgendwelchen &#039;&#039;Botschaften&#039;&#039;, die abgesetzt oder zurückgezogen werden. Es kann sich dabei um Bytes handeln, die über den Bus gehen, oder auch schlicht um eine der Steuer- oder Handshakeleitungen, die einen bestimmten Pegel annimmt. Da der Bus Low-aktiv arbeitet, sind insbesondere die Steuerleitungen &#039;&#039;aktiv&#039;&#039;, wenn sie einen niedrigen Spannungspegel annehmen. Die entsprechende Botschaft ist dann &#039;&#039;gesendet&#039;&#039; (oder &#039;&#039;abgesetzt&#039;&#039;). Wegen Wired-and können auch mehrere Busteilnehmer eine Botschaft zugleich absetzen. Sie bleibt dann solange abgesetzt, bis sämtliche Teilnehmer sie wieder &#039;&#039;zurückgezogen&#039;&#039; haben.&lt;br /&gt;
&lt;br /&gt;
Mit der DAV-Botschaft (data valid) wird signalisiert, dass der Datenbus gültige Daten enthält, die nun gelesen werden können. Wird die EOI-Botschaft (end or identify) zusammen mit einem Byte übertragen, so handelt es sich um das letzte Byte einer längeren Nachricht. Die ATN-Botschaft (attention) fordert alle Busteilnehmer auf, sämtliche Bustätigkeit zu unterbrechen und den Datenbus freizugeben (etwaige Talker nehmen ihr Byte vom Bus).&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
Die Schnittstelle wurde vollständig in bedrahteter Technologie auf einer einseitigen Platine aufgebaut. Für die serielle Schnittstelle kommt der MAX232 zum Einsatz, die Busankopplung nehmen die klassichen SN75160 (Daten) und SN75162 (Steuerleitungen). Zusammengehalten wird beides von einem ATmega16 oder pinkompatiblen. Die Bustreiber sind eigentlich typisch; den -160 bekommt man bei Reichelt. Den zweiten gibt es dort noch als -161; dem fehlen allerdings zwei wichtige Signale, es muss also der -162 sein.&lt;br /&gt;
&lt;br /&gt;
Notfalls lassen sich die Treiber auch aus alten GPIB-Karten ausschlachten...&lt;br /&gt;
&lt;br /&gt;
Zuletzt habe ich noch ein geregeltes Netzteil (7805) spendiert, um die Karte über Hohlstecker zu versorgen. Man halte sich dabei die vergleichsweise große Verlustleistung der Bustreiber vor Augen, wenn man mit dem Gedanken spielt, die Karte über USB zu versorgen: Im Leerlauf insgesamt etwa 150mA.&lt;br /&gt;
&lt;br /&gt;
Zum Bus hin habe ich den typischen Centronics-Stecker (&#039;&#039;micro ribbon connector&#039;&#039;) verbaut. Da ist etwas Vorsicht geboten, denn die gibt es auch in gespiegelter Bauform. Der Stecker ist trapezförmig; die normale Bauform hat das schmale Ende unten (Richtung Platine), die gespiegelte Version nach oben. Ich habe die normale Version gewählt.&lt;br /&gt;
&lt;br /&gt;
Es gibt auf der Platine keine diskrete Logik für die ATN-Leitung. Das mag mancheinem vielleicht schon aufgefallen sein, der alte GPIB-PCI-Steckkarten gesehen hat -- die glichen anfangs einem TTL-Grab. Hintergrund ist, dass in der Spezifikation ein recht zeitkritisches Verhalten als Antwort auf die ATN-Botschaft vereinbart ist. Nämlich haben alle Busteilnehmer bei Empfang der ATN-Botschaft ihren Busbetrieb binnen 200ns einzustellen und die Treiber zu deaktivieren.&lt;br /&gt;
&lt;br /&gt;
Das Zeitfenster von 200ns ist recht sportlich, um es mit einem Interrupt aufzufangen, gerade bei den alten Mikroprozessors, die auf den Steckkarten verbaut wurden, und auch für den AVR. Daher hat man diese Spezifikation (und noch ein paar weitere) mit diskreter Logik erschlagen. Diese hat sich dann schnell um die Bustreiber gekümmert und einfach ein Flipflop gesetzt. Dieses hat der Mikroprozessor dann bei nächster Gelegenheit abgeholt und hatte damit wieder genug Zeit, zu reagieren.&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
Die Software ist in C für avr-gcc geschrieben.&lt;br /&gt;
&lt;br /&gt;
=== Controller-Betrieb ===&lt;br /&gt;
Die fehlende diskrete Logik hat zur Konsequenz, dass die Schnittstelle eigentlich nur als Controller standardkonform funktioniert. Denn nur dann kümmert sie sich selbst um die ATN-Botschaft und muss demnach nicht auf fremde ATN-Botschaften reagieren, was sie ja aus Zeitgründen nicht innerhalb des spezifizierten Zeitfensters kann. Würde man die Schnittstelle &#039;&#039;nur&#039;&#039; als &#039;&#039;Sprecher&#039;&#039; (Talker) betreiben, könnte der momentane Controller die ATN-Botschaft versenden und gleich darauf ein paar Daten auf den Bus legen. Tut er das so schnell wie möglich, also nach 200ns, hätte die Schnittstelle keine Chance, etwaige Daten vom Bus zu nehmen, denn mit zwei Prozessorzyklen des AVR (bei 8MHz) wären die 200ns schon beim Sprung in den Interrupt verstrichen (rjmp mit zwei Zyklen = 250ns). Und da sind noch nicht die vier Takte drin, die bis zum Interruptvektor vergehen, denn es muss ja noch der Programmzähler auf den Stack gelegt werden.&lt;br /&gt;
&lt;br /&gt;
Praktisch ist der Bus in Wired-and ausgeführt, d.h. es entstehen zumindest keine Kurzschlüsse, wenn zwei gleichzeitig reden, weil die Treiber nicht schnell genug abgeschaltet werden. Es können aber Daten kaputt gehen, wenn andere Teilnehmer die Daten früher vom Bus lesen, als jemand anderes seine Treiber abschaltet. Und zwar nach folgendem Szenario:&lt;br /&gt;
* Wir legen ein Byte auf den Bus und&lt;br /&gt;
* signalisieren das mit der DAV-Botschaft.&lt;br /&gt;
* Ein paar Hörer lesen das Byte vom Bus.&lt;br /&gt;
* Der Controller setzt die ATN-Botschaft ab,&lt;br /&gt;
* er wartet die 200ns und&lt;br /&gt;
* legt seinerseits ein Byte auf den Bus (dieses kollidiert mit unserem) und&lt;br /&gt;
* signalisiert das mit der DAV-Botschaft. Die DAV-Botschaft bleibt also bestehen (Wired-and).&lt;br /&gt;
* Ein paar andere Hörer lesen das (&#039;&#039;&#039;kaputte&#039;&#039;&#039;) Byte vom Bus.&lt;br /&gt;
* Wir bemerken die ATN-Botschaft und ziehen Byte und ATN-Botschaft zurück.&lt;br /&gt;
* Wegen Wired-and ist die DAV-Botschaft noch immer aktiv.&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
Der Betrieb als Hörer leidet am gleichen Problem, hier ist allerdings das Lesen vom Bus kritisch. Ein Sprecher könnte ein Datenbyte auf den Bus legen und dies mit der DAV-Botschaft signalisieren. Das bemerken wir und beginnen mit dem Lesevorgang (Interrupt betreten und so weiter). Indes unterbricht ein Controller die Übertragung mit der ATN-Botschaft der Bus enthält dann ungültige Daten. Und wir fahren munter mit dem begonnenen Lesevorgang fort...&lt;br /&gt;
&lt;br /&gt;
Unterm Strich: Meistens funktioniert es.&lt;br /&gt;
&lt;br /&gt;
=== Protokoll ===&lt;br /&gt;
Für das Protokoll über die serielle Schnittstelle habe ich mich vom &#039;&#039;Universal Language Interface&#039;&#039; (ULI) von Hewlett-Packard inspirieren lassen. Das Heftchen von 1993 fiel mir zufällig in die Hände und ich fand das ganz passend.&lt;br /&gt;
&lt;br /&gt;
Das Prinzip dahinter ist recht einfach. Früher hat man eine GPIB-Karte in den Computer gesteckt und bekam einen Treiber für ein recht bekanntes Betriebssystem seiner Zeit. Dazu kamen ein paar Bibliotheken für BASIC, C, Pascal und so weiter, die entsprechende Funktionen boten. Dazu gehörten Lese- und Schreibbefehle &#039;&#039;ibrd()&#039;&#039; und &#039;&#039;ibwr()&#039;&#039;, Funktionen zur Adressiereung und allerlei Zubehör. Je nach Hersteller waren diese Funktionen dann mehr oder weniger ähnlich und/oder inkompatibel.&lt;br /&gt;
&lt;br /&gt;
Beim ULI dagegen erzeugte der Treiber quasi eine Gerätedatei, die man in der jeweiligen Programmiersprache dann mit Standard-E/A öffnen konnte. Das entspricht in etwa dem, was sich unter *nix schon länger bewährt hat. Eine Bibliothek gibt es nicht mehr, stattdessen werden Befehle zeilenweise in dieses Gerät geschrieben und Antworten kommen zeilenweise wieder heraus. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Zeilenweise&#039;&#039; ist in diesem Zusammenhang schwierig. Einerseits könnten Zeilenendzeichen (Wagenrücklauf CR, Zeilenvorschub LF) auch im Nutzdatenstrom vorkommen, andererseits konstruierte sich anfangs jeder Hersteller von GPIB-Messgeräten ein eigenes Bild vom Zeilenende. Manche wollten nur ein CR oder LF, manche CRLF, ein Semikolon oder die EOI-Botschaft (die EOI-Steuerleitung kann zusammen mit dem letzten übertragenen Byte gesetzt werden und signalisiert dann das Zeilenende). Glücklicherweise waren und sind die meisten Geräte recht tolerant und akzeptieren eine Vielzahl dieser Möglichkeiten, wenn man mit ihnen spricht. Tragischerweise antworten sie aber auch mit einer Vielzahl dieser Möglichkeiten, wenn sie umgekehrt mit uns sprechen...&lt;br /&gt;
&lt;br /&gt;
=== Architektur ===&lt;br /&gt;
Die Firmware ist mehrschichtig konstruiert. Ganz unten liegen zwei Ringpuffer, einer für die serielle Schnittstelle und einer für den GPIB. Diese Puffer kümmern sich um die Handshakes (Dreileitung für GPIB und RTS/CTS für die serielle).&lt;br /&gt;
&lt;br /&gt;
Darüber liegt eine Strom-Schicht (Strom von Datenstrom), die aus den eingehenden Datenströmen der Ringpuffer die Zeilenenden herausfischt und die Zeilenenden in den ausgehenden Strömen erzeugt. Von da an sind beide Schnittstellen an die C-Laufzeitbibliothek angeschlossen, sodass die Kommunikation in weiten Teilen wie gewohnt mit puts()/printf()/... abläuft. Die Zeilenenden in den Eingangsströmen werden dabei als End-of-file (EOF) dargestellt. Da man allerdings kein EOF in den Ausgangsströmen erzeugen kann (könnte man schon, mit fclose(); diese Funktion ist aber schon anderweitig vergeben), werden die Zeilenenden mit einem &#039;&#039;flush&#039;&#039; ausgelöst. Blöderweise ist auch fflush() schon vergeben, daher zwei spezifische Routinen.&lt;br /&gt;
&lt;br /&gt;
Obenauf liegt ein Terminal und verbindet die beiden Schnittstellen über das ULI.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Beispiel ===&lt;br /&gt;
Eine Sitzung mit dem Universalzähler &#039;&#039;PM6652&#039;&#039; und dem Generator &#039;&#039;PM5192&#039;&#039; könnte etwa so aussehen:&lt;br /&gt;
&lt;br /&gt;
Die Baudrate wird automatisch am ersten empfangenen Zeilenvorschub ermittelt:&lt;br /&gt;
 $ echo &amp;gt; ttyUSB1&lt;br /&gt;
Schnittstelle einschalten und den Zähler (Adresse 14) parametrisieren:&lt;br /&gt;
 $ echo &amp;quot;ONLINE&amp;quot; &amp;gt; ttyUSB1&lt;br /&gt;
 $ echo &amp;quot;REMOTE 14&amp;quot; &amp;gt; ttyUSB1&lt;br /&gt;
 $ echo &amp;quot;OUTPUT 14;D&amp;quot; &amp;gt; ttyUSB1&lt;br /&gt;
 $ echo &amp;quot;OUTPUT;F1TE1G0SM5&amp;quot; &amp;gt; ttyUSB1&lt;br /&gt;
Zähler auf 1337Hz einstellen:&lt;br /&gt;
 $ echo &amp;quot;REMOTE 15&amp;quot; &amp;gt; ttyUSB1&lt;br /&gt;
 $ echo &amp;quot;OUTPUT 15;OUT 15;WSLA4F1337&amp;quot; &amp;gt; ttyUSB1&lt;br /&gt;
Messung durchführen und Ergebnis abholen:&lt;br /&gt;
 $ echo &amp;quot;TRIGGER 14&amp;quot; &amp;gt; ttyUSB1&lt;br /&gt;
 $ echo &amp;quot;ENTER 14&amp;quot; &amp;gt; ttyUSB1&lt;br /&gt;
 $ line &amp;lt; ttyUSB1&lt;br /&gt;
 FA 001.3370011E+3&lt;br /&gt;
&lt;br /&gt;
Die Anführungszeichen sind nötig, damit die Shell das Semikolon nicht als Befehlsende interpretiert.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Schaltung ==&lt;br /&gt;
[[Datei:gpib-rs232-sch.png|miniatur|Schaltplan]]&lt;br /&gt;
[[Datei:gpib-rs232-brd.png|miniatur|Board]]&lt;br /&gt;
Die Schaltung ist in EAGLE realisiert; Maßstab des Board ist 1:2, also nicht wundern... Das ganze hat mit drei Drahtbrücken einseitig funktioniert. Die Drahtbrücke oben links verbindet die Schirmung mit Masse.&lt;br /&gt;
&lt;br /&gt;
Schaltplan und Board stelle ich vorerst unter der aktuellen [http://creativecommons.org/licenses/by-nc-sa/3.0/de/ CC-BY-NC-SA] zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
== Downloads ==&lt;br /&gt;
Die jeweils aktuelle Version hängt am jüngsten Beitrag im Thread.&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/256475 Thread zum Artikel]&lt;br /&gt;
* http://www.interfacebus.com/Design_Connector_GPIB.html GPIB Bus &amp;lt;small&amp;gt;Ja ich weiß, GPIB Bus ist wie LCD-Display, aber die Seite heißt nunmal so...&amp;lt;/small&amp;gt;&lt;br /&gt;
* http://linux-gpib.sourceforge.net/doc_html/index.html Typischer Satz von Bibliotheksfunktionen&lt;br /&gt;
* http://www.ni.com/pdf/manuals/370915a.pdf Universal Language Interface&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;br /&gt;
[[Kategorie:UART und RS232]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=RGB_Touch_Matrix&amp;diff=83426</id>
		<title>RGB Touch Matrix</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=RGB_Touch_Matrix&amp;diff=83426"/>
		<updated>2014-06-29T22:35:47Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Links nach Relevanz angeordnet&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Conny G.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es soll eine RGB Touch Matrix entwickelt werden, die z.B. für RGB-Touch-Tische eingesetzt werden kann.&lt;br /&gt;
Beispiel für einen Touch-Tisch: http://www.it-gecko.de/100pixel-rgb-led-tisch-interaktiv-touch.html &lt;br /&gt;
Dieser ist jedoch vom Hardware-Konzept sehr aufwändig gelöst, deshalb ist das Ziel des Projekts als Kern der Lösung zwei Dinge möglichst effizient zu lösen:&lt;br /&gt;
* die einzelnen RGB &amp;amp; Touch Pixel&lt;br /&gt;
* die Verbindung der Pixel auf Basis eines Busses&lt;br /&gt;
Effizient heisst: geringe Bauteilkosten, einfache Herstellung der Pixel und einfach Verkabelung, idealerweise nur ein Bus von 1-2 Leitungen (zzgl. GND).&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Eine RGB-Touch-Matrix besteht aus folgenden Komponenten:&lt;br /&gt;
&lt;br /&gt;
* Steuereinheit (Master), die die Touch-Werte auswertet und entsprechend RGB-Werte an die Pixel (Slave) zurücksendet&lt;br /&gt;
* eine größere Zahl (10x10 = 100 oder 10x20 = 200) RGB &amp;amp; Touch-Pixel, die jede Zelle beleuchten und für jede Zelle ein Touch-Sensing durchführen&lt;br /&gt;
* einem Bus zwischen diesen Komponenten&lt;br /&gt;
&lt;br /&gt;
== Bus ==&lt;br /&gt;
&lt;br /&gt;
Die RGB-Touch-Pixel sollen über einen Bus verbunden werden. Das könnte entweder ein sternförmiger Bus sein oder eine Daisy-Chain wie die WS2811-Chips ihn bilden.&lt;br /&gt;
&lt;br /&gt;
=== Ein Szenario mit Daisy Chain ===&lt;br /&gt;
&lt;br /&gt;
Es sei eine CLK-Leitung vorausgesetzt, diese könnte jedoch auch implizit durch festes Timing gelöst werden (wie WS2811).&lt;br /&gt;
&lt;br /&gt;
Ablauf:&lt;br /&gt;
&lt;br /&gt;
Zunächst in Richtung MOSI, also Master sendet eine Chain von Daten an den ersten Slave.&lt;br /&gt;
&lt;br /&gt;
* durch eine vorhergehende Pause ist der &amp;quot;LATCH &amp;amp; RESET&amp;quot;-Zustand eingetreten, d.h. alle Slaves wissen: wenn jetzt was kommt, dann ist das der Anfang&lt;br /&gt;
* Der Master sendet Bit für Bit an den ersten Slave&lt;br /&gt;
* der erste Slave nimmt sich die ersten 8x3=24 Bits und schreibt sie in seinen Zwischenspeicher für den RGB-Wert&lt;br /&gt;
* der erste Slave schreibt jedes weitere Bit direkt an den Ausgang ohne es weiter anzusehen&lt;br /&gt;
* dasselbe tut jeder weitere Node&lt;br /&gt;
* Pause: LATCH &amp;amp; RESET&lt;br /&gt;
&lt;br /&gt;
Das ist die Richtung &amp;quot;RGB an Slaves&amp;quot;, von den WS2811 bekannt.&lt;br /&gt;
&lt;br /&gt;
Die Rückrichtung:&lt;br /&gt;
es müsste also jetzt beim Master an MISO nach und nach, Bit für Bit die Chain an Daten aus den Slaves ankommen, also muss sich hier das ganze Spektakel umgekehrt abspielen.&lt;br /&gt;
Während also die Bits in der &amp;quot;hin&amp;quot;-Richtung durchschieben, müssten ebenfalls die Bits in der Rück-Richtung durchshiften.&lt;br /&gt;
&lt;br /&gt;
* Pause = LATCH &amp;amp; RESET setzt alle Slaves in Startzustand.&lt;br /&gt;
* wenn jetzt der erste Slave seine Daten bekommt, dann müsste er einfach gleichzeitig am Ausgang entweder seine oder die Daten des nächsten Node setzen&lt;br /&gt;
* er erhält also das erste Bit vom Master. Jetzt setzt er das erste Bit  seiner Sensordaten&lt;br /&gt;
* nach den ersten 24 Bits (= seine RGB-Daten) sind seine Sensordaten durch (24 Bit Sensor-Daten)&lt;br /&gt;
* ab dann lauscht er auf seinem Eingang für Sensordaten vom nächsten Node und er reicht jedes Bit, das dort ankommt direkt an den Master weiter&lt;br /&gt;
* spannenderweise passiert es genau zum selben Zeitpunkt, dass er seine 24 Bit RGB-Daten durchhat und dann die weiteren Bits weiterreicht wenn er die Daten des nächsten Node für Rück weiterreichen soll, das läuft also 100% parallel&lt;br /&gt;
* der 2. Slave tut genau dasselbe&lt;br /&gt;
&lt;br /&gt;
Nun kommen beim Hinsenden der RGBs genau der Strom an Sensordaten wieder zurück.&lt;br /&gt;
&lt;br /&gt;
Vorteile: &lt;br /&gt;
* Die Datenübertragung dauert genauso lange wie es dauert die Daten seriell auf einen Bus zu schicken, da ist keine Zeitverzögerung&lt;br /&gt;
* es müssen vom Master keine Nodes addressiert und abgefragt werden, also maximal effizient&lt;br /&gt;
* für die bidirektionale Übertragung brauche ich keine Extrazeit, die Rückdaten kommen gleichzeitig&lt;br /&gt;
* es ist völlig egal, wieviele Slaves ich habe, solange die Gesamtübertragungrate noch die gewünschte Framerate hergibt. Danach kann man den Bus splitten und z.B. die ganze Kette in 2 Teile trennen und einfach 2x einspeisen, dann kann man mit selber Framerate doppelt soviele Slaves abdecken&lt;br /&gt;
* die Übertragung ist maximal Stör-un-anfällig, weil die Distanz zwischen den Clients kurz ist und das Signal jedesmal neu gesendet wird&lt;br /&gt;
* man braucht keine Tranceiver, die Attiny sind gleichzeitig die Tranceiver&lt;br /&gt;
* man braucht nur 2 Leitungen mit GND, wenn es mit implizitem Takt läuft&lt;br /&gt;
&lt;br /&gt;
Idealerweise hängen alle Slaves einfach an einem Strang als einfachstmögliche Konstellation - einfache Verkabelung, keine mehrfach-Einspeisung in der Software.&lt;br /&gt;
Für einen 10x10 RGB-Touch-Tisch sind das 100 Slaves. Jeder hat 24 Bits zu bekommen, ergibt 2400 Bits.&lt;br /&gt;
Mal Framerate von 25 ergibt 25 x 2.400 Bits = 60.000 Bits pro Sekunde.&lt;br /&gt;
Vorsichtshalber betreiben wir den Bus mit 100 kBit, dann  sind wir nicht in einem technisch kritischen Bereich und brauchen nur einen Strang. (Die WS2811 machen 800 kBit, also das 8-fache).&lt;br /&gt;
250 kbit sollten noch ebenso einfach machbar sein, dann kann auch ein 10x20 Tisch in einem Strang betrieben werden&lt;br /&gt;
&lt;br /&gt;
Das Protokoll wäre auch mit nur einer Leitung denkbar, wenn noch einbaut, dass man den Slaves mitteilt: jetzt gehört die Leitung Euch!&lt;br /&gt;
Zum Beispiel: man sendet eine Chain von 0xffffff an alle (d.h. der RGB-Wert 0xffffff steht nicht zur Verfügung) und weiss: jetzt kommen als nächstes solange Bits zurück (Mode: MISO), bis mindestens eine Pause von xx Millisekunden da ist, dann ist der Mode wieder MOSI.&lt;br /&gt;
Man müsste gezielt RGB-Frames dafür ausfallen lassen, d.h. es reduziert die Framerate ein wenig und die Abtastrate der Touches ist auf 5-10/Sekunde begrenzt (das ist ausreichend).&lt;br /&gt;
Zum Beispiel: grundsätzliche Framerate 35 FPS, jeder 5. fällt aus für Touch-Sensing, dann habe ich 7x Touch pro Sekunde und 28 RGB-Frames.&lt;br /&gt;
Ein Problem mit unregelmässiger Refreshrate gibt es hier nicht, da alle Slaves beim letzten RGB-Wert bleiben und weiterleuchten, nur die Aktualisierung &amp;quot;stockt&amp;quot; für eine 35stel Sekunde, das ist nicht wahrnehmbar.&lt;br /&gt;
&lt;br /&gt;
== RGB &amp;amp; Touch Pixel ==&lt;br /&gt;
Ein Pixel soll die Abmaße von 45x45mm bis maximal 50x50mm haben. Um Trennwände zwischen den Pixeln verwenden zu können, sollte auf die Maximalgröße verzichtet werden.&lt;br /&gt;
&lt;br /&gt;
Für die Beleuchtung ist eine RGB vorgesehen, welche über drei verschiedene PWM-Kanäle angesteuert wird. Hierbei sollten mindestens 8bit oder besser 10bit Auflösungen angestrebt werden, um flüssige Übergänge zu erhalten.&lt;br /&gt;
&lt;br /&gt;
Die Idee zur Erkennung ist eine Infrarot-LED zu verwenden, welche eine Wellenlänge von ca. 940-950nm bedient, um einen IR-Strahl auszusenden. Wenn sich ein Objekt über dem Pixel befindet, wird dieser Strahl reflektiert und eine Fotodiode (inkl. Arbeitsbereich 940-950nm) im Pixel erkennt diese Infrarotstrahlen. Dabei muss darauf geachtet werden, dass die IR-LED möglichst nach &amp;quot;oben&amp;quot; strahlt, um nicht direkt die Fotodiode zu beeinflussen. Somit kann die Fotodiode nur eine Reflektion erkennen.&lt;br /&gt;
Diese Reflektion kann an der Diode mittels Spannungsabfall über einen ADC ausgewertet werden. &lt;br /&gt;
&lt;br /&gt;
Um die Touch-Erkennung etwas zu &amp;quot;tunen&amp;quot; können Filter verwendet werden. Als Beispiel sei das Umgebungslicht kurz erwähnt. Denn je nach Helligkeit der Umgebung verändert sich die Charakteristik des Touch. Wenn also dies nicht berücksichtigt wird, könnte im zweifelsfall eine Erkennung bei Sonnenschein schwer werden. Ebenso kann die RGB im eigenen Pixel die Helligkeit entschieden verändert, sodass die Fotodiode andere Verhaltensweise vorweist. Um für die Filterung keine zusätzlichen Hardwarekomponenten und Kosten zu erhalten bietet sich eine Softwarelösung an. Beispielsweise könnte die Fotodiode (RGB aus) einen Wert messen und abspeichern. Nun hat man einen Parameter für die Umgebungshelligkeit. Anschließend kann eine Messung (RGB an) einen Parameter liefern wenn auch der Pixel von innen beleuchtet wird.&lt;br /&gt;
&lt;br /&gt;
== Bauteil-Kandidaten ==&lt;br /&gt;
&lt;br /&gt;
* [http://de.aliexpress.com/item/1000PCS-LOT-5050-highlighted-red-green-and-blue-LED-light-emitting-diode-RGB-LED/1759436080.html RGB-LED] 21USD/1000&lt;br /&gt;
&lt;br /&gt;
* [http://de.aliexpress.com/item/free-shipping-10000pcs-lot-5mm-LED-IR-water-clear-led-diode-850nm-940nm-LED-Light-Emitting/1665949654.html IR-LED] 21USD/1000&lt;br /&gt;
&lt;br /&gt;
* [http://de.aliexpress.com/item/2-X-1000-pcs-Lot-3MM-940NM-Photodiode-Infrared-Emission-Controls-FZ0444-Free-Shipping/1508783472.html IR-Photodiode] 50USD/2000&lt;br /&gt;
&lt;br /&gt;
* [http://www.digikey.de/product-detail/de/ATTINY841-SSU/ATTINY841-SSU-ND/4437435 ATtiny841] 1€@500&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* Forumsthread [http://www.mikrocontroller.net/topic/337623 Projektidee RGB Pixel mit Touch] (aktueller Thread für &amp;quot;ein Pixel pro Platine&amp;quot;)&lt;br /&gt;
* Forumsthread [http://www.mikrocontroller.net/topic/326662 LED Tisch mit Berührungs-/Gegenstandserkennung] (ursprünglicher Thread)&lt;br /&gt;
* Forumsthread [http://www.mikrocontroller.net/topic/329090 Schwierigkeiten passenden Bus zu finden]&lt;br /&gt;
&lt;br /&gt;
[[Category:Projekte| ]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Diskussion:RGB_Touch_Matrix&amp;diff=83399</id>
		<title>Diskussion:RGB Touch Matrix</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Diskussion:RGB_Touch_Matrix&amp;diff=83399"/>
		<updated>2014-06-26T17:11:55Z</updated>

		<summary type="html">&lt;p&gt;Maybee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Daisy-Chain / Kommunikation ==&lt;br /&gt;
&lt;br /&gt;
=== SPI ===&lt;br /&gt;
&lt;br /&gt;
Bei der Daisy-Chain könnte man auch einfach MISO vom letzten Slave als Ausgang für die Daten nehmen, dann werden alle x Bits durchgeschoben. Der Master tauscht immer 1 Byte RGB gegen ein Byte Touchdaten. Gelatcht wird dann nicht wenn ein slave 24 bit drinnen hat, sondern wenn clock länger als x µS still war. Damit können die slaves einfache Schieberegister imitieren und man hat die Clock synchron an allen Slaves, damit spart man sich den Delay von jedem Slave in der Chain. --93.188.26.218 26.06.2014 12:53&lt;br /&gt;
&lt;br /&gt;
: Möglichkeiten gibt es viele. Der Charme einer Daisy-Chain mit UART liegt in der einzelnen Kommunikationsleitung: geringstmöglicher Verdrahtungsaufwand. --[[Benutzer:Maybee|Maybee]] ([[Benutzer Diskussion:Maybee|Diskussion]]) 19:11, 26. Jun. 2014 (CEST)&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=RGB_Touch_Matrix&amp;diff=83388</id>
		<title>RGB Touch Matrix</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=RGB_Touch_Matrix&amp;diff=83388"/>
		<updated>2014-06-24T18:44:18Z</updated>

		<summary type="html">&lt;p&gt;Maybee: /* Bauteil-Kandidaten */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Conny G.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es soll eine RGB Touch Matrix entwickelt werden, die z.B. für RGB-Touch-Tische eingesetzt werden kann.&lt;br /&gt;
Beispiel für einen Touch-Tisch: http://www.it-gecko.de/100pixel-rgb-led-tisch-interaktiv-touch.html &lt;br /&gt;
Dieser ist jedoch vom Hardware-Konzept sehr aufwändig gelöst, deshalb ist das Ziel des Projekts als Kern der Lösung zwei Dinge möglichst effizient zu lösen:&lt;br /&gt;
* die einzelnen RGB &amp;amp; Touch Pixel&lt;br /&gt;
* die Verbindung der Pixel auf Basis eines Busses&lt;br /&gt;
Effizient heisst: geringe Bauteilkosten, einfache Herstellung der Pixel und einfach Verkabelung, idealerweise nur ein Bus von 1-2 Leitungen (zzgl. GND).&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Eine RGB-Touch-Matrix besteht aus folgenden Komponenten:&lt;br /&gt;
&lt;br /&gt;
* Steuereinheit, die die Touch-Werte auswertet und entsprechend RGB-Werte an die Pixel zurücksendet&lt;br /&gt;
* eine größere Zahl (10x10 = 100 oder 10x20 = 200) RGB &amp;amp; Touch-Pixel, die jede Zelle beleuchten und für jede Zelle ein Touch-Sensing durchführen&lt;br /&gt;
* einem Bus zwischen diesen Komponenten&lt;br /&gt;
&lt;br /&gt;
== Bus ==&lt;br /&gt;
&lt;br /&gt;
Die RGB-Touch-Pixel sollen über einen Bus verbunden werden. Das könnte entweder ein sternförmiger Bus sein oder eine Daisy-Chain wie die WS2811-Chips ihn bilden.&lt;br /&gt;
&lt;br /&gt;
=== Ein Szenario mit Daisy Chain ===&lt;br /&gt;
&lt;br /&gt;
Es sei eine CLK-Leitung vorausgesetzt, diese könnte jedoch auch implizit durch festes Timing gelöst werden (wie WS2811).&lt;br /&gt;
&lt;br /&gt;
Ablauf:&lt;br /&gt;
&lt;br /&gt;
Zunächst in Richtung MOSI, also Master sendet eine Chain von Daten an den ersten Slave.&lt;br /&gt;
&lt;br /&gt;
* durch eine vorhergehende Pause ist der &amp;quot;LATCH &amp;amp; RESET&amp;quot;-Zustand eingetreten, d.h. alle Slaves wissen: wenn jetzt was kommt, dann ist das der Anfang&lt;br /&gt;
* Der Master sendet Bit für Bit an den ersten Slave&lt;br /&gt;
* der erste Slave nimmt sich die ersten 8x3=24 Bits und schreibt sie in seinen Zwischenspeicher für den RGB-Wert&lt;br /&gt;
* der erste Slave schreibt jedes weitere Bit direkt an den Ausgang ohne es weiter anzusehen&lt;br /&gt;
* dasselbe tut jeder weitere Node&lt;br /&gt;
* Pause: LATCH &amp;amp; RESET&lt;br /&gt;
&lt;br /&gt;
Das ist die Richtung &amp;quot;RGB an Slaves&amp;quot;, von den WS2811 bekannt.&lt;br /&gt;
&lt;br /&gt;
Die Rückrichtung:&lt;br /&gt;
es müsste also jetzt beim Master an MISO nach und nach, Bit für Bit die Chain an Daten aus den Slaves ankommen, also muss sich hier das ganze Spektakel umgekehrt abspielen.&lt;br /&gt;
Während also die Bits in der &amp;quot;hin&amp;quot;-Richtung durchschieben, müssten ebenfalls die Bits in der Rück-Richtung durchshiften.&lt;br /&gt;
&lt;br /&gt;
* Pause = LATCH &amp;amp; RESET setzt alle Slaves in Startzustand.&lt;br /&gt;
* wenn jetzt der erste Slave seine Daten bekommt, dann müsste er einfach gleichzeitig am Ausgang entweder seine oder die Daten des nächsten Node setzen&lt;br /&gt;
* er erhält also das erste Bit vom Master. Jetzt setzt er das erste Bit  seiner Sensordaten&lt;br /&gt;
* nach den ersten 24 Bits (= seine RGB-Daten) sind seine Sensordaten durch (24 Bit Sensor-Daten)&lt;br /&gt;
* ab dann lauscht er auf seinem Eingang für Sensordaten vom nächsten Node und er reicht jedes Bit, das dort ankommt direkt an den Master weiter&lt;br /&gt;
* spannenderweise passiert es genau zum selben Zeitpunkt, dass er seine 24 Bit RGB-Daten durchhat und dann die weiteren Bits weiterreicht wenn er die Daten des nächsten Node für Rück weiterreichen soll, das läuft also 100% parallel&lt;br /&gt;
* der 2. Slave tut genau dasselbe&lt;br /&gt;
&lt;br /&gt;
Nun kommen beim Hinsenden der RGBs genau der Strom an Sensordaten wieder zurück.&lt;br /&gt;
&lt;br /&gt;
Vorteile: &lt;br /&gt;
* Die Datenübertragung dauert genauso lange wie es dauert die Daten seriell auf einen Bus zu schicken, da ist keine Zeitverzögerung&lt;br /&gt;
* es müssen vom Master keine Nodes addressiert und abgefragt werden, also maximal effizient&lt;br /&gt;
* für die bidirektionale Übertragung brauche ich keine Extrazeit, die Rückdaten kommen gleichzeitig&lt;br /&gt;
* es ist völlig egal, wieviele Slaves ich habe, solange die Gesamtübertragungrate noch die gewünschte Framerate hergibt. Danach kann man den Bus splitten und z.B. die ganze Kette in 2 Teile trennen und einfach 2x einspeisen, dann kann man mit selber Framerate doppelt soviele Slaves abdecken&lt;br /&gt;
* die Übertragung ist maximal Stör-un-anfällig, weil die Distanz zwischen den Clients kurz ist und das Signal jedesmal neu gesendet wird&lt;br /&gt;
* man braucht keine Tranceiver, die Attiny sind gleichzeitig die Tranceiver&lt;br /&gt;
* man braucht nur 2 Leitungen mit GND, wenn es mit implizitem Takt läuft&lt;br /&gt;
&lt;br /&gt;
Idealerweise hängen alle Slaves einfach an einem Strang als einfachstmögliche Konstellation - einfache Verkabelung, keine mehrfach-Einspeisung in der Software.&lt;br /&gt;
Für einen 10x10 RGB-Touch-Tisch sind das 100 Slaves. Jeder hat 24 Bits zu bekommen, ergibt 2400 Bits.&lt;br /&gt;
Mal Framerate von 25 ergibt 25 x 2.400 Bits = 60.000 Bits pro Sekunde.&lt;br /&gt;
Vorsichtshalber betreiben wir den Bus mit 100 kBit, dann  sind wir nicht in einem technisch kritischen Bereich und brauchen nur einen Strang. (Die WS2811 machen 800 kBit, also das 8-fache).&lt;br /&gt;
250 kbit sollten noch ebenso einfach machbar sein, dann kann auch ein 10x20 Tisch in einem Strang betrieben werden&lt;br /&gt;
&lt;br /&gt;
Das Protokoll wäre auch mit nur einer Leitung denkbar, wenn noch einbaut, dass man den Slaves mitteilt: jetzt gehört die Leitung Euch!&lt;br /&gt;
Zum Beispiel: man sendet eine Chain von 0xffffff an alle (d.h. der RGB-Wert 0xffffff steht nicht zur Verfügung) und weiss: jetzt kommen als nächstes solange Bits zurück (Mode: MISO), bis mindestens eine Pause von xx Millisekunden da ist, dann ist der Mode wieder MOSI.&lt;br /&gt;
Man müsste gezielt RGB-Frames dafür ausfallen lassen, d.h. es reduziert die Framerate ein wenig und die Abtastrate der Touches ist auf 5-10/Sekunde begrenzt (das ist ausreichend).&lt;br /&gt;
Zum Beispiel: grundsätzliche Framerate 35 FPS, jeder 5. fällt aus für Touch-Sensing, dann habe ich 7x Touch pro Sekunde und 28 RGB-Frames.&lt;br /&gt;
Ein Problem mit unregelmässiger Refreshrate gibt es hier nicht, da alle Slaves beim letzten RGB-Wert bleiben und weiterleuchten, nur die Aktualisierung &amp;quot;stockt&amp;quot; für eine 35stel Sekunde, das ist nicht wahrnehmbar.&lt;br /&gt;
&lt;br /&gt;
== RGB &amp;amp; Touch Pixel ==&lt;br /&gt;
&lt;br /&gt;
== Bauteil-Kandidaten ==&lt;br /&gt;
&lt;br /&gt;
* [http://de.aliexpress.com/item/1000PCS-LOT-5050-highlighted-red-green-and-blue-LED-light-emitting-diode-RGB-LED/1759436080.html RGB-LED] 21USD/1000&lt;br /&gt;
&lt;br /&gt;
* [http://de.aliexpress.com/item/free-shipping-10000pcs-lot-5mm-LED-IR-water-clear-led-diode-850nm-940nm-LED-Light-Emitting/1665949654.html IR-LED] 21USD/1000&lt;br /&gt;
&lt;br /&gt;
* [http://de.aliexpress.com/item/2-X-1000-pcs-Lot-3MM-940NM-Photodiode-Infrared-Emission-Controls-FZ0444-Free-Shipping/1508783472.html IR-Photodiode] 50USD/2000&lt;br /&gt;
&lt;br /&gt;
* [http://www.digikey.de/product-detail/de/ATTINY841-SSU/ATTINY841-SSU-ND/4437435 ATtiny841] 1€@500&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* Forumsthread [http://www.mikrocontroller.net/topic/326662 LED Tisch mit Berührungs-/Gegenstandserkennung]&lt;br /&gt;
* Forumsthread [http://www.mikrocontroller.net/topic/329090 Schwierigkeiten passenden Bus zu finden]&lt;br /&gt;
* [[Audio-Projekt|Link zu anderem Projekt]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Projekte| ]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR_Typen&amp;diff=83374</id>
		<title>AVR Typen</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR_Typen&amp;diff=83374"/>
		<updated>2014-06-20T22:27:17Z</updated>

		<summary type="html">&lt;p&gt;Maybee: aktualisierter Link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== AT90S ==&lt;br /&gt;
Die &amp;quot;Basic Line&amp;quot; der Atmel [[AVR]]-Reihe. Sie beinhaltet die ersten [[AVR|AVRs]] die produziert wurden und deren Bezeichnung mit &amp;quot;AT90S&amp;quot; beginnt. Alle Typen wurden mit der Zeit von den beiden Nachfolgereihen ersetzt: ATmega bzw. ATtiny.&lt;br /&gt;
&lt;br /&gt;
Einige neue AVR-Controller tragen eine mit AT90-&#039;&#039;ohne S&#039;&#039; beginnende Bezeichnung, haben aber einen &amp;quot;moderneren&amp;quot; Kern. Z.B. sind die Typen AT90PWM2/3 und AT90CAN128 vom Funktionsumfang (interner RC, USART etc.) den ATmegas zuzuordnen.&lt;br /&gt;
&lt;br /&gt;
== ATmega ==&lt;br /&gt;
Die ATmega-[[Mikrocontroller]] sind ein Teil der AVR-Controllerfamilie. Zusammen mit den ATtiny lösen die ATmega die AT90S-Serie schrittweise ab, wobei es in den meisten Fällen weitgehend pin- und funktionskompatiblen Ersatz für abgekündigte Controller gibt (ATmega8 bzw. ATmega8A statt AT90S4433, ATmega8515 statt AT90S8515 usw.).&lt;br /&gt;
&lt;br /&gt;
Atmel ATmega AVRs werden mit aktiviertem internem Taktgeber ausgeliefert. Schließt man eine andere externe Taktquelle an (Quarz, Quarzoszillator o.ä), wird diese nicht automatisch genutzt. Zum Aktivieren müssen die Fuse-Bits des Controllers entsprechend eingestellt werden (siehe Datenblatt).&lt;br /&gt;
&lt;br /&gt;
ATmegas mit integriertem [[JTAG]]-Interface (z.Zt. solche ab 16kB Flash-Speicher und mehr als 28 Pins&amp;lt;!-- wg. ATmega168--&amp;gt;) werden ab Werk mit aktiviertem JTAG-Interface ausgeliefert. Dieses Interface belegt vier Port-Pins (z.&amp;amp;nbsp;B. am PORTC bei ATmega16/32), die nicht für eigene Anwendungen genutzt werden können, solange das JTAG-Interface aktiviert ist. Das Interface lässt sich über ein Fuse-Bit (JTAGEN) dauerhaft und über ein Bit (JTD) in dem (oder einem der) MC-Kontroll-Register (Datenblatt nach JTD durchsuchen) per Software zur Laufzeit an- und abschalten. Weiteres im Datenblatt des jeweiligen Controllers in den Abschnitten Memory-Programming (Fuse) und JTAG/ICE (JTD).&lt;br /&gt;
&lt;br /&gt;
Beim ATmega128 ist ab Werk die Mega103-Kompatibilitäts-fuse gesetzt. Um alle Erweiterungen des Mega128 gegenüber dem Mega103 zu nutzen muss diese deaktivert werden. Diese Fuse sorgt außerdem dafür, dass das SRAM in einem anderen Adressbereich liegt. Dadurch funktionieren C-Programme nur bis zum ersten Funktionsaufruf. Siehe auch [[AVR_Checkliste#Besonderheiten_bei_ATmega128_und_seinen_Derivaten_im_64-Pin-Gehäuse | AVR Checkliste: Besonderheiten bei ATmega64 / ATmega128]]&lt;br /&gt;
&lt;br /&gt;
== ATtiny ==&lt;br /&gt;
&lt;br /&gt;
Die ATtiny stellen das untere Ende der neuen AVR Linie von Atmel dar und waren zunächst durch das Fehlen von internem [[RAM#SRAM|SRAM]] gekennzeichnet. Mittlerweile gibt es aber so bemerkenswerte Controller wie den ATtiny4313, deren Möglichkeiten und Funktionen den ATmegas in nichts nachstehen.&lt;br /&gt;
&lt;br /&gt;
Ein weiterer Unterschied zu den ATmegas ist der fehlende Hardwaremultiplizierer. Jede Multiplikation muss also in Software ausgeführt werden. Eine Übersicht über die Verfügbarkeit verschiedener Befehle bietet die [[AVR_Assembler_-_Vergleichstabelle|AVR-Assembler Befehlsvergleichstabelle]].&lt;br /&gt;
&lt;br /&gt;
== ATxmega ==&lt;br /&gt;
Neueste Generation von AVR-Controllern mit neuem internen Aufbau, hoher Taktrate (32 MHz), niedriger Spannung (1,6 - 3,6V), vielen Schnittstellen, in 44 - 100 poligen SMD-Gehäusen. Besonderheiten: ADC mit 2 Megasample/12 Bit, vierpoliges Programm- und Debug- Interface PDI (VTref, CLK, DATA, GND)  erfordert z.B. einen AVR_JTAGICE-mkII Programmer. PDI (Flash und Debug) funktioniert mit C-Code z.B. mit AVR Studio 4.19. &lt;br /&gt;
&lt;br /&gt;
Leider ist die Xmega-Reihe zu den AVR-Prozessoren der Mega- oder Tiny-Serien nicht  kompatibel (viel komplizierter, anderer Aufbau der IO-Baugruppen, der Interrupts, der C-Funktionen etc.). Prozessor-Manuals zeigen weder Assembler noch C-Beispiele für Ansteuerung der IO-Baugruppen. C-Programmbeispiele (geeignet für AVR-Studio) findet man erst in Xmega Application Notes. Einen Überblick gibt es von [http://www.stromflo.de/dokuwiki/doku.php?id=xmega-c-tutorial Florian Grotz] oder in dem [http://www.jtronics.de/avr-projekte/xmega-tutorial.html jtronics Xmega Tutorial]  .&lt;br /&gt;
&lt;br /&gt;
== Sonstiges ==&lt;br /&gt;
&lt;br /&gt;
Die AT89-Familie gehört nicht zu den AVR-Typen mit dem AVR-RISC-Befehlssatz, sondern ist eine [[8051|Intel-8051]]-kompatible 8-Bit µC-Serie.&lt;br /&gt;
&lt;br /&gt;
=== Tiny vs Mega ===&lt;br /&gt;
Die modernen Typen sind die Tiny (=winzig) und die Mega (=riesig). Die ATTiny haben kleinere Gehäuse als die ATMega, mit weniger Pins. Dies führt bei ähnlicher Funktionalität wie die Megas zu extremen Mehrfachbelegungen der Pins und auch eher zu Überschneidungen der Pinfunktionalität. Die Tiny sind daher eher für sehr hohe Stückzahlen geeignet, wo die Einsparung über die Stückzahl kommt. Anfänger und Bastler sind mit den ATMega besser bedient, da es weniger Limitierungen gibt.&lt;br /&gt;
&lt;br /&gt;
Tinys haben keinen Hardware-Multiplizierer.&lt;br /&gt;
&lt;br /&gt;
==Nomenklatur==&lt;br /&gt;
===ATmega===&lt;br /&gt;
Auch wenn die Namensgebung auf den ersten Blick bedingt durch die vielen verfügbaren Modelle kompliziert aussieht, so folgt sie doch immer (von wenigen Ausnahmen abgesehen) einem einfachen Schema. &lt;br /&gt;
&lt;br /&gt;
Nehmen wir einen aktuellen Baustein als Beispiel: *ATmega48PA-AU*. Der Name besteht aus 5 Teilen:&lt;br /&gt;
# Der Baureihe (hier: &amp;quot;ATmega&amp;quot;)&lt;br /&gt;
# Einer Nummer, immer eine Zweierpotenz (hier: 4). Diese Zahl gibt die Größe des Flashspeichers in [https://de.wikipedia.org/wiki/Kibibyte Kibibyte] an. &lt;br /&gt;
# Bis zu zwei weiteren Ziffern (hier: 8). Sie definieren die Zusatzfunktionen sowie Zahl der I/O-Ports.&lt;br /&gt;
# Bis zu zwei Buchstaben (hier: PA), die für die Revision sowie spezielle stromsparende Architekturen stehen.&lt;br /&gt;
# Einem Bindestrich und zwei weiteren Buchstaben, die die Bauform angeben (hier: AU).&lt;br /&gt;
&lt;br /&gt;
====Baureihe====&lt;br /&gt;
&lt;br /&gt;
Hier gibt es nur zwei Reihen: Den kleinen ATtiny mit reduziertem Funktionsumfang und den großen ATmega.&lt;br /&gt;
&lt;br /&gt;
====Speichergröße====&lt;br /&gt;
&lt;br /&gt;
Während die Größe des Flashspeichers (Programmspeicher) direkt im Namen angegeben ist, ergibt sich die Größe von RAM und EEPROM nur indirekt aus dieser Nummer, wobei natürlich die Bausteine mit großem Flash auch mehr RAM und EEPROM haben als kleinere. Grob gilt diese Zuordnung:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Flash (kB)  !! EEPROM (B) !! RAM (B)&lt;br /&gt;
|-&lt;br /&gt;
| 2           ||   tiny: 128      ||  tiny: 128&lt;br /&gt;
|-&lt;br /&gt;
| 4           ||   tiny: var., mega: 256      ||  tiny: 256, mega: 512&lt;br /&gt;
|-&lt;br /&gt;
| 8           ||   tiny: var., mega: 512      ||  tiny: 512, mega: 1024&lt;br /&gt;
|-&lt;br /&gt;
| 16          ||   512      ||  1024&lt;br /&gt;
|-&lt;br /&gt;
| 32          ||   1024     ||  2048&lt;br /&gt;
|-&lt;br /&gt;
| 64          ||   2048*)   ||  4096*)&lt;br /&gt;
|-&lt;br /&gt;
| 128 - 256   ||   4096     ||  4K - 16K&lt;br /&gt;
|}&lt;br /&gt;
 *)Atmega640 verfügt über den doppelten Speicher&lt;br /&gt;
&lt;br /&gt;
====Zusatzfunktionen / Größe====&lt;br /&gt;
Die Ziffer(n) nach der Flashgröße geben die Ausstattungsmerkmale des Bausteins an. Die folgende Tabelle gilt für die Atmega-Reihe:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Ziffer  !! Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| - ||  Keine Ziffer markiert die Bausteine der ersten Generation. Sie verfügen in der Regel über eine niedrigere maximale Taktrate (8/16 MHz anstatt 10/20 MHz), eine höhere Minimal-Spannung (2,7 anstatt 1,8 Volt), weniger Interrupt-Quellen und PWM-Kanäle&lt;br /&gt;
|-&lt;br /&gt;
| 0 ||  Reihe von 32 - 256 kB in einem größeren Gehäuse mit höherer Anzahl an I/O-Pins. Etwas älter als die aktuellen Reihen 4 und 8.&lt;br /&gt;
|-&lt;br /&gt;
| 1 ||  Kennzeichnet eine verbesserte Version des Atmega128 / 256, aber älter als aktuelle 4er Reihe&lt;br /&gt;
|-&lt;br /&gt;
| 4 ||  Reihe von 16 bis 128 kB Flash, alle pinkompatibel in 40-44 poligem Gehäuse. Neueste Baureihe, alle in pico-power-Technologie mit vielen verbesserten Funktionen wie externen Interrupts, Timern, USART...&lt;br /&gt;
|-&lt;br /&gt;
| 5 ||  Reihe von 16 bis 64 kB&lt;br /&gt;
|-&lt;br /&gt;
| 8 ||  Reihe von 4 bis 32 kB, alle pinkompatibel in 28-32 poligem Gehäuse. Neueste Baureihe, alle in pico-power-Technologie mit vielen verbesserten Funktionen wie externen Interrupts, Timern, USART.... (auch in der Attiny-Reihe vorhanden)&lt;br /&gt;
|-&lt;br /&gt;
| 9 ||  Reihe von 16 bis 64 kB mit integriertem Controller für LC-Displays, folglich in großen Gehäusen (64-/100-polig)&lt;br /&gt;
|}&lt;br /&gt;
Aus dieser Liste stechen einige Bausteine als Außenseiter hervor:&lt;br /&gt;
* Atmega8515 / Atmega8535&lt;br /&gt;
* Atmega640: Im Prinzip ein Atmega64 mit deutlich mehr Hardware-Ressourcen (4 UARTs, 16 ADC-Kanäle...) und doppelt soviel EEPROM / SRAM.&lt;br /&gt;
&lt;br /&gt;
====Revision / Architektur====&lt;br /&gt;
Die (optionalen) Buchstaben vor dem Bindestrich geben Auskunft über den Stromverbrauch und Spannungsbereich&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Buchstabe  !! Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| A ||  Zweite Revision - meist nur eine Umstellung der internen Strukturen ohne Auswirkung für den Benutzer&lt;br /&gt;
|-&lt;br /&gt;
| L / V ||  &amp;quot;Low-Voltage&amp;quot;: Speziell für niedrigere Taktraten (8 bzw. 10 MHz) sowie niedrigere Eingangsspannungen (1,8 bzw. 2,7V) selektierte Bausteine&lt;br /&gt;
|-&lt;br /&gt;
| P/PA ||  &amp;quot;Pico-Power&amp;quot;: Reduzierter Stromaufnahme, besonders in tiefen Sleep-Modes (&amp;lt; 1uA); Manche Bausteine (z.B. Mega48) gibt es als P und PA&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Bauform====&lt;br /&gt;
Die beiden Buchstaben nach dem Bindestrich geben Auskunft über die Bauform. Die Zahl der Pins des jeweiligen Gehäusetyps hängt vom Baustein ab.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Buchstaben  !! Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
| A ||  TQFP-Gehäuse&lt;br /&gt;
|-&lt;br /&gt;
| C ||  BGA-Gehäuse&lt;br /&gt;
|-&lt;br /&gt;
| I ||  Bleihaltig - nicht mehr erhältlich&lt;br /&gt;
|-&lt;br /&gt;
| J ||  PLCC-Gehäuse&lt;br /&gt;
|-&lt;br /&gt;
| M ||  (V)QFN- / MLF- Gehäuse&lt;br /&gt;
|-&lt;br /&gt;
| P ||  DIP-Gehäuse  (bastlerfreundlich!)&lt;br /&gt;
|-&lt;br /&gt;
| S ||  SOIC-Gehäuse&lt;br /&gt;
|-&lt;br /&gt;
| U ||  Bleifrei, RoHS-kompatibel&lt;br /&gt;
|-&lt;br /&gt;
| X ||  TSSOP-Gehäuse&lt;br /&gt;
|} &lt;br /&gt;
&lt;br /&gt;
===ATtiny===&lt;br /&gt;
Bei den ATtiny-Bausteinen ist die Nummerierung deutlich unübersichtlicher als in der ATmega-Reihe. Die erste Ziffer gibt wie auch bei ATmega die Größe des Flash-Speichers an. Die obenstehenden Tabellen für Baureihe, Bauform, Revision und Speichergröße gelten ebenfalls (Ausnahmen: ATtiny5 mit 0,5 Kilobytes Flash sowie ATtiny4 und ATtiny9 mit 0,5 bzw. 1 kB Flash). Die Zusatzfunktionen und Baugröße sind aber nicht deutlich&lt;br /&gt;
&lt;br /&gt;
== Vergleichstabelle(n) / Ausstattung ==&lt;br /&gt;
=== AT90S - Reihe ===&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;font-size:10px;&amp;quot; id=&amp;quot;AVR_Features_AT90S&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Typ||Flash (Kbytes)||EEPROM (Bytes)||SRAM (Bytes)||Max I/O Pins||F.max (MHz)||Vcc (V)||Analog &amp;lt;br/&amp;gt;Compa&amp;amp;shy;rator||16-bit Timer||8-bit Timer||Brown Out Detector||On Chip Oscillator||PWM Chan&amp;amp;shy;nels||RTC||Self Prog&amp;amp;shy;ram Memory||Boot Code||SPI||TWI (I2C)||UART||Watch&amp;amp;shy;dog||Bau&amp;amp;shy;form&lt;br /&gt;
|- &amp;lt;!-- START - AT90S2313 -------------------------------------&amp;gt;&lt;br /&gt;
|[http://www.atmel.com/dyn/resources/prod_documents/doc0839.pdf AT90S2313]&amp;lt;ref&amp;gt;veraltet → ATtiny2313&amp;lt;/ref&amp;gt;&lt;br /&gt;
|2&lt;br /&gt;
|128&lt;br /&gt;
|128&lt;br /&gt;
|15&lt;br /&gt;
|10&lt;br /&gt;
|2.7-6.0&lt;br /&gt;
|Ja&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|1&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP20 SOIC20&lt;br /&gt;
|- &amp;lt;!-- START - AT90S2323 ---------------------------------------&amp;gt;&lt;br /&gt;
|[http://www.atmel.com/atmel/acrobat/doc1004.pdf AT90S2323]&amp;lt;ref&amp;gt;veraltet → ATtiny25/45/85&amp;lt;/ref&amp;gt;&lt;br /&gt;
|2&lt;br /&gt;
|128&lt;br /&gt;
|128&lt;br /&gt;
|3&lt;br /&gt;
|10&lt;br /&gt;
|2.7-6.0&lt;br /&gt;
|Nein&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|0&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP8 SOIC8&lt;br /&gt;
|- &amp;lt;!-- START - AT90S2343 ------------------------------&amp;gt;&lt;br /&gt;
|[http://www.atmel.com/atmel/acrobat/doc1004.pdf AT90S2343]&amp;lt;ref&amp;gt;veraltet → ATtiny25/45/85&amp;lt;/ref&amp;gt;&lt;br /&gt;
|2&lt;br /&gt;
|128&lt;br /&gt;
|128&lt;br /&gt;
|5&lt;br /&gt;
|10&lt;br /&gt;
|2.7-6.0&lt;br /&gt;
|Nein&lt;br /&gt;
|0&lt;br /&gt;
|1&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|0&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP8 SOIC8 &lt;br /&gt;
|- &amp;lt;!-- START - AT90S8515 ----------------------------------&amp;gt;&lt;br /&gt;
|[http://www.atmel.com/atmel/acrobat/doc0841.pdf AT90S8515]&amp;lt;ref&amp;gt;veraltet → ATmega16/162/32/644&amp;lt;/ref&amp;gt;&lt;br /&gt;
|8&lt;br /&gt;
|512&lt;br /&gt;
|512&lt;br /&gt;
|32&lt;br /&gt;
|8&lt;br /&gt;
|2.7-6.0&lt;br /&gt;
|Ja&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|1 (16-Bit)&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP40 PLCC44 TQFP44&lt;br /&gt;
&amp;lt;!-- diesen Kommentar entfernen nach dem Kopieren dieser Eingabehilfe&lt;br /&gt;
|-&lt;br /&gt;
|Typ&lt;br /&gt;
|Flash (Kbytes)&lt;br /&gt;
|EEPROM (Bytes)&lt;br /&gt;
|SRAM (Bytes)&lt;br /&gt;
|Max I/O Pins&lt;br /&gt;
|F.max (MHz)&lt;br /&gt;
|Vcc (V)&lt;br /&gt;
|A/D Chan&amp;amp;shy;nels&lt;br /&gt;
|Ana&amp;amp;shy;log&amp;lt;br/&amp;gt;Compa&amp;amp;shy;rator&lt;br /&gt;
|16-bit Timer&lt;br /&gt;
|8-bit Timer&lt;br /&gt;
|Brown Out Detec&amp;amp;shy;tor&lt;br /&gt;
|On Chip Osci&amp;amp;shy;llator&lt;br /&gt;
|PWM Chan&amp;amp;shy;nels&lt;br /&gt;
|RTC&lt;br /&gt;
|Self Pro&amp;amp;shy;gram Memory&lt;br /&gt;
|Boot Code&lt;br /&gt;
|SPI&lt;br /&gt;
|TWI&lt;br /&gt;
|UART&lt;br /&gt;
|Watch&amp;amp;shy;dog&lt;br /&gt;
|Bau&amp;amp;shy;formen&lt;br /&gt;
|Preis&lt;br /&gt;
&amp;lt;!-- diesen Kommentar entfernen nach dem Kopieren dieser Eingabehilfe--&amp;gt;&lt;br /&gt;
&amp;lt;!-- ENDE - AT90Sxxxx ---------------------------------------------------------&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ATtiny - Reihe ===&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;font-size:10px;&amp;quot; id=&amp;quot;AVR_Features_ATtiny&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Typ||Flash (Kbytes)||EEPROM (Bytes)||SRAM (Bytes)||Max I/O Pins||F.max (MHz)||Vcc (V)||A/D Channels||Analog Comparator||16-bit Timer||8-bit Timer||Brown Out Detector||On Chip Oscillator||PWM Channels||RTC||Self Program Memory||Boot Code||SPI||TWI (I2C)||UART||Watchdog||Bauform(en)||Preis&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/Images/doc8127.pdf ATtiny10]&lt;br /&gt;
|1&lt;br /&gt;
| --&lt;br /&gt;
|32&lt;br /&gt;
|4&lt;br /&gt;
|12&lt;br /&gt;
|1.8-5.5&lt;br /&gt;
|4 8-bit&lt;br /&gt;
|Ja&lt;br /&gt;
|1&lt;br /&gt;
| --&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|2&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|SOT23&lt;br /&gt;
| 0.83-0.99&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/dyn/resources/prod_documents/doc1006.pdf ATtiny11]&lt;br /&gt;
|1&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
|6&lt;br /&gt;
|6&lt;br /&gt;
|2.7-5.5&lt;br /&gt;
| --&lt;br /&gt;
|Ja&lt;br /&gt;
| --&lt;br /&gt;
|1&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
| --&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP8 SOIC8&lt;br /&gt;
| 0.58-0.87&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/dyn/resources/prod_documents/doc1006.pdf ATtiny12]&lt;br /&gt;
|1&lt;br /&gt;
|64&lt;br /&gt;
| --&lt;br /&gt;
|6&lt;br /&gt;
|8&lt;br /&gt;
|1.8-5.5&lt;br /&gt;
| --&lt;br /&gt;
|Ja&lt;br /&gt;
| --&lt;br /&gt;
|1&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
| --&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP8 SOIC8&lt;br /&gt;
| 1.00-1.20&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/Images/doc8126.pdf ATtiny13A]&lt;br /&gt;
|1&lt;br /&gt;
|64&lt;br /&gt;
|64&lt;br /&gt;
|6&lt;br /&gt;
|20&lt;br /&gt;
|1.8-5.5&lt;br /&gt;
|4 10bit&lt;br /&gt;
|Ja&lt;br /&gt;
| --&lt;br /&gt;
|1&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|1&amp;lt;ref&amp;gt;Timer-PWM&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP8 SOIC8&lt;br /&gt;
| 0.60-1.20&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/dyn/resources/prod_documents/doc1187.pdf ATtiny15]&lt;br /&gt;
|1&lt;br /&gt;
|64&lt;br /&gt;
| --&lt;br /&gt;
|6&lt;br /&gt;
|1.6&lt;br /&gt;
|2.7-5.5&lt;br /&gt;
|4 10bit&lt;br /&gt;
|Ja&lt;br /&gt;
| --&lt;br /&gt;
|2&lt;br /&gt;
|Ja&lt;br /&gt;
|ONLY&lt;br /&gt;
|1&amp;lt;ref&amp;gt;150kHz 8bit&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP8 SOIC8&lt;br /&gt;
| 1.15&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/Images/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf ATtiny45]&lt;br /&gt;
|4&lt;br /&gt;
|256&lt;br /&gt;
|256&lt;br /&gt;
|6&lt;br /&gt;
|20&lt;br /&gt;
|2.7-5.5&lt;br /&gt;
|4&lt;br /&gt;
|Ja&lt;br /&gt;
| --&lt;br /&gt;
|2&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|2&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP8 SOIC8&lt;br /&gt;
| 0.90-2.00&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/dyn/resources/prod_documents/doc2586.pdf ATtiny85]&lt;br /&gt;
|8&lt;br /&gt;
|512&lt;br /&gt;
|512&lt;br /&gt;
|6&lt;br /&gt;
|20&lt;br /&gt;
|1.8-5.5&lt;br /&gt;
|4&lt;br /&gt;
|Ja&lt;br /&gt;
| --&lt;br /&gt;
|2&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|2&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Nein&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP8 SOIC8&lt;br /&gt;
| 0.90-2.00&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/dyn/resources/prod_documents/doc2543.pdf ATtiny2313]&lt;br /&gt;
|2&lt;br /&gt;
|128&lt;br /&gt;
|128&lt;br /&gt;
|18&lt;br /&gt;
|20&lt;br /&gt;
|2.7-5.5&lt;br /&gt;
| --&lt;br /&gt;
|Ja&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|4&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;usip&amp;quot;&amp;gt;+USI&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;usi&amp;quot;&amp;gt;USI&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;usart&amp;quot;&amp;gt;USART&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP20 SOIC20 QFN20 MLF20&lt;br /&gt;
| 1.30&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/Images/doc8246.pdf ATtiny4313]&lt;br /&gt;
|4&lt;br /&gt;
|256&lt;br /&gt;
|256&lt;br /&gt;
|18&lt;br /&gt;
|20&lt;br /&gt;
|1.8-5.5&lt;br /&gt;
| --&lt;br /&gt;
|Ja&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|4&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;usip&amp;quot;&amp;gt;+USI&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;usi&amp;quot;&amp;gt;USI&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;usart&amp;quot;&amp;gt;USART&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP20 SOIC20 QFN20 MLF20&lt;br /&gt;
| 1.00-2.00&lt;br /&gt;
|-&lt;br /&gt;
|[http://atmel.com/dyn/resources/prod_documents/doc8006.pdf ATtiny24]&lt;br /&gt;
|2&lt;br /&gt;
|128&lt;br /&gt;
|128&lt;br /&gt;
|12&lt;br /&gt;
|20&lt;br /&gt;
|2.7-5.5&lt;br /&gt;
|8 10bit&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|4&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;usip&amp;quot;&amp;gt;+USI&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;usi&amp;quot;&amp;gt;USI&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP14 SOIC14 QFN20/MLF20&lt;br /&gt;
|0.85&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/Images/doc8183.pdf ATtiny84A]&lt;br /&gt;
|8&lt;br /&gt;
|512&lt;br /&gt;
|512&lt;br /&gt;
|12&lt;br /&gt;
|20&lt;br /&gt;
|1.8-5.5&lt;br /&gt;
|8 10bit&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|4&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;usip&amp;quot;&amp;gt;+USI&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;usi&amp;quot;&amp;gt;USI&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP14 SOIC14 QFN20/MLF20&lt;br /&gt;
|1,00-4,00&lt;br /&gt;
|-&lt;br /&gt;
|[http://atmel.com/dyn/resources/prod_documents/doc2588.pdf  ATtiny261]&lt;br /&gt;
|2&lt;br /&gt;
|128&lt;br /&gt;
|128&lt;br /&gt;
|16&lt;br /&gt;
|20&lt;br /&gt;
|1,8-5,5&lt;br /&gt;
|11&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|2&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;usip&amp;quot;&amp;gt;+USI&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;usi&amp;quot;&amp;gt;USI&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP20 SOIC20 MLF20 (TSSOP20 bei Tiny261A)&lt;br /&gt;
|1,15&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ATmega - Reihe ===&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;font-size:10px;&amp;quot; id=&amp;quot;AVR_Features_ATMega&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Typ||Flash &amp;lt;br/&amp;gt;(Kbytes)||EEPROM &amp;lt;br/&amp;gt;(Bytes)||SRAM &amp;lt;br/&amp;gt;(Bytes)||Max I/O &amp;lt;br/&amp;gt;Pins||F.max &amp;lt;br/&amp;gt;(MHz)||Vcc (V)||A/D &amp;lt;br/&amp;gt;Chan&amp;amp;shy;nels||Ana&amp;amp;shy;log &amp;lt;br/&amp;gt;Compa&amp;amp;shy;rator||16-bit &amp;lt;br/&amp;gt;Timer||8-bit &amp;lt;br/&amp;gt;Timer||Brown Out Detec&amp;amp;shy;tor||On Chip Oscillator||PWM Chan&amp;amp;shy;nels||RTC||Self Pro&amp;amp;shy;gram Memory||Boot Code||SPI||TWI (I2C)||UART||Watch&amp;amp;shy;dog||Bau&amp;amp;shy;form||Preis&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/dyn/resources/prod_documents/2486S.pdf ATmega8]&amp;lt;br&amp;gt;[http://www.atmel.com/Images/Atmel-8159-8-bit-AVR-microcontroller-ATmega8A_datasheet.pdf ATmega8A]&lt;br /&gt;
|8&lt;br /&gt;
|512&lt;br /&gt;
|1K&lt;br /&gt;
|23&lt;br /&gt;
|16&lt;br /&gt;
|2.7-5.5&lt;br /&gt;
|6 10bit PDIP&amp;lt;br/&amp;gt;8 10bit TQFP QFN/MLF&lt;br /&gt;
|Ja&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|3&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;br/&amp;gt;USART&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP28 TQFP32 QFN/MLF32&lt;br /&gt;
| 1.50-4.00&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/dyn/resources/prod_documents/doc2466.pdf ATmega16]&lt;br /&gt;
|16&lt;br /&gt;
|512&lt;br /&gt;
|1K&lt;br /&gt;
|32&lt;br /&gt;
|16&lt;br /&gt;
|2.7-5.5&lt;br /&gt;
|8 10bit&lt;br /&gt;
|Ja&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|4&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;ms&amp;quot;&amp;gt;Master/Slave&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|1&amp;lt;ref name=&amp;quot;usart&amp;quot;&amp;gt;USART&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP40 TQFP44 QFN/MLF44&lt;br /&gt;
| 2.60-2.85&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/dyn/resources/prod_documents/doc2513.pdf ATmega162]&lt;br /&gt;
|16&lt;br /&gt;
|512&lt;br /&gt;
|1K&lt;br /&gt;
|35&lt;br /&gt;
|16&lt;br /&gt;
|2.7-5.5&lt;br /&gt;
|Keine&lt;br /&gt;
|Ja&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|6&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;ms&amp;quot;&amp;gt;Master/Slave&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Nein&lt;br /&gt;
|2&amp;lt;ref name=&amp;quot;usart&amp;quot;&amp;gt;USART&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP40 TQFP44 QFN/MLF44&lt;br /&gt;
| 2.70-3.80&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/dyn/resources/prod_documents/doc2503.pdf ATmega32]&lt;br /&gt;
|32&lt;br /&gt;
|1K&lt;br /&gt;
|2K&lt;br /&gt;
|32&lt;br /&gt;
|16&lt;br /&gt;
|2.7-5.5&lt;br /&gt;
|8 10bit&lt;br /&gt;
|Ja&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|4&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;ms&amp;quot;&amp;gt;Master/Slave&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|1&amp;lt;ref name=&amp;quot;usart&amp;quot;&amp;gt;USART&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP40 TQFP44 QFN/MLF44&lt;br /&gt;
| 3.20-4.60&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/Images/doc8271.pdf ATmega48A]&lt;br /&gt;
|4&lt;br /&gt;
|256&lt;br /&gt;
|512&lt;br /&gt;
|23&lt;br /&gt;
|20&lt;br /&gt;
|1.8-5.5&lt;br /&gt;
|6 10bit PDIP&amp;lt;br/&amp;gt;8 10bit TQFP QFN/MLF&lt;br /&gt;
|Ja&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|6&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;ms&amp;quot;&amp;gt;Master/Slave&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|1&amp;lt;ref name=&amp;quot;usart&amp;quot;&amp;gt;USART&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP28 TQFP32 QFN/MLF32&lt;br /&gt;
| 2.00-4.50&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/Images/doc8271.pdf ATmega88A]&lt;br /&gt;
|8&lt;br /&gt;
|512&lt;br /&gt;
|1K&lt;br /&gt;
|23&lt;br /&gt;
|20&lt;br /&gt;
|1.8-5.5&lt;br /&gt;
|6 10bit PDIP&amp;lt;br/&amp;gt;8 10bit TQFP QFN/MLF&lt;br /&gt;
|Ja&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|6&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;ms&amp;quot;&amp;gt;Master/Slave&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|1&amp;lt;ref name=&amp;quot;usart&amp;quot;&amp;gt;USART&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP28 TQFP32 QFN/MLF32&lt;br /&gt;
| 2.00-4.50&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|[http://www.atmel.com/Images/doc8011.pdf ATmega164]&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|PDIP40 TQFP44 QFN/MLF44&lt;br /&gt;
| 2.00-4.50&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|[http://www.atmel.com/Images/doc8271.pdf ATmega168A]&lt;br /&gt;
|16&lt;br /&gt;
|512&lt;br /&gt;
|1K&lt;br /&gt;
|23&lt;br /&gt;
|20&lt;br /&gt;
|1.8-5.5&lt;br /&gt;
|6 10bit PDIP&amp;lt;br/&amp;gt;8 10bit TQFP QFN/MLF&lt;br /&gt;
|Ja&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|6&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;ms&amp;quot;&amp;gt;Master/Slave&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|1&amp;lt;ref name=&amp;quot;usart&amp;quot;&amp;gt;USART&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP28 TQFP32 QFN/MLF32&lt;br /&gt;
| 2.00-4.50&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|[http://www.atmel.com/Images/doc8271.pdf ATmega328]&lt;br /&gt;
|32&lt;br /&gt;
|1K&lt;br /&gt;
|2K&lt;br /&gt;
|23&lt;br /&gt;
|20&lt;br /&gt;
|1.8-5.5&lt;br /&gt;
|6 10bit PDIP&amp;lt;br/&amp;gt;8 10bit TQFP QFN/MLF&lt;br /&gt;
|Ja&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|6&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;ms&amp;quot;&amp;gt;Master/Slave&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|1&amp;lt;ref name=&amp;quot;usart&amp;quot;&amp;gt;USART&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP28 TQFP32 QFN/MLF32&lt;br /&gt;
| 2.00-4.50&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/Images/doc8272.pdf ATmega324A]&lt;br /&gt;
|32&lt;br /&gt;
|1K&lt;br /&gt;
|2K&lt;br /&gt;
|32&lt;br /&gt;
|20&lt;br /&gt;
|1.8-5.5&lt;br /&gt;
|8 10bit&lt;br /&gt;
|Ja&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|6&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;ms&amp;quot;&amp;gt;Master/Slave&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|2&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP40 TQFP44 VQFN44 QFN/MLF44 DRQFN44 VFBGA49&lt;br /&gt;
| 3.50-4.50&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/atmel/acrobat/doc2490.pdf ATmega64]&amp;lt;ref&amp;gt;Geliefert im ATmega103-Modus. Fuse ändern!&amp;lt;/ref&amp;gt;&lt;br /&gt;
|64&lt;br /&gt;
|2K&lt;br /&gt;
|4K&lt;br /&gt;
|53&lt;br /&gt;
|16&lt;br /&gt;
|2.7-5.5&lt;br /&gt;
|8 10bit&lt;br /&gt;
|Ja&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|2 8bit, 6 2-16bit&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;ms&amp;quot;&amp;gt;Master/Slave&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|1&amp;lt;ref name=&amp;quot;usart&amp;quot;&amp;gt;USART&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
| TQFP64 QFN/MLF64&lt;br /&gt;
| 7.50-9.50&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/dyn/resources/prod_documents/doc2593.pdf  ATmega644]&lt;br /&gt;
|64&lt;br /&gt;
|2K&lt;br /&gt;
|4K&lt;br /&gt;
|32&lt;br /&gt;
|20&lt;br /&gt;
|1.8-5.5&lt;br /&gt;
|8 10bit&lt;br /&gt;
|Ja&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|6&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;ms&amp;quot;&amp;gt;Master/Slave&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|1&amp;lt;ref name=&amp;quot;usart&amp;quot;&amp;gt;USART&amp;lt;/ref&amp;gt; 2&amp;lt;ref&amp;gt;beim 644P&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP40 TQFP44 QFN/MLF44&lt;br /&gt;
| 6.80-7.50&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/dyn/resources/prod_documents/doc2467.pdf ATmega128]&lt;br /&gt;
|128&lt;br /&gt;
|4K&lt;br /&gt;
|4K&lt;br /&gt;
|53&lt;br /&gt;
|16&lt;br /&gt;
|2.7-5.5&lt;br /&gt;
|8 10bit&lt;br /&gt;
|Ja&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|2 8bit&amp;lt;br/&amp;gt;6 2-16bit&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;ms&amp;quot;&amp;gt;Master/Slave&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|2&amp;lt;ref name=&amp;quot;usart&amp;quot;&amp;gt;USART&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|TQFP64 QFN/MLF64&lt;br /&gt;
|8.05-8.40  &lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/dyn/products/product_card.asp?part_id=4331 ATmega1284P]&lt;br /&gt;
|128&lt;br /&gt;
|4K&lt;br /&gt;
|16K&lt;br /&gt;
|32&lt;br /&gt;
|20&lt;br /&gt;
|1.8-5.5&lt;br /&gt;
|8 10bit&lt;br /&gt;
|Ja&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|6 &lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;ms&amp;quot;&amp;gt;Master/Slave&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|2&amp;lt;ref name=&amp;quot;usart&amp;quot;&amp;gt;USART&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP40 TQFP44 QFN/MLF44&lt;br /&gt;
|5.00-7.00&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/dyn/resources/prod_documents/doc2549.pdf ATmega2560]&lt;br /&gt;
|256&lt;br /&gt;
|4K&lt;br /&gt;
|8K&lt;br /&gt;
|86&lt;br /&gt;
|16&lt;br /&gt;
|2.7-5.5&lt;br /&gt;
|16 10bit&lt;br /&gt;
|Ja&lt;br /&gt;
|4&lt;br /&gt;
|2&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|16&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;ms&amp;quot;&amp;gt;Master/Slave&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|4&amp;lt;ref name=&amp;quot;usart&amp;quot;&amp;gt;USART&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|TQFP100&lt;br /&gt;
|8.00-15.00&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/atmel/acrobat/doc2512.pdf ATmega8515]&lt;br /&gt;
|8&lt;br /&gt;
|512&lt;br /&gt;
|512&lt;br /&gt;
|35&lt;br /&gt;
|16&lt;br /&gt;
|2.7-5.5&lt;br /&gt;
|Keine&lt;br /&gt;
|Ja&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|1 8-bit, 1 16-bit&lt;br /&gt;
|Nein&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;ms&amp;quot;&amp;gt;Master/Slave&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Nein&lt;br /&gt;
|1&amp;lt;ref name=&amp;quot;usart&amp;quot;&amp;gt;USART&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP40 TQFP44 PLCC44 QFN/MLF44&lt;br /&gt;
|3.20-3.90&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.atmel.com/atmel/acrobat/doc2502.pdf ATmega8535]&lt;br /&gt;
|8&lt;br /&gt;
|512&lt;br /&gt;
|512&lt;br /&gt;
|32&lt;br /&gt;
|16&lt;br /&gt;
|2.7-5.5&lt;br /&gt;
|8 10bit&lt;br /&gt;
|Ja&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|2 8-bit, 2 16-bit&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&lt;br /&gt;
|Ja&amp;lt;ref name=&amp;quot;ms&amp;quot;&amp;gt;Master/Slave&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|1&amp;lt;ref name=&amp;quot;usart&amp;quot;&amp;gt;USART&amp;lt;/ref&amp;gt;&lt;br /&gt;
|Ja&lt;br /&gt;
|PDIP44 PLCC44 QFN/MLF44&lt;br /&gt;
|3.15-3.75&lt;br /&gt;
&amp;lt;!-- START - ATMegaxxxx -------------------------------------------------------&amp;gt;&lt;br /&gt;
&amp;lt;!-- diesen Kommentar entfernen nach dem Kopieren dieser Eingabehilfe -- &amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Typ&lt;br /&gt;
|Flash (Kbytes)&lt;br /&gt;
|EEPROM (Bytes)&lt;br /&gt;
|SRAM (Bytes)&lt;br /&gt;
|Max I/O Pins&lt;br /&gt;
|F.max (MHz)&lt;br /&gt;
|Vcc (V)&lt;br /&gt;
|A/D Channels&lt;br /&gt;
|Analog Comparator&lt;br /&gt;
|16-bit Timer&lt;br /&gt;
|8-bit Timer&lt;br /&gt;
|Brown Out Detector&lt;br /&gt;
|On Chip Oscillator&lt;br /&gt;
|PWM Channels&lt;br /&gt;
|RTC&lt;br /&gt;
|Self Program Memory&lt;br /&gt;
|Boot Code&lt;br /&gt;
|SPI&lt;br /&gt;
|TWI&lt;br /&gt;
|UART&lt;br /&gt;
|Watchdog&lt;br /&gt;
|Bauform(en)&lt;br /&gt;
|Preis&lt;br /&gt;
&amp;lt;!-- diesen Kommentar entfernen nach dem Kopieren dieser Eingabehilfe--&amp;gt;&lt;br /&gt;
&amp;lt;!-- ENDE - ATMegaxxxx --------------------------------------------------------&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Hinweis: Die angegebenen Preise sind Richtwerte. Es empfiehlt sich die Verwendung einer Preissuchmaschine, z.B. [http://www.google.de/shopping google.de/shopping].&lt;br /&gt;
&lt;br /&gt;
=== ATXMega - Reihe ===&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;font-size:10px;&amp;quot; id=&amp;quot;AVR_Features_ATXMega&amp;quot; &lt;br /&gt;
|-&lt;br /&gt;
!Typ||Flash &amp;lt;br/&amp;gt;(Kbytes)||EEPROM &amp;lt;br/&amp;gt;(KBytes)||SRAM &amp;lt;br/&amp;gt;(KBytes)||Boot &amp;lt;br/&amp;gt;(Kbytes)||Max I/O &amp;lt;br/&amp;gt;Pins||F.max &amp;lt;br/&amp;gt;(MHz)||Vcc (V)||ADC||DAC||PWM &amp;lt;br/&amp;gt;Channels||16-Bit &amp;lt;br/&amp;gt;Timer||SPI||TWI&amp;lt;br/&amp;gt;(I2C)||UART||Bau&amp;amp;shy;formen&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega16a4&lt;br /&gt;
|16&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|4&lt;br /&gt;
|34&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|12-CH @ 12-Bit&lt;br /&gt;
|2-CH @ 12-Bit&lt;br /&gt;
|16&lt;br /&gt;
|5&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|5&lt;br /&gt;
|TQFP44&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega32a4&lt;br /&gt;
|32&lt;br /&gt;
|1&lt;br /&gt;
|4&lt;br /&gt;
|4&lt;br /&gt;
|34&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|12-CH @ 12-Bit&lt;br /&gt;
|2-CH @ 12-Bit&lt;br /&gt;
|16&lt;br /&gt;
|5&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|5&lt;br /&gt;
|TQFP44&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega64a4&lt;br /&gt;
|64&lt;br /&gt;
|2&lt;br /&gt;
|4&lt;br /&gt;
|4&lt;br /&gt;
|34&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|12-CH @ 12-Bit&lt;br /&gt;
|2-CH @ 12-Bit&lt;br /&gt;
|16&lt;br /&gt;
|5&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|5&lt;br /&gt;
|TQFP44&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega128a4&lt;br /&gt;
|128&lt;br /&gt;
|2&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|34&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|12-CH @ 12-Bit&lt;br /&gt;
|2-CH @ 12-Bit&lt;br /&gt;
|16&lt;br /&gt;
|5&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|5&lt;br /&gt;
|TQFP44&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega64a3&lt;br /&gt;
|64&lt;br /&gt;
|2&lt;br /&gt;
|4&lt;br /&gt;
|4&lt;br /&gt;
|50&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|2x 8-CH @ 12-Bit&lt;br /&gt;
|2-CH @ 12-Bit&lt;br /&gt;
|22&lt;br /&gt;
|7&lt;br /&gt;
|3&lt;br /&gt;
|2&lt;br /&gt;
|7&lt;br /&gt;
|TQFP64&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega128a3&lt;br /&gt;
|128&lt;br /&gt;
|2&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|50&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|2x 8-CH @ 12-Bit&lt;br /&gt;
|2-CH @ 12-Bit&lt;br /&gt;
|22&lt;br /&gt;
|7&lt;br /&gt;
|3&lt;br /&gt;
|2&lt;br /&gt;
|7&lt;br /&gt;
|TQFP64&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega192a3&lt;br /&gt;
|192&lt;br /&gt;
|2&lt;br /&gt;
|16&lt;br /&gt;
|8&lt;br /&gt;
|50&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|2x 8-CH @ 12-Bit&lt;br /&gt;
|2-CH @ 12-Bit&lt;br /&gt;
|22&lt;br /&gt;
|7&lt;br /&gt;
|3&lt;br /&gt;
|2&lt;br /&gt;
|7&lt;br /&gt;
|TQFP64&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega256a3&lt;br /&gt;
|256&lt;br /&gt;
|4&lt;br /&gt;
|16&lt;br /&gt;
|8&lt;br /&gt;
|50&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|2x 8-CH @ 12-Bit&lt;br /&gt;
|2-CH @ 12-Bit&lt;br /&gt;
|22&lt;br /&gt;
|7&lt;br /&gt;
|3&lt;br /&gt;
|2&lt;br /&gt;
|7&lt;br /&gt;
|TQFP64&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega64a1&lt;br /&gt;
|64&lt;br /&gt;
|2&lt;br /&gt;
|4&lt;br /&gt;
|4&lt;br /&gt;
|78&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|2x 8-CH @ 12-Bit&lt;br /&gt;
|2x 2-CH @ 12-Bit&lt;br /&gt;
|24&lt;br /&gt;
|8&lt;br /&gt;
|4&lt;br /&gt;
|4&lt;br /&gt;
|8&lt;br /&gt;
|TQFP100&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega128a1&lt;br /&gt;
|128&lt;br /&gt;
|2&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|78&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|2x 8-CH @ 12-Bit&lt;br /&gt;
|2x 2-CH @ 12-Bit&lt;br /&gt;
|24&lt;br /&gt;
|8&lt;br /&gt;
|4&lt;br /&gt;
|4&lt;br /&gt;
|8&lt;br /&gt;
|TQFP100&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega192a1&lt;br /&gt;
|192&lt;br /&gt;
|2&lt;br /&gt;
|16&lt;br /&gt;
|8&lt;br /&gt;
|78&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|2x 8-CH @ 12-Bit&lt;br /&gt;
|2x 2-CH @ 12-Bit&lt;br /&gt;
|24&lt;br /&gt;
|8&lt;br /&gt;
|4&lt;br /&gt;
|4&lt;br /&gt;
|8&lt;br /&gt;
|TQFP100&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega256a1&lt;br /&gt;
|256&lt;br /&gt;
|4&lt;br /&gt;
|16&lt;br /&gt;
|8&lt;br /&gt;
|78&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|2x 8-CH @ 12-Bit&lt;br /&gt;
|2x 2-CH @ 12-Bit&lt;br /&gt;
|24&lt;br /&gt;
|8&lt;br /&gt;
|4&lt;br /&gt;
|4&lt;br /&gt;
|8&lt;br /&gt;
|TQFP100&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega384a1&lt;br /&gt;
|384&lt;br /&gt;
|4&lt;br /&gt;
|32&lt;br /&gt;
|8&lt;br /&gt;
|78&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|2x 8-CH @ 12-Bit&lt;br /&gt;
|2x 2-CH @ 12-Bit&lt;br /&gt;
|24&lt;br /&gt;
|8&lt;br /&gt;
|4&lt;br /&gt;
|4&lt;br /&gt;
|8&lt;br /&gt;
|TQFP100&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega16d4&lt;br /&gt;
|16&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|4&lt;br /&gt;
|34&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|12-CH @ 12-Bit&lt;br /&gt;
|0&lt;br /&gt;
|16&lt;br /&gt;
|4&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|TQFP44&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega32d4&lt;br /&gt;
|32&lt;br /&gt;
|1&lt;br /&gt;
|4&lt;br /&gt;
|4&lt;br /&gt;
|34&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|12-CH @ 12-Bit&lt;br /&gt;
|0&lt;br /&gt;
|16&lt;br /&gt;
|4&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|TQFP44&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega64d4&lt;br /&gt;
|64&lt;br /&gt;
|2&lt;br /&gt;
|4&lt;br /&gt;
|4&lt;br /&gt;
|34&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|12-CH @ 12-Bit&lt;br /&gt;
|0&lt;br /&gt;
|16&lt;br /&gt;
|4&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|TQFP44&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega128d4&lt;br /&gt;
|128&lt;br /&gt;
|2&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|34&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|12-CH @ 12-Bit&lt;br /&gt;
|0&lt;br /&gt;
|16&lt;br /&gt;
|4&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|TQFP44&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega64d3&lt;br /&gt;
|64&lt;br /&gt;
|2&lt;br /&gt;
|4&lt;br /&gt;
|4&lt;br /&gt;
|50&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|16-CH @ 12-Bit&lt;br /&gt;
|0&lt;br /&gt;
|18&lt;br /&gt;
|5&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|3&lt;br /&gt;
|TQFP64&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega128d3&lt;br /&gt;
|128&lt;br /&gt;
|2&lt;br /&gt;
|8&lt;br /&gt;
|8&lt;br /&gt;
|50&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|16-CH @ 12-Bit&lt;br /&gt;
|0&lt;br /&gt;
|18&lt;br /&gt;
|5&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|3&lt;br /&gt;
|TQFP64&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega192d3&lt;br /&gt;
|192&lt;br /&gt;
|2&lt;br /&gt;
|16&lt;br /&gt;
|8&lt;br /&gt;
|50&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|16-CH @ 12-Bit&lt;br /&gt;
|0&lt;br /&gt;
|18&lt;br /&gt;
|5&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|3&lt;br /&gt;
|TQFP64&lt;br /&gt;
|-&lt;br /&gt;
|ATxmega256d3&lt;br /&gt;
|256&lt;br /&gt;
|4&lt;br /&gt;
|16&lt;br /&gt;
|8&lt;br /&gt;
|50&lt;br /&gt;
|32&lt;br /&gt;
|1,6 - 3,6&lt;br /&gt;
|16-CH @ 12-Bit&lt;br /&gt;
|0&lt;br /&gt;
|18&lt;br /&gt;
|5&lt;br /&gt;
|2&lt;br /&gt;
|2&lt;br /&gt;
|3&lt;br /&gt;
|TQFP64&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Weitere Vergleichstabellen ==&lt;br /&gt;
Vergleichstabellen zum Downloaden gibt es unter Anderem&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/242328 von Andreas], Stand 19.12.2011; vollständig,&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/232939 von Sven], Stand 22.09.2011; weiter eingedampft.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ATtiny ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;font-size:10px;&amp;quot; id=&amp;quot;AVR_Features_ATtiny&amp;quot;&lt;br /&gt;
|+ Device-specific Features&amp;lt;br/&amp;gt;&amp;amp;nbsp;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
! Device&lt;br /&gt;
! Flash [KiB]&lt;br /&gt;
! Pin Anz&amp;amp;shy;ahl&lt;br /&gt;
! Max. &amp;amp;fnof;&amp;lt;sub&amp;gt;CPU&amp;lt;/sub&amp;gt; [MHz]&lt;br /&gt;
! of Touch Kan&amp;amp;shy;äle&lt;br /&gt;
! Hard&amp;amp;shy;ware Qtouch&lt;br /&gt;
! Max I/O Pins&lt;br /&gt;
! Ext Inter&amp;amp;shy;rupts&lt;br /&gt;
! SPI&lt;br /&gt;
! TWI&lt;br /&gt;
! UART&lt;br /&gt;
! LIN&lt;br /&gt;
! ADC Kan&amp;amp;shy;äle&lt;br /&gt;
! ADC Auf&amp;amp;shy;lö&amp;amp;shy;sung [bits]&lt;br /&gt;
! ADC Speed [ksps]&lt;br /&gt;
! Temp. Sensor&lt;br /&gt;
! SRAM [KiB]&lt;br /&gt;
! EEPROM [Bytes]&lt;br /&gt;
! Self Pro&amp;amp;shy;gram Memory&lt;br /&gt;
! pico&amp;amp;shy;Power&lt;br /&gt;
! Temp. Bereich [°C]&lt;br /&gt;
! I/O Supply Class [V]&lt;br /&gt;
! Opera&amp;amp;shy;ting Volt&amp;amp;shy;age [V&amp;lt;sub&amp;gt;CC&amp;lt;/sub&amp;gt;]&lt;br /&gt;
! Timers&lt;br /&gt;
! Output Com&amp;amp;shy;pare Kan&amp;amp;shy;äle&lt;br /&gt;
! Input Capt&amp;amp;shy;ure Kan&amp;amp;shy;äle&lt;br /&gt;
! PWM Kan&amp;amp;shy;äle&lt;br /&gt;
! 32kHz RTC&lt;br /&gt;
! Device&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny28L || 2 || 28 || 4 || &amp;amp;mdash; || &amp;amp;mdash; || 11 || 10 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || &amp;amp;mdash; || 0.03 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1 || 0 || 0 || 0 || &amp;amp;mdash; || ATtiny28L&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny26 || 2 || 20 || 16 || &amp;amp;mdash; || &amp;amp;mdash; || 16 || 11 || 1 || 1 || 0 || 0 || 11 || 10 || 15 || &amp;amp;mdash; || 0.12 || 128 || &amp;amp;mdash; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 3 || 0 || 4 || &amp;amp;mdash; || ATtiny26&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny13 || 1 || 8 || 20 || &amp;amp;mdash; || &amp;amp;mdash; || 6 || 6 || 0 || 0 || 0 || 0 || 4 || 10 || 15 || &amp;amp;mdash; || 0.06 || 64 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1 || 2 || 0 || 2 || &amp;amp;mdash; || ATtiny13&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny2313 || 2 || 20 || 20 || 4 || &amp;amp;mdash; || 18 || 18 || 2 || 1 || 1 || 0 || 0 || 0 || 15 || &amp;amp;mdash; || 0.12 || 128 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 4 || 1 || 4 || &amp;amp;mdash; || ATtiny2313&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny25 || 2 || 8 || 20 || 4 || &amp;amp;mdash; || 6 || 6 || 1 || 1 || 0 || 0 || 4 || 10 || 15 || &amp;amp;radic; || 0.12 || 128 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;105 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 5 || 0 || 6 || &amp;amp;mdash; || ATtiny25&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny85 || 8 || 8 || 20 || 3 || &amp;amp;mdash; || 6 || 6 || 1 || 1 || 0 || 0 || 4 || 10 || 15 || &amp;amp;radic; || 0.5 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 5 || 0 || 6 || &amp;amp;mdash; || ATtiny85&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny45 || 4 || 8 || 20 || 3 || &amp;amp;mdash; || 6 || 6 || 1 || 1 || 0 || 0 || 4 || 10 || 15 || &amp;amp;radic; || 0.25 || 256 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 5 || 0 || 6 || &amp;amp;mdash; || ATtiny45&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny24 || 2 || 14 || 20 || 4 || &amp;amp;mdash; || 12 || 12 || 1 || 1 || 0 || 0 || 8 || 10 || 15 || &amp;amp;radic; || 0.12 || 128 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 4 || 1 || 4 || &amp;amp;mdash; || ATtiny24&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny44 || 4 || 14 || 20 || 6 || &amp;amp;mdash; || 12 || 12 || 1 || 1 || 0 || 0 || 8 || 10 || 15 || &amp;amp;radic; || 0.25 || 256 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 4 || 1 || 4 || &amp;amp;mdash; || ATtiny44&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny84 || 8 || 14 || 20 || 6 || &amp;amp;mdash; || 12 || 12 || 1 || 1 || 0 || 0 || 8 || 10 || 15 || &amp;amp;radic; || 0.5 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 4 || 1 || 4 || &amp;amp;mdash; || ATtiny84&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny261 || 2 || 20 || 20 || 4 || &amp;amp;mdash; || 16 || 16 || 1 || 1 || 0 || 0 || 11 || 10 || 15 || &amp;amp;radic; || 0.12 || 128 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 6 || 1 || 6 || &amp;amp;mdash; || ATtiny261&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny461 || 4 || 20 || 20 || 8 || &amp;amp;mdash; || 16 || 16 || 1 || 1 || 0 || 0 || 11 || 10 || 15 || &amp;amp;radic; || 0.25 || 256 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 6 || 1 || 6 || &amp;amp;mdash; || ATtiny461&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny861 || 8 || 20 || 20 || 8 || &amp;amp;mdash; || 16 || 16 || 1 || 1 || 0 || 0 || 11 || 10 || 15 || &amp;amp;radic; || 0.5 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 6 || 1 || 6 || &amp;amp;mdash; || ATtiny861&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny13A || 1 || 8 || 20 || &amp;amp;mdash; || &amp;amp;mdash; || 6 || 6 || 0 || 0 || 0 || 0 || 4 || 10 || 15 || &amp;amp;mdash; || 0.06 || 64 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;125 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1 || 2 || 0 || 2 || &amp;amp;mdash; || ATtiny13A&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny48 || 4 || 32 || 12 || 12 || &amp;amp;mdash; || 28 || 28 || 1 || 1 || 0 || 0 || 8 || 10 || 15 || &amp;amp;radic; || 0.25 || 64 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 4 || 1 || 2 || &amp;amp;mdash; || ATtiny48&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny88 || 8 || 32 || 12 || 12 || &amp;amp;mdash; || 28 || 28 || 1 || 1 || 0 || 0 || 8 || 10 || 15 || &amp;amp;radic; || 0.5 || 64 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 4 || 1 || 2 || &amp;amp;mdash; || ATtiny88&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny24A || 2 || 14 || 20 || 4 || &amp;amp;mdash; || 12 || 12 || 1 || 1 || 0 || 0 || 8 || 10 || 15 || &amp;amp;radic; || 0.12 || 128 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 4 || 1 || 4 || &amp;amp;mdash; || ATtiny24A&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny44A || 4 || 14 || 20 || 6 || &amp;amp;mdash; || 12 || 12 || 1 || 1 || 0 || 0 || 8 || 10 || 15 || &amp;amp;radic; || 0.25 || 256 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 4 || 1 || 4 || &amp;amp;mdash; || ATtiny44A&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny43U || 4 || 20 || 8 || 8 || &amp;amp;mdash; || 16 || 16 || 1 || 1 || 0 || 0 || 4 || 10 || 15 || &amp;amp;radic; || 0.25 || 64 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 0.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 0.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 4 || 0 || 4 || &amp;amp;mdash; || ATtiny43U&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny10 || 1 || 6 || 12 || 1 || &amp;amp;mdash; || 4 || 4 || 0 || 0 || 0 || 0 || 4 || 8 || 15 || &amp;amp;mdash; || 0.03 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;125 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1 || 2 || 1 || 2 || &amp;amp;mdash; || ATtiny10&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny4 || 0.5 || 6 || 12 || 1 || &amp;amp;mdash; || 4 || 4 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || &amp;amp;mdash; || 0.03 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;125 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1 || 2 || 1 || 2 || &amp;amp;mdash; || ATtiny4&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny5 || 0.5 || 6 || 12 || 1 || &amp;amp;mdash; || 4 || 4 || 0 || 0 || 0 || 0 || 4 || 8 || 15 || &amp;amp;mdash; || 0.03 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;125 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1 || 2 || 1 || 2 || &amp;amp;mdash; || ATtiny5&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny9 || 1 || 6 || 12 || 1 || &amp;amp;mdash; || 4 || 4 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || &amp;amp;mdash; || 0.03 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;125 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1 || 2 || 1 || 2 || &amp;amp;mdash; || ATtiny9&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny261A || 2 || 20 || 20 || 4 || &amp;amp;mdash; || 16 || 16 || 1 || 1 || 0 || 0 || 11 || 10 || 15 || &amp;amp;radic; || 0.12 || 128 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;105 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 6 || 1 || 6 || &amp;amp;mdash; || ATtiny261A&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny461A || 4 || 20 || 20 || 8 || &amp;amp;mdash; || 16 || 16 || 1 || 1 || 0 || 0 || 11 || 10 || 15 || &amp;amp;radic; || 0.25 || 256 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 6 || 1 || 6 || &amp;amp;mdash; || ATtiny461A&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny861A || 8 || 20 || 20 || 8 || &amp;amp;mdash; || 16 || 16 || 1 || 1 || 0 || 0 || 11 || 10 || 15 || &amp;amp;radic; || 0.5 || 512 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 6 || 1 || 6 || &amp;amp;mdash; || ATtiny861A&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny2313A || 2 || 20 || 20 || &amp;amp;mdash; || &amp;amp;mdash; || 18 || 18 || 2 || 1 || 1 || 0 || 0 || 0 || 15 || &amp;amp;mdash; || 0.12 || 128 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 4 || 1 || 4 || &amp;amp;mdash; || ATtiny2313A&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny4313 || 4 || 20 || 20 || &amp;amp;mdash; || &amp;amp;mdash; || 18 || 18 || 2 || 1 || 1 || 0 || 0 || 0 || 15 || &amp;amp;mdash; || 0.25 || 256 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 4 || 1 || 4 || &amp;amp;mdash; || ATtiny4313&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny167 || 16 || 20 || 16 || 8 || &amp;amp;mdash; || 16 || 16 || 2 || 1 || 1 || 1 || 11 || 10 || 15 || &amp;amp;radic; || 0.5 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 3 || 1 || 9 || &amp;amp;radic; || ATtiny167&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny87 || 8 || 20 || 16 || &amp;amp;mdash; || &amp;amp;mdash; || 16 || 16 || 2 || 1 || 1 || 1 || 11 || 10 || 15 || &amp;amp;radic; || 0.5 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 3 || 1 || 9 || &amp;amp;radic; || ATtiny87&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny20 || 2 || 14 || 12 || 5 || &amp;amp;radic; || 12 || 12 || 1 || 1 || 0 || 0 || 8 || 10 || 15 || &amp;amp;radic; || 0.12 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 4 || 1 || 3 || &amp;amp;mdash; || ATtiny20&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny40 || 4 || 20 || 12 || 12 || &amp;amp;radic; || 18 || 18 || 1 || 1 || 0 || 0 || 12 || 10 || 15 || &amp;amp;radic; || 0.25 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 4 || 1 || 2 || &amp;amp;mdash; || ATtiny40&lt;br /&gt;
|-&lt;br /&gt;
| ATtiny84A || 8 || 14 || 20 || 6 || &amp;amp;mdash; || 12 || 12 || 1 || 1 || 0 || 0 || 8 || 10 || 15 || &amp;amp;radic; || 0.5 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 4 || 1 || 4 || &amp;amp;mdash; || ATtiny84A&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;General Features&#039;&#039;&#039;&amp;lt;br/&amp;gt;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;CPU&#039;&#039;&#039; || 8-bit AVR&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Quadrature Decoder Kanäle&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;USB Transceiver&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;USB Speed&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;USB Interface&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;CAN&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;SSC&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Ethernet&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;SD / eMMC&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Segment LCD&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Grafik LCD&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Video Decoder&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Kamera Interface&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Analog Comparators&#039;&#039;&#039; || 1&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Resistive Touch Screen&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;DAC Kanäle&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;DAC Auflösung [bits]&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;External Bus Interface&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;DRAM Memory&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;NAND Interface&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;FPU&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;MPU / MMU&#039;&#039;&#039; || nein / nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Crypto Engine&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Calibrated RC Oscillator&#039;&#039;&#039; || ja&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ATmega ===&lt;br /&gt;
&lt;br /&gt;
{|  class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;font-size:10px;&amp;quot; id=&amp;quot;AVR_Features_ATmega&amp;quot;&lt;br /&gt;
|+ Device-specific Features&amp;lt;br/&amp;gt;&amp;amp;nbsp;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
! Device&lt;br /&gt;
! Flash [KiB]&lt;br /&gt;
! Pin Anz&amp;amp;shy;ahl&lt;br /&gt;
! Max. &amp;amp;fnof;&amp;lt;sub&amp;gt;CPU&amp;lt;/sub&amp;gt; [MHz]&lt;br /&gt;
! of Touch Kan&amp;amp;shy;äle&lt;br /&gt;
! Max I/O Pins&lt;br /&gt;
! Ext Inter&amp;amp;shy;rupts&lt;br /&gt;
! USB Trans&amp;amp;shy;cei&amp;amp;shy;ver&lt;br /&gt;
! USB Speed&lt;br /&gt;
! USB Inter&amp;amp;shy;face&lt;br /&gt;
! SPI&lt;br /&gt;
! TWI&lt;br /&gt;
! UART&lt;br /&gt;
! CAN&lt;br /&gt;
! LIN&lt;br /&gt;
! Seg&amp;amp;shy;ment LCD&lt;br /&gt;
! ADC Kan&amp;amp;shy;äle&lt;br /&gt;
! ADC Auf&amp;amp;shy;lö&amp;amp;shy;sung [bits]&lt;br /&gt;
! ADC Speed [ksps]&lt;br /&gt;
! Ana&amp;amp;shy;log Com&amp;amp;shy;para&amp;amp;shy;tors&lt;br /&gt;
! DAC Kan&amp;amp;shy;äle&lt;br /&gt;
! DAC Auf&amp;amp;shy;lö&amp;amp;shy;sung [bits]&lt;br /&gt;
! Temp. Sensor&lt;br /&gt;
! SRAM [KiB]&lt;br /&gt;
! EEPROM [Bytes]&lt;br /&gt;
! Self Pro&amp;amp;shy;gram Memory&lt;br /&gt;
! pico&amp;amp;shy;Power&lt;br /&gt;
! Temp. Bereich [°C]&lt;br /&gt;
! I/O Supply Class [V]&lt;br /&gt;
! Opera&amp;amp;shy;ting Volt&amp;amp;shy;age [V&amp;lt;sub&amp;gt;CC&amp;lt;/sub&amp;gt;]&lt;br /&gt;
! Timers&lt;br /&gt;
! Output Com&amp;amp;shy;pare Kan&amp;amp;shy;äle&lt;br /&gt;
! Input Capt&amp;amp;shy;ure Kan&amp;amp;shy;äle&lt;br /&gt;
! PWM Kan&amp;amp;shy;äle&lt;br /&gt;
! 32kHz RTC&lt;br /&gt;
! Device&lt;br /&gt;
|-&lt;br /&gt;
| ATmega8 || 8 || 32 || 16 || 12 || 23 || 2 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 1 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 3 || 1 || 3 || &amp;amp;radic; || ATmega8&lt;br /&gt;
|-&lt;br /&gt;
| ATmega8515 || 8 || 44 || 16 || 16 || 35 || 3 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 0 || 1 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || &amp;amp;mdash; || 0.5 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 3 || 1 || 3 || &amp;amp;mdash; || ATmega8515&lt;br /&gt;
|-&lt;br /&gt;
| ATmega8535 || 8 || 44 || 16 || 16 || 32 || 3 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 0.5 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega8535&lt;br /&gt;
|-&lt;br /&gt;
| ATmega16 || 16 || 44 || 16 || 16 || 32 || 3 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 1 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega16&lt;br /&gt;
|-&lt;br /&gt;
| ATmega32 || 32 || 44 || 16 || 16 || 32 || 3 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 2 || 1024 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega32&lt;br /&gt;
|-&lt;br /&gt;
| ATmega64 || 64 || 64 || 16 || 16 || 53 || 8 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 1 || 2 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 4 || 8 || 2 || 7 || &amp;amp;radic; || ATmega64&lt;br /&gt;
|-&lt;br /&gt;
| ATmega128 || 128 || 64 || 16 || 16 || 53 || 8 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 1 || 2 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 4096 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 4 || 8 || 2 || 7 || &amp;amp;radic; || ATmega128&lt;br /&gt;
|-&lt;br /&gt;
| ATmega162 || 16 || 44 || 16 || 16 || 35 || 3 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 0 || 2 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 || &amp;amp;mdash; || 1 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 4 || 6 || 2 || 6 || &amp;amp;radic; || ATmega162&lt;br /&gt;
|-&lt;br /&gt;
| ATmega48 || 4 || 32 || 20 || 12 || 23 || 24 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 0.5 || 256 || &amp;amp;mdash; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega48&lt;br /&gt;
|-&lt;br /&gt;
| ATmega88 || 8 || 32 || 20 || 12 || 23 || 24 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 1 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega88&lt;br /&gt;
|-&lt;br /&gt;
| ATmega168 || 16 || 32 || 20 || 16 || 23 || 24 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 1 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega168&lt;br /&gt;
|-&lt;br /&gt;
| AT90CAN128 || 128 || 64 || 16 || 16 || 53 || 8 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 1 || 2 || 1 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 4096 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 4 || 8 || 2 || 7 || &amp;amp;radic; || AT90CAN128&lt;br /&gt;
|-&lt;br /&gt;
| ATmega325 || 32 || 64 || 16 || 16 || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 2 || 1024 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega325&lt;br /&gt;
|-&lt;br /&gt;
| ATmega3250 || 32 || 100 || 16 || 16 || 69 || 25 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 2 || 1024 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega3250&lt;br /&gt;
|-&lt;br /&gt;
| ATmega6450 || 64 || 100 || 16 || &amp;amp;mdash; || 69 || 25 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega6450&lt;br /&gt;
|-&lt;br /&gt;
| ATmega645 || 64 || 64 || 16 || 16 || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega645&lt;br /&gt;
|-&lt;br /&gt;
| ATmega329 || 32 || 64 || 16 || 16 || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 100 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 2 || 1024 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega329&lt;br /&gt;
|-&lt;br /&gt;
| ATmega3290 || 32 || 100 || 16 || 16 || 69 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 160 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 2 || 1024 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega3290&lt;br /&gt;
|-&lt;br /&gt;
| ATmega649 || 64 || 64 || 16 || 16 || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 100 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega649&lt;br /&gt;
|-&lt;br /&gt;
| ATmega6490 || 64 || 100 || 16 || 16 || 69 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 160 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega6490&lt;br /&gt;
|-&lt;br /&gt;
| ATmega640 || 64 || 100 || 16 || 16 || 86 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 5 || 1 || 4 || 0 || 0 || 0 || 16 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 8 || 4096 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 6 || 16 || 4 || 15 || &amp;amp;radic; || ATmega640&lt;br /&gt;
|-&lt;br /&gt;
| ATmega1281 || 128 || 64 || 16 || 16 || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 3 || 1 || 2 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 8 || 4096 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 6 || 16 || 2 || 8 || &amp;amp;radic; || ATmega1281&lt;br /&gt;
|-&lt;br /&gt;
| ATmega2561 || 256 || 64 || 16 || &amp;amp;mdash; || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 3 || 1 || 2 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 8 || 4096 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 6 || 16 || 2 || 8 || &amp;amp;radic; || ATmega2561&lt;br /&gt;
|-&lt;br /&gt;
| ATmega2560 || 256 || 100 || 16 || &amp;amp;mdash; || 86 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 5 || 1 || 4 || 0 || 0 || 0 || 16 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 8 || 4096 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 6 || 16 || 4 || 15 || &amp;amp;radic; || ATmega2560&lt;br /&gt;
|-&lt;br /&gt;
| ATmega1280 || 128 || 100 || 16 || 16 || 86 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 5 || 1 || 4 || 0 || 0 || 0 || 16 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 8 || 4096 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 6 || 16 || 4 || 15 || &amp;amp;radic; || ATmega1280&lt;br /&gt;
|-&lt;br /&gt;
| ATmega644 || 64 || 44 || 20 || 16 || 32 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 3 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega644&lt;br /&gt;
|-&lt;br /&gt;
| AT90CAN32 || 32 || 64 || 16 || 16 || 53 || 8 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 1 || 2 || 1 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 2 || 1024 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 4 || 8 || 2 || 7 || &amp;amp;radic; || AT90CAN32&lt;br /&gt;
|-&lt;br /&gt;
| AT90CAN64 || 64 || 64 || 16 || 16 || 53 || 8 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 1 || 2 || 1 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 4 || 8 || 2 || 7 || &amp;amp;radic; || AT90CAN64&lt;br /&gt;
|-&lt;br /&gt;
| AT90USB1286 || 128 || 64 || 16 || 16 || 48 || 16 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 8 || 4096 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 4 || 10 || 1 || 9 || &amp;amp;radic; || AT90USB1286&lt;br /&gt;
|-&lt;br /&gt;
| AT90USB1287 || 128 || 64 || 16 || 16 || 48 || 16 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbo&amp;quot;&amp;gt;Device + OTG&amp;lt;/ref&amp;gt; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 8 || 4096 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 4 || 10 || 1 || 9 || &amp;amp;radic; || AT90USB1287&lt;br /&gt;
|-&lt;br /&gt;
| AT90USB647 || 64 || 64 || 16 || 16 || 48 || 16 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbo&amp;quot;&amp;gt;Device + OTG&amp;lt;/ref&amp;gt; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 4 || 10 || 1 || 9 || &amp;amp;radic; || AT90USB647&lt;br /&gt;
|-&lt;br /&gt;
| AT90USB646 || 64 || 64 || 16 || 16 || 48 || 16 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 4 || 10 || 1 || 9 || &amp;amp;radic; || AT90USB646&lt;br /&gt;
|-&lt;br /&gt;
| ATmega164P || 16 || 44 || 20 || 16 || 32 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 3 || 1 || 2 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 1 || 512 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega164P&lt;br /&gt;
|-&lt;br /&gt;
| ATmega324P || 32 || 44 || 20 || 16 || 32 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 3 || 1 || 2 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 2 || 1024 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega324P&lt;br /&gt;
|-&lt;br /&gt;
| ATmega165P || 16 || 64 || 16 || 16 || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 1 || 512 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega165P&lt;br /&gt;
|-&lt;br /&gt;
| ATmega169P || 16 || 64 || 16 || 16 || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 100 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 1 || 512 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega169P&lt;br /&gt;
|-&lt;br /&gt;
| ATmega644P || 64 || 44 || 20 || 16 || 32 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 3 || 1 || 2 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega644P&lt;br /&gt;
|-&lt;br /&gt;
| AT90PWM1 || 8 || 24 || 16 || 8 || 19 || 4 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 0 || 0 || 0 || 0 || 0 || 8 || 10 || 125 || 2 || 0 || 0 || &amp;amp;mdash; || 0.5 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;105 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 4 || 12 || 1 || 7 || &amp;amp;mdash; || AT90PWM1&lt;br /&gt;
|-&lt;br /&gt;
| ATmega329P || 32 || 64 || 20 || 16 || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 100 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 2 || 1024 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega329P&lt;br /&gt;
|-&lt;br /&gt;
| ATmega3290P || 32 || 100 || 20 || 16 || 69 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 160 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 2 || 1024 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega3290P&lt;br /&gt;
|-&lt;br /&gt;
| ATmega325P || 32 || 64 || 20 || 16 || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 2 || 1024 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega325P&lt;br /&gt;
|-&lt;br /&gt;
| ATmega3250P || 32 || 100 || 20 || 16 || 69 || 25 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 2 || 1024 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega3250P&lt;br /&gt;
|-&lt;br /&gt;
| AT90USB82 || 8 || 32 || 16 || 12 || 22 || 21 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 2 || 0 || 1 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 || &amp;amp;mdash; || 0.5 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 5 || 1 || 4 || &amp;amp;mdash; || AT90USB82&lt;br /&gt;
|-&lt;br /&gt;
| AT90USB162 || 16 || 32 || 16 || &amp;amp;mdash; || 22 || 21 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 2 || 0 || 1 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 || &amp;amp;mdash; || 0.5 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 5 || 1 || 4 || &amp;amp;mdash; || AT90USB162&lt;br /&gt;
|-&lt;br /&gt;
| AT90PWM216 || 16 || 24 || 16 || 12 || 19 || 4 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 0 || 1 || 0 || 0 || 0 || 8 || 10 || 125 || 2 || 1 || 10 || &amp;amp;mdash; || 1 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;105 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 4 || 12 || 1 || 7 || &amp;amp;mdash; || AT90PWM216&lt;br /&gt;
|-&lt;br /&gt;
| AT90PWM316 || 16 || 32 || 16 || 12 || 27 || 4 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 0 || 1 || 0 || 0 || 0 || 11 || 10 || 125 || 3 || 1 || 10 || &amp;amp;mdash; || 1 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;105 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 5 || 16 || 1 || 12 || &amp;amp;mdash; || AT90PWM316&lt;br /&gt;
|-&lt;br /&gt;
| ATmega48P || 4 || 32 || 20 || 12 || 23 || 24 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;radic; || 0.5 || 256 || &amp;amp;mdash; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega48P&lt;br /&gt;
|-&lt;br /&gt;
| ATmega88P || 8 || 32 || 20 || 12 || 23 || 24 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;radic; || 1 || 512 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega88P&lt;br /&gt;
|-&lt;br /&gt;
| ATmega168P || 16 || 32 || 20 || 16 || 23 || 24 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;radic; || 1 || 512 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega168P&lt;br /&gt;
|-&lt;br /&gt;
| ATmega328P || 32 || 32 || 20 || 16 || 23 || 24 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;radic; || 2 || 1024 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega328P&lt;br /&gt;
|-&lt;br /&gt;
| AT90PWM3B || 8 || 32 || 16 || 8 || 27 || 4 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 0 || 1 || 0 || 0 || 0 || 11 || 10 || 125 || 3 || 1 || 10 || &amp;amp;mdash; || 0.5 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;105 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 5 || 16 || 1 || 12 || &amp;amp;mdash; || AT90PWM3B&lt;br /&gt;
|-&lt;br /&gt;
| AT90PWM2B || 8 || 24 || 16 || 8 || 19 || 4 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 0 || 1 || 0 || 0 || 0 || 8 || 10 || 125 || 2 || 1 || 10 || &amp;amp;mdash; || 0.5 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;105 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 4 || 12 || 1 || 7 || &amp;amp;mdash; || AT90PWM2B&lt;br /&gt;
|-&lt;br /&gt;
| ATmega32U4 || 32 || 44 || 16 || 14 || 26 || 13 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 2 || 1 || 1 || 0 || 0 || 0 || 12 || 10 || 15 || 1 || 0 || 0 || &amp;amp;radic; || 2.5 || 1024 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 4 || 12 || 2 || 8 || &amp;amp;mdash; || ATmega32U4&lt;br /&gt;
|-&lt;br /&gt;
| ATmega1284P || 128 || 44 || 20 || 16 || 32 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 3 || 1 || 2 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 16 || 4096 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega1284P&lt;br /&gt;
|-&lt;br /&gt;
| ATmega16U4 || 16 || 44 || 16 || 14 || 26 || 13 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 2 || 1 || 1 || 0 || 0 || 0 || 12 || 10 || 15 || 1 || 0 || 0 || &amp;amp;radic; || 1.25 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 4 || 12 || 2 || 8 || &amp;amp;mdash; || ATmega16U4&lt;br /&gt;
|-&lt;br /&gt;
| ATmega16A || 16 || 44 || 16 || 16 || 32 || 3 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 1 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega16A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega32A || 32 || 44 || 16 || 16 || 32 || 3 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 2 || 1024 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega32A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega88PA || 8 || 32 || 20 || 12 || 23 || 24 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;radic; || 1 || 512 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega88PA&lt;br /&gt;
|-&lt;br /&gt;
| ATmega324PA || 32 || 44 || 20 || 16 || 32 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 3 || 1 || 2 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 2 || 1024 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega324PA&lt;br /&gt;
|-&lt;br /&gt;
| ATmega48PA || 4 || 32 || 20 || 12 || 23 || 24 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;radic; || 0.5 || 256 || &amp;amp;mdash; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega48PA&lt;br /&gt;
|-&lt;br /&gt;
| ATmega164PA || 16 || 44 || 20 || 16 || 32 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 3 || 1 || 2 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 1 || 512 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega164PA&lt;br /&gt;
|-&lt;br /&gt;
| ATmega64A || 64 || 64 || 16 || 16 || 53 || 8 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 1 || 2 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 4 || 8 || 2 || 7 || &amp;amp;radic; || ATmega64A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega128A || 128 || 64 || 16 || 16 || 53 || 8 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 1 || 2 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 4096 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 4 || 8 || 2 || 7 || &amp;amp;radic; || ATmega128A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega8A || 8 || 32 || 16 || 12 || 23 || 2 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 1 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || &amp;amp;mdash; || &amp;amp;mdash; || 3 || &amp;amp;radic; || ATmega8A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega168PA || 16 || 32 || 20 || 16 || 23 || 24 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;radic; || 1 || 512 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega168PA&lt;br /&gt;
|-&lt;br /&gt;
| ATmega8U2 || 8 || 32 || 16 || &amp;amp;mdash; || 22 || 20 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 2 || 0 || 1 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 || &amp;amp;mdash; || 0.5 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 5 || 1 || 4 || &amp;amp;mdash; || ATmega8U2&lt;br /&gt;
|-&lt;br /&gt;
| ATmega16U2 || 16 || 32 || 16 || 12 || 22 || 21 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 2 || 0 || 1 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 || &amp;amp;mdash; || 0.5 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 5 || 1 || 4 || &amp;amp;mdash; || ATmega16U2&lt;br /&gt;
|-&lt;br /&gt;
| ATmega32U2 || 32 || 32 || 16 || 12 || 22 || 20 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 2 || 0 || 1 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 || &amp;amp;mdash; || 1 || 1024 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 5 || 1 || 4 || &amp;amp;mdash; || ATmega32U2&lt;br /&gt;
|-&lt;br /&gt;
| ATmega644PA || 64 || 44 || 20 || 16 || 32 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 3 || 1 || 2 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega644PA&lt;br /&gt;
|-&lt;br /&gt;
| ATmega16M1 || 16 || 32 || 16 || 12 || 27 || 27 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 0 || 1 || 1 || 1 || 0 || 11 || 10 || 125 || 4 || 1 || 10 || &amp;amp;radic; || 1 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 14 || 1 || 10 || &amp;amp;mdash; || ATmega16M1&lt;br /&gt;
|-&lt;br /&gt;
| ATmega32M1 || 32 || 32 || 16 || 12 || 27 || 27 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 0 || 1 || 1 || 1 || 0 || 11 || 10 || 125 || 4 || 1 || 10 || &amp;amp;radic; || 2 || 1024 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 14 || 1 || 10 || &amp;amp;mdash; || ATmega32M1&lt;br /&gt;
|-&lt;br /&gt;
| ATmega64M1 || 64 || 32 || 16 || 12 || 27 || 27 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 0 || 1 || 1 || 1 || 0 || 11 || 10 || 125 || 4 || 1 || 10 || &amp;amp;radic; || 4 || 2048 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2 || 14 || 1 || 10 || &amp;amp;mdash; || ATmega64M1&lt;br /&gt;
|-&lt;br /&gt;
| ATmega169PA || 16 || 64 || 16 || 16 || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 100 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 1 || 512 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega169PA&lt;br /&gt;
|-&lt;br /&gt;
| ATmega48A || 4 || 32 || 20 || 12 || 23 || 24 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;radic; || 0.5 || 256 || &amp;amp;mdash; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega48A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega88A || 8 || 32 || 20 || 12 || 23 || 24 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;radic; || 1 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega88A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega168A || 16 || 32 || 20 || 16 || 23 || 24 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;radic; || 1 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega168A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega328 || 32 || 32 || 20 || 16 || 23 || 24 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;radic; || 2 || 1024 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega328&lt;br /&gt;
|-&lt;br /&gt;
| ATmega164A || 16 || 44 || 20 || 16 || 32 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 3 || 1 || 2 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 1 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega164A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega324A || 32 || 44 || 20 || 16 || 32 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 3 || 1 || 2 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 2 || 1024 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega324A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega644A || 64 || 44 || 20 || 16 || 32 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 3 || 1 || 2 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega644A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega1284 || 128 || 44 || 20 || 16 || 32 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 3 || 1 || 2 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 16 || 4096 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 6 || 1 || 6 || &amp;amp;radic; || ATmega1284&lt;br /&gt;
|-&lt;br /&gt;
| AT90PWM81 || 8 || 20 || 16 || &amp;amp;mdash; || 20 || 3 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 1 || 0 || 0 || 0 || 0 || 0 || 11 || 10 || 125 || 3 || 1 || 10 || &amp;amp;radic; || 0.25 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;125 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 2.7&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1 || 8 || 1 || 6 || &amp;amp;mdash; || AT90PWM81&lt;br /&gt;
|-&lt;br /&gt;
| ATmega165PA || 16 || 64 || 16 || 16 || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 1 || 512 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega165PA&lt;br /&gt;
|-&lt;br /&gt;
| ATmega325A || 32 || 64 || 20 || 16 || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 2 || 1024 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega325A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega3250A || 32 || 100 || 20 || 16 || 69 || 25 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 2 || 1024 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega3250A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega645A || 64 || 64 || 16 || 16 || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega645A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega645P || 64 || 64 || 16 || 16 || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega645P&lt;br /&gt;
|-&lt;br /&gt;
| ATmega6450P || 64 || 100 || 20 || &amp;amp;mdash; || 69 || 25 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega6450P&lt;br /&gt;
|-&lt;br /&gt;
| ATmega6450A || 64 || 100 || 20 || &amp;amp;mdash; || 69 || 25 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 0 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega6450A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega169A || 16 || 64 || 16 || 16 || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 100 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 1 || 512 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega169A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega329A || 32 || 64 || 20 || 16 || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 100 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 2 || 1024 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega329A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega649A || 64 || 64 || 16 || 16 || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 100 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega649A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega3290A || 32 || 100 || 20 || 16 || 69 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 160 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 2 || 1024 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega3290A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega649P || 64 || 64 || 16 || 16 || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 100 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega649P&lt;br /&gt;
|-&lt;br /&gt;
| ATmega6490A || 64 || 100 || 20 || 16 || 69 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 160 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;mdash; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega6490A&lt;br /&gt;
|-&lt;br /&gt;
| ATmega6490P || 64 || 100 || 20 || 16 || 69 || 32 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 160 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 4 || 2048 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega6490P&lt;br /&gt;
|-&lt;br /&gt;
| ATmega329PA || 32 || 64 || 20 || 16 || 54 || 17 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 2 || 1 || 1 || 0 || 0 || 100 || 8 || 10 || 15 || 1 || 0 || 0 || &amp;amp;mdash; || 2 || 1024 || &amp;amp;radic; || &amp;amp;radic; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 1.8&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;5.5 || 3 || 4 || 1 || 4 || &amp;amp;radic; || ATmega329PA&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;General Features&#039;&#039;&#039;&amp;lt;br/&amp;gt;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;CPU&#039;&#039;&#039; || 8-bit AVR&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Hardware Qtouch&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Quadrature Decoder Kanäle&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;SSC&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Ethernet&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;SD / eMMC&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Grafik LCD&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Video Decoder&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Kamera Interface&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Resistive Touch Screen&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;External Bus Interface&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;DRAM Memory&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;NAND Interface&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;FPU&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;MPU / MMU&#039;&#039;&#039; || nein / nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Crypto Engine&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Calibrated RC Oscillator&#039;&#039;&#039; || ja&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== ATxmega ===&lt;br /&gt;
&lt;br /&gt;
{|  class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;font-size:10px;&amp;quot; id=&amp;quot;AVR_Features_ATxmega&amp;quot;&lt;br /&gt;
|+ Device-specific Features&amp;lt;br/&amp;gt;&amp;amp;nbsp;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
! Device&lt;br /&gt;
! Flash [KiB]&lt;br /&gt;
! Pin Anz&amp;amp;shy;ahl&lt;br /&gt;
! Anzahl Touch Kan&amp;amp;shy;äle&lt;br /&gt;
! Max I/O Pins&lt;br /&gt;
! Ext Inter&amp;amp;shy;rupts&lt;br /&gt;
! USB Trans&amp;amp;shy;cei&amp;amp;shy;ver&lt;br /&gt;
! USB Speed&lt;br /&gt;
! USB Inter&amp;amp;shy;face&lt;br /&gt;
! SPI&lt;br /&gt;
! TWI&lt;br /&gt;
! UART&lt;br /&gt;
! Seg&amp;amp;shy;ment LCD&lt;br /&gt;
! ADC Kan&amp;amp;shy;äle&lt;br /&gt;
! ADC Speed [ksps]&lt;br /&gt;
! Ana&amp;amp;shy;log Com&amp;amp;shy;para&amp;amp;shy;tors&lt;br /&gt;
! DAC Kan&amp;amp;shy;äle&lt;br /&gt;
! DAC Auf&amp;amp;shy;lö&amp;amp;shy;sung [bits]&lt;br /&gt;
! SRAM [KiB]&lt;br /&gt;
! EEPROM [Bytes]&lt;br /&gt;
! Ext&amp;amp;shy;ern&amp;amp;shy;al Bus Inter&amp;amp;shy;face&lt;br /&gt;
! DRAM Memory&lt;br /&gt;
! Crypto Engine&lt;br /&gt;
! Timers&lt;br /&gt;
! Output Com&amp;amp;shy;pare Kan&amp;amp;shy;äle&lt;br /&gt;
! Input Capt&amp;amp;shy;ure Kan&amp;amp;shy;äle&lt;br /&gt;
! PWM Kan&amp;amp;shy;äle&lt;br /&gt;
! Device&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega64A1 || 64 || 100 || 16 || 78 || 78 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 12 || 4 || 8 || 0 || 16 || 2000 || 4 || 4 || 12 || 4 || 2048 || 1 || ja&amp;lt;ref name=&amp;quot;sdram&amp;quot;&amp;gt;SDRAM&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 8 || 24 || 24 || 24 || ATxmega64A1&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega128A1 || 128 || 100 || 16 || 78 || 78 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 12 || 4 || 8 || 0 || 16 || 2000 || 4 || 4 || 12 || 8 || 2048 || 1 || ja&amp;lt;ref name=&amp;quot;sdram&amp;quot;&amp;gt;SDRAM&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 8 || 24 || 24 || 24 || ATxmega128A1&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega64A3 || 64 || 64 || 16 || 50 || 50 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 10 || 2 || 7 || 0 || 16 || 2000 || 4 || 2 || 12 || 4 || 2048 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 7 || 22 || 22 || 22 || ATxmega64A3&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega128A3 || 128 || 64 || 16 || 50 || 50 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 10 || 2 || 7 || 0 || 16 || 2000 || 4 || 2 || 12 || 8 || 2048 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 7 || 22 || 22 || 22 || ATxmega128A3&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega192A3 || 192 || 64 || 16 || 50 || 50 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 10 || 2 || 7 || 0 || 16 || 2000 || 4 || 2 || 12 || 16 || 2048 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 7 || 22 || 22 || 22 || ATxmega192A3&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega256A3 || 256 || 64 || 16 || 50 || 50 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 10 || 2 || 7 || 0 || 16 || 2000 || 4 || 2 || 12 || 16 || 4096 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 7 || 22 || 22 || 22 || ATxmega256A3&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega16A4 || 16 || 44 || 16 || 34 || 34 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 7 || 2 || 5 || 0 || 12 || 2000 || 2 || 2 || 12 || 3.3 || 1024 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 5 || 16 || 16 || 16 || ATxmega16A4&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega32A4 || 32 || 44 || 16 || 34 || 34 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 7 || 2 || 5 || 0 || 12 || 2000 || 2 || 2 || 12 || 4 || 1024 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 5 || 16 || 16 || 16 || ATxmega32A4&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega64A4 || 64 || 44 || &amp;amp;mdash; || 34 || 34 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 7 || 2 || 5 || 0 || 12 || 2000 || 2 || 2 || 12 || 4 || 2048 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 5 || 16 || 16 || 16 || ATxmega64A4&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega128A4 || 128 || 44 || &amp;amp;mdash; || 34 || 34 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 7 || 2 || 5 || 0 || 12 || 2000 || 2 || 2 || 12 || 8 || 2048 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 5 || 16 || 16 || 16 || ATxmega128A4&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega256A3B || 256 || 64 || 16 || 47 || 49 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 8 || 2 || 6 || 0 || 16 || 2000 || 4 || 2 || 12 || 16 || 4096 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 7 || 22 || 22 || 22 || ATxmega256A3B&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega256D3 || 256 || 64 || 16 || 50 || 50 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 5 || 2 || 3 || 0 || 16 || 200 || 2 || 0 || 0 || 16 || 4096 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 5 || 18 || 18 || 18 || ATxmega256D3&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega192D3 || 192 || 64 || 16 || 50 || 50 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 5 || 2 || 3 || 0 || 16 || 200 || 2 || 0 || 0 || 16 || 2048 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 5 || 18 || 18 || 18 || ATxmega192D3&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega128D3 || 128 || 64 || 16 || 50 || 50 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 5 || 2 || 3 || 0 || 16 || 200 || 2 || 0 || 0 || 8 || 2048 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 5 || 18 || 18 || 18 || ATxmega128D3&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega64D3 || 64 || 64 || 16 || 50 || 50 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 5 || 2 || 3 || 0 || 16 || 200 || 2 || 0 || 0 || 4 || 2048 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 5 || 18 || 18 || 18 || ATxmega64D3&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega128D4 || 128 || 44 || &amp;amp;mdash; || 34 || 34 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 4 || 2 || 2 || 0 || 12 || 200 || 2 || 0 || 0 || 8 || 2048 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 4 || 14 || 14 || 14 || ATxmega128D4&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega64D4 || 64 || 44 || &amp;amp;mdash; || 34 || 34 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 4 || 2 || 2 || 0 || 12 || 200 || 2 || 0 || 0 || 4 || 2048 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 4 || 14 || 14 || 14 || ATxmega64D4&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega32D4 || 32 || 44 || 16 || 34 || 34 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 4 || 2 || 2 || 0 || 12 || 200 || 2 || 0 || 0 || 4 || 1024 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 4 || 14 || 14 || 14 || ATxmega32D4&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega16D4 || 16 || 44 || 16 || 34 || 34 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 4 || 2 || 2 || 0 || 12 || 200 || 2 || 0 || 0 || 2 || 1024 || 0 || &amp;amp;mdash; || &amp;amp;mdash; || 4 || 14 || 14 || 14 || ATxmega16D4&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega16A4U || 16 || 44 || 16 || 34 || 34 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 7 || 2 || 5 || 0 || 12 || 2000 || 2 || 2 || 12 || 3.3 || 1024 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 5 || 16 || 16 || 16 || ATxmega16A4U&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega32A4U || 32 || 44 || 16 || 34 || 34 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 7 || 2 || 5 || 0 || 12 || 2000 || 2 || 2 || 12 || 4 || 1024 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 5 || 16 || 16 || 16 || ATxmega32A4U&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega64A3U || 64 || 64 || 16 || 50 || 50 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 10 || 2 || 7 || 0 || 16 || 2000 || 4 || 2 || 12 || 4 || 2048 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 7 || 22 || 22 || 22 || ATxmega64A3U&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega128A3U || 128 || 64 || 16 || 50 || 50 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 10 || 2 || 7 || 0 || 16 || 2000 || 4 || 2 || 12 || 8 || 2048 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 7 || 22 || 22 || 22 || ATxmega128A3U&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega192A3U || 192 || 64 || 16 || 50 || 50 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 10 || 2 || 7 || 0 || 16 || 2000 || 4 || 2 || 12 || 16 || 2048 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 7 || 22 || 22 || 22 || ATxmega192A3U&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega256A3U || 256 || 64 || 16 || 50 || 50 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 10 || 2 || 7 || 0 || 16 || 2000 || 4 || 2 || 12 || 16 || 4096 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 7 || 22 || 22 || 22 || ATxmega256A3U&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega256A3BU || 256 || 64 || 16 || 47 || 49 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 8 || 2 || 6 || 0 || 16 || 2000 || 4 || 2 || 12 || 16 || 4096 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 7 || 22 || 22 || 22 || ATxmega256A3BU&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega64B3 || 64 || 64 || 16 || 36 || 36 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 2 || 1 || 1 || 100 || 8 || 2000 || 2 || 0 || 0 || 4 || 2048 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 2 || 6 || 6 || 6 || ATxmega64B3&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega128B3 || 128 || 64 || 16 || 36 || 36 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 2 || 1 || 1 || 100 || 8 || 2000 || 2 || 0 || 0 || 4 || 2048 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 2 || 6 || 6 || 6 || ATxmega128B3&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega128B1 || 128 || 100 || 16 || 53 || 53 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 3 || 1 || 2 || 160 || 16 || 2000 || 4 || 0 || 0 || 8 || 2048 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 3 || 10 || 10 || 10 || ATxmega128B1&lt;br /&gt;
|-&lt;br /&gt;
| ATxmega64B1 || 64 || 100 || 16 || 53 || 53 || 1 || ja&amp;lt;ref name=&amp;quot;usbs&amp;quot;&amp;gt;Full Speed&amp;lt;/ref&amp;gt; || ja&amp;lt;ref name=&amp;quot;usbd&amp;quot;&amp;gt;Device&amp;lt;/ref&amp;gt; || 3 || 1 || 2 || 160 || 16 || 2000 || 4 || 0 || 0 || 8 || 2048 || 0 || &amp;amp;mdash; || ja&amp;lt;ref name=&amp;quot;cry&amp;quot;&amp;gt;AES/DES&amp;lt;/ref&amp;gt; || 3 || 10 || 10 || 10 || ATxmega64B1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;General Features&#039;&#039;&#039;&amp;lt;br/&amp;gt;&amp;amp;nbsp;&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Max. &amp;amp;fnof;&amp;lt;sub&amp;gt;CPU&amp;lt;/sub&amp;gt; [MHz]&#039;&#039;&#039; || 32&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;CPU&#039;&#039;&#039; || 8-bit AVR&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Hardware Qtouch&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Quadrature Decoder Kanäle&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;CAN&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;LIN&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;SSC&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Ethernet&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;SD / eMMC&#039;&#039;&#039; || 0&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Grafik LCD&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Video Decoder&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Kamera Interface&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;ADC Auflösung [bits]&#039;&#039;&#039; || 12&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Resistive Touch Screen&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Temp. Sensor&#039;&#039;&#039; || ja&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Self Program Memory&#039;&#039;&#039; || ja&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;NAND Interface&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;picoPower&#039;&#039;&#039; || ja&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Temp. Bereich [°C]&#039;&#039;&#039; || &amp;amp;minus;40&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;85&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;I/O Supply Class [V]&#039;&#039;&#039; || 1.6&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;3.6&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Operating Voltage [V&amp;lt;sub&amp;gt;CC&amp;lt;/sub&amp;gt;]&#039;&#039;&#039; || 1.6&amp;amp;nbsp;&amp;amp;ndash;&amp;amp;nbsp;3.6&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;FPU&#039;&#039;&#039; || nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;MPU / MMU&#039;&#039;&#039; || nein / nein&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;32kHz RTC&#039;&#039;&#039; || ja&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;Calibrated RC Oscillator&#039;&#039;&#039; || ja&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Referenzen ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.avrfreaks.net/index.php?module=Freaks%20Devices&amp;amp;func=devCompare Vergleichstabelle] von AVRFreaks&lt;br /&gt;
* [http://www.atmel.com/products/selector_overview.aspx Parametrische Suche bei Atmel]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR]]&lt;br /&gt;
[[Kategorie:Liste mit Bauteilen]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR_Net-IO_Bausatz_von_Pollin&amp;diff=83357</id>
		<title>AVR Net-IO Bausatz von Pollin</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR_Net-IO_Bausatz_von_Pollin&amp;diff=83357"/>
		<updated>2014-06-17T19:21:09Z</updated>

		<summary type="html">&lt;p&gt;Maybee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier steht eine Beschreibung des Pollin Bausatzes [http://www.pollin.de/shop/shop.php?cf=detail.php&amp;amp;pg=NQ==&amp;amp;a=MTQ5OTgxOTk= AVR-NET-IO. Best.Nr. 810 058], oder als aufgebautes Fertigmodul, Best.Nr. 810 073. &lt;br /&gt;
&lt;br /&gt;
Einige Features: Ethernet-Platine mit ATmega32 und Netzwerkcontroller ENC28J60. Die Platine verfügt über 8 digitale Ausgänge, 4 digitale und 4 ADC-Eingänge, welche alle über einen Netzwerkanschluss (TCP/IP) abgerufen bzw. geschaltet werden können.&lt;br /&gt;
&lt;br /&gt;
[[Datei:AVR-NET-IO ADD-ON.JPG|thumb|right|400px|AVR-NET-IO (links) mit zusätzlicher SUB-D Anschlussplatine (rechts, nicht im Lieferumfang)und Add-On-Board (oben, mit aufgelötetem RFM12-433-Modul, beides nicht im Lieferumfang). Ebenso ist zusätzlich ein nicht im Lieferumfang enthaltener kleiner Kühlkörper auf einem der Spannungsregler montiert und die Schraubklemmen zur Stromversorgung wurden durch Buchsen ersetzt.]]&lt;br /&gt;
&lt;br /&gt;
== Technische Daten ==&lt;br /&gt;
&lt;br /&gt;
* Betriebsspannung 9 V AC/DC&lt;br /&gt;
* Stromaufnahme ca. 190 mA&lt;br /&gt;
* bzw. 5V DC, 1A (Steckernetzteil) an J6&lt;br /&gt;
* 8 digitale Ausgänge (0/5 V) [PC0-PC7 an J3]&lt;br /&gt;
* 4 digitale Eingänge (0/5 V) [PA0-PA3 an J3]&lt;br /&gt;
* 4 ADC-Eingänge (10 Bit) [PA4-PA7 an Schraubklemmen]&lt;br /&gt;
* LCD-Anschluss (HD44780 komp. Controller nötig) [PD2-7,PB0,PB3 an EXT]&lt;br /&gt;
* [[ENC28J60]]&lt;br /&gt;
* [http://www.atmel.com/dyn/Products/Product_card.asp?part_id=2014 ATmega32] Mikrocontroller&lt;br /&gt;
&lt;br /&gt;
Maße (L×B×H): 108×76×22 mm.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
=== AVR-NET-IO ===&lt;br /&gt;
&lt;br /&gt;
Die Schaltung des AVR-NET-IO ist recht einfach:&lt;br /&gt;
* Ein ATmega32 Mikrocontroller enthält die gesamte Software&lt;br /&gt;
* Ein ENC28J60 Ethernet-Controller für das Senden und Empfangen von Ethernet Frames (MAC und PHY Ethernet Layer) ist über [[SPI]] mit dem ATmega32 verbunden&lt;br /&gt;
* Ein Ethernet RJ-45 MagJack TRJ 0011 BA NL von [http://www.trxcom.com/ Trxcom] mit eingebautem Übertrager und Anzeige-LEDs am ENC28J60.&lt;br /&gt;
* Ein MAX232 für die serielle Schnittstelle&lt;br /&gt;
* Zwei Spannungsregler, 5 V und 3,3 V&lt;br /&gt;
* &amp;quot;Hühnerfutter&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Fast alle I/O Pins des ATmega32 sind irgendwo auf Anschlüssen herausgeführt. Entweder auf dem SUB-D Stecker, dem EXT oder ISP Wannensteckern oder den blauen Anschlussklemmen. Eine Schutzbeschaltung gibt es nicht.&lt;br /&gt;
&lt;br /&gt;
Die blauen Anschlussklemmen haben eine Nut und eine Feder mit denen man&lt;br /&gt;
sie zusammenstecken kann, dadurch ist das Anlöten wesentlich leichter&lt;br /&gt;
und sie stehen auch sauber in der Reihe.&lt;br /&gt;
&lt;br /&gt;
=== Erweiterungsplatine ===&lt;br /&gt;
&lt;br /&gt;
Seit Januar 2010 gibt es auch eine Erweiterungsplatine &lt;br /&gt;
&lt;br /&gt;
[http://www.pollin.de/shop/dt/Nzg4OTgxOTk-/Bausaetze/Diverse/Bausatz_Add_on_fuer_AVR_NET_IO.html Add-on für AVR-NET-IO-Board Best.Nr. 810 112]&lt;br /&gt;
&lt;br /&gt;
Diese Platine erweitert das NET-IO um:&lt;br /&gt;
&lt;br /&gt;
* SD-Karten-Slot über SPI&lt;br /&gt;
* Display über PCF 8574&lt;br /&gt;
* Infrarot-Empfang&lt;br /&gt;
* [[RFM12]] Funkmodul (nicht im Lieferumfang enthalten)&lt;br /&gt;
&lt;br /&gt;
Eine Aufstellung bekannter Fehler findet sich weiter unten [[#Bekannte Fehler|Bekannte Fehler - Erweiterungplatine]] &lt;br /&gt;
&lt;br /&gt;
Erste Erfahrungsberichte im Forum http://www.mikrocontroller.net/topic/161354&lt;br /&gt;
&lt;br /&gt;
=== Hardware-Umbauten &amp;amp; -Verbesserungen ===&lt;br /&gt;
&lt;br /&gt;
* Kühlkörper auf dem 7805 - (Vorsicht: Der LM317T ist rückseitig spannungsführend. Den Kühlkörper also keinesfalls an beide Spannungsregler anschließen!)&lt;br /&gt;
* MAX232 nach anfänglicher Konfiguration nicht bestücken um Strom zu sparen oder um zwei weitere I/O-Pins zu gewinnen&lt;br /&gt;
* 10µF-Elkos für MAX232N (C14-C17) durch 1µF ersetzen. Eine 10µF-Version für den MAX232 gibt es nicht. Die 10µF-Elkos können auch Ursache einer nicht funktionierenden RS232 sein.&lt;br /&gt;
** Laut Spezifikation sind auch mehr als 1µF erlaubt. Selbst Atmel verwendet beim STK500 10µF. Dies führt keinesfalls dazu, dass die RS232 nicht mehr funktioniert.&lt;br /&gt;
* Die IC-Fassungen aus &amp;quot;Pollins Resterampe&amp;quot; durch Fassungen mit gedrehten Kontakten ersetzen. &lt;br /&gt;
* &#039;&#039;Netz&#039;&#039; LED nicht bestücken oder größere Widerstände einlöten um Strom zu sparen (R3)&lt;br /&gt;
* Vorwiderstände der Ethernet-LEDs größer machen (z.&amp;amp;nbsp;B. verdoppeln) um Strom zu sparen (R6,R7)&lt;br /&gt;
* Linear-Spannungsregler ersetzen&lt;br /&gt;
* Kondensator an AREF-Pin des ATmega32 (ATmega32 Datenblatt) (100nF gegen Masse)&lt;br /&gt;
* Kondensator an den RESET-Pin des ATmega32 ([http://www.atmel.com/dyn/resources/prod_documents/doc2521.pdf Atmel Application Note AVR042: AVR Hardware Design Considerations]) Wenn man diese Quelle genauer liest, ist das aber eher unnötig. - Kondensator bei selbstbau-ISP empfehlenswert.&lt;br /&gt;
* Umbau auf 3,3 V:&lt;br /&gt;
** Ersatz der Spannungsregler durch einen einzigen 3,3 V Regler&lt;br /&gt;
** Anpassen (verkleinern) des LED-Vorwiderstands R3 für 3,3 Volt Betrieb&lt;br /&gt;
** Reduktion der Taktfrequenz (Austausch von Q2) auf den bei 3,3V erlaubten Bereich des ATmega32 ( ATmega32(L)  3.3V /8.0 Mhz Takt )&lt;br /&gt;
** Ersatz des MAX232 durch einen MAX3232&lt;br /&gt;
[[Bild:POWER.JPG|thumb|400px|5V Stromversorgung über USB Kabel, ohne 5 V Spannungsregler und Gleichrichterdioden, Vorsicht: kein Verpolungsschutz!  ]]&lt;br /&gt;
* ATmega32 vom ENC28J60 takten (OSC2)&lt;br /&gt;
* Betrieb mit Gleichspannung:&lt;br /&gt;
** Dioden D2 und D5 durch Drahtbrücken ersetzen, D1 und D4 nicht bestücken (komplette Entfernung des Brückengleichrichters, beinhaltet Verlust des Verpolungsschutzes)&lt;br /&gt;
** Diode D2 bestücken, D5 durch Drahtbrücke ersetzen, D1 und D4 nicht bestücken (Brückengleichrichter durch Verpolungsschutze ersetzen)&lt;br /&gt;
*** ??? Ist dies nicht kontraproduktiv? Bei mir wurde durch D2-Bestückung die Eingangsspannung von ca. 5,2 V am LM317T auf ca. 4,6 V gedrückt, so dass am ENC28J60 nur ca. 2,6 V ankamen (außerhalb der lt. Datenblatt &amp;quot;Operating voltage range of 3.14V to 3.45V&amp;quot;). Man müsste also ein geregeltes Netzteil mit ca. 5,5 V anschließen um 5 und 3,3 V zu erzielen. Dann lieber den Verpolungsschutz durch andere Maßnahmen sicherstellen.&lt;br /&gt;
** Beim Betrieb von USB beachten, dass USB-Spezifikation keinesfalls 5V garantiert, sondern Spannung bis runter 4.4V erlaubt und dann u.U. durch den LM317 nicht mehr genügend Spannung am ENC anliegt. Das äußert sich so, dass zwar der Atmega einwandfrei funktioniert, die Ethernet-Kommunikation aber nicht oder nur sehr sporadisch.&lt;br /&gt;
* Betrieb mit Steckernetzteil&lt;br /&gt;
** Wenn man ein energieeffizientes Stecker-Schaltnetzteil mit 5V, 1A direkt an J6 kontaktiert, kann man sich die o.g. Um- und Ausbauten sparen. Kein Spannungsregler wird mehr heiß, kein Kühlkörper wird benötigt, das Board arbeitet absolut stabil. &lt;br /&gt;
* Ersatz des ATmega32 durch einen ATmega644 oder ATmega1284p mit mehr FLASH-Speicher.&lt;br /&gt;
** Der ATmega644 und auch der ATMega1284p sind nicht mit der Pollin-Firmware kompatibel&lt;br /&gt;
* 100nF über alle drei IC Störunterdrückung zusätzlich bestücken&lt;br /&gt;
&lt;br /&gt;
== Inbetriebnahme der Originalsoftware ==&lt;br /&gt;
=== Einleitung ===&lt;br /&gt;
&lt;br /&gt;
Die bei Auslieferung (Stand September 2008) in den ATmega32 gebrannte Firmware stellt sich manchmal recht zickig an. Es scheint dann die Netzwerk-Schnittstelle, ggf. auch  die serielle Schnittstelle, nicht zu funktionieren. Falls es Probleme geben sollte, sollte man erst einmal ein Firmwareupdate versuchen. Dies geschieht über die serielle Schnittstelle mittels des Programmes NetServer (aktuelle Version 1.03, Februar 2010), die dem Bausatz beiliegt. &lt;br /&gt;
&lt;br /&gt;
Falls die serielle Schnittstelle ebenfalls nicht zugänglich ist, kann mit den im folgenden beschriebenen Schritten die Inbetriebnahme der Software möglich sein. Dazu benötigt man:&lt;br /&gt;
&lt;br /&gt;
* Einen Windows-PC mit Ethernet-Schnittstelle und RS232-Schnittstelle (ein Prolific RS232-USB Konverter funktioniert)&lt;br /&gt;
* Entweder&lt;br /&gt;
**zwei normale (&#039;&#039;straight through&#039;&#039;) Ethernet-Kabel und einen Ethernet Switch/Hub, oder&lt;br /&gt;
**ein gekreuztes(&#039;&#039;cross over&#039;&#039;) Ethernet-Kabel&lt;br /&gt;
* Einen AVR Programmer (Hardware und Software). Zum Beispiel einen [[AVR Dragon]] oder [[STK500]] mit [[AVR Studio]] oder das [[Pollin ATMEL Evaluations-Board]] und [[avrdude]].&lt;br /&gt;
* Die [http://www.pollin.de/shop/ds/MTQ5OTgxOTk-.html Pollin NetServer Software], Version 1.03 (oder neuer)&lt;br /&gt;
&lt;br /&gt;
=== Gelieferten ATmega32 richtig einstellen ===&lt;br /&gt;
[[image:fuse_bits_avr_studio.jpg|thumb|right|250px|Einstellungen der Fuse-Bits mittels AVR Studio 4]]&lt;br /&gt;
Die Fuses der gelieferten ATmega32s scheinen nicht immer mit den im Handbuch auf Seite 12 als erforderlich angegebenen Fuse-Einstellungen übereinzustimmen.&lt;br /&gt;
&lt;br /&gt;
Dies kann man mittels eines Programmers ändern. LFuse = 0xBF, HFuse = 0xD2. Das genaue Vorgehen hängt dabei vom verwendeten Programmer ab. Bei der Gelegenheit kann man ebenfalls eine Sicherheitskopie des ursprünglichen Flash-Inhalts und des EEPROMs anfertigen. Das EEPROM scheint die MAC-Adresse des Ethernet-Ports zu enthalten.&lt;br /&gt;
&lt;br /&gt;
Entgegen der Spezifikation im Handbuch von Pollin sollten die &#039;&#039;&#039;HFuses auf 0xC2&#039;&#039;&#039; gesetzt werden, d. h. CKOPT-Fuse programmiert (dies ist in der Software Version 1.03 bereits vollzogen). Das sorgt für einen stabilen Betrieb des AVR-Oszillators im &amp;quot;full rail-to-rail swing&amp;quot;-Mode bei 16 MHz. Atmel garantiert ansonsten nur stabilen Betrieb bis 8 MHz. Siehe ATmega32-Datenblatt, Kapitel 8.4, Crystal Oscillator.&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
==== Funktionsfähige Konfiguration - AVR-Prog ====&lt;br /&gt;
&lt;br /&gt;
[[Bild:Avrprog.png|thumb|right|250px]]&lt;br /&gt;
Benutzer von AVR-Prog können die nachfolgenden Einstellungen für die Lock- und Fuse-Bits verwenden. Hierbei handelt es sich um die ausgelesenen Einstellungen eines funktionsfähigen Controllers. Allerdings sollte, laut Handbuch des AVR-NET-IO-Boards, das Fuse-Bit EESAVE eigentlich gesetzt sein. &lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch per avrdude die Einstellung getroffen werden:&lt;br /&gt;
 avrdude -c stk500v2 -pm32 -U lfuse:w:0xBF:m&lt;br /&gt;
und &lt;br /&gt;
 avrdude -c stk500v2 -pm32 -U hfuse:w:0xC2:m&lt;br /&gt;
&lt;br /&gt;
Anschließend muß noch der Bootloader und die Firmware aktualisiert werden (siehe Handbuch AVR-NET-IO-Board Seite 12 Punkt 3).&lt;br /&gt;
&lt;br /&gt;
=== PC Konfiguration ===&lt;br /&gt;
&lt;br /&gt;
==== PC normalerweise nicht im 192.168.0.0/24 Subnetz ====&lt;br /&gt;
&lt;br /&gt;
Betreibt man den PC nicht im 192.168.0.0/24 Subnetz, muss er wie folgt umkonfiguriert werden, oder die IP Adresse des Boards wird entsprechend angepasst. ( Siehe Handbuch Seite 14ff. Das ist meist sinnvoller und auch einfacher. ) &lt;br /&gt;
&lt;br /&gt;
Den PC vom normalen Netzwerk abstecken[1]. Zur Umkonfiguration dazu bei Windows XP in der Systemsteuerung &#039;&#039;Netzwerkverbindungen&#039;&#039; aufrufen und die lokale &#039;&#039;LAN-Verbindung&#039;&#039; markieren. Dann in der rechten Leiste &#039;&#039;Einstellungen dieser Verbindung ändern&#039;&#039; aufrufen. &lt;br /&gt;
&lt;br /&gt;
Es erscheint der Dialog &#039;&#039;Eigenschaften von &amp;lt;Verbindungsname&amp;gt;&#039;&#039;. In der Liste im Dialog zu &#039;&#039;Internetprotokoll (TCP/IP)&#039;&#039; gehen. Ein Doppelklick auf den Eintrag öffnet den &#039;&#039;Eigenschaften von Internetprotokoll (TCP/IP)&#039;&#039; Dialog.&lt;br /&gt;
&lt;br /&gt;
In diesem Dialog &#039;&#039;Folgende IP-Adresse verwenden:&#039;&#039; auswählen und zum Beispiel&lt;br /&gt;
&lt;br /&gt;
IP-Adresse: &#039;&#039;&#039;192.168.0.100&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Subnetzmaske: &#039;&#039;&#039;255.255.255.0&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Standardgateway: &#039;&#039;&#039;192.168.0.1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
eingeben. &lt;br /&gt;
&lt;br /&gt;
Anmerkung von bitman:&lt;br /&gt;
[1] Dies ist spätestens ab Windows XP nicht mehr notwendig, wenn das Netz 192.168.0.0/24 noch frei ist. Dann kann man einfach den Client &#039;&#039;zusätzlich&#039;&#039; in diesem Netzwerk zusätzlich einbinden über Einstellungen/Netzwerkverbindungen/Lanverbindung/Eigenschaften/TCP-IP/Eigenschaften/Erweitert/IP-Adresse hinzufügen. Es werden dann eben mehrere IP-Adressen an den NIC gebunden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alle geöffneten Dialoge nacheinander mit OK schließen.&lt;br /&gt;
&lt;br /&gt;
Alternativ bietet sich das Umprogrammieren des Boards über die serielle Schnittstelle an. Die Werte für IP-Adresse, Netzmaske und Standard-Gateway werden mit den dokumentierten SETxx-Befehlen geändert, das Board neu gestartet und ans vorhandene Netzwerk gesteckt.&lt;br /&gt;
&lt;br /&gt;
Im EEPROM sind folgende Werte vorprogrammiert:&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
3EE - 3F3 MAC-ADRESSE&amp;lt;br&amp;gt;&lt;br /&gt;
3F4 - 3F7 GATEWAY&amp;lt;br&amp;gt;&lt;br /&gt;
3F8 - 3FB NETMASK&amp;lt;br&amp;gt;&lt;br /&gt;
3FC - 3FF IP-ADRESSE&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PC bereits im 192.168.0.0/24 Subnetz ====&lt;br /&gt;
&lt;br /&gt;
In diesem Fall muss man prüfen, ob die IP-Adresse 192.168.0.90 bereits im Subnetz verwendet wird. Ist dies der Fall, muss das verwendete Gerät mit dieser IP vorübergehend aus dem Subnetz entfernt werden. Es sei denn, dabei handelt es sich um den PC. In diesem Fall muss er wie zuvor umkonfiguriert werden. Ansonsten kann der unverändert im Netz verbleiben.&lt;br /&gt;
&lt;br /&gt;
Dem AVR-NET-IO gibt man eine neue, zuvor unbenutzte Adresse (siehe unten). Dann kann das abgekoppelte Gerät wieder angeschlossen werden, beziehungsweise der PC zurückkonfiguriert werden.&lt;br /&gt;
&lt;br /&gt;
=== AVR-NET-IO anschließen ===&lt;br /&gt;
&lt;br /&gt;
Musste man den PC umkonfigurieren, so werden jetzt nur der PC und der AVR-NET-IO über Ethernet miteinander verbunden. Je nach Ethernet-Kabel benötigt man dazu einen Switch/Hub oder nicht.&lt;br /&gt;
&lt;br /&gt;
Musste man den PC nicht umkonfigurieren, so kann man den AVR-NET-IO wie einen normalen Rechner an das vorhandenen Netz anschließen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich schließt man die serielle Schnittstelle des AVR-NET-IO an den PC an.&lt;br /&gt;
&lt;br /&gt;
=== Firmware 1.03 einspielen ===&lt;br /&gt;
&lt;br /&gt;
Laut Handbuch sollte der AVR-NET-IO jetzt über Ethernet funktionieren. Ebenso sollte er über die serielle Schnittstelle und ein Terminalprogramm konfigurierbar sein. Beides ist offensichtlich im Auslieferungszustand selten der Fall.&lt;br /&gt;
&lt;br /&gt;
Auch wenn sich Pollins NetServer Software nicht mit dem AVR-NET-IO verbinden lässt, so ist sie jedoch in der Lage eine neue Firmware 1.03 einzuspielen. Das Vorgehen ist im Handbuch auf Seite 12 beschrieben. NetServer präsentiert dabei ein paar einfache Anweisungen denen man folgen sollte.&lt;br /&gt;
&lt;br /&gt;
Wenn sich nach dem scheinbar erfolgreichem Einspielen der Firmware, später nichts tut, so sollte die Firmware mit gesetztem &amp;quot;FailSafe&amp;quot; in der mitgelieferten NetServer-Software nochmals Eingespielt werden.&lt;br /&gt;
&lt;br /&gt;
=== Abschluss ===&lt;br /&gt;
&lt;br /&gt;
Jetzt sollte sich die NetServer Software mit dem AVR-NET-IO über Ethernet verbinden lassen. Dies macht es wiederum möglich, den AVR-NET-IO mit einer anderen IP-Adresse zu versehen. Will man den AVR-NET-IO in einem anderen Subnetz betreiben kann man dies jetzt einstellen.&lt;br /&gt;
&lt;br /&gt;
Nachdem man die IP-Adresse neu eingestellt hat, muss man den PC zurückkonfigurieren und kann dann sowohl den AVR-NET-IO und den PC zusammen betreiben.&lt;br /&gt;
&lt;br /&gt;
== Funktionsumfang der Originalsoftware ==&lt;br /&gt;
Die Originalsoftware ist sehr einfach gestrickt. Im AVR Net-IO läuft ein Programm, welches am Port 50290 ein Textschnittstelle bereit stellt. Diese Schnittstelle kann sowohl über die RS232 als auch über Ethernet angesprochen werden kann. Mit diesem Programm ist es möglich, alle Eingänge sowie alle Ausgänge anzusprechen, als auch die Konfiguration der Netzwerkeinstellungen zu verändern. Die Karte versteht dann folgende Befehle:&lt;br /&gt;
* SETPORT&lt;br /&gt;
Einen digitalen Ausgang auf 0 oder 1 schalten&lt;br /&gt;
* GETPORT&lt;br /&gt;
Den Status eines digital Ausgangs/Eingangs abfragen&lt;br /&gt;
* GETSTATUS&lt;br /&gt;
Den Status aller digital Ausgänge abfragen&lt;br /&gt;
* GETADC&lt;br /&gt;
Den Messwert eines analogen Eingangs ermitteln&lt;br /&gt;
* SETIP&lt;br /&gt;
Die IP-Adresse des Boards ändern&lt;br /&gt;
* GETIP&lt;br /&gt;
Die eingestellte IP-Adresse abfragen&lt;br /&gt;
* SETMASK&lt;br /&gt;
Die Netzwerkmaske verändern&lt;br /&gt;
* GETMASK&lt;br /&gt;
Die eingestelle Netzwerkmaske abfragen&lt;br /&gt;
* SETGW&lt;br /&gt;
Das Netzwerk-Gateway verändern &lt;br /&gt;
* GETGW&lt;br /&gt;
Das eingestellte Netzwerk-Gateway abfragen&lt;br /&gt;
* INITLCD&lt;br /&gt;
Ein angeschlossenes LCD initialisieren&lt;br /&gt;
* WRITELCD&lt;br /&gt;
Einen Text am LCD ausgeben&lt;br /&gt;
* CLEARLCD&lt;br /&gt;
Ein angeschlossenes LCD löschen&lt;br /&gt;
* VERSION&lt;br /&gt;
Die Versionsnummer des Programms ausgeben&lt;br /&gt;
&lt;br /&gt;
Dazu gibt es ein auf Java basierendes Programm, welches alternativ zu einem Terminalprogramm benutzt werden kann. Es zeigt den Status der Portpins an und diese lassen sich auch mit der Maus verändern. Die Messwerte der 4 analogen Eingänge werden ständig angezeigt, wobei es möglich ist, durch einstellbare Faktoren die internen Werte gleich in sinnvolle Einheiten umrechnen zu lassen. Diese Messwerte können auch in eine Datei geloggt werden.&lt;br /&gt;
Neben der Möglichkeit, alle Kommandos auch händisch einzugeben, wird das Java-Programm auch benötigt, um einen Firmware-Update der Net-IO Platine durchzuführen.&lt;br /&gt;
Alles in allem ist dieses Frontend aber mehr als Testumgebung anzusehen, um damit die Hardware in Betrieb zu nehmen. Für einen sinnvollen Dauereinsatz ist das Programm deutlich zu einfach und unflexibel gestrickt. Auch kann die grafische Aufbereitung der Anzeige- und Kontrollelemente nicht befriedigen.&lt;br /&gt;
&lt;br /&gt;
== Bekannte Fehler ==&lt;br /&gt;
=== AVR-NET-IO ===&lt;br /&gt;
&lt;br /&gt;
Siehe auch [[#Hardware-Umbauten_.26_-Verbesserungen|Hardware-Umbauten und Verbesserungen]]&amp;lt;br&amp;gt;&lt;br /&gt;
Käufer berichten von fehlenden Bauteilen im Bausatz (Wannenstecker, Widerstände, Kondensatoren, Induktivitäten). Für Reklamationen: [https://www.pollin.de/shop/kontakt_service/reklamation.html]&lt;br /&gt;
&lt;br /&gt;
* Die Stückliste auf Seite 4 in den Anleitung mit den Versionsangaben&lt;br /&gt;
** &#039;&#039;Stand 20.08.2008, kloiber, #1100, wpe&#039;&#039; (gedruckt im Bausatz)&lt;br /&gt;
** &#039;&#039;Stand 20.08.2008, cd, #all, wpe&#039;&#039; (auf der CD)&lt;br /&gt;
:ist falsch. Pollin legt dem Bausatz irgendwann ab September 2008 einen gedruckten Korrekturzettel bei. Die Online-Version der Anleitung ist korrigiert.&lt;br /&gt;
* Im Schaltplan auf Seite 7 in den Anleitungen mit den Versionen&lt;br /&gt;
** &#039;&#039;Stand 20.08.2008, kloiber, #1100, wpe&#039;&#039; (gedruckt im Bausatz)&lt;br /&gt;
** &#039;&#039;Stand 20.08.2008, cd, #all, wpe&#039;&#039; (auf der CD)&lt;br /&gt;
** &#039;&#039;Stand 03.09.2008, online, #all, wpe&#039;&#039; (Online)&lt;br /&gt;
:ist eine 25-polige SUB-D Buchse gezeichnet. Geliefert wird und in der Stückliste verzeichnet ist ein Stecker.&lt;br /&gt;
&lt;br /&gt;
* Die September 2008 ausgelieferte Firmware im ATmega32  funktioniert bei vielen nicht und muss erst upgedatet werden (siehe [[#Inbetriebnahme der Originalsoftware|Inbetriebnahme der Originalsoftware]])&lt;br /&gt;
&lt;br /&gt;
* Im Flash der gelieferten AVR ist anders als beschrieben nur der Bootloader enthalten, die eigentliche Firmware muss erst mit Hilfe der Updatefunktion geladen werden. Wenn zusätzlich auch die Fuses falsch gebrannt sind, dann funktioniert das Update nicht, auch wenn das PC Programm was anderes behauptet.&lt;br /&gt;
&lt;br /&gt;
* Die Fuse-Einstellungen des ausgelieferten ATmega32 entspricht nicht der Anleitung (siehe [[#Inbetriebnahme der Originalsoftware|Inbetriebnahme der Originalsoftware]])&lt;br /&gt;
&lt;br /&gt;
* Bausatz, gekauft am 27.10.08, Anleitungsversion 19.09.08, ohne Probleme oder erkennbare Fehler zusammengebaut und in Betrieb genommen.&lt;br /&gt;
&lt;br /&gt;
* Bausatz gekauft 29.09.2008, Pinbelegung des 25 poligen D-Sub &amp;quot;Anschlusses&amp;quot; stimmt nicht mit der Anleitung überein. Der Aufdruck auf der Platine ist falsch. Pin1 &amp;lt;-&amp;gt; Pin13, Pin2 &amp;lt;-&amp;gt; Pin12 usw. Setzt man den D-Sub Stecker ein, so sind dessen Pinnummern korrekt. Bei einem Bausatz gekauft 05/2013 ist dies ebenfalls noch der Fall.&lt;br /&gt;
&lt;br /&gt;
* 3 Bausätze Anf. Oktober 2008 gekauft, bei einem waren 2 LM317 dabei, dafür fehlte der 7805 - aus der Bastelkiste ersetzt. Alle haben jedoch auf Anhieb funktioniert&lt;br /&gt;
&lt;br /&gt;
* Bausatz gekauft Ende Januar 2009. Die Lock-Bits (u.a. für PonyProg2000) werden falsch beschrieben. Die in Klammern aufgeführten Werte stimmen bei einem Bit nicht. Die Texte &amp;quot;Programmiert/Unprogrammiert&amp;quot; hingegen schon. Bei den Bauteilen gab es 4 Kondensatoren mit der Aufschrift &amp;quot;220&amp;quot;, ich habe diese durch welche mit 22p ersetzt, da ich nicht sicher war ob wirklich 22p geliefert wurden. Dafür wurden statt einem zwei 7805 und statt einem mindestens vier LM317 mitgeliefert.&lt;br /&gt;
&lt;br /&gt;
* Bausatz geliefert 22.4.2009. Alles vollständig, zusammengebaut, läuft. Software-Version 1.03. Für den oben schon genannten Steckverbinder wurde eine Buchse geliefert. Allerdings stimmen die PIN-Nummern im Schaltplan nicht mit den PIN-Nummern auf der Buchse überein (sie sind gespiegelt), daher liefen die Test-LEDs zunächst nicht.&lt;br /&gt;
&lt;br /&gt;
* Bausatz geliefert 11.7.2009. Spannungsregler LM317T fehlt, grüne statt roter LED. Ein Kondensator 22pF zu viel. LM317T wurde auf Anfrage kostenlos nachgeliefert (27.7.). Inbetriebnahme problemlos.&lt;br /&gt;
&lt;br /&gt;
* Bausatz geliefert 24.7.2009. Ein Quarz 16MHz zu viel, ebenfalls grüne statt rote LED.&lt;br /&gt;
&lt;br /&gt;
* Bausatz geliefert 20.08.2009. Ein Kondensator 22pF zuviel und grüne statt rote LED.&lt;br /&gt;
&lt;br /&gt;
* Bausatz Juli &#039;09 gekauft, grüne statt rote LED&lt;br /&gt;
&lt;br /&gt;
* Bausatz 25.09.09 geliefert, grüne Betriebs-LED, ein ELKO zuviel, Fehler 1µF am MAX232 statt 100nF behoben, richtiger C wird mitgeliefert, Aufbau komplett nach Pollin Anleitung durchgeführt, auf Anhieb fehlerfrei!&lt;br /&gt;
&lt;br /&gt;
* Bausatz 17.10.09 geliefert, grüne Betriebs-LED, zwei 100nF Kondensatoren zu wenig. Aufbau und Inbetriebnahme problemlos.&lt;br /&gt;
&lt;br /&gt;
* Bausatz 21.10.09 gekauft, grüne Betriebs-LED. Aufbau problemlos, RS232 läuft nicht. LAN läuft&lt;br /&gt;
&lt;br /&gt;
* Bausatz Nov. 09 gekauft, grüne LED, alles o.k.&lt;br /&gt;
&lt;br /&gt;
* Bausatz Nov. 09 gekauft, grüne LED, ENC28J60, MAX232 und ATmega32 fehlen, Nachlieferung nach einer Woche&lt;br /&gt;
&lt;br /&gt;
* Bausatz Nov. 09 gekauft,Bauteile komplett.Verbindungsaufbau Seriell klappt erst nach mehreren Versuchen.Problem gelöst:Spannung an MAX und Mega zu niedrig&lt;br /&gt;
&lt;br /&gt;
* Bausatz Dez. 09 gekauft, grüne LED, 100µF Kondensator fehlt, alles o.k.&lt;br /&gt;
&lt;br /&gt;
* Bausatz August 09 gekauft, alle teile da nach Einstellen der fusebits lief alles perfekt&lt;br /&gt;
&lt;br /&gt;
* Bausatz Okt. 09 gekauft, ein 100nF Kondensator und 25MHz Quarz fehlten ... hab beim lokalen Elektronikhändler keinen 25Mhz Grundton Quarz sondern nur im 3. Oberton bekommen aber mit R2.2k parallel zum Quarz schwingt er in der Schaltung schön bei 25Mhz. Mit 1µF am MAX232 funktioniert jetzt auch die RS232.&lt;br /&gt;
&lt;br /&gt;
* 2x Bausatz Feb. 10 gekauft, bei beiden fehlten 7805, L1+L2 je 100µH sowie 4x falscher Wert Kondensator an Max232 vorhanden. Fehlende Bauteile nachgelötet und Funktion getestet. Hat alles einwandfrei funktioniert!!!&lt;br /&gt;
&lt;br /&gt;
* Bausatz März. 10 gekauft, RS232 Printbuchse fehlt, dafür 1x 10pol Wannenstecker zuviel. Grüne LED statt Rot. Funktioniert ansonsten einwandfrei.&lt;br /&gt;
&lt;br /&gt;
* Bausatz Jan. 10 gekauft, gelbe LED statt rot, C14...C17: 10µF, weder seriell noch via Ethernet Konnektivität. Nach Austausch von C14-C17 gegen 1µF, wenigstens serielle Kontaktaufnahme möglich, kein Ethernet auch nach Flash von 1.03 mit NetServer.&lt;br /&gt;
&lt;br /&gt;
* Bausatz Feb. 10 gekauft, Spannungsregler LM317T fehlte&lt;br /&gt;
&lt;br /&gt;
* Bausatz März 10 gekauft, gelbe statt rote LED geliefert, aber Aufbau und inbetriebnahme lt. Handbuch ohne Probleme&lt;br /&gt;
&lt;br /&gt;
* Bausatz März 10 gekauft und gelbe statt rote LED geliefert, funzt wunderbar gemäß Anleitung&lt;br /&gt;
&lt;br /&gt;
* Fertig gelötete Platine gekauft. µC war falsch im Sockel.&lt;br /&gt;
&lt;br /&gt;
* Bausatz April 10 gekauft und gelbe statt rote LED geliefert, ADM232LJN statt MAX232 - Funktion erst nach Ersetzung des ADM durch nen MAX&lt;br /&gt;
&lt;br /&gt;
* Bausatz April 10 gekauft und gelbe statt rote LED geliefert, ADM232LJN statt MAX232 - funktionierte sofort auch mit dem ADM232LJN.&lt;br /&gt;
&lt;br /&gt;
* Bausatz April 10 gekauft wurde mit grüner statt roter LED Ausgeliefert&lt;br /&gt;
&lt;br /&gt;
* Bausatz Juni 10 gekauft: wurde mit grüner statt roter Netz-LED ausgeliefert, 2x 22pF Kerko zuviel&lt;br /&gt;
&lt;br /&gt;
* Bausatz August 10 gekauft: komplett und sofort funktioniert&lt;br /&gt;
&lt;br /&gt;
* Bausatz Juli 10 gekauft: 2 Quarze mit 16 MHz geliefert, statt 1x 16MHz und   1x25MHz.&lt;br /&gt;
&lt;br /&gt;
* Bausatz September 10 gekauft: hat sofort funktioniert. 1x 3,3k und 1x 10k Widerstand zuviel. Statt 100nF Kondensatoren wurden 1µF geliefert -&amp;gt; Platzprobleme auf der Platine durch grössere Bauform. LED grün.&lt;br /&gt;
&lt;br /&gt;
* Bausatz Oktober  6 gekauft: alles funktioniert. LED grün statt rot.&lt;br /&gt;
&lt;br /&gt;
* Fertigmodul Oktober 10 gekauft: Auf Anhieb alles funktioniert!&lt;br /&gt;
&lt;br /&gt;
* Bausatz Oktober 10 gekauft: komplett und sofort funktioniert&lt;br /&gt;
&lt;br /&gt;
* Bausatz November 10 gekauft: komplett und sofort funktioniert (sogar mit der neusten Pollin Firmware 1.03 schon drauf) LED grün statt rot.&lt;br /&gt;
&lt;br /&gt;
* Bausatz November 10 gekauft. Nach Bezug neuer Feinst-Lötspitzen konnte ich ihn dann auch zusammenlöten. Es hat sofort alles funktioniert, obwohl ich nur 12V bzw. 9V Gleichspannung zur Verfügung hatte, und nicht sicher war, wieviel die Komponenten wirklich benötigen. Der Regler wird auch bei 9V Gleichspannungsversorgung noch sehr warm. Da muss auf jeden Fall ein Kühlkörper dran! Ich habe auch eine grüne LED bekommen, ist mir aber wurscht :-)&lt;br /&gt;
&lt;br /&gt;
* Bausatz Dezember 10 gekauft: komplett und funktionierte sofort. Firmware 1.03, grüne LED (Ein Quarz und ein IC-Sockel zu viel)&lt;br /&gt;
&lt;br /&gt;
* Bausatz Januar 2011 gekauft: nur genau die richtige Anzahl Teile dabei, Firmware 1.03, grüne LED, ging auf Anhieb&lt;br /&gt;
&lt;br /&gt;
* 2x Bausatz Januar 2011 gekauft: beide grüne LED, und 1x doppelter Satz Jumper/Stiftleiste, 22PF und Anschlussklemmen. Rest vollständig und beide haben sofort nach zusammenbau funktioniert.&lt;br /&gt;
&lt;br /&gt;
* Februar 2011: AVR-NET-IO: die Diode D5 fehlt, 10 µF gegen 1 µF für MAX232 getauscht, Flash im ATmega32 war programmiert, passende IP-Adr über serielle Schnittstelle eingestellt; ADD-ON: für R1 war 22Ω statt 0,2Ω beigelegt, durch richtigen ersetzt, Beschreibung der LED Bestückung mangelhaft / oe1smc&lt;br /&gt;
&lt;br /&gt;
* Februar 2011: AVR-NET-IO: 1 Diode zuviel, 2 Spulen fehlen, LED grün. Die fehlenden Spulen wurden durch welche aus der Bastelkiste ersetzt - funktioniert. Der 7805 bekam einen kleinen Kühlkörper spendiert.&lt;br /&gt;
&lt;br /&gt;
* Februar 2011: AVR-NET-IO: 2x 10k Widerstände fehlen. Dafür eine Diode zu viel.&lt;br /&gt;
&lt;br /&gt;
* Ende Februar 2011: Zwei Bausaetze an jeweils zwei Adressen, alles in Ordnung.&lt;br /&gt;
&lt;br /&gt;
* Ende März 2011: 2x 25 Mhz Quarz statt 1x16 u. 1x25 Mhz. LED fehlt. Bausatz funktioniert nach Tausch des Quarz den mir mein Freund oe9rsv aus seinem Fundus spendiert hat. Danke auch für die Hilfe beim Fehler suchen.&lt;br /&gt;
&lt;br /&gt;
* Mitte 2010 gekauft: 1x 100nF fehlt&lt;br /&gt;
&lt;br /&gt;
* Mitte Juni 2011: Beide Quarze fehlen und beide Spannungsregler fehlen, Pollin wollte, dass ich das ganze Paket zurückschicke für einen Austausch. Ein 51Ω zu viel. 16Mhz im Handel und 25Mhz vom alten Mobo ausgelötet. Läuft wunderbar.&lt;br /&gt;
&lt;br /&gt;
* Anfang Juni 2011: Beide Quarze fehlen und beide Spannungsregler fehlen, nach kurzer Mail an Pollin (leider ohne Antwort) wurden diese nach ca. 1 Woche in einem Brief nachgeliefert.&lt;br /&gt;
&lt;br /&gt;
* August 2011: alles 1a...&lt;br /&gt;
&lt;br /&gt;
* August 2011: Platine fehlte -&amp;gt; in Nachlieferung&lt;br /&gt;
&lt;br /&gt;
* 30 August 2011: alles 1a...&lt;br /&gt;
&lt;br /&gt;
* 06 Sep. 2011: alles 1a...&lt;br /&gt;
&lt;br /&gt;
* August 2011: 6 Stück bestellt, bei einem haben die 100nF Kondensatoren gefehlt, bei einem zwei LM317 statt 7805 und LM317. Angerufen, 3 Tage später Nachlieferung erhalten.&lt;br /&gt;
&lt;br /&gt;
* Nov. 2011: &#039;&#039;&#039;Net_IO&#039;&#039;&#039; vollständig. Einspielen der Firmware 1.03 war erforderlich. Bei &#039;&#039;&#039;Add-On&#039;&#039;&#039; immer noch falscher Q1 BC548 (NPN) in Stückliste und Lieferung. BC327-40 oder BC328-40 (PNP) nachgefordert. R11 und R24 mitgeliefert, entsprechend Beschreibung V1.1 von Pollin&#039;s Download. Beiliegende Beschreibung war älter, ohne diese Widerstände.&lt;br /&gt;
&lt;br /&gt;
* Ende Nov.2011, alle Teile dabei, Firmware war drauf, sofort funktioniert.&lt;br /&gt;
&lt;br /&gt;
* Anfang Dez.2011, komplett bestückte Platine gekauft. Auf 7805 Kühlkörper gebaut, da er nach 1 Minute schon ausgestiegen ist (LED hat das Pumpen angefangen). Firmware 1.03 musste noch aufgespielt werden danach funktioniert alles einwandfrei. In Betrieb mit 10V DC&lt;br /&gt;
&lt;br /&gt;
* Ende Dez.2011 2xNET-IO und 2xADD bestellt, 4 verschieden volle Kisten bekommen... WSL16 ist mit Verriegelung, geht nicht aufs Board, Jumper fehlen, Spannungsregler doppelt, Poti Löcher zu klein, lsb3 fehlt, SD-Slot hab ich jetzt 3, 100nF hab ich jetzt 4 übrig ... also immer noch lustig. HW-Stand immer noch 1.0 ( gab es überhaupt eine 1.1?)&lt;br /&gt;
&lt;br /&gt;
* Mitte Jan. 2012, 10pol. beide Wannenstecker nicht dabei, Firmware war drauf, sofort funktioniert. 1 LED zuviel. Unproblematische Nachlieferung bei Reklamation (wegen der beiden Wannenstecker kam ein PAKET!).&lt;br /&gt;
&lt;br /&gt;
* Ende Feb. 2012, Um die PHP-Scripte über öffentlichen Webserver zu betreiben muss mit SETGW die Gateway-Adresse des lokalen Routers eingetragen werden. Bei der NAT im Router sollte z.B. Port 8080 auf den internen Port 50290 umgeleitet werden, da manche Provider diesen Port für die Socket-Kommunikation nicht zulassen.&lt;br /&gt;
&lt;br /&gt;
* Juli 2012, Bausatz vollständig, Nach Aufbau sofort den 7805 mit einem kleinen Kühlkörper versehen, da er sonst thermisch überlastet wird! hat weder auf LAN noch RS232 reagiert, musste erst Update einspielen (Download Pollin), danach funktionierte alles einwandfrei!&lt;br /&gt;
&lt;br /&gt;
* Januar 2013, Bausatz vollständig, 7805 mit Kühlkörper versehen, nach Aufbau ohne Probleme funktioniert&lt;br /&gt;
&lt;br /&gt;
* Februar 2013, Bausatz komplett, Aufbau ohne Probleme, 7805 nur leicht warm, LAN funktioniert, RS232 noch ohne Funktion.&lt;br /&gt;
&lt;br /&gt;
* Oktober 2013, Bausatz komplett laut Stückliste, problemloser Aufbau, 7805 leicht warm am 10V DC. RS232 und LAN funktionierten auf Anhieb.&lt;br /&gt;
&lt;br /&gt;
* Januar 2014, Bausatz komplett, Aufbau ohne Probleme, Betrieb mit 9V DC, LAN funktioniert auf Anhieb, RS232 noch nicht getestet.&lt;br /&gt;
&lt;br /&gt;
* März 2014, Komplettgerät, von ca. 100 Versuchen gerade mal 2 erfolgreiche Zugänge. Weder LAN noch RS232 mit Putty funktionierten.&lt;br /&gt;
&lt;br /&gt;
=== Erweiterungsplatine ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die nachfolgend genannten Änderungen sind in der Bauanleitung V1.1 mit Stand 07.12.2011 (Wichtig! Es gibt mehr als eine V1.1 ...) bereits berücksichtigt, R3 wird allerdings mit 3,6kΩ angegeben.&lt;br /&gt;
&lt;br /&gt;
Um bei einem Neuaufbau parallele Widerstände zu vermeiden, sollten folgende Änderungen auf dem Addon-Board gemacht werden:&lt;br /&gt;
*R2 1,5kΩ ersetzen mit 2kΩ&lt;br /&gt;
*R3 1,8K ersetzen mit 3,3kΩ&lt;br /&gt;
*R19 470kΩ ersetzen zu 470Ω&lt;br /&gt;
*Q1 BC548 ersetzen durch BC327 oder BC328 (Hauptsache PNP! und mehr als 100mA)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACHTUNG&#039;&#039;&#039; beim Anschluß eines LC-Displays an J5 (über I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C, PCF 8574): Vcc/5V liegt an Pin 1, GND an Pin 2 von J5. Es gibt etliche Displays mit abweichender Belegung Pin 1 GND und Pin 2 Vcc!&lt;br /&gt;
&lt;br /&gt;
Auch beim Add-On gibt es fehlende oder falsche Bauteile im Bausatz und Fehler im Schaltplan und auf der Platine:&lt;br /&gt;
&lt;br /&gt;
*Stand Feb. 2011: R2 wird mit 2,2kΩ und R3 wird mit 3,6kΩ ausgeliefert. Somit werden die 3,3 V richtig erzeugt. R19 hat 470Ω. Der ISP-Anschluß ist nicht vollständig durchgeschleift, es besteht keine Verbindung der RESET-Leitung zwischen ISP und ISP1 (Abhilfe: Drahtbrücke einlöten, [http://www.mikrocontroller.net/topic/161354#1600385 Quelle]). &lt;br /&gt;
&lt;br /&gt;
*Stand Nov. 2011: bei mir ist die RESET-Leitung korrekt zw. ISP und ISP1 verbunden. Es gibt jetzt auch einen R24 (470Ohm) und R11 (1KOhm), der in der bei mir mitgelieferten Bauanleitung fehlt, in der zum Download (V1.1) angebotenen  aber drin steht. Es wird immer noch der falsche Q1 BC548C (NPN) mitgeliefert. Das Schaltsymbol für einen PNP ist richtig im Schaltplan gezeichnet.&lt;br /&gt;
&lt;br /&gt;
*Stand Dez. 2011: R24 (470Ω) kann mit 0Ω ersetzt und R11 (1kΩ) völlig weggelassen werden. Diese Widerstände bilden einen (eigentlich überflüssigen) Spannungsteiler in der MISO Leitung. Der Spannungsteiler hat allerdings auch eine Schutzfunktion, falls weitere Slaves am SPI-Bus hängen, die 5V-Pegel nutzen, z. B. ISP-Programmierer. (siehe [http://son.ffdf-clan.de/include.php?path=forumsthread&amp;amp;threadid=1167&amp;amp;postid=9203 1284p: Board, ich oder beide verwirrt?])&lt;br /&gt;
&lt;br /&gt;
*Sept&#039;12: Bausatz mit Stecker anstelle einer Buchse ausgeliefert, 5mm anstelle von 3mm LED&#039;s dafür aber 3 Poti zuviel.&lt;br /&gt;
&lt;br /&gt;
*Sept&#039;12: Ebenfalls Bausatz mit Sub-D-Stecker statt Buchse ausgeliefert, 5mm anstelle von 3mm LED&#039;s und 3 Potis zuviel.&lt;br /&gt;
&lt;br /&gt;
*Stand März 2013: Die Belegung der 25 pol. Sub-D-Buchse im Schaltplan der Anleitung V1.1 (und früher) ist falsch dargestellt. SCL und SDA des I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C-Busses liegen wie beim AVR-NET-IO Board auf Pin 2 bzw. 3 und nicht auf Pin 11 bzw. 12 der Buchse. Ein 1:1 verdrahtetes Kabel funktioniert.&lt;br /&gt;
&lt;br /&gt;
== Andere Software für den Client-PC ==&lt;br /&gt;
=== NetIOLib ===&lt;br /&gt;
&lt;br /&gt;
In C# geschriebene Bibliothek zur Ansteuerung der Platine im Orginalzustand. Inkl. Beispielsoftware und Quellcode (GNU GPL) &lt;br /&gt;
&lt;br /&gt;
Links gehen nicht:&lt;br /&gt;
DLL: [http://www.tware.org/downloads/NetIOLib_dll.zip Download-Link]&lt;br /&gt;
Source: [http://www.tware.org/downloads/NetIOLib_src.zip Download-Link]&lt;br /&gt;
&lt;br /&gt;
=== E2000-NET-IO-Multi-Control ===&lt;br /&gt;
Mti dem E2000-NET-IO-Multi-Control ist es möglich, die vom dem E2000-NET-IO-Designer erstellten Projekte zu öffnen und die AVR-NET-IO&#039;s zu steuern. &lt;br /&gt;
&lt;br /&gt;
Die Anwendung liegt dem [http://www.mikrocontroller.net/articles/AVR_Net-IO_Bausatz_von_Pollin#E2000-NET-IO-Designer_.28Windows.5BXP.2F7.5D_.2F_Android.29 E2000-NET-IO-Designer] bei.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ControlIO ===&lt;br /&gt;
Einfache Bibliothek zur Ansteuerung mit Originalfirmware.&lt;br /&gt;
http://www.mikrocontroller.net/topic/149695&lt;br /&gt;
&lt;br /&gt;
=== JAVA Lib ===&lt;br /&gt;
Einfache Java-Bibliothek zur Ansteuerung mit Originalfirmware.&lt;br /&gt;
http://son.ffdf-clan.de/?path=forumsthread&amp;amp;threadid=611&lt;br /&gt;
&lt;br /&gt;
=== PHP ===&lt;br /&gt;
PHP Klasse zur Ansteuerung mit der Originalfirmware. (Opensource Lizenz)&lt;br /&gt;
http://blog.coldtobi.de/1_coldtobis_blog/archive/298_pollin_net-io_php_library.html&lt;br /&gt;
&lt;br /&gt;
PHP Funktionen zum Ansteuern der Originalfirmware. (Free for All Lizenz)&lt;br /&gt;
http://defcon-cc.dyndns.org/wiki/index.php/Pollin_AVR-NetIO_PHP_Wrapper&lt;br /&gt;
&lt;br /&gt;
== Clients für Smartphones ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== AVR NET IO Control (Windows Phone 7.5,7.8,8.0) ===&lt;br /&gt;
&lt;br /&gt;
Freie App zur steuerung des AVR NET IO.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;App im Market: [http://www.windowsphone.com/de-de/store/app/avr-net-io-controll/030d107f-9a27-4a62-ac8f-cb74e79c0500 AVR NET IO Control]&#039;&#039;&#039;&lt;br /&gt;
=== App NetIO (Windows Mobile 6.5) ===&lt;br /&gt;
Frei verfügbare App für Windows Mobile zur Ansteuerung mit der Orginalsoftware. Das HTC HD2 wird damit zur Fernsteuerung für das AVR Net-IO Board.&lt;br /&gt;
http://www.heesch.net/netio.aspx&lt;br /&gt;
&lt;br /&gt;
=== NET-IO Control (Android) ===&lt;br /&gt;
Eine Application für das Android Betriebssystem zur Steuerung des AVR Net-IO Boards. Es ist möglich, alle Ausgänge zu steuern und alle Eingänge anzuzeigen. Die Analogen Eingänge können mit einem Berechnungsfaktor versehen werden. &#039;&#039;Geplant ist noch ein Offsetwert.&#039;&#039; Außerdem kann jedem analogen Wert eine Einheit zugeordnet werden. Die Ausgänge können in der neusten Version in einen Tastermodus gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
[[Datei:NET-IO-Control.png|200px]] [[Datei:NET-IO-Control2.png|200px]] [[Datei:NET-IO-Control3.png|200px]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Trial-Version: [https://play.google.com/store/apps/details?id=de.android.AVR.NETIOControlTRAIL Google-Play]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
(In dieser Probe Version können nur 1 Output und 2 Inputs gesteuert werden)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vollversion: [https://play.google.com/store/apps/details?id=de.android.AVR.NETIOControl Google-Play]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
(Kostet im Google-Play 3,00 €)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Weitere Informationen sind auf der Entwickler-Seite zu finden:  [http://elektronik2000.de/ Elektronik2000.de]&lt;br /&gt;
&lt;br /&gt;
=== E2000-NET-IO-Designer (Windows[XP/7] / Android) ===&lt;br /&gt;
[[Datei:E2000-NET-IO-Designer.png|400px|right]]&lt;br /&gt;
Mit dem E2000-NET-IO-Designer ist es möglich, eine grafische Oberfläche für die NET-IOs von Pollin zu erstellen. Dafür werden Knöpfe, Texte und Anzeigebilder zur Verfügung gestellt. Jedes dieser Element kann &amp;quot;Aufgaben&amp;quot; übernehmen um die NET-IOs zu steuern oder einen Status des NET-IO anzuzeigen. Weitere Icons können von dem Benutzer selbst in den entsprechenden Ordner gelegt werden und in die Oberfläche eingebunden werden. Es können mehrere Seiten designt werden die durch einen selbst positionierten Knopf erreichbar sind. Die Android Application arbeitet somit im Fullscreen-Modus. Des weiteren ist es möglich, mehrere NET-IO&#039;s in einem Projekt zu benutzen. Nach dem erstellen der grafischen Oberfläche mit dem E2000-NET-IO-Designer, kann mit der Android APP das Projekt einfach gedownloaded werden. Dafür baut die APP eine Verbindung zum E2000-NET-IO-Designer auf und läd alle benötigten Dateien herunter (Achtung: Firewall-Einstellungen beachten). Die designten Oberflächen können außerdem noch mit der E2000-NET-IO-Multi-Control.exe auf dem Computer ausgeführt werden. Dadurch ist es Möglich, seine NET-IOs vom PC aus zu steuern über eine selbst designte Oberfläche. &lt;br /&gt;
&lt;br /&gt;
Zum Ausführen des E2000-NET-IO-Designer muss .NET Framework 4.0 installiert sein und es muss eine Internetverbindung exisitieren.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features:&#039;&#039;&#039;&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Grafische Oberfläche am PC erstellen&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Verwendung von eigenen Button- und Hintergrundbildern&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Designbare Anzeige von Digital- und Analogwerten&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Steuern von mehreren AVR-NET-IO Boards&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Unterstützung der E2000-NET-IO Firmware (mehere Boards gleichzeitig)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Designte Steuerungen können auf dem PC oder dem Handy ausgeführt werden (Android)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Schnelle Verbindung&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Einfache übertragung auf das Handy durch Projekt Download&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://www.elektronik2000.de/downloads.php?id=44 Download E2000-NET-IO-Designer]&lt;br /&gt;
&lt;br /&gt;
[http://www.elektronik2000.de/hilfe/E2000Netdesigneruebersicht.html Online Hilfe]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Weitere Informationen sind auf der Entwickler-Seite zu finden:  [http://elektronik2000.de/ Elektronik2000.de]&lt;br /&gt;
&lt;br /&gt;
=== NetIO ( iPhone &amp;amp; Android ) ===&lt;br /&gt;
&amp;lt;div style=&amp;quot;float: left; margin-right: 20px&amp;quot;&amp;gt;[[Datei:Netio_logo.png|70px]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Schöne universelle Fernbedienung für das Board (iOS / Android). Konfigurierbar über einen Browserbasierten Editor. &amp;lt;br&amp;gt;&lt;br /&gt;
Unterstützt TCP socket Verbindungen, kann http request absetzen und kann auch Webseiten einbinden (z.B. IP-Kameras). Kann mehrere &lt;br /&gt;
Boards gleichzeitig steuern! Einfach super schnell ins Projekt eingebaut... Es gibt Buttons (die auch als Taster konfiguriert werden können), Slider, Switches und einfache Labels. Dinge können geschaltet oder Daten ausgelesen und mit regex dargstellt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&#039;float: right&#039;&amp;gt;&lt;br /&gt;
[[Datei:Netio_TV.png|190px]]&lt;br /&gt;
[[Datei:Netio_iphone5.png|190px]]&lt;br /&gt;
[[Datei:NetIO_appflow.jpg|190px]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
AppStore Link: http://itunes.apple.com/app/netio/id464924297?mt=8 &amp;lt;br/&amp;gt;&lt;br /&gt;
Google Play Link: https://play.google.com/store/apps/details?id=com.luvago.netio &amp;lt;br/&amp;gt;&lt;br /&gt;
Die gleiche Konfiguration kann auch mit einem [https://github.com/davideickhoff/NetIO-OSX-Dashboard-Widget OSX Widget] benutzt werden. &amp;lt;br/&amp;gt;&lt;br /&gt;
Webseite: http://netio.davideickhoff.de &lt;br /&gt;
&lt;br /&gt;
Hinweis: &amp;lt;br&amp;gt; Man findet es unter &amp;quot;NetIO&amp;quot; im Store, im Icon selbst und in iTunes wird es als &amp;quot;Controller&amp;quot; angezeigt. &amp;lt;br&amp;gt;&lt;br /&gt;
Die eigene Konfiguration kann man mit dem [http://netio.davideickhoff.de/editor Online Editor] vorher am PC erstellen.&lt;br /&gt;
Eine fertige [http://netio.davideickhoff.de/editor/?config=pollin AVR-NET-IO Konfiguration] gibt es als funktionierendes Beispiel schon als Preset.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;div style=&#039;clear: both&#039;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== AVR Net IO (iPhone) ===&lt;br /&gt;
[[Datei:AVRNetIO-Screenshot1.png|160px|rechts]]&lt;br /&gt;
Update 15.12.2011: Die Neue Version 1.3 ist seit gestern im AppStore. Fehlerkorrekturen und ein robusteres Handling machen die App nun zur universellen AVR-Net-IO-Steuerung.&lt;br /&gt;
&lt;br /&gt;
Mit der [http://itunes.apple.com/de/app/avr-net-io/id460991760?mt=8 iPhone App AVR-Net-IO] kann das Board ferngesteuert werden. Die Fernsteuerung umfasst in der Version 1.1 folgende Funktionen:&amp;lt;br&amp;gt;&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;ADC-Werte zyklisch auslesen und darstellen&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Digital-Inputs zyklisch darstellen&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Digital-Outputs können über Buttons geschaltet werden. Die Werte der Digital-Outputs werden zuerst ausgelesen und zeigen den zuletzt gesetzten Wert an.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Terminal-Modus: Hier können beliebige AVR-Net-IO-Befehle eingegeben werden. Das Ergebnis wird 1:1 angezeigt, wie es vom Board kommt. Hilfreich für Tests bei Eigenentwicklungen und Konfigurationen.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Mehr Infos gibt&#039;s dazu direkt von den Entwicklern auf [http://www.facebook.com/pages/AVR-Net-IO/187799687958255?ref=nf AVR-net-IO Facebook-Page] oder direkt auf deren Homepage [http://www.ondics.de/apps/1001/ Homepage].&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Hinweis: MIt der aktuellen Version 1.1 gibt es noch bei manchen Boards Probleme beim auslesen und anzeigen der ADC- und Digital-Werte. Das Terminal funzt problemlos. Die Entwickler kümmern sich gerade drum und haben einen baldigen Update versprochen.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Andere Software statt der Originalsoftware von Pollin ==&lt;br /&gt;
&lt;br /&gt;
Die Umrüstung auf einen Webserver durch Austausch der Software (und ev. des ATmega32) bietet sich an. Kleiner Hinweis dabei: wenn zum Flashen ein ISP-Adapter verwendet wird, diesen unbedingt vor dem Start der neuen Software abziehen! Der ISP arbeitet nämlich über dieselbe SPI-Schnittstelle über die auch der ENC28J60 angesteuert wird. Ein eventuell noch angeschlossener, wenn auch passiver ISP-Adapter stört diese Kommunikation, d.h. das Programm an sich scheint zu laufen, aber die Ethernet-Schnittstelle funktioniert nicht.&lt;br /&gt;
&lt;br /&gt;
=== E2000 - Logik ===&lt;br /&gt;
&lt;br /&gt;
[[Datei:E2000-Logik-Bedienoberflaeche.jpg|500px|rechts]]&lt;br /&gt;
&lt;br /&gt;
Anwenderfreundliche Logik-Software von Elektronik2000.de zur Steuerung des AVR-NET-IO. Der ATMEGA32 wird durch einen ATMEGA644 ersetzt und mit der E2000-Firmware beschrieben. Nun ist es möglich in der E2000-Logik Software eine Logikschaltung zu erstellen und diese auf das NET-IO-Board zu übertragen. Dort wird diese Schaltung simuliert. Dies funktioniert komplett ohne einen Computer.&lt;br /&gt;
&lt;br /&gt;
Durch ein Erweiterungsboard von Elektronik2000.de ist es auch möglich, das Board ohne Internet laufen zu lassen eine RTC (RealTimeClock) übernimmt dabei die Uhrzeitgesteuerten Funktionen. Auf dieser Erweiterung ist auch ein EEPROM integriert, um Firmware-Updates über Netzwerk einzuspielen (in Zukunft). Diese Erweiterung bietet außerdem die Anbindung an das E2000-Bus-System, durch das es möglich ist das AVR-NET-IO-Board durch weitere Ein- und Ausgänge zu erweitern.&lt;br /&gt;
&lt;br /&gt;
Das Designen von Schaltaufgaben wird in diesem Programm grafisch dargestellt, durch das ein einfaches Anpassen seiner Logikschaltungen möglich ist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Eine Steuerung des E2000-NET-IO ist möglich durch den Intregrieten Webserver, die PC-Software (E2000-NET-IO Control) oder der Androidsoftware. All diese Können gleichzeitig auf das E2000-NET-IO zugreifen und Funktionen ausführen. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Weitere Informationen gibt es auf der Entwicklerseite: [http://www.elektronik2000.de Elektronik2000.de]&lt;br /&gt;
&lt;br /&gt;
=== Bascom Version von Hütti ===&lt;br /&gt;
&lt;br /&gt;
(Quelle: http://bascom-forum.de/index.php/topic,1781.45.html )&lt;br /&gt;
dort am Ende der Seite.&lt;br /&gt;
&lt;br /&gt;
=== Ben&#039;s Bascom Quellcode ===&lt;br /&gt;
&lt;br /&gt;
(Quelle: http://members.home.nl/bzijlstra/software/examples/enc28j60.htm )&lt;br /&gt;
&lt;br /&gt;
Muss aber für Bascom 1.11.9.3 angepasst werden, siehe Code von Hütti !&lt;br /&gt;
&lt;br /&gt;
=== U. Radigs Webserver ===&lt;br /&gt;
&lt;br /&gt;
Angepasster Sourcecode von U.Radig: http://www.mikrocontroller.net/attachment/40027/Webserver_MEGA32.hex&lt;br /&gt;
oder selbst anpassen: &lt;br /&gt;
Ändere in der Datei ENC28J60.H:&lt;br /&gt;
 #define ENC28J60_PIN_CS    4&lt;br /&gt;
(Quelle: http://www.mikrocontroller.net/topic/109988#988386)&lt;br /&gt;
&lt;br /&gt;
Temporären Dateien (*.d, *,lst,*.o) vorher im Verzeichnis löschen &#039;&#039;make clean&#039;&#039;, damit neu compiliert wird.&lt;br /&gt;
&lt;br /&gt;
IP: 192.168.0.99&amp;lt;br&amp;gt;&lt;br /&gt;
User: admin&amp;lt;br&amp;gt;&lt;br /&gt;
Pass: uli1&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den orginal SourceCode gibt&#039;s übrigens hier:http://www.ulrichradig.de/home/index.php/avr/eth_m32_ex&lt;br /&gt;
&lt;br /&gt;
Bei den Fuses BOOTRST ausschalten, da die Software keinen Bootloader enthält.&lt;br /&gt;
&lt;br /&gt;
IP: 192.168.1.90&amp;lt;br&amp;gt;&lt;br /&gt;
User: admin&amp;lt;br&amp;gt;&lt;br /&gt;
Pass: tim&amp;lt;br&amp;gt;&lt;br /&gt;
Test: http://beitz-online.dyndns.org&amp;lt;br&amp;gt;&lt;br /&gt;
Test: http://pieper-online.dyndns.org&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weiterentwicklung des Radig-Codes von RoBue: &amp;lt;br&amp;gt;&lt;br /&gt;
- 1-Wire-Unterstützung (Anschlus an PORTA7) &amp;lt;br&amp;gt;&lt;br /&gt;
- PORTA0-3 digitaler Eingang (ein/aus) &amp;lt;br&amp;gt;&lt;br /&gt;
- PORTA4-6 analoger Eingang (0 - 1023) &amp;lt;br&amp;gt;&lt;br /&gt;
- LCD an PORTC &amp;lt;br&amp;gt;&lt;br /&gt;
- Schalten in Abhängigkeit von Temperatur und analogem Wert &amp;lt;br&amp;gt;&lt;br /&gt;
- (Teilweise) Administration über Weboberfläche &amp;lt;br&amp;gt;&lt;br /&gt;
- Erweiterung des cmd-Befehlsatzes für telnet/rs232 &amp;lt;br&amp;gt;&lt;br /&gt;
Gedacht ist der Einsatz des AVR-NET-IO-Bausatzes für Heizungs- oder Haussteuerung) &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test: http://avrboard.eluhost.de/&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Quelle:&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.mikrocontroller.net/attachment/43307/AVR-NET-IO_RoBue_V1.3.zip&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.mikrocontroller.net/attachment/44569/AVR-NET-IO_RoBue_V1.4.zip&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.mikrocontroller.net/attachment/46720/AVR-NET-IO_RoBue_1.5-final_hoffentlich_.zip)&lt;br /&gt;
&lt;br /&gt;
Bei der Ver 1.5 sind die Ports PD2+3 fürs 4bit LCD (Ext.) vertauscht ! Gruß B.P&lt;br /&gt;
&lt;br /&gt;
=== Simon Ks Webserver (uip-Stack) ===&lt;br /&gt;
Angepasster Sourcecode von Simon K: http://www.mikrocontroller.net/attachment/39939/uWebSrv.zip&lt;br /&gt;
IP: 192.168.0.93:8080&amp;lt;br&amp;gt;&lt;br /&gt;
Um diesen Code mit einem Atmega1284P verwenden zu können, muss in der main.c in Zeile 38, &amp;quot;TIMSK&amp;quot; durch &amp;quot;TIMSK1&amp;quot; ersetzt werden.&lt;br /&gt;
Die Fusebits für den Atmega1284p ohne Bootloader sind:&lt;br /&gt;
lfuse=0xFF, hfuse=0xD9, efuse=0xFF&lt;br /&gt;
&lt;br /&gt;
=== Ethersex Server ===&lt;br /&gt;
&lt;br /&gt;
http://www.ethersex.de - Einfach für atmega32 compilieren und funktioniert.&lt;br /&gt;
&lt;br /&gt;
=== Etherrape Server ===&lt;br /&gt;
&lt;br /&gt;
http://www.lochraster.org/etherrape/ &lt;br /&gt;
&lt;br /&gt;
ist in jedem Fall hier auch zu erwähnen zumal es sich beim etherrape um das Ursprungsprojekt von ethersex handelt.&lt;br /&gt;
Es scheint aber bei der Weiterentwicklung wenig zu passieren.&lt;br /&gt;
Ausführliche Dokumentation findet sich unter http://wiki.lochraster.org/wiki/Etherrape&lt;br /&gt;
&lt;br /&gt;
=== Mini SRCP Server (kommerziell, Closed-Source)===&lt;br /&gt;
&lt;br /&gt;
Damit wird die Platine zu einer Modellbahnsteuerung, die&lt;br /&gt;
über das Netzwerkprotokoll SRCP mit verschiedenen Programmen&lt;br /&gt;
gesteuert werden kann.&lt;br /&gt;
&lt;br /&gt;
[http://www.7soft.de/de/mini_srcp_server/index.html Infoseite] zur Hardware&lt;br /&gt;
und das zugrundeliegende [http://www.der-moba.de/index.php/Digitalprojekt Digitalprojekt].&lt;br /&gt;
&lt;br /&gt;
=== Avr ArtNET-Node ===&lt;br /&gt;
&lt;br /&gt;
Hiermit kann die Platine zu einem Art-Net Node werden, mit dem sich ein DMX-Universe über Ethernet übertragen lässt. Basiert auf den Quellen von Ulrich Radig.&lt;br /&gt;
&lt;br /&gt;
Dokumentation: [http://www.dmxcontrol.de/wiki/Art-Net-Node_f%C3%BCr_25_Euro Art-Net-Node für 25 Euro]&lt;br /&gt;
&lt;br /&gt;
=== Webserver von G. Menke ===&lt;br /&gt;
&lt;br /&gt;
Ein Webserver (basierend auf den Sourcen von U. Radig), der so angepasst ist, dass alle Ein- und Ausgänge wie bei der originalen Pollin-Software genutzt werden können (8xDIGOUT, 4xDIGIN, 4xADIN). Der Webserver kann daher direkt auf das Net-IO geladen werden. Im ZIP-File sind ein ReadMe und alle C-Sourcen enthalten.&amp;lt;br&amp;gt;&amp;lt;i&amp;gt;Download&amp;lt;/i&amp;gt;:&lt;br /&gt;
[http://gm.stream-center.de/webserver/ Webserver mit passender IO]&lt;br /&gt;
&lt;br /&gt;
=== OpenMCP === &lt;br /&gt;
&#039;&#039;&#039;(Projekt scheint erloschen - Links all down - Jan. 2014)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Tolles Projekt, welches viele Features bietet und stabil läuft. Hervorzuheben ist die Übersichtlichkeit der Programmteile/Module und die vielleicht nicht ganz komplette Dokumentation. Man merkt, dass viel Arbeit und Liebe in diesem Projekt steckt. Herausgekommen ist dabei eine einfach zu handhabende Entwicklungsumgebung. Anfänger können, dank des gut durchdachten CGI-Systems, welches sich um alle wichtigen Sachen kümmert, leicht eigene CGI implementieren. Alle Ausgaben erfolgen nur mit printf über die Standardausgabe und werden automatisch richtig per Netzwerk übertragen, dadurch ist es auch für den Anfänger recht gut geeignet, da man sich nicht mit der Netzwerkprogrammierung auseinander setzen muss.&lt;br /&gt;
&lt;br /&gt;
Die Software belegt im Moment (Stand Juli 2010) ca. 55 Kb im Flash, so dass man das Board mit einem grösseren µC (z.B. ATMega644) aufrüsten muss.&lt;br /&gt;
&lt;br /&gt;
[http://wiki.neo-guerillaz.de Projekt und Doku]&lt;br /&gt;
&lt;br /&gt;
Der Autor stellt zwei über das Internet erreichbare Testboards bereit unter http://www.neo-guerillaz.de:81 und http://www.neo-guerillaz.de:82 die beide unter OpenMCP laufen, je auf einen AVR-NETIO mit einem ATmega644 und dem eigentlichen Board mit einem ATmega2561. Zusätzlich ist gerade eine Version für das myAVR in Arbeit die schon ordentlich Fortschritte macht.&lt;br /&gt;
&lt;br /&gt;
=== OpenMLP ===&lt;br /&gt;
Auf openMCP basierender Port nach [http://avr.myluna.de LunaAVR] (GPL). Umfangreiche Funktionalität und direkte Anpassung an die Sprache. Abgespeckte Version auch auf Atmega32 lauffähig. Die Original-Dokumentation kann zum Großteil hergenommen werden. Einige Zusatzfeatures. Leichte Konfiguration und guter Einstieg für Anfänger und zum Verständnis der Serverfunktionalität.&lt;br /&gt;
&lt;br /&gt;
[http://avr.myluna.de/doku.php?id=de:openmlp Artikelseite]&lt;br /&gt;
[http://forum.myluna.de/viewtopic.php?f=8&amp;amp;t=13 Forum]&lt;br /&gt;
&lt;br /&gt;
=== ENC28J60 I/O-Webserver von Thomas Heldt ===&lt;br /&gt;
&lt;br /&gt;
Ein Modul-Webserver (Softwarekompatibel zum Pollin Webserver), der durch div. Module erweitert werden kann, Software in Bascom basierend auf dem Code von Ben Zijlsta wurde erweitert und angepasst:&lt;br /&gt;
&lt;br /&gt;
[http://mikrocontroller.heldt.eu/index.php?page=enc28j60-io-webserver Projekt und Software]&lt;br /&gt;
&lt;br /&gt;
=== AVR-Netino ===&lt;br /&gt;
[http://code.google.com/p/avr-netino/ Projekt und Software]&lt;br /&gt;
&lt;br /&gt;
Arduino fürs Net-IO&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* Diskussion zu diesem Projekt: http://www.mikrocontroller.net/topic/109988&lt;br /&gt;
* [http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en022889 ENC28J60 Produktseite]&lt;br /&gt;
* [http://ww1.microchip.com/downloads/en/DeviceDoc/39662c.pdf ENC28J60 Datenblatt(pdf)]&lt;br /&gt;
* [http://son.ffdf-clan.de Forum für AVR-Net-IO]&lt;br /&gt;
* [http://avr.myluna.de/doku.php?id=de:openmlp LunaAVR openMLP ]&lt;br /&gt;
* [http://bascom-forum.de/index.php/topic,1781.0.html Bascom Forum ]&lt;br /&gt;
* [http://hobbyelektronik.org/w/index.php/AVR-NET-IO-Shield Shield für den NET-IO]&lt;br /&gt;
&lt;br /&gt;
[[Category:AVR-Boards]]&lt;br /&gt;
[[Category:Ethernet|P]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=RGB_Touch_Matrix&amp;diff=83317</id>
		<title>RGB Touch Matrix</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=RGB_Touch_Matrix&amp;diff=83317"/>
		<updated>2014-06-12T01:18:36Z</updated>

		<summary type="html">&lt;p&gt;Maybee: /* Siehe auch */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Conny G.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es soll eine RGB Touch Matrix entwickelt werden, die z.B. für RGB-Touch-Tische eingesetzt werden kann.&lt;br /&gt;
Beispiel für einen Touch-Tisch: http://www.it-gecko.de/100pixel-rgb-led-tisch-interaktiv-touch.html &lt;br /&gt;
Dieser ist jedoch vom Hardware-Konzept sehr aufwändig gelöst, deshalb ist das Ziel des Projekts als Kern der Lösung zwei Dinge möglichst effizient zu lösen:&lt;br /&gt;
* die einzelnen RGB &amp;amp; Touch Pixel&lt;br /&gt;
* die Verbindung der Pixel auf Basis eines Busses&lt;br /&gt;
Effizient heisst: geringe Bauteilkosten, einfache Herstellung der Pixel und einfach Verkabelung, idealerweise nur ein Bus von 1-2 Leitungen (zzgl. GND).&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Eine RGB-Touch-Matrix besteht aus folgenden Komponenten:&lt;br /&gt;
&lt;br /&gt;
* Steuereinheit, die die Touch-Werte auswertet und entsprechend RGB-Werte an die Pixel zurücksendet&lt;br /&gt;
* eine größere Zahl (10x10 = 100 oder 10x20 = 200) RGB &amp;amp; Touch-Pixel, die jede Zelle beleuchten und für jede Zelle ein Touch-Sensing durchführen&lt;br /&gt;
* einem Bus zwischen diesen Komponenten&lt;br /&gt;
&lt;br /&gt;
== Bus ==&lt;br /&gt;
&lt;br /&gt;
Die RGB-Touch-Pixel sollen über einen Bus verbunden werden. Das könnte entweder ein sternförmiger Bus sein oder eine Daisy-Chain wie die WS2811-Chips ihn bilden.&lt;br /&gt;
&lt;br /&gt;
=== Ein Szenario mit Daisy Chain ===&lt;br /&gt;
&lt;br /&gt;
Es sei eine CLK-Leitung vorausgesetzt, diese könnte jedoch auch implizit durch festes Timing gelöst werden (wie WS2811).&lt;br /&gt;
&lt;br /&gt;
Ablauf:&lt;br /&gt;
&lt;br /&gt;
Zunächst in Richtung MOSI, also Master sendet eine Chain von Daten an den ersten Slave.&lt;br /&gt;
&lt;br /&gt;
* durch eine vorhergehende Pause ist der &amp;quot;LATCH &amp;amp; RESET&amp;quot;-Zustand eingetreten, d.h. alle Slaves wissen: wenn jetzt was kommt, dann ist das der Anfang&lt;br /&gt;
* Der Master sendet Bit für Bit an den ersten Slave&lt;br /&gt;
* der erste Slave nimmt sich die ersten 8x3=24 Bits und schreibt sie in seinen Zwischenspeicher für den RGB-Wert&lt;br /&gt;
* der erste Slave schreibt jedes weitere Bit direkt an den Ausgang ohne es weiter anzusehen&lt;br /&gt;
* dasselbe tut jeder weitere Node&lt;br /&gt;
* Pause: LATCH &amp;amp; RESET&lt;br /&gt;
&lt;br /&gt;
Das ist die Richtung &amp;quot;RGB an Slaves&amp;quot;, von den WS2811 bekannt.&lt;br /&gt;
&lt;br /&gt;
Die Rückrichtung:&lt;br /&gt;
es müsste also jetzt beim Master an MISO nach und nach, Bit für Bit die Chain an Daten aus den Slaves ankommen, also muss sich hier das ganze Spektakel umgekehrt abspielen.&lt;br /&gt;
Während also die Bits in der &amp;quot;hin&amp;quot;-Richtung durchschieben, müssten ebenfalls die Bits in der Rück-Richtung durchshiften.&lt;br /&gt;
&lt;br /&gt;
* Pause = LATCH &amp;amp; RESET setzt alle Slaves in Startzustand.&lt;br /&gt;
* wenn jetzt der erste Slave seine Daten bekommt, dann müsste er einfach gleichzeitig am Ausgang entweder seine oder die Daten des nächsten Node setzen&lt;br /&gt;
* er erhält also das erste Bit vom Master. Jetzt setzt er das erste Bit  seiner Sensordaten&lt;br /&gt;
* nach den ersten 24 Bits (= seine RGB-Daten) sind seine Sensordaten durch (24 Bit Sensor-Daten)&lt;br /&gt;
* ab dann lauscht er auf seinem Eingang für Sensordaten vom nächsten Node und er reicht jedes Bit, das dort ankommt direkt an den Master weiter&lt;br /&gt;
* spannenderweise passiert es genau zum selben Zeitpunkt, dass er seine 24 Bit RGB-Daten durchhat und dann die weiteren Bits weiterreicht wenn er die Daten des nächsten Node für Rück weiterreichen soll, das läuft also 100% parallel&lt;br /&gt;
* der 2. Slave tut genau dasselbe&lt;br /&gt;
&lt;br /&gt;
Nun kommen beim Hinsenden der RGBs genau der Strom an Sensordaten wieder zurück.&lt;br /&gt;
&lt;br /&gt;
Vorteile: &lt;br /&gt;
* Die Datenübertragung dauert genauso lange wie es dauert die Daten seriell auf einen Bus zu schicken, da ist keine Zeitverzögerung&lt;br /&gt;
* es müssen vom Master keine Nodes addressiert und abgefragt werden, also maximal effizient&lt;br /&gt;
* für die bidirektionale Übertragung brauche ich keine Extrazeit, die Rückdaten kommen gleichzeitig&lt;br /&gt;
* es ist völlig egal, wieviele Slaves ich habe, solange die Gesamtübertragungrate noch die gewünschte Framerate hergibt. Danach kann man den Bus splitten und z.B. die ganze Kette in 2 Teile trennen und einfach 2x einspeisen, dann kann man mit selber Framerate doppelt soviele Slaves abdecken&lt;br /&gt;
* die Übertragung ist maximal Stör-un-anfällig, weil die Distanz zwischen den Clients kurz ist und das Signal jedesmal neu gesendet wird&lt;br /&gt;
* man braucht keine Tranceiver, die Attiny sind gleichzeitig die Tranceiver&lt;br /&gt;
* man braucht nur 2 Leitungen mit GND, wenn es mit implizitem Takt läuft&lt;br /&gt;
&lt;br /&gt;
Idealerweise hängen alle Slaves einfach an einem Strang als einfachstmögliche Konstellation - einfache Verkabelung, keine mehrfach-Einspeisung in der Software.&lt;br /&gt;
Für einen 10x10 RGB-Touch-Tisch sind das 100 Slaves. Jeder hat 24 Bits zu bekommen, ergibt 2400 Bits.&lt;br /&gt;
Mal Framerate von 25 ergibt 25 x 2.400 Bits = 60.000 Bits pro Sekunde.&lt;br /&gt;
Vorsichtshalber betreiben wir den Bus mit 100 kBit, dann  sind wir nicht in einem technisch kritischen Bereich und brauchen nur einen Strang. (Die WS2811 machen 800 kBit, also das 8-fache).&lt;br /&gt;
250 kbit sollten noch ebenso einfach machbar sein, dann kann auch ein 10x20 Tisch in einem Strang betrieben werden&lt;br /&gt;
&lt;br /&gt;
Das Protokoll wäre auch mit nur einer Leitung denkbar, wenn noch einbaut, dass man den Slaves mitteilt: jetzt gehört die Leitung Euch!&lt;br /&gt;
Zum Beispiel: man sendet eine Chain von 0xffffff an alle (d.h. der RGB-Wert 0xffffff steht nicht zur Verfügung) und weiss: jetzt kommen als nächstes solange Bits zurück (Mode: MISO), bis mindestens eine Pause von xx Millisekunden da ist, dann ist der Mode wieder MOSI.&lt;br /&gt;
Man müsste gezielt RGB-Frames dafür ausfallen lassen, d.h. es reduziert die Framerate ein wenig und die Abtastrate der Touches ist auf 5-10/Sekunde begrenzt (das ist ausreichend).&lt;br /&gt;
Zum Beispiel: grundsätzliche Framerate 35 FPS, jeder 5. fällt aus für Touch-Sensing, dann habe ich 7x Touch pro Sekunde und 28 RGB-Frames.&lt;br /&gt;
Ein Problem mit unregelmässiger Refreshrate gibt es hier nicht, da alle Slaves beim letzten RGB-Wert bleiben und weiterleuchten, nur die Aktualisierung &amp;quot;stockt&amp;quot; für eine 35stel Sekunde, das ist nicht wahrnehmbar.&lt;br /&gt;
&lt;br /&gt;
== RGB &amp;amp; Touch Pixel ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* Forumsthread [http://www.mikrocontroller.net/topic/326662 LED Tisch mit Berührungs-/Gegenstandserkennung]&lt;br /&gt;
* Forumsthread [http://www.mikrocontroller.net/topic/329090 Schwierigkeiten passenden Bus zu finden]&lt;br /&gt;
* [[Audio-Projekt|Link zu anderem Projekt]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Projekte| ]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR&amp;diff=83292</id>
		<title>AVR</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR&amp;diff=83292"/>
		<updated>2014-06-08T19:05:37Z</updated>

		<summary type="html">&lt;p&gt;Maybee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die AVR-[[Mikrocontroller]] von [http://www.atmel.com Atmel] sind wegen ihrer übersichtlichen internen Struktur, der [[ISP | In-System-Programmierbarkeit]], und der Vielzahl von kostenlosen Programmen zur Softwareentwicklung (Assembler, Compiler) beliebt. Diese Eigenschaften und der Umstand, dass viele Typen in einfach handhabbaren DIL-Gehäusen (DIP) verfügbar sind, machen den AVR zum idealen Mikrocontroller für Anfänger. &lt;br /&gt;
&lt;br /&gt;
Über die Bedeutung des Namens &amp;quot;AVR&amp;quot; gibt es verschiedene Ansichten; manche meinen er sei eine Abkürzung für &#039;&#039;&#039;A&#039;&#039;&#039;dvanced &#039;&#039;&#039;V&#039;&#039;&#039;irtual [[RISC|&#039;&#039;&#039;R&#039;&#039;&#039;ISC]], andere vermuten dass der Name aus den Anfangsbuchstaben der Namen der Entwickler (&#039;&#039;&#039;A&#039;&#039;&#039;lf Egin Bogen und &#039;&#039;&#039;V&#039;&#039;&#039;egard Wollan &#039;&#039;&#039;R&#039;&#039;&#039;ISC) zusammengesetzt wurde. Laut Atmel ist der Name bedeutungslos.&lt;br /&gt;
&lt;br /&gt;
==Architektur==&lt;br /&gt;
&lt;br /&gt;
Die Architektur ist eine 8-Bit-[[Harvard-Architektur]], das heißt, es gibt getrennte Busse zum Programmspeicher ([[Speicher#Flash-ROM |Flash-ROM]], dieser ist 16 bit breit) und Schreib-Lese-Speicher ([[Speicher#RAM |RAM]]). Programmcode kann ausschließlich aus dem Programmspeicher ausgeführt werden. Weiterhin sind die Adressräume getrennt (d.h. die erste Speicherstelle im Flash-Speicher hat die gleiche Adresse (0) wie die erste Speicherstelle im RAM). Bei der Programmierung in Assembler und einigen C-Compilern bedeutet dies, dass sich Konstanten aus dem ROM nicht mit dem gleichen Code laden lassen wie Daten aus dem RAM. Abgesehen davon ist der Aufbau des Controllers recht übersichtlich und birgt wenige Fallstricke.&lt;br /&gt;
&lt;br /&gt;
* 32 größtenteils gleichwertige Register&lt;br /&gt;
* davon 1-3 16-bit-Zeigerregister (paarweise)&lt;br /&gt;
* ca. 110 Befehle, die meist 1-2 Taktzyklen dauern&lt;br /&gt;
* Taktfrequenz bis 32MHz&lt;br /&gt;
* Betriebsspannung von 1,8 - 5,5 V&lt;br /&gt;
* Speicher&lt;br /&gt;
**1-256 kB [[Speicher#Flash-ROM | Flash-ROM]]&lt;br /&gt;
**0-4 kB [[Speicher#EEPROM | EEPROM]]&lt;br /&gt;
**0-16 kB [[speicher#RAM | RAM]]&lt;br /&gt;
* Peripherie: [[AD-Wandler]] 10 bit, 8- und 16-Bit-[[Timer]] mit [[PWM]], [[SPI]], [[I²C]] (TWI), [[UART]], Analog-[[Komparator]], [[Watchdog]]&lt;br /&gt;
* [[Speicher#Mit_XMEM-Interface | 64kB Externer SRAM]] (ATmega128, ATmega64,  ATmega8515/162); (Bei den XMEGAs bis zu 16 MB (128 Mbit) externer SDRAM)&lt;br /&gt;
* [[JTAG]] bei den größeren ATmegas&lt;br /&gt;
* [[debugWire]] bei den neueren AVRs&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
* [http://www.mikroe.com/mikropascal/avr]: Mikropascal, mit einer eingeschränkten kostenlosen Testversion&lt;br /&gt;
* [[AVR-Studio]]: Kostenlose Enwicklungsumgebung mit Simulator&lt;br /&gt;
* [http://www.atmel.com/tools/atmelstudio.aspx Atmel Studio 6]: Kostenlose Enwicklungsumgebung mit Simulator&lt;br /&gt;
* [http://sourceforge.net/projects/kontrollerlab/ KontrollerLab]: Kostenlose Entwicklungsumgebung für KDE&lt;br /&gt;
* [http://corpsman.de/index.php?doc=projekte/klab Klab]: Kostenlose Entwicklungsumgebung für KDE/GTK2/Win32 (als FPC/Lazarus Quellcode verfügbar, Nachbau von KontrollerLab)&lt;br /&gt;
* [http://www.microsoft.com/germany/Express/product/visualcplusplusexpress.aspx Microsoft Visual C++ Express]: Kostenlose Enwicklungsumgebung (Win),über makefile&lt;br /&gt;
* [http://netbeans.org Netbeans]: Plugin-basierte, kostenlose Entwicklungsumgebung (Windows, Mac, Linux, und Solaris). [http://mattzz.dyndns.org/wiki/bin/view/Projects/ArduinoAndNetbeans  Hier] findet sich ein Howto für das Setup von AVR (z.B. für Arduino)&lt;br /&gt;
* [[AVR Eclipse]]: Plugin-basierte kostenlose Entwicklungsumgebung (Win, Linux, Mac)&lt;br /&gt;
* [[Code::Blocks]]: Freie Entwicklungsumgebung (Win, Linux, Mac), die auch für AVR-Projekte Unterstützung anbietet&lt;br /&gt;
* [[AVR-GCC]]: Kostenloser C-Compiler&lt;br /&gt;
* [[LunaAVR]]: Kostenlose, objektbasierte Basic/Pascal-ähnliche Programmiersprache und Entwicklungsumgebung mit Compiler/Assembler und Disassembler (Win, Linux, Mac). http://avr.myluna.de&lt;br /&gt;
* [http://sourceforge.net/projects/avra/ AVRA]: freier AVR-Assembler&lt;br /&gt;
* [http://www.mcselec.com/bascom-avr.htm Bascom AVR] beliebter Basic-Compiler&lt;br /&gt;
* [http://www.e-lab.de AVRCo Pascal Compiler]&lt;br /&gt;
* [http://amforth.sourceforge.net/ amforth]:  interaktiver und erweiterbarer Kommandointerpreter für AVR unter GNU Lizenz (Open Source)&lt;br /&gt;
* [[SJC]]: Experimenteller Java-Compiler unter GPL mit AVR-Unterstützung&lt;br /&gt;
* [http://www.atnel.pl/mkAVRCalculator_build_57en.rar mkAvrCalculator]: User friendly fuse bits calculator and GUI for avrdude&lt;br /&gt;
&lt;br /&gt;
== Boards &amp;amp; Starterkits ==&lt;br /&gt;
&lt;br /&gt;
Siehe dazu auch die Artikel in der [[:Kategorie:AVR-Boards|Kategorie AVR-Boards]] und den Artikel zur [[AVR_In_System_Programmer|AVR Programmierung]].&lt;br /&gt;
&lt;br /&gt;
* [[STK200]]&lt;br /&gt;
* [[STK500]]&lt;br /&gt;
* [[STK600]]&lt;br /&gt;
* [[AVR Dragon]] &lt;br /&gt;
* [[AVR Butterfly]]&lt;br /&gt;
* [[AVR Raven]]&lt;br /&gt;
* AVR-ISP / AVR-ISP mkII&lt;br /&gt;
* [http://www.ehajo.de/Bausaetze/AVR-ISP-Stick AVR-ISP-Stick]&lt;br /&gt;
* [http://www.ehajo.de/Bausaetze/µISP-Stick µISP-Stick]&lt;br /&gt;
* [http://www.ehajo.de/Bausaetze/USP-Stick USP-Stick]&lt;br /&gt;
* AVR JTAG-ICE&lt;br /&gt;
* [http://www.robotikhardware.de RN-Control]&lt;br /&gt;
* [http://www.conrad.de C-Control PRO]&lt;br /&gt;
* [http://www.myavr.de myAVR Board]&lt;br /&gt;
* [http://www.rowalt.de AVR Lehrbuch und -bausatz]&lt;br /&gt;
* [http://www.pollin.de Pollin] - preiswerte Starterkits sowie Lösungen für RFID-125kHz und EtherNet&lt;br /&gt;
* [http://www.lochraster.org/rumpus Rumpus von lochraster.org] ist ein günstiges und gut dokumentiertes Starterkit mit Atmega 168&lt;br /&gt;
* [http://www.das-labor.org/wiki/Laborboard  Laborboard von das-labor.org] - Bauplan Lochrasterplatine mit Atmega32&lt;br /&gt;
* [http://nibo.nicai-systems.de Roboterbausatz NIBO 2] - autonomer Roboter mit einem ATmega128 und einem ATmega88 / [http://nibobee.nicai-systems.de Roboterbausatz NIBObee] - Roboter für Einsteiger mit ATmega16 und integriertem USB-Programmer&lt;br /&gt;
* [http://www.nerdkits.com Nerdkit - Starterkit inkl. Doku] - ideal für Anfänger&lt;br /&gt;
* [http://arduino.cc/ Arduino] - Ein modulares System mit verschiedenen Entwicklungsboards (insbesondere auch eins mit ATmega1280, dem mit den vielen dünnen Beinchen), das aufgrund der Nutzung einer JAVA-IDE und &amp;quot;Wiring&amp;quot; besonders einfach zu nutzen ist. Es gibt verschiedene Clones unter Namen wie Freeduino, Seeeduino etc., auch den Lilypad zum Einnähen in Kleidung und Verschaltung mittels leitender Fäden. Die neueren Versionen können über einen standardmäßig mit ausgelieferten Bootloader ohne sonstige Hardware direkt über USB bespielt werden.&lt;br /&gt;
* [http://www.aevum-mechatronik.de Modularis] - AVR Mikrocontroller-Boards (z.T. mit Zusatz-Speicher und USB) die über Flachbandkabel erweitert werden können. Es gibt bis jetzt Zubehör-Module mit Taster, Motor H-Brücke, XBee und Winkelsensor.&lt;br /&gt;
* [http://www.b-redemann.de AVR Mikrocontroller Lehrbuch (R. Walter, 3. Auflage 2009) und Bauteilesatz incl. Leiterplatte; www.b-redemann.de]&lt;br /&gt;
* [http://weigu.lu/b/mices2 mices2] - Entwicklungsboard zum [http://www.weigu.lu/a Gratis Assembler Kurs]. Integriertes Programmiergerät (USB, avrisp mk2 kompatibel). Spannungsvrsorgung über USB. Platine einseitig, leicht zu bestücken. Viele Schnittstellen (1-Wire, I2C, EIA232 ...), D/A-Wandler, Mikrofonschaltung., Audioverstärker ...&lt;br /&gt;
* [https://guloshop.de/shop/Mikrocontroller-Programmierung/::45.html gulostart] – [[Steckbrett|Steckplatinen]]-basiertes Lernpaket / Einsteiger-Set mit ausführlicher Anleitung. Verwendet ausschließlich [http://de.wikipedia.org/wiki/Open_source Open-Source-Software], kann fast alle DIP-ATtiny/ATmega programmieren. Für USB-Schnittstelle.&lt;br /&gt;
* [http://corpsman.de/index.php?doc=avrnetio/atmegaboard Atmegaboard] Eagle Daten für ein Testboard zur Nutzung 2er Atmegas gleichzeitig. Weitere Adapterplatinen sowie Source Code sind ebenfalls verfügbar.&lt;br /&gt;
* [http://matrixstorm.com/avr/tinyusbboard/ tinyUSBboard] - Ein sehr sehr preiswertes, Arduino und BASCOM kompatibles Board mit onboard USB Interface und [http://matrixstorm.com/avr/tinyusbboard/#firmwaresotherbootloader auswechelbarem Bootloader].&lt;br /&gt;
* [http://www.ehajo.de/Bausaetze/aTeVaL aTeVaL-Board] - Nachfolger des bekannten Pollin Evalboards. ISP-mkii-Klon &amp;amp; Seriell/USB-Wandler via USB. Testhardware auf der Platine: Taster, LED, Summer, Potis, ...&lt;br /&gt;
* [https://www.olimex.com/Products/AVR/ verschiedene Boards von Olimex]&lt;br /&gt;
&lt;br /&gt;
== Projekte ==&lt;br /&gt;
Siehe dazu auch die Artikel in der [[:Kategorie:AVR-Projekte|Kategorie AVR-Projekte]].&lt;br /&gt;
&lt;br /&gt;
* [[PWM_foxlight]] - LED Lampe mit PWM&lt;br /&gt;
* [[Digitaler Funktionsgenerator]]&lt;br /&gt;
* [[Midi Rekorder mit MMC/SD-Karte]]&lt;br /&gt;
* [[Schrittmotor-Controller (Stepper)]]&lt;br /&gt;
* [[Pulsuhrempfänger mit AVR Butterfly]]&lt;br /&gt;
* [[DCF77-Funkwecker mit AVR]]&lt;br /&gt;
* [[Fahrradcomputer]]&lt;br /&gt;
* [[Einfacher und billiger Webserver mit AtMega32]]&lt;br /&gt;
* [[AVR RFM12]]&lt;br /&gt;
* [[RF SOAP]] USB / AtMega88 / RFM12, optional LiPo Akku mit Lader&lt;br /&gt;
* [http://www.andreadrian.de/schach/#Selbstbau_Schachcomputer_SHAH Selbstbau Schachcomputer SHAH mit ATMega88V]&lt;br /&gt;
* [[Giess-o-mat]] - vollautomatische Blumengießanlage&lt;br /&gt;
* [http://www.zipfelmaus.com/led-flitzer/ POV-LED mit ATmega8, USB und Beschleunigungssensor]&lt;br /&gt;
* [http://g-heinrichs.de/attiny/ ATtiny-Mikrokontroller für Schulbedarf]&lt;br /&gt;
* [http://www.weigu.lu/b Kleine USB-Bibliothek (C, BASCOM und Assembler) für ATMEL-USB-AVRs]&lt;br /&gt;
* [http://volkszaehler.org/ Ein tolles Smartmeter mit kompletter Middleware!]&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
&lt;br /&gt;
* [[AVR-Tutorial]]&lt;br /&gt;
* [[AVR-GCC-Tutorial]]&lt;br /&gt;
* http://www.avr-asm-tutorial.net&lt;br /&gt;
* [http://www.weigu.lu/a weigu.lu/a]: Gratis Assembler Kurs (pdf). Mehrere hundert Seiten mit vielen neuen Grafiken. Besonders zum Selbststudium geeignet. Es existiert auch ein [http://www.weigu.lu/b/mices2 Entwicklungsboard] zum Kurs.&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
 	&lt;br /&gt;
* C.Kühnel Programmieren der AVR RISC Mikrocontroller mit BASCOM-AVR ISBN 3898119378 (2000) ISBN 3907857046 (2.Aufl.2004) ISBN 978-3-907857-14-4 (3. überarbeitete und erweiterte Auflage 2010)&lt;br /&gt;
* R.Mittermayr AVR-RISC: Embedded Software selbst entwickeln Franzis 2008 ISBN 3772341071&lt;br /&gt;
* F.Schäffer AVR: Hardware und C-Programmierung in der Praxis Elektor 2008 ISBN 3895762008 [http://www.blafusel.de/books/avr.html Webseite des Autors, Codebeispiele und Leseprobe]&lt;br /&gt;
* G.Schmitt Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie...Oldenbourg 4.Aufl.2008  ISBN 3486587900 ISBN 3486580167 (2006) ISBN 3486577174 (2005) [http://www.oldenbourg-wissenschaftsverlag.de/olb/de/1.c.1495224.de Verlags-Webseite mit Buchauszügen]&lt;br /&gt;
* M.Schwabl-Schmidt Programmiertechniken für AVR-Mikrocontroller Elektor 2008 ISBN 3895761761 [http://www.schwabl-schmidt.de/index.php/buecher Webseite des Autors]&lt;br /&gt;
* M.Schwabl-Schmidt Systemprogrammierung für AVR-Mikrocontroller Elektor 2009 ISBN 3895762180&lt;br /&gt;
* W.Trampert Messen,Steuern und Regeln mit AVR Mikrocontrollern Franzis 2004 ISBN 3772342981&lt;br /&gt;
* W.Trampert AVR-RISC Mikrocontroller Franzis ISBN 3772354769 (2003) ISBN 3772354742 (2002) ISBN 3772354750 (2000)&lt;br /&gt;
* P.Urbanek Embedded Systems: Ein umfassendes Grundlagenwerk ... (2007) ISBN 3981123018 [http://www.ulb.tu-darmstadt.de/tocs/188146911.pdf Inhaltsverzeichnis]&lt;br /&gt;
* S./F.Volpe AVR-Mikrocontroller-Praxis Elektor 2001 ISBN 3895760633&lt;br /&gt;
* R.Walter AVR-Mikrocontroller-Lehrbuch 3. Auflage Denkholz 2009 ISBN 9783981189445 [http://www.rowalt.de/mc/avr/avrbuch/index.htm Webseite des Autors, Buch-Download in geringer Auflösung]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tipps &amp;amp; Hinweise ==&lt;br /&gt;
&lt;br /&gt;
* [[AVR Typen]] - Die verschiedenen Typen (AT90S, ATmega, ATtiny)&lt;br /&gt;
* [[AVR Checkliste]] - Liste mit Hinweisen zur Lösung üblicher Probleme&lt;br /&gt;
* [http://blog.coldtobi.de/1_coldtobis_blog/archive/87_little_endianess_guide_for_atmel_avr.html (Little) Endianess Guide for Atmel AVR] Übersicht über die Endianess der AVR und AVR32&lt;br /&gt;
* [[AVR Fuses|Fuse-Bits]] - Das Setzen der Fuse-Bits ist ein berüchtigter Fallstrick bei den AVRs; vor dem Rumspielen damit unbedingt diese Hinweise lesen!&lt;br /&gt;
* [[AVR In System Programmer]] - Programmierhardware&lt;br /&gt;
* [[Pony-Prog Tutorial]] - Hinweise zur Programmiersoftware PonyProg&lt;br /&gt;
* [[AVRDUDE]] - Programmiersoftware für die Kommandozeile&lt;br /&gt;
* [[AVR-GCC-Codeoptimierung]] - Wie man mehr aus dem Controller herausholen kann, ohne ein Assembler-Guru sein zu muessen.&lt;br /&gt;
* [[AVR Softwarepool]] - Verschiedene Softwaremodule und Codeschnippsel aus der Codesammlung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
* [http://revision3.com/systm/avr101 AVR101] - systm Videocast von Revision3 Internet Television (engl.).&lt;br /&gt;
&lt;br /&gt;
Weitere Verweise (Links) auf externe Informationen und Projekte finden sich in der &#039;&#039;&#039;[[Linksammlung#AVR|Linksammlung]]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Anmerkungen ===&lt;br /&gt;
&lt;br /&gt;
Es gibt nur wenige Typen mit D/A-Wandler (z.B. AT90PWM2); hierfür benutze man PWM oder externe Bausteine.&lt;br /&gt;
&lt;br /&gt;
Die Takterzeugung ist bei AVRs recht einfach gehalten. So gibt es bei den meisten Modellen keine internen PLLs um „krumme“ Prozessor- oder Peripherietaktfrequenzen zu erzeugen, noch ist der Peripherie-Takt vom Prozessortakt abkoppelbar. Einige AVR verfügen über eine PLL, um damit z.B. einen Timer mit Frequenzen über der Systemfrequenz zu takten oder höhere Systemfrequenz aus niederfrequenteren Taktquellen zu erzeugen (vgl. u.a. Datenblatt ATtiny861). Die Baudrate serieller Schnittstellen lässt sich nicht gebrochen einstellen, so dass gegebenenfalls ein zur Baudrate passender Quarz oder Resonator zu verwenden ist.&lt;br /&gt;
&lt;br /&gt;
Für die serielle Programmierung des Flash-Speichers sind 4 Datenleitungen erforderlich und die Taktversorgung muss sicher gestellt sein. Es ist darauf zu achten, dass bei Einstellung der Taktquelle (Fuses) auch die vorhandene Taktquelle ausgewählt wird. Für die Hochvolt-Programmierung (so genannt wegen 12 V am RESET-Anschluss) werden je nach Chip sehr viele Leitungen benötigt. Einige Modelle verfügen über eine Debugwire-Schnittstelle, für die im Betrieb zwei Leitungen ausreichen.&lt;br /&gt;
&lt;br /&gt;
Nicht zu verwechseln ist die 8-bit-AVR-Serie mit AVR32. Letztere ist eine 32-bit-Architektur mit recht viel Ähnlichkeit zu Controllern auf Basis eines ARM-Cores. Controller der ATxmega-Serie verfügen über mehr Funktionen als die &amp;quot;traditionellen&amp;quot; AVR (z.B. DMA- und Eventsystem, 12Bit A-D-Wandler). ATxmega sind jedoch für 3,3V-Betrieb ausgelegt und ausschließlich in SMD-Bauform erhältlich.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Mikrocontroller]]&lt;br /&gt;
[[Category:AVR| ]]&lt;br /&gt;
__NOTOC__&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=IRMP&amp;diff=83284</id>
		<title>IRMP</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=IRMP&amp;diff=83284"/>
		<updated>2014-06-07T06:23:21Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Von &#039;&#039;&#039;Frank M. ([http://www.mikrocontroller.net/user/show/ukw ukw])&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Datei:irmp-title.png| |Scan eines NEC-kompatiblen Fernbedienungssignals]]&lt;br /&gt;
&lt;br /&gt;
Da RC5 nicht nur veraltet, sondern mittlerweile obsolet ist und immer mehr die elektronischen Geräte der fernöstlichen Unterhaltungsindustrie in unseren Haushalten Einzug finden, ist es an der Zeit, einen IR-Decoder zu entwickeln, der ca. 90% aller bei uns im täglichen Leben zu findenden IR-Fernbedienungen &amp;quot;versteht&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Im folgenden wird IRMP als &amp;quot;Infrarot-Multiprotokoll-Decoder&amp;quot; in allen Einzelheiten vorgestellt. Auch das Gegenstück, nämlich IRSND als IR-Encoder, wird in diesem Artikel behandelt.&lt;br /&gt;
&lt;br /&gt;
= IRMP - Infrarot-Multiprotokoll-Decoder =&lt;br /&gt;
&lt;br /&gt;
[[Datei:IRMP-TSOP1736.png|miniatur|Anschluß eines IR-Empfängers an µC]]&lt;br /&gt;
&lt;br /&gt;
=== Unterstützte µCs ===&lt;br /&gt;
&lt;br /&gt;
[[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] ist u.a. lauffähig auf folgenden AVR µCs:&lt;br /&gt;
&lt;br /&gt;
* ATtiny87,  ATtiny167&lt;br /&gt;
* ATtiny45,  ATtiny85&lt;br /&gt;
* ATtiny44,  ATtiny84&lt;br /&gt;
* ATmega8,   ATmega16,  ATmega32&lt;br /&gt;
* ATmega162&lt;br /&gt;
* ATmega164, ATmega324, ATmega644,  ATmega644P, ATmega1284&lt;br /&gt;
* ATmega88,  ATmega88P, ATmega168,  ATmega168P, ATmega328P&lt;br /&gt;
&lt;br /&gt;
Es gibt aber auch Portierungen auf diverse PIC µCs - für den CCS- und C18-Compiler. Auch ist [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] mittlerweile auf ARM STM32 und Stellaris LM4F120 Launchpad von TI (ARM Cortex M4) lauffähig.&lt;br /&gt;
&lt;br /&gt;
=== Unterstützte IR-Protokolle ===&lt;br /&gt;
&lt;br /&gt;
[[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] - der Infrarot-Fernbedienungsdecoder, der mehrere Protokolle auf einmal decodieren kann, beherrscht folgende Protokolle (in alphabetischer Reihenfolge):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Protokoll || Hersteller&lt;br /&gt;
|-&lt;br /&gt;
| [[IRMP#A1TVBOX|A1TVBOX]] || ADB (Advanced Digital Broadcast), z.B. A1 TV Box &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#APPLE|APPLE]] || Apple &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#B&amp;amp;O|B&amp;amp;O]] || Bang &amp;amp; Olufsen &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#BOSE|BOSE]] || Bose &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#DENON|DENON]] || Denon, Sharp &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#FDC|FDC]] || FDC Keyboard &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#GRUNDIG_+_NOKIA|GRUNDIG]] || Grundig &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#GRUNDIG_+_NOKIA|NOKIA]] || Nokia, z.B. D-Box &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#IR60 (SDA2008)|IR60 (SDA2008)]] || Diverse europäische Hersteller &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#JVC|JVC]] || JVC &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#KASEIKYO|KASEIKYO]] || Panasonic, Technics, Denon und andere japanische Hersteller, welche Mitglied der &amp;quot;Japan&#039;s Association for Electric Home Application&amp;quot; sind. &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#KATHREIN|KATHREIN]]  || KATHREIN &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#LEGO|LEGO]]   || Lego &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#LGAIR|LGAIR]]   || LG Air Conditioner &#039;&#039;&#039;(NEU, nur im SVN)&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#MATSUSHITA|MATSUSHITA]] || Matsushita &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#NEC16|NEC16]]  || JVC, Daewoo &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#NEC42|NEC42]]  || JVC &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#NEC_+_extended_NEC|NEC]] || NEC, Yamaha, Canon, Tevion, Harman/Kardon, Hitachi, JVC, Pioneer, Toshiba, Xoro, Orion, NoName und viele weitere japanische Hersteller. &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#NETBOX|NETBOX]]  || Netbox &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#NIKON|NIKON]] || NIKON &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#NUBERT|NUBERT]] || Nubert, z.B. Subwoofer System &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#ORTEK|ORTEK]] || Ortek, Hama (z. Zt. nur im SVN!) &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#RC5_+_RC5X|RC5]] || Philips und andere europäische Hersteller &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#RC6_+_RC6A|RC6A]] || Philips, Kathrein und andere Hersteller, z.B. XBOX &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#RC6_+_RC6A|RC6]] || Philips und andere europäische Hersteller &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#RCCAR|RCCAR]] || RC Car: IR Fernbedienung für Modellfahrzeuge &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#RECS80|RECS80]] || Philips, Nokia, Thomson, Nordmende, Telefunken, Saba &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#RECS80EXT|RECS80EXT]] || Philips, Technisat, Thomson, Nordmende, Telefunken, Saba &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#RCMM|RCMM]] || Fujitsu-Siemens z.B. Activy keyboard &#039;&#039;&#039;(NEU!)&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#ROOMBA|ROOMBA]] || iRobot Roomba Staubsauger&lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#SAMSUNG32|SAMSUNG32]] || Samsung &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#SAMSUNG|SAMSUNG]] || Samsung &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#SIEMENS_+_RUWIDO|RUWIDO]] || RUWIDO (z.B. T-Home-Mediareceiver, MERLIN-Tastatur (Pollin)) &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#SIEMENS_+_RUWIDO|SIEMENS]] || Siemens, z.B. Gigaset M740AV &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#SIRCS|SIRCS]] || Sony &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#SPEAKER|SPEAKER]] || Lautsprecher Systeme wie z.B. X-Tensions &#039;&#039;&#039;(NEU, nur im SVN!)&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#TELEFUNKEN|TELEFUNKEN]] || Telefunken &lt;br /&gt;
|- &lt;br /&gt;
| [[IRMP#THOMSON|THOMSON]] || Thomson&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Jedes dieser Protokolle ist einzeln aktivierbar. Wer möchte, kann alle Protokolle aktivieren. Wer nur ein Protokoll braucht, kann alle anderen deaktivieren. Es wird nur das vom Compiler übersetzt, was auch benötigt wird.&lt;br /&gt;
&lt;br /&gt;
=== Entstehung ===&lt;br /&gt;
&lt;br /&gt;
Der auf AVR- und PIC-µCs einsetzbare Source zu [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] entstand im Rahmen des [[Word Clock]] Projektes.&lt;br /&gt;
&lt;br /&gt;
=== Thread im Forum ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Anlass für einen eigenen [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]]-Artikel ist folgender Thread in der Codesammlung: [http://www.mikrocontroller.net/topic/162119 Beitrag: IRMP - Infrared Multi Protocol Decoder]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== IR-Protokolle ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:nec-protocol.png|miniatur|NEC-Protokoll, Reichelt RGB-LED-Fernbedienung, T-&amp;gt;A: 9,14ms, A-&amp;gt;B: 4,42ms, B-&amp;gt;C: 660us]]&lt;br /&gt;
&lt;br /&gt;
Einige Hersteller verwenden ihr eigenes hausinterne Protokoll, dazu gehören u.a. Sony, Samsung und Matsushita. Philips hat [[IRMP#RC5 + RC5X|RC5]] entwickelt und natürlich auch selbst benutzt. [[IRMP#RC5 + RC5X|RC5]] galt damals in Europa als &#039;&#039;das&#039;&#039; Standard-IR-Protokoll, welches von vielen europäischen Herstellern übernommen wurde. Mittlerweile ist [[IRMP#RC5 + RC5X|RC5]] fast gar nicht mehr anzutreffen - man kann es eigentlich als &amp;quot;ausgestorben&amp;quot; abhaken. Der Nachfolger RC6 wird zwar noch in einigen aktuellen europäischen Geräten eingesetzt, ist aber auch nur vereinzelt vorzufinden.&lt;br /&gt;
&lt;br /&gt;
Auch die japanischen Hersteller haben versucht, einen eigenen Standard zu etablieren, nämlich das sog. [[IRMP#KASEIKYO|Kaseikyo]]- (oder auch &amp;quot;Japan-&amp;quot;) Protokoll. Dieses ist mit einer Bitlänge von 48 sehr universell und allgemein verwendbar. Richtig durchgesetzt hat es sich aber bis heute nicht - auch wenn man es hier und da im heimischen Haushalt vorfindet.&lt;br /&gt;
&lt;br /&gt;
Heutzutage wird (auch vornehmlich bei japanischen Geräten) das [[IRMP#NEC_+_extended_NEC|NEC]]-Protokoll verwendet - und zwar von den unterschiedlichsten (Marken- und auch Noname-)Herstellern. Ich schätze den &amp;quot;Marktanteil&amp;quot; auf ca. 80% beim [[IRMP#NEC_+_extended_NEC|NEC]]-Protokoll. Fast alle Fernbedienungen im alltäglichen Einsatz verwenden bei mir den [[IRMP#NEC_+_extended_NEC|NEC]]-IR-Code. Das fängt beim Fernseher an, geht über vom DVD-Player zur Notebook-Fernbedienung und reicht bis zur Noname-MultiMedia-Festplatte - um nur einige Beispiele zu nennen.&lt;br /&gt;
&lt;br /&gt;
== Kodierungen ==&lt;br /&gt;
&lt;br /&gt;
[[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] unterstützt folgende IR-Codings:&lt;br /&gt;
&lt;br /&gt;
* [[IRMP#Pulse Distance|Pulse Distance]], typ. Beispiel: [[IRMP#NEC_+_extended_NEC|NEC]]&lt;br /&gt;
* [[IRMP#Pulse Width|Pulse Width]], typ. Beispiel: [[IRMP#SIRCS|Sony SIRCS]]&lt;br /&gt;
* [[IRMP#Biphase|Biphase (Manchester)]], typ. Beispiel: Philips [[IRMP#RC5_+_RC5X|RC5]], [[IRMP#RC6_+_RC6A|RC6]]&lt;br /&gt;
* [[IRMP#Pulse Position|Pulse Position (NRZ)]], typ. Beispiel: [[IRMP#NETBOX|Netbox]]&lt;br /&gt;
* [[IRMP#Pulse Distance Width|Pulse Distance Width]], typ. Beispiel: [[IRMP#NUBERT|Nubert]]&lt;br /&gt;
&lt;br /&gt;
Die Pulse werden dabei moduliert - üblicherweise mit 36kHz oder 38kHz - um Umwelteinflüsse wie Raum- oder Sonnenlicht ausfiltern zu können.&lt;br /&gt;
&lt;br /&gt;
=== Pulse Distance ===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Pulse-Distance.png|miniatur|Pulse Distance Coding]]&lt;br /&gt;
&lt;br /&gt;
Eine Pulse Distance Kodierung erkennt man an der folgenden Regel:&lt;br /&gt;
&lt;br /&gt;
* es gibt nur &#039;&#039;&#039;eine Pulslänge&#039;&#039;&#039; und &#039;&#039;&#039;zwei verschiedene Pausenlängen.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Pulse Width ===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Pulse-Width.png|miniatur|Pulse Width Coding]]&lt;br /&gt;
&lt;br /&gt;
Bei der Pulse Width Kodierung gilt die Regel:&lt;br /&gt;
&lt;br /&gt;
* es gibt &#039;&#039;&#039;zwei verschiedene Pulslängen&#039;&#039;&#039; und nur &#039;&#039;&#039;eine Pausenlänge&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Pulse Distance Width ===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Pulse-Distance-Width.png|miniatur|Pulse Distance Width Coding]]&lt;br /&gt;
&lt;br /&gt;
Dies ist ein Mischmasch aus Pulse Distance und Pulse Width Coding.&lt;br /&gt;
&lt;br /&gt;
Also:&lt;br /&gt;
&lt;br /&gt;
* es gibt &#039;&#039;&#039;zwei verschiedene Pulslängen&#039;&#039;&#039; und &#039;&#039;&#039;zwei verschiedene Pausenlängen.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Biphase ===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Biphase-Coding.png|miniatur|Biphase Coding]]&lt;br /&gt;
&lt;br /&gt;
Bei der Biphase Kodierung entscheidet die Reihenfolge von Puls und Pause über den Wert des Bits.&lt;br /&gt;
&lt;br /&gt;
Damit erkennt man ein Biphase-Coding an folgendem Kriterium:&lt;br /&gt;
&lt;br /&gt;
* es kommen genau &#039;&#039;&#039;eine&#039;&#039;&#039; Pausen- und eine Pulslänge, sowie jeweils die &#039;&#039;&#039;doppelten&#039;&#039;&#039; Puls-/Pausenlängen vor&lt;br /&gt;
&lt;br /&gt;
Normalerweise sind die Längen für die Pulse und Pausen gleich, d.h. die Signalform ist symmetrisch. IRMP erkennt aber auch Protokolle, die mit unterschiedlichen Puls-/Pause-Längen arbeiten. Dies ist zum Beispiel bei dem [[IRMP#A1TVBOX|A1TVBOX]]-Protokoll der Fall.&lt;br /&gt;
&lt;br /&gt;
=== Pulse Position ===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Pulse-Position.png|miniatur|Pulse Position Coding]]&lt;br /&gt;
&lt;br /&gt;
Die Pulse Position Kodierung kennt man von den üblichen UARTs. Hier hat jedes Bit eine feste Länge. Je nach Wert (0 oder 1) ist es ein Puls oder eine Pause.&lt;br /&gt;
&lt;br /&gt;
Typisches Kriterium für ein &#039;&#039;&#039;Pulse Position Protokoll&#039;&#039;&#039; ist:&lt;br /&gt;
&lt;br /&gt;
* es kommen &#039;&#039;&#039;Vielfache&#039;&#039;&#039; einer Grund-Puls-/Pausenlänge vor&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Eine tabellarische Aufstellung der verschiedenen IR-Protokolle findet man hier: [[IRMP#Die_IR-Protokolle_im_Detail|Die IR-Protokolle im Detail]].&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Die dort angegebenen Timingwerte sind Idealwerte. Bei einigen Fernbedienungen in der Praxis weichen sie um bis zu 40% voneinander ab. Deshalb arbeitet [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] mit Minimum-/Maximumsgrenzen, um bzgl. des Zeitverhaltens tolerabel zu sein.&lt;br /&gt;
&lt;br /&gt;
== Protokoll-Erkennung ==&lt;br /&gt;
&lt;br /&gt;
Die von [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] decodierten Protokolle haben etwas gemeinsames: Sie weisen alle ein Start-Bit auf, welches vom Timing her ausgezeichnet, d.h. einmalig ist.&lt;br /&gt;
&lt;br /&gt;
Anhand dieses Start-Bit-Timings werden die verschiedenen Protokolle unterschieden. [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] misst also das Timing des Start-Bits und stellt dann &amp;quot;on-thy-fly&amp;quot; seine Timingtabellen auf das erkannte Protokoll um, damit die nach dem Start-Bit gesandten Daten in einem Rutsch eingelesen werden können, ohne das komplette Telegramm (Frame) erst speichern zu müssen. [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] wartet also nicht darauf, dass ein kompletter Frame eingelesen wurde, sondern legt direkt nach der ersten Pulserkennung los.&lt;br /&gt;
&lt;br /&gt;
Ist das gelesene Start-Bit nicht eindeutig, fährt [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] &amp;quot;mehrspurig&amp;quot;, d.h. es werden zum Beispiel zwei mögliche Protokolle gleichzeitig verfolgt. Sobald aus Plausibilitätsgründen eines der beiden Protokolle nicht mehr möglich sein kann, wird komplett auf das andere Protokoll gewechselt.&lt;br /&gt;
&lt;br /&gt;
Realisiert wird die Erkennung über eine [[Statemachine]], die [[AVR-GCC-Tutorial/Die_Timer_und_Zähler_des_AVR|timergesteuert]] über eine [[Interrupt|Interruptroutine]] in regelmäßigen Abständen (üblicherweise 15.000 mal in der Sekunde) aufgerufen wird. Die [[Statemachine]] kennt (unter anderem) folgende Zustände:&lt;br /&gt;
&lt;br /&gt;
* Erkenne den ersten Puls des Start-Bits&lt;br /&gt;
* Erkenne die Pause des Start-Bits&lt;br /&gt;
* Erkenne den Puls des ersten Datenbits&lt;br /&gt;
&lt;br /&gt;
Danach sind die Puls/Pause-Längen des Startbits bekannt. Nun werden alle vom Anwender aktivierten Protokolle nach diesen Längen durchsucht. Wurde ein Protokoll gefunden, werden die Timing-Tabellen dieses Protokolls geladen und im weiteren geprüft, ob die nachfolgenden Puls-/Pause-Zeiten innerhalb der geladenen Werte übereinstimmen.&lt;br /&gt;
&lt;br /&gt;
Es geht also weiter in der [[Statemachine]] mit folgenden Zuständen&lt;br /&gt;
&lt;br /&gt;
* Erkenne die Pausen der Datenbits&lt;br /&gt;
* Erkenne die Pulse der Datenbits&lt;br /&gt;
* Prüfe Timing. Wenn abweichend, schalte um auf ein anderes noch in Frage kommendes IR-Protokoll, ansonsten schalte [[Statemachine]] komplett zurück&lt;br /&gt;
* Erkenne das Stop-Bit, falls das Protokoll eines vorsieht&lt;br /&gt;
* Prüfe Daten auf Plausibilität, wie CRC oder andere redundante Datenbits&lt;br /&gt;
* Wandle die Daten in Geräte-Adresse und Kommando&lt;br /&gt;
* Erkenne Wiederholungen durch längere Tastendrücke, setze entsprechendes Flag&lt;br /&gt;
&lt;br /&gt;
Tatsächlich ist die [[Statemachine]] noch etwas komplizierter, da manche Protokolle gar kein Start-Bit (z.B. [[IRMP#DENON|Denon]]) bzw. mehrere Start-Bits (z.B. 4 bei [[IRMP#B.26O|B&amp;amp;O]]) haben bzw. mitten im Frame ein weiteres Synchronisierungs-Bit (z.B. [[IRMP#SAMSUNG|Samsung]]) vorsehen. Diese besonderen Bedingungen werden durch protokollspezifische &amp;quot;Spezialbehandlungen&amp;quot; im Code abgefangen.&lt;br /&gt;
&lt;br /&gt;
Das Umschalten auf ein anderes Protokoll kann mehrfach während des Empfangs des Frames geschehen, z.B. von [[IRMP#NEC42|NEC42]] (42 Bit) auf [[IRMP#NEC16|NEC16]] (8 Bit + Sync-Bit + 8 Bit), wenn vorzeitig ein zusätzliches Synchronisierungsbit erkannt wurde, oder von [[IRMP#NEC + extended NEC|NEC]]/[[IRMP#NEC42|NEC42]] (32/42 Bit) auf [[IRMP#JVC|JVC]] (16 Bit), wenn das Stop-Bit vorzeitig auftrat. Schwierig wird es dann, wenn zwei mögliche Protokolle nach Erkennung des Start-Bits unterschiedliche Kodierungen verwenden, z.B. wenn das eine Protokoll ein [[IRMP#Pulse Distance|Pulse Distance Coding]] und das andere ein [[IRMP#Biphase|Biphase Coding (Manchester)]] benutzt. Hier speichert [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] die jeweils völlig verschieden ermittelten Bits für beide Codierungen, um dann später die einen oder anderen&lt;br /&gt;
Werte wieder zu verwerfen.&lt;br /&gt;
&lt;br /&gt;
Desweiteren senden einige Fernbedienungen bei bestimmten Protokollen aus Gründen der Redundanz (Fehlererkennung) oder wegen längeren Tastendrucks Wiederholungsframes. Diese werden von IRMP unterschieden: Die für die Fehlererkennung zuständigen Frames werden von IRMP geprüft, aber nicht an die Anwendung zurückgegeben, die anderen werden als langer Tastendruck erkannt und entsprechend von IRMP gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
== Download ==&lt;br /&gt;
&lt;br /&gt;
Version 2.4.0, Stand vom 20.02.2014&lt;br /&gt;
&lt;br /&gt;
Download Release-Version: [http://www.mikrocontroller.net/wikifiles/7/79/Irmp.zip Irmp.zip] &lt;br /&gt;
&lt;br /&gt;
[[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] &amp;amp; [[IRMP#IRSND_-_Infrarot-Multiprotokoll-Encoder|IRSND]] sind nun auch über SVN abrufbar: [http://www.mikrocontroller.net/svnbrowser/irmp/ IRMP im SVN], Download [http://www.mikrocontroller.net/svnbrowser/irmp/?view=tar Tarball]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achtung:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Die Version im SVN kann eine Zwischen- oder Test-Version sein, die nicht den hier dokumentierten Stand widerspiegelt! Im Zweifel verwendet man besser den obigen Download-Link auf Irmp.zip.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Die Software-Änderungen kann man sich hier anschauen: [http://www.mikrocontroller.net/articles/IRMP#Software-Historie_IRMP Software-Historie IRMP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Source-Code ==&lt;br /&gt;
&lt;br /&gt;
Der Source-Code lässt sich einfach für AVR-µCs übersetzen, indem man unter Windows die Projekt-Datei irmp.aps in das AVR Studio 4 lädt.&lt;br /&gt;
&lt;br /&gt;
Für andere Entwicklungsumgebungen ist leicht ein Projekt bzw. Makefile angelegt. Zum Source gehören:&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irmp.c?view=markup irmp.c] - Der eigentliche IR-Decoder&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irmpprotocols.h?view=markup irmpprotocols.h] - Sämtliche Definitionen zu den IR-Protokollen&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irmpsystem.h?view=markup irmpsystem.h] - Vom Zielsystem abhängige Definitionen für AVR/PIC/STM32&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irmp.h?view=markup irmp.h] - Include-Datei für die Applikation&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irmpconfig.h?view=markup irmpconfig.h] - Anzupassende Konfigurationsdatei &lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/main.c?view=markup main.c] - Beispiel Anwendung&lt;br /&gt;
&lt;br /&gt;
{{Warnung|&lt;br /&gt;
;WICHTIG: Im Applikations-Source sollte nur irmp.h per include eingefügt werden, also lediglich:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;irmp.h&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle anderen Include-Dateien werden automatisch über irmp.h &amp;quot;eingefügt&amp;quot;. Siehe dazu auch die Beispieldatei main.c.&lt;br /&gt;
&lt;br /&gt;
Desweiteren muss die Preprocessor-Konstante &#039;&#039;&#039;F_CPU im Projekt bzw. Makefile&#039;&#039;&#039; gesetzt werden. Diese sollte mindestens den Wert 8000000UL haben, der Prozessor sollte also zumindest mit 8 MHz laufen.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Auch auf PIC-Prozessoren ist [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] lauffähig. Für den PIC-CCS-Compiler sind entsprechende Preprocessor-Konstanten bereits gesetzt, so dass man [http://www.mikrocontroller.net/svnbrowser/irmp/irmp.c?view=markup irmp.c] direkt in der CCS-Entwicklungsumgebung verwenden kann. Lediglich eine kleine Interrupt-Routine wie&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void  TIMER2_isr(void) &lt;br /&gt;
{&lt;br /&gt;
 irmp_ISR ();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ist hinzuzufügen, wobei man den Interrupt auf 66µs (also 15kHz) stellt. &lt;br /&gt;
&lt;br /&gt;
Für AVR-Prozessoren ist ein Beispiel für die Anwendung von [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] in [http://www.mikrocontroller.net/svnbrowser/irmp/main.c?view=markup main.c] zu finden - im wesentlichen geht es da um die [[AVR-GCC-Tutorial/Die_Timer_und_Zähler_des_AVR|Timer]]-Initialisierung und den Abruf der empfangenen IR-Telegramme.&lt;br /&gt;
&lt;br /&gt;
Für das Stellaris LM4F120 Launchpad von TI (ARM Cortex M4) ist eine entsprechende Timer-Initialisierungsfunktion in [http://www.mikrocontroller.net/svnbrowser/irmp/main.c?view=markup main.c] bereits integriert.&lt;br /&gt;
&lt;br /&gt;
Ebenso kann [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] auf STM32-Mikroprozessoren eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
=== Konfiguration ===&lt;br /&gt;
&lt;br /&gt;
Die Konfiguration von [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] wird über Parameter in [http://www.mikrocontroller.net/svnbrowser/irmp/irmpconfig.h?view=markup irmpconfig.h] vorgenommen, nämlich:&lt;br /&gt;
&lt;br /&gt;
* [[IRMP#F_INTERRUPTS|Anzahl Interrupts pro Sekunde]]&lt;br /&gt;
* [[IRMP#IRMP_SUPPORT_xxx_PROTOCOL|Unterstützte IR-Protokolle]]&lt;br /&gt;
* [[IRMP#IRMP_PORT_LETTER + IRMP_BIT_NUMBER|Hardware-Pin zum IR-Empfänger]]&lt;br /&gt;
* [[IRMP#IRMP_LOGGING|IR-Logging]]&lt;br /&gt;
&lt;br /&gt;
=== Einstellungen in irmpconfig.h ===&lt;br /&gt;
&lt;br /&gt;
[[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] decodiert sämtliche oben aufgelisteten Protokolle in einer ISR. Dafür sind einige Angaben nötig. Diese werden in [http://www.mikrocontroller.net/svnbrowser/irmp/irmpconfig.h?view=markup irmpconfig.h] eingestellt.&lt;br /&gt;
&lt;br /&gt;
==== F_INTERRUPTS ====&lt;br /&gt;
&lt;br /&gt;
Anzahl der Interrupts pro Sekunde. Der Wert kann zwischen 10000 und 20000 eingestellt werden. Je höher der Wert, desto besser die Auflösung und damit die Erkennung. Allerdings erkauft man sich diesen Vorteil mit erhöhter CPU-Last. Der Wert 15000 ist meist ein guter Kompromiss.&lt;br /&gt;
&lt;br /&gt;
Standardwert:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define F_INTERRUPTS                            15000      // interrupts per second&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== IRMP_SUPPORT_xxx_PROTOCOL ====&lt;br /&gt;
&lt;br /&gt;
Hier lässt sich einstellen, welche Protokolle von [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] unterstützt werden sollen. Die Standardprotokolle sind bereits aktiv. Möchte man weitere Protokolle einschalten bzw. einige aus Speicherplatzgründen deaktivieren, sind die entsprechenden Werte in [http://www.mikrocontroller.net/svnbrowser/irmp/irmpconfig.h?view=markup irmpconfig.h] anzupassen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// typical protocols, disable here!             Enable  Remarks                 F_INTERRUPTS            Program Space&lt;br /&gt;
#define IRMP_SUPPORT_SIRCS_PROTOCOL             1       // Sony SIRCS           &amp;gt;= 10000                 ~150 bytes&lt;br /&gt;
#define IRMP_SUPPORT_NEC_PROTOCOL               1       // NEC + APPLE          &amp;gt;= 10000                 ~300 bytes&lt;br /&gt;
#define IRMP_SUPPORT_SAMSUNG_PROTOCOL           1       // Samsung + Samsung32  &amp;gt;= 10000                 ~300 bytes&lt;br /&gt;
#define IRMP_SUPPORT_MATSUSHITA_PROTOCOL        1       // Matsushita           &amp;gt;= 10000                  ~50 bytes&lt;br /&gt;
#define IRMP_SUPPORT_KASEIKYO_PROTOCOL          1       // Kaseikyo             &amp;gt;= 10000                 ~250 bytes&lt;br /&gt;
&lt;br /&gt;
// more protocols, enable here!                 Enable  Remarks                 F_INTERRUPTS            Program Space&lt;br /&gt;
#define IRMP_SUPPORT_DENON_PROTOCOL             0       // DENON, Sharp         &amp;gt;= 10000                 ~250 bytes&lt;br /&gt;
#define IRMP_SUPPORT_RC5_PROTOCOL               0       // RC5                  &amp;gt;= 10000                 ~250 bytes&lt;br /&gt;
#define IRMP_SUPPORT_RC6_PROTOCOL               0       // RC6 &amp;amp; RC6A           &amp;gt;= 10000                 ~250 bytes&lt;br /&gt;
#define IRMP_SUPPORT_JVC_PROTOCOL               0       // JVC                  &amp;gt;= 10000                 ~150 bytes&lt;br /&gt;
#define IRMP_SUPPORT_NEC16_PROTOCOL             0       // NEC16                &amp;gt;= 10000                 ~100 bytes&lt;br /&gt;
#define IRMP_SUPPORT_NEC42_PROTOCOL             0       // NEC42                &amp;gt;= 10000                 ~300 bytes&lt;br /&gt;
#define IRMP_SUPPORT_IR60_PROTOCOL              0       // IR60 (SDA2008)       &amp;gt;= 10000                 ~300 bytes&lt;br /&gt;
#define IRMP_SUPPORT_GRUNDIG_PROTOCOL           0       // Grundig              &amp;gt;= 10000                 ~300 bytes&lt;br /&gt;
#define IRMP_SUPPORT_SIEMENS_PROTOCOL           0       // Siemens Gigaset      &amp;gt;= 15000                 ~550 bytes&lt;br /&gt;
#define IRMP_SUPPORT_NOKIA_PROTOCOL             0       // Nokia                &amp;gt;= 10000                 ~300 bytes&lt;br /&gt;
&lt;br /&gt;
// exotic protocols, enable here!               Enable  Remarks                 F_INTERRUPTS            Program Space&lt;br /&gt;
#define IRMP_SUPPORT_BOSE_PROTOCOL              0       // BOSE                 &amp;gt;= 10000                 ~150 bytes&lt;br /&gt;
#define IRMP_SUPPORT_KATHREIN_PROTOCOL          0       // Kathrein             &amp;gt;= 10000                 ~200 bytes&lt;br /&gt;
#define IRMP_SUPPORT_NUBERT_PROTOCOL            0       // NUBERT               &amp;gt;= 10000                  ~50 bytes&lt;br /&gt;
#define IRMP_SUPPORT_BANG_OLUFSEN_PROTOCOL      0       // Bang &amp;amp; Olufsen       &amp;gt;= 10000                 ~200 bytes&lt;br /&gt;
#define IRMP_SUPPORT_RECS80_PROTOCOL            0       // RECS80 (SAA3004)     &amp;gt;= 15000                  ~50 bytes&lt;br /&gt;
#define IRMP_SUPPORT_RECS80EXT_PROTOCOL         0       // RECS80EXT (SAA3008)  &amp;gt;= 15000                  ~50 bytes&lt;br /&gt;
#define IRMP_SUPPORT_THOMSON_PROTOCOL           0       // Thomson              &amp;gt;= 10000                 ~250 bytes&lt;br /&gt;
#define IRMP_SUPPORT_NIKON_PROTOCOL             0       // NIKON camera         &amp;gt;= 10000                 ~250 bytes&lt;br /&gt;
#define IRMP_SUPPORT_NETBOX_PROTOCOL            0       // Netbox keyboard      &amp;gt;= 10000                 ~400 bytes (PROTOTYPE!)&lt;br /&gt;
#define IRMP_SUPPORT_ORTEK_PROTOCOL             0       // ORTEK (Hama)         &amp;gt;= 10000                 ~150 bytes&lt;br /&gt;
#define IRMP_SUPPORT_TELEFUNKEN_PROTOCOL        0       // Telefunken 1560      &amp;gt;= 10000                 ~150 bytes&lt;br /&gt;
#define IRMP_SUPPORT_FDC_PROTOCOL               0       // FDC3402 keyboard     &amp;gt;= 10000 (better 15000)  ~150 bytes (~400 in combination with RC5)&lt;br /&gt;
#define IRMP_SUPPORT_RCCAR_PROTOCOL             0       // RC Car               &amp;gt;= 10000 (better 15000)  ~150 bytes (~500 in combination with RC5)&lt;br /&gt;
#define IRMP_SUPPORT_ROOMBA_PROTOCOL            0       // iRobot Roomba        &amp;gt;= 10000                 ~150 bytes&lt;br /&gt;
#define IRMP_SUPPORT_RUWIDO_PROTOCOL            0       // RUWIDO, T-Home       &amp;gt;= 15000                 ~550 bytes&lt;br /&gt;
#define IRMP_SUPPORT_A1TVBOX_PROTOCOL           0       // A1 TV BOX            &amp;gt;= 15000 (better 20000)  ~300 bytes&lt;br /&gt;
#define IRMP_SUPPORT_LEGO_PROTOCOL              0       // LEGO Power RC        &amp;gt;= 20000                 ~150 bytes&lt;br /&gt;
#define IRMP_SUPPORT_RCMM_PROTOCOL              0       // RCMM 12,24, or 32    &amp;gt;= 20000                 ~150 bytes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedes von [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] unterstützte IR-Protokoll &amp;quot;verbrät&amp;quot; ungefähr den oben angegebenen Speicher an Code. Hier kann man Optimierungen vornehmen: Zum Beispiel ist die Modulationsfrequenz von 455kHz beim [[IRMP#B&amp;amp;O|B&amp;amp;O]]-Protokoll weitab von den Frequenzen, die von den anderen Protokollen verwendet werden. Hier braucht man evtl. andere IR-Empfänger, anderenfalls kann man diese Protokolle einfach deaktiveren. Zum Beispiel kann man mit einem TSOP1738 kein [[IRMP#B&amp;amp;O|B&amp;amp;O]]-Protokoll (455kHz) mehr empfangen. &lt;br /&gt;
&lt;br /&gt;
Ausserdem werden die Protokolle [[IRMP#SIEMENS_+_RUWIDO|SIEMENS]]/[[IRMP#FDC|FDC]]/[[IRMP#RCCAR|RCCAR]] erst ab einer Scan-Frequenz von ca. 15kHz zuverlässig erkannt. Bei [[IRMP#LEGO|LEGO]] sind es sogar 20kHz. Wenn man also diese Protokolle nutzen will, muss man [[IRMP#F_INTERRUPTS|F_INTERRUPTS]] entsprechend anpassen, sonst erscheint beim Übersetzen eine entsprechende Warnung und die entsprechenden Protokolle werden dann automatisch abgeschaltet.&lt;br /&gt;
&lt;br /&gt;
==== IRMP_PORT_LETTER + IRMP_BIT_NUMBER ====&lt;br /&gt;
&lt;br /&gt;
Über diese Konstanten wird der Pin am µC beschrieben, an welchem der IR-Empfänger angeschlossen ist.&lt;br /&gt;
&lt;br /&gt;
Standardwert ist PORT B6:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/*---------------------------------------------------------------------------&lt;br /&gt;
 * Change hardware pin here for ATMEL AVR&lt;br /&gt;
 *---------------------------------------------------------------------------&lt;br /&gt;
 */&lt;br /&gt;
#if defined (ATMEL_AVR)                         // use PB6 as IR input on AVR&lt;br /&gt;
#  define IRMP_PORT_LETTER                      B&lt;br /&gt;
#  define IRMP_BIT_NUMBER                       6&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese beiden Werte sind an den tatsächlichen Hardware-Pin des µCs anzupassen. &lt;br /&gt;
&lt;br /&gt;
Dies gilt ebenso für die STM32-µCs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/*----------------------------------------------------------------------------&lt;br /&gt;
 * Change hardware pin here for ARM STM32&lt;br /&gt;
 *----------------------------------------------------------------------------&lt;br /&gt;
 */&lt;br /&gt;
#elif defined (ARM_STM32)                       // use C13 as IR input on STM32&lt;br /&gt;
#  define IRMP_PORT_LETTER                      C&lt;br /&gt;
#  define IRMP_BIT_NUMBER                       13&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bei den PIC-Prozessoren gibt es lediglich die anzupassende Konstante &#039;&#039;&#039;IRMP_PIN&#039;&#039;&#039; - je nach Compiler:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/*----------------------------------------------------------------------------&lt;br /&gt;
 * Change hardware pin here for PIC C18 compiler&lt;br /&gt;
 *----------------------------------------------------------------------------&lt;br /&gt;
 */&lt;br /&gt;
#elif defined (PIC_C18)                         // use RB4 as IR input on PIC&lt;br /&gt;
#  define IRMP_PIN                              PORTBbits.RB4&lt;br /&gt;
&lt;br /&gt;
/*----------------------------------------------------------------------------&lt;br /&gt;
 * Change hardware pin here for PIC CCS compiler&lt;br /&gt;
 *----------------------------------------------------------------------------&lt;br /&gt;
 */&lt;br /&gt;
#elif defined (PIC_CCS)                         // use PB4 as IR input on PIC&lt;br /&gt;
#  define IRMP_PIN                              PIN_B4&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== IRMP_USE_CALLBACK ====&lt;br /&gt;
&lt;br /&gt;
Standardwert:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define IRMP_USE_CALLBACK                      0        // flag: 0 = don&#039;t use callbacks, 1 = use callbacks, default is 0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn man Callbacks einschaltet, wird bei jeder Pegeländerung des Eingangs eine Callback-Funktion aufgerufen. Dies kann zum Beispiel dafür verwendet werden, das eingehende IR-Signal sichtbar zu machen, also als Signal an einem weiteren Pin auszugeben.&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define LED_PORT PORTD                                  // LED at PD6&lt;br /&gt;
#define LED_DDR  DDRD&lt;br /&gt;
#define LED_PIN  6&lt;br /&gt;
&lt;br /&gt;
/*-----------------------------------------------------------------------------------------------------------------------&lt;br /&gt;
 * Called (back) from IRMP module&lt;br /&gt;
 * This example switches a LED (which is connected to Vcc)&lt;br /&gt;
 *-----------------------------------------------------------------------------------------------------------------------&lt;br /&gt;
 */&lt;br /&gt;
void&lt;br /&gt;
led_callback (uint8_t on)&lt;br /&gt;
{&lt;br /&gt;
    if (on)&lt;br /&gt;
    {&lt;br /&gt;
       LED_PORT &amp;amp;= ~(1 &amp;lt;&amp;lt; LED_PIN);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
       LED_PORT |= (1 &amp;lt;&amp;lt; LED_PIN);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main ()&lt;br /&gt;
{&lt;br /&gt;
    ...&lt;br /&gt;
    irmp_init ();&lt;br /&gt;
&lt;br /&gt;
    LED_DDR |= (1 &amp;lt;&amp;lt; LED_PIN);         // LED pin to output&lt;br /&gt;
    LED_PORT |= (1 &amp;lt;&amp;lt; LED_PIN);        // switch LED off (active low)&lt;br /&gt;
    irmp_set_callback_ptr (led_callback);&lt;br /&gt;
&lt;br /&gt;
    sei ();&lt;br /&gt;
    ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== IRMP_LOGGING ====&lt;br /&gt;
&lt;br /&gt;
Mit IRMP_LOGGING kann das Protokollieren von eingehenden IR-Frames eingeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
Standardwert:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define IRMP_LOGGING                            0       // 1: log IR signal (scan), 0: do not. default is 0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weitere Erläuterungen siehe [[IRMP#Scannen_von_unbekannten_IR-Protokollen|Scannen von unbekannten IR-Protokollen]].&lt;br /&gt;
&lt;br /&gt;
=== Anwendung von IRMP ===&lt;br /&gt;
&lt;br /&gt;
Die von [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] unterstützten Protokolle weisen Bitlängen - teilweise variabel, teilweise fest - von 2 bis 48 Bit auf. Diese werden über Preprocessor-Defines beschrieben.&lt;br /&gt;
&lt;br /&gt;
[[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] trennt diese IR-Telegramme prinzipiell in 3 Bereiche:&lt;br /&gt;
&lt;br /&gt;
 1. ID für verwendetes Protokoll&lt;br /&gt;
 2. Adresse bzw. Herstellercode&lt;br /&gt;
 3. Kommando&lt;br /&gt;
&lt;br /&gt;
Mittels der Funktion&lt;br /&gt;
&lt;br /&gt;
   irmp_get_data (IRMP_DATA * irmp_data_p)&lt;br /&gt;
&lt;br /&gt;
kann man ein decodiertes Telegramm abrufen. Der Return-Wert ist 1, wenn ein Telegramm eingelesen wurde, sonst 0. Im ersten Fall werden die Struct-Members&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    irmp_data_p-&amp;gt;protocol (8 Bit)&lt;br /&gt;
    irmp_data_p-&amp;gt;address (16 Bit)&lt;br /&gt;
    irmp_data_p-&amp;gt;command (16 Bit)&lt;br /&gt;
    irmp_data_p-&amp;gt;flags (8 Bit)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gefüllt.&lt;br /&gt;
&lt;br /&gt;
Das heisst: am Ende bekommt man dann über irmp_get_data() einfach drei&lt;br /&gt;
Werte (Protokoll, Adresse und Kommando-Code), die man über ein if oder switch checken kann, z.&amp;amp;nbsp;B. hier eine Routine, welche die Tasten 1-9 auf einer Fernbedienung auswertet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
   IRMP_DATA irmp_data;&lt;br /&gt;
&lt;br /&gt;
   if (irmp_get_data (&amp;amp;irmp_data))&lt;br /&gt;
   {&lt;br /&gt;
      if (irmp_data.protocol == IRMP_NEC_PROTOCOL &amp;amp;&amp;amp;     // NEC-Protokoll&lt;br /&gt;
          irmp_data.address == 0x1234)                   // Adresse 0x1234&lt;br /&gt;
      {&lt;br /&gt;
         switch (irmp_data.command)&lt;br /&gt;
         {&lt;br /&gt;
            case 0x0001: key1_pressed(); break;          // Taste 1&lt;br /&gt;
            case 0x0002: key2_pressed(); break;          // Taste 2&lt;br /&gt;
            ...&lt;br /&gt;
            case 0x0009: key9_pressed(); break;          // Taste 9&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier die möglichen Werte für irmp_data.protocol, siehe auch [http://www.mikrocontroller.net/svnbrowser/irmp/irmpprotocols.h?view=markup irmpprotocols.h]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define IRMP_SIRCS_PROTOCOL                      1              // Sony&lt;br /&gt;
#define IRMP_NEC_PROTOCOL                        2              // NEC, Pioneer, JVC, Toshiba, NoName etc.&lt;br /&gt;
#define IRMP_SAMSUNG_PROTOCOL                    3              // Samsung&lt;br /&gt;
#define IRMP_MATSUSHITA_PROTOCOL                 4              // Matsushita&lt;br /&gt;
#define IRMP_KASEIKYO_PROTOCOL                   5              // Kaseikyo (Panasonic etc)&lt;br /&gt;
#define IRMP_RECS80_PROTOCOL                     6              // Philips, Thomson, Nordmende, Telefunken, Saba&lt;br /&gt;
#define IRMP_RC5_PROTOCOL                        7              // Philips etc&lt;br /&gt;
#define IRMP_DENON_PROTOCOL                      8              // Denon, Sharp&lt;br /&gt;
#define IRMP_RC6_PROTOCOL                        9              // Philips etc&lt;br /&gt;
#define IRMP_SAMSUNG32_PROTOCOL                 10              // Samsung32: no sync pulse at bit 16, length 32 instead of 37&lt;br /&gt;
#define IRMP_APPLE_PROTOCOL                     11              // Apple, very similar to NEC&lt;br /&gt;
#define IRMP_RECS80EXT_PROTOCOL                 12              // Philips, Technisat, Thomson, Nordmende, Telefunken, Saba&lt;br /&gt;
#define IRMP_NUBERT_PROTOCOL                    13              // Nubert&lt;br /&gt;
#define IRMP_BANG_OLUFSEN_PROTOCOL              14              // Bang &amp;amp; Olufsen&lt;br /&gt;
#define IRMP_GRUNDIG_PROTOCOL                   15              // Grundig&lt;br /&gt;
#define IRMP_NOKIA_PROTOCOL                     16              // Nokia&lt;br /&gt;
#define IRMP_SIEMENS_PROTOCOL                   17              // Siemens, e.g. Gigaset&lt;br /&gt;
#define IRMP_FDC_PROTOCOL                       18              // FDC keyboard&lt;br /&gt;
#define IRMP_RCCAR_PROTOCOL                     19              // RC Car&lt;br /&gt;
#define IRMP_JVC_PROTOCOL                       20              // JVC (NEC with 16 bits)&lt;br /&gt;
#define IRMP_RC6A_PROTOCOL                      21              // RC6A, e.g. Kathrein, XBOX&lt;br /&gt;
#define IRMP_NIKON_PROTOCOL                     22              // Nikon&lt;br /&gt;
#define IRMP_RUWIDO_PROTOCOL                    23              // Ruwido, e.g. T-Home Mediareceiver&lt;br /&gt;
#define IRMP_IR60_PROTOCOL                      24              // IR60 (SDA2008)&lt;br /&gt;
#define IRMP_KATHREIN_PROTOCOL                  25              // Kathrein&lt;br /&gt;
#define IRMP_NETBOX_PROTOCOL                    26              // Netbox keyboard (bitserial)&lt;br /&gt;
#define IRMP_NEC16_PROTOCOL                     27              // NEC with 16 bits (incl. sync)&lt;br /&gt;
#define IRMP_NEC42_PROTOCOL                     28              // NEC with 42 bits&lt;br /&gt;
#define IRMP_LEGO_PROTOCOL                      29              // LEGO Power Functions RC&lt;br /&gt;
#define IRMP_THOMSON_PROTOCOL                   30              // Thomson&lt;br /&gt;
#define IRMP_BOSE_PROTOCOL                      31              // BOSE&lt;br /&gt;
#define IRMP_A1TVBOX_PROTOCOL                   32              // A1 TV Box&lt;br /&gt;
#define IRMP_ORTEK_PROTOCOL                     33              // ORTEK - Hama&lt;br /&gt;
#define IRMP_TELEFUNKEN_PROTOCOL                34              // Telefunken (1560)&lt;br /&gt;
#define IRMP_ROOMBA_PROTOCOL                    35              // iRobot Roomba vacuum cleaner&lt;br /&gt;
#define IRMP_RCMM32_PROTOCOL                    36              // Fujitsu-Siemens (Activy remote control)&lt;br /&gt;
#define IRMP_RCMM24_PROTOCOL                    37              // Fujitsu-Siemens (Activy keyboard)&lt;br /&gt;
#define IRMP_RCMM12_PROTOCOL                    38              // Fujitsu-Siemens (Activy keyboard)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Werte für die Adresse und das Kommando muss man natürlich einmal für eine unbekannte Fernbedienung auslesen und dann über ein UART oder LC-Display ausgeben, um sie dann im Programm hart zu kodieren. Oder man hat eine kleine Anlernroutine, wo man einmal die gewünschten Tasten drücken muss, um sie anschließend im EEPROM abzuspeichern. Ein Beispiel dazu findet man im Artikel [http://www.mikrocontroller.net/articles/DIY_Lernfähige_Fernbedienung_mit_IRMP Lernfähige IR-Fernbedienung mit IRMP].&lt;br /&gt;
&lt;br /&gt;
Eine weitere [http://www.mikrocontroller.net/svnbrowser/irmp/main.c?view=markup Beispiel-Main-Funktion] ist im Zip-File enthalten, da sieht man dann auch die Initialisierung des Timers.&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;Entprellen&amp;quot; von Tasten ===&lt;br /&gt;
&lt;br /&gt;
Um zu unterscheiden, ob eine Taste lange gedrückt wurde oder lediglich einzeln, dient das Bit IRMP_FLAG_REPETITION. Dieses wird im Struct-Member &#039;&#039;&#039;flags&#039;&#039;&#039; gesetzt, wenn eine Taste auf der Fernbedienung längere Zeit gedrückt wurde und dadurch immer wieder dasselbe Kommando innerhalb kurzer Zeitabstände ausgesandt wird.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    if (irmp_data.flags &amp;amp; IRMP_FLAG_REPETITION)&lt;br /&gt;
    {&lt;br /&gt;
      // Benutzer hält die Taste länger runter&lt;br /&gt;
      // entweder:&lt;br /&gt;
      //   ich ignoriere die (Wiederholungs-)Taste&lt;br /&gt;
      // oder:&lt;br /&gt;
      //   ich benutze diese Info, um einen Repeat-Effekt zu nutzen&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
      // Es handelt sich um eine neue Taste&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dies kann zum Beispiel dafür genutzt werden, um die Tasten 0-9 zu &amp;quot;entprellen&amp;quot;, indem man Kommandos mit gesetztem Bit IRMP_FLAG_REPETITION ignoriert. Bei dem Drücken auf die Tasten VOLUME+ oder VOLUME- kann die wiederholte Auswertung ein und desselben Kommandos aber durchaus gewünscht sein - zum Beispiel, um [[LED-Fading|LEDs zu faden]].&lt;br /&gt;
&lt;br /&gt;
Wenn man nur Einzeltasten auswerten will, kann man obigen IF-Block reduzieren auf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    if (! (irmp_data.flags &amp;amp; IRMP_FLAG_REPETITION))&lt;br /&gt;
    {&lt;br /&gt;
      // Es handelt sich um eine neue Taste&lt;br /&gt;
      // ACTION!&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Arbeitsweise ==&lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Working Horse&amp;quot; von [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] ist die Interrupt Service Routine irmp_ISR() welche 15.000 mal pro Sekunde aufgerufen werden sollte. Weicht dieser Wert ab, muss die Preprocessor-Konstante [[IRMP#F_INTERRUPTS|F_INTERRUPTS]] in [http://www.mikrocontroller.net/svnbrowser/irmp/irmpconfig.h?view=markup irmpconfig.h] angepasst werden. Der Wert kann zwischen 10kHz und 20kHz eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
irmp_ISR() detektiert zunächst die Länge und die Form des/der Startbits und ermittelt daraus das verwendete Protokoll. Sobald das Protokoll erkannt wurde, werden die weiter einzulesenden Bits parametrisiert, um dann möglichst effektiv in den weiteren Aufrufen das komplette IR-Telegramm einzulesen.&lt;br /&gt;
&lt;br /&gt;
Um direkt Kritikern den Wind aus den Segeln zu nehmen:&lt;br /&gt;
&lt;br /&gt;
Ich weiss, die ISR ist ziemlich groß. Aber da sie sich wie eine State Machine verhält, ist der tatsächlich ausgeführte Code pro Durchlauf relativ gering. Solange es &amp;quot;dunkel&amp;quot; ist (und das ist es ja die meiste Zeit ;-)) ist die aufgewendete Zeit sogar verschwindend gering. Im WordClock-Projekt werden mit ein- und demselben Timer 8 ISRs aufgerufen, davon ist die irmp_ISR() nur eine unter vielen. Bei mindestens 8 MHz CPU-Takt traten bisher keine Timing-Probleme auf. Daher sehe ich bei der Länge von irmp_ISR überhaupt kein Problem.&lt;br /&gt;
&lt;br /&gt;
Ein Quarz ist nicht unbedingt notwendig, es funktioniert auch mit dem internen Oszillator des AVRs, wenn man die Prescaler-Fuse entsprechend gesetzt hat, dass die CPU auch mit 8MHz rennt ... Die Fuse-Werte für einen ATMEGA88 findet man in [http://www.mikrocontroller.net/svnbrowser/irmp/main.c?view=markup main.c].&lt;br /&gt;
&lt;br /&gt;
== Scannen von unbekannten IR-Protokollen ==&lt;br /&gt;
&lt;br /&gt;
Stellt man in [http://www.mikrocontroller.net/svnbrowser/irmp/irmpconfig.h?view=markup irmpconfig.h] in der Zeile&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    #define IRMP_LOGGING    0   // 1: log IR signal (scan), 0: do not (default)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
den Wert für [[IRMP#IRMP_LOGGING|IRMP_LOGGING]] auf 1, wird in [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] eine Protokollierung eingeschaltet: Es werden dann die Hell- und Dunkelphase auf dem UART des Microntrollers mit 9600Bd ausgegeben: 1=Dunkel, 0=Hell. Eventuell müssen dann die Konstanten in den Funktionen uart_init() und uart_putc() angepasst werden; das kommt auf den verwendeten AVR-µC an.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hinweis: Für PIC-Prozessoren gibt es ein eigenes Logging-Modul namens [http://www.mikrocontroller.net/svnbrowser/irmp/irmpextlog.c?view=markup irmpextlog.c]. Dieses ermöglicht das Logging über USB. Für AVR-Prozessoren ist [http://www.mikrocontroller.net/svnbrowser/irmp/irmpextlog.c?view=markup irmpextlog.c] irrelevant&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Nimmt man diese Protokoll-Scans mit einem Terminal-Emulationsprogramm auf und speichert sie dann als normale Datei ab, kann man diese Scan-Dateien zur Analyse verwenden, um damit [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] an das unbekannte Protokoll anzupassen - siehe nächstes Kapitel.&lt;br /&gt;
&lt;br /&gt;
Wer eine Fernbedienung hat, die nicht von [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] unterstützt wird, kann mir  ([http://www.mikrocontroller.net/user/show/ukw ukw]) gern die Scan-Dateien zuschicken. Ich schaue dann, ob das Protokoll in das IRMP-Konzept passt und passe gegebenenfalls den Source an.&lt;br /&gt;
&lt;br /&gt;
== IRMP unter Linux und Windows ==&lt;br /&gt;
&lt;br /&gt;
=== Übersetzen ===&lt;br /&gt;
&lt;br /&gt;
[http://www.mikrocontroller.net/svnbrowser/irmp/irmp.c?view=markup irmp.c] lässt sich auch unter Linux direkt kompilieren, um damit Infrarot-Scans, welche in Dateien gespeichert sind, direkt zu testen. Im Unterordner IR-Data finden sich solche Dateien, die man dem [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] direkt zum &amp;quot;Fraß&amp;quot; vorwerfen kann. &lt;br /&gt;
&lt;br /&gt;
Das Übersetzen von [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] geht folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
    make -f makefile.lnx&lt;br /&gt;
&lt;br /&gt;
Dabei werden 3 IRMP-Versionen erzeugt:&lt;br /&gt;
&lt;br /&gt;
* irmp-10kHz: Version für 10kHz Scans&lt;br /&gt;
* irmp-15kHz: Version für 15kHz Scans&lt;br /&gt;
* irmp-20kHz: Version für 20kHz Scans&lt;br /&gt;
&lt;br /&gt;
=== Aufruf von IRMP ===&lt;br /&gt;
&lt;br /&gt;
Der Aufruf geschieht dann über:&lt;br /&gt;
&lt;br /&gt;
  ./irmp-nnkHz [-l|-p|-a|-v] &amp;lt; scan-file&lt;br /&gt;
&lt;br /&gt;
Die angegebenen Optionen schließen sich aus, das heisst, es kann jeweils nur eine Option zu einer Zeit angegeben werden:&lt;br /&gt;
&lt;br /&gt;
Option:&lt;br /&gt;
&lt;br /&gt;
   -l  List             gibt eine Liste der Pulse und Pausen aus&lt;br /&gt;
   -a analyze           analysiert die Puls-/Pausen und schreibt ein &amp;quot;Spektrum&amp;quot; in ASCII-Form&lt;br /&gt;
   -v verbose           ausführliche Ausgabe&lt;br /&gt;
   -p  Print Timings    gibt für alle Protokolle eine Timing-Tabelle aus&lt;br /&gt;
&lt;br /&gt;
Beispiele:&lt;br /&gt;
&lt;br /&gt;
=== Normale Ausgabe ===&lt;br /&gt;
&lt;br /&gt;
   ./irmp-10kHz &amp;lt; IR-Data/orion_vcr_07660BM070.txt&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 -------------------------------------------------------------------------&lt;br /&gt;
 # Taste 1&lt;br /&gt;
 00000001110111101000000001111111 p =  2, a = 0x7b80, c = 0x0001, f = 0x00&lt;br /&gt;
 -------------------------------------------------------------------------&lt;br /&gt;
 # Taste 2&lt;br /&gt;
 00000001110111100100000010111111 p =  2, a = 0x7b80, c = 0x0002, f = 0x00&lt;br /&gt;
 -------------------------------------------------------------------------&lt;br /&gt;
 # Taste 3&lt;br /&gt;
 00000001110111101100000000111111 p =  2, a = 0x7b80, c = 0x0003, f = 0x00&lt;br /&gt;
 -------------------------------------------------------------------------&lt;br /&gt;
 # Taste 4&lt;br /&gt;
 00000001110111100010000011011111 p =  2, a = 0x7b80, c = 0x0004, f = 0x00&lt;br /&gt;
 -------------------------------------------------------------------------&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Listen-Ausgabe ===&lt;br /&gt;
&lt;br /&gt;
   ./irmp-10kHz -l &amp;lt; IR-Data/orion_vcr_07660BM070.txt&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
# Taste 1&lt;br /&gt;
pulse: 91 pause: 44&lt;br /&gt;
pulse: 6 pause: 5&lt;br /&gt;
pulse: 6 pause: 6&lt;br /&gt;
pulse: 6 pause: 5&lt;br /&gt;
pulse: 6 pause: 5&lt;br /&gt;
pulse: 6 pause: 5&lt;br /&gt;
pulse: 6 pause: 6&lt;br /&gt;
pulse: 6 pause: 5&lt;br /&gt;
pulse: 6 pause: 16&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analyse ===&lt;br /&gt;
&lt;br /&gt;
   ./irmp-10kHz -a &amp;lt; IR-Data/orion_vcr_07660BM070.txt&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
START PULSES:&lt;br /&gt;
 90 o 1&lt;br /&gt;
 91 oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo 33&lt;br /&gt;
 92 ooo 2&lt;br /&gt;
pulse avg: 91.0=9102.8 us, min: 90=9000.0 us, max: 92=9200.0 us, tol:  1.1%&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
START PAUSES:&lt;br /&gt;
 43 oo 1&lt;br /&gt;
 44 oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo 25&lt;br /&gt;
 45 oooooooooooooooooooooooo 10&lt;br /&gt;
pause avg: 44.2=4425.0 us, min: 43=4300.0 us, max: 45=4500.0 us, tol:  2.8%&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
PULSES:&lt;br /&gt;
  5 o 17&lt;br /&gt;
  6 ooooooooooooooooooooooooooooooooooooooooooooooooooooooo 562&lt;br /&gt;
  7 oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo 609&lt;br /&gt;
pulse avg:  6.5= 649.8 us, min:  5= 500.0 us, max:  7= 700.0 us, tol: 23.1%&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
PAUSES:&lt;br /&gt;
  4 ooooooooooooooooooooooo 169&lt;br /&gt;
  5 oooooooooooooooooooooooooooooooooooooooooooooooooooooooooo 412&lt;br /&gt;
  6 oooo 31&lt;br /&gt;
pause avg:  4.8= 477.5 us, min:  4= 400.0 us, max:  6= 600.0 us, tol: 25.7%&lt;br /&gt;
 15 oooooo 43&lt;br /&gt;
 16 oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo 425&lt;br /&gt;
 17 oooooooooo 72&lt;br /&gt;
pause avg: 16.1=1605.4 us, min: 15=1500.0 us, max: 17=1700.0 us, tol:  6.6%&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hier sieht man die gemessenen Zeiten aller Pulse und Pausen als (liegende) Glockenkurven, welche natürlich wegen der ASCII-Darstellung nicht gerade einer Idealkurve entsprechen. Je schmaler die gemessenen Kanäle, desto besser ist das Timing der Fernbedienung.&lt;br /&gt;
&lt;br /&gt;
Aus obigem Output kann man herauslesen:&lt;br /&gt;
&lt;br /&gt;
* Das Start-Bit hat eine Pulslänge zwischen 9000 und 9200 usec, im Mittel sind es 9102 usec. Die Abweichung von diesem Mittelwert liegt bei 1,1 Prozent.&lt;br /&gt;
&lt;br /&gt;
* Das Start-Bit hat eine Pausenlänge zwischen 4300 usec und 4500 usec, der Mittelwert beträgt 4424 usec. Der Fehler liegt bei 2,8 Prozent.&lt;br /&gt;
&lt;br /&gt;
* Die Pulslänge eines Datenbits liegt zwischen 500 usec und 700 usec, im Mittel sind es 650 usec, der Fehler liegt bei (stolzen) 23,1 Prozent!&lt;br /&gt;
&lt;br /&gt;
Desweiteren gibt es noch 2 verschieden lange Pausen (für die Bits 0 und 1), das Ablesen der Werte überlasse ich dem geneigten Leser ;-)&lt;br /&gt;
&lt;br /&gt;
=== Ausführliche Ausgabe ===&lt;br /&gt;
&lt;br /&gt;
    ./irmp-10kHz -v &amp;lt; IR-Data/orion_vcr_07660BM070.txt&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
# 1 - IR-cmd: 0x0001&lt;br /&gt;
   0.200ms [starting pulse]&lt;br /&gt;
  13.700ms [start-bit: pulse = 91, pause = 44]&lt;br /&gt;
protocol = NEC, start bit timings: pulse:  62 - 118, pause:  30 -  60&lt;br /&gt;
pulse_1:   3 -   8&lt;br /&gt;
pause_1:  11 -  23&lt;br /&gt;
pulse_0:   3 -   8&lt;br /&gt;
pause_0:   3 -   8&lt;br /&gt;
command_offset: 16&lt;br /&gt;
command_len:     16&lt;br /&gt;
complete_len:    32&lt;br /&gt;
stop_bit:         1&lt;br /&gt;
  14.800ms [bit  0: pulse =   6, pause =   5] 0&lt;br /&gt;
  16.000ms [bit  1: pulse =   6, pause =   6] 0&lt;br /&gt;
  17.100ms [bit  2: pulse =   6, pause =   5] 0&lt;br /&gt;
  18.200ms [bit  3: pulse =   6, pause =   5] 0&lt;br /&gt;
  19.300ms [bit  4: pulse =   6, pause =   5] 0&lt;br /&gt;
  20.500ms [bit  5: pulse =   6, pause =   6] 0&lt;br /&gt;
  21.600ms [bit  6: pulse =   6, pause =   5] 0&lt;br /&gt;
  23.800ms [bit  7: pulse =   6, pause =  16] 1&lt;br /&gt;
  26.100ms [bit  8: pulse =   6, pause =  17] 1&lt;br /&gt;
  28.300ms [bit  9: pulse =   6, pause =  16] 1&lt;br /&gt;
  29.500ms [bit 10: pulse =   6, pause =   6] 0&lt;br /&gt;
  31.700ms [bit 11: pulse =   6, pause =  16] 1&lt;br /&gt;
  34.000ms [bit 12: pulse =   6, pause =  17] 1&lt;br /&gt;
  36.200ms [bit 13: pulse =   6, pause =  16] 1&lt;br /&gt;
  38.500ms [bit 14: pulse =   6, pause =  17] 1&lt;br /&gt;
  39.600ms [bit 15: pulse =   6, pause =   5] 0&lt;br /&gt;
  41.900ms [bit 16: pulse =   6, pause =  17] 1&lt;br /&gt;
  43.000ms [bit 17: pulse =   6, pause =   5] 0&lt;br /&gt;
  44.100ms [bit 18: pulse =   6, pause =   5] 0&lt;br /&gt;
  45.200ms [bit 19: pulse =   6, pause =   5] 0&lt;br /&gt;
  46.400ms [bit 20: pulse =   7, pause =   5] 0&lt;br /&gt;
  47.500ms [bit 21: pulse =   6, pause =   5] 0&lt;br /&gt;
  48.600ms [bit 22: pulse =   6, pause =   5] 0&lt;br /&gt;
  49.800ms [bit 23: pulse =   6, pause =   6] 0&lt;br /&gt;
  50.900ms [bit 24: pulse =   5, pause =   6] 0&lt;br /&gt;
  53.100ms [bit 25: pulse =   6, pause =  16] 1&lt;br /&gt;
  55.400ms [bit 26: pulse =   6, pause =  17] 1&lt;br /&gt;
  57.600ms [bit 27: pulse =   6, pause =  16] 1&lt;br /&gt;
  59.900ms [bit 28: pulse =   6, pause =  17] 1&lt;br /&gt;
  62.100ms [bit 29: pulse =   6, pause =  16] 1&lt;br /&gt;
  64.400ms [bit 30: pulse =   6, pause =  17] 1&lt;br /&gt;
  66.700ms [bit 31: pulse =   6, pause =  17] 1&lt;br /&gt;
stop bit detected&lt;br /&gt;
  67.300ms code detected, length = 32&lt;br /&gt;
  67.300ms p =  2, a = 0x7b80, c = 0x0001, f = 0x00&lt;br /&gt;
-------------------------------------------------------------------------------&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Timing-Tabelle ===&lt;br /&gt;
&lt;br /&gt;
     ./irmp-10kHz -p&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
IRMP_TIMEOUT_LEN:        165&lt;br /&gt;
IRMP_KEY_REPETITION_LEN  1500&lt;br /&gt;
&lt;br /&gt;
PROTOCOL       S  S-PULSE    S-PAUSE    PULSE-0    PAUSE-0    PULSE-1    PAUSE-1&lt;br /&gt;
====================================================================================&lt;br /&gt;
SIRCS          1   21 -  27    4 -   7    4 -   8    4 -   8   10 -  14    4 -   8&lt;br /&gt;
NEC            1   53 - 127   26 -  64    2 -   9    2 -   9    2 -   9    9 -  25&lt;br /&gt;
NEC (rep)      1   53 - 127   13 -  32    2 -   9    2 -   9    2 -   9    9 -  25&lt;br /&gt;
SAMSUNG        1   40 -  51   40 -  51    3 -   8    2 -   7    3 -   8    9 -  20&lt;br /&gt;
MATSUSHITA     1   27 -  43   27 -  43    4 -  13    4 -  13    4 -  13   15 -  38&lt;br /&gt;
KASEIKYO       1   29 -  38   14 -  20    1 -   8    1 -   7    1 -   8    5 -  20&lt;br /&gt;
RECS80         1    1 -   3   66 -  83    0 -   3   43 -  55    0 -   3   66 -  83&lt;br /&gt;
RC5            1    7 -  11    7 -  11    7 -  11&lt;br /&gt;
DENON          1    1 -   4               1 -   4    6 -  10    1 -   4   16 -  22&lt;br /&gt;
RC6            1   23 -  30    7 -  11    3 -   6&lt;br /&gt;
RECS80EXT      1    1 -   3   34 -  39    0 -   3   43 -  55    0 -   3   66 -  83&lt;br /&gt;
NUBERT         1   10 -  17    2 -   5    3 -   7    9 -  17   10 -  17    2 -   5&lt;br /&gt;
BANG_OLUFSEN   1    1 -   3   27 -  35&lt;br /&gt;
BANG_OLUFSEN   2    1 -   3   27 -  35&lt;br /&gt;
BANG_OLUFSEN   3    1 -   3  140 - 165&lt;br /&gt;
BANG_OLUFSEN   4    1 -   3   27 -  35&lt;br /&gt;
BANG_OLUFSEN   -                          1 -   3   27 -  35    1 -   3   83 - 104&lt;br /&gt;
GRUNDIG/NOKIA  1    3 -   7   22 -  33    3 -   7&lt;br /&gt;
SIEMENS        1    2 -   4    2 -   4    2 -   4&lt;br /&gt;
FDC            1   18 -  24    8 -  12    1 -   5    1 -   3    1 -   5    5 -  10&lt;br /&gt;
RCCAR          1   17 -  23   17 -  23    4 -   8    5 -  13    4 -   8    2 -   7&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Zahlen sind in diesem Fall Einheiten von 10kHz. Zum Beispiel entspricht die Zahl 27 dem Wert 27/10000 = 2,7msec.&lt;br /&gt;
&lt;br /&gt;
Bei längeren Ausgaben sollte man das Programm &amp;quot;less&amp;quot; verwenden, um seitenweise zu blättern, z.B.:&lt;br /&gt;
&lt;br /&gt;
    ./irmp-10kHz -v &amp;lt; IR-Data/Samsung_DVD_Rec_00062C.txt | less&lt;br /&gt;
&lt;br /&gt;
Diese Scan-Dateien halfen mir nicht nur bei der Entwicklung des IRMP, sondern können auch bei der Anpassung des Sources an neue IR-Protokolle sehr hilfreich sein.&lt;br /&gt;
&lt;br /&gt;
Mittlerweile kann man [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] auch unter Windows nutzen, nämlich folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
* Eingabeaufforderung starten&lt;br /&gt;
* In das Verzeichnis irmp wechseln&lt;br /&gt;
* Aufruf von:&lt;br /&gt;
            irmp-10kHz.exe &amp;lt; IR-Data\rc5x.txt&lt;br /&gt;
&lt;br /&gt;
Da manche Ausgaben sehr lang werden, empfiehlt es sich auch hier, die Ausgabe in eine Datei zu lenken oder in den more weiterzuleiten, damit man seitenweise blättern kann:&lt;br /&gt;
&lt;br /&gt;
            irmp-10kHz.exe &amp;lt; IR-Data\rc5x.txt | more&lt;br /&gt;
&lt;br /&gt;
Auch hier gelten dieselben Optionen wie für die Linux-Version.&lt;br /&gt;
&lt;br /&gt;
== Fernbedienungen ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Protokoll || Bezeichnung || Gerät || Device Address&lt;br /&gt;
|-&lt;br /&gt;
| [[IRMP#NEC_+_extended_NEC|NEC]] || Toshiba CT-9859 || Fernseher || 0x5F40&lt;br /&gt;
|-&lt;br /&gt;
| || Toshiba VT-728G || V-728G Videorekorder || 0x5B44&lt;br /&gt;
|-&lt;br /&gt;
| || Elta 8848 MP 4 || DVD-Player || 0x7F00&lt;br /&gt;
|-&lt;br /&gt;
| || AS-218 || Askey TV-View CHP03X (TV-Karte) || 0x3B86&lt;br /&gt;
|-&lt;br /&gt;
| || Cyberhome ??? || Cyberhome DVD Player || 0x6D72&lt;br /&gt;
|-&lt;br /&gt;
| || WD TV Live || Western Digital Multimediaplayer || 0x1F30&lt;br /&gt;
|-&lt;br /&gt;
| || Canon WL-DC100 || Kamera Canon PowerShot G5 || 0xB1CA&lt;br /&gt;
|-&lt;br /&gt;
| [[IRMP#NEC16|NEC16]] || Daewoo || Videorekorder || 0x0015&lt;br /&gt;
|-&lt;br /&gt;
| [[IRMP#KASEIKYO|KASEIKYO]] || Technics EUR646497 || AV Receiver SA-AX 730 || 0x2002&lt;br /&gt;
|-&lt;br /&gt;
| || Panasonic TV || Fernseher TX-L32EW6 || 0x2002&lt;br /&gt;
|-&lt;br /&gt;
| [[IRMP#RC5_+_RC5X|RC5]] || Loewe Assist/RC3/RC4 || Fernseher (FB auf TV-Mode) || 0x0000&lt;br /&gt;
|-&lt;br /&gt;
| [[IRMP#RC6_+_RC6A|RC6]] || Philips Television || Fernseher (FB auf TV-Mode) || 0x0000&lt;br /&gt;
|-&lt;br /&gt;
| [[IRMP#SIRCS|SIRCS]] || Sony RM-816 || Fernseher (FB auf TV-Mode) || 0x0000&lt;br /&gt;
|-&lt;br /&gt;
| [[IRMP#DENON|DENON]] || DENON RC970 || AVR3805 (Verstärker) || 0x0008&lt;br /&gt;
|-&lt;br /&gt;
| || DENON RC970 || DVD/CD-Player || 0x0002&lt;br /&gt;
|-&lt;br /&gt;
| || DENON RC970 || Tuner || 0x0006&lt;br /&gt;
|-&lt;br /&gt;
| [[IRMP#SAMSUNG32|SAMSUNG32]] || Samsung AA59-00484A || LE40D550 Fernseher || 0x0707&lt;br /&gt;
|-&lt;br /&gt;
| || LG AKB72033901 || Blu-Ray Player BD370 || 0x2D2D&lt;br /&gt;
|-&lt;br /&gt;
| [[IRMP#APPLE|APPLE]] || Apple || Apple Dock (iPod 2) || 0x0020&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== IR-Tastaturen ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:irmp-fdc3402.jpg|miniatur|FDC-3402-Tastatur]]&lt;br /&gt;
&lt;br /&gt;
[[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] unterstützt ab Version 1.7.0 auch IR-Tastaturen, nämlich die Infrarot-Tastatur FDC-3402 - erhältlich bei Pollin (Art. 711 056) für weniger als 2 EUR.&lt;br /&gt;
&lt;br /&gt;
Beim Erkennen einer Taste gibt [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] folgende Daten zurück:&lt;br /&gt;
&lt;br /&gt;
 Protokoll-Nummer (irmp_data.protocol): 18&lt;br /&gt;
 Addresse         (irmp_data.address):  0x003F&lt;br /&gt;
&lt;br /&gt;
Als Kommando (irmp_data.command) werden folgende Werte zurückgeliefert:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Code || Taste || Code || Taste || Code || Taste || Code || Taste || Code || Taste || Code || Taste || Code || Taste || Code || Taste&lt;br /&gt;
|-&lt;br /&gt;
| 0x0000 ||      || 0x0010 || TAB || 0x0020 || &#039;s&#039; || 0x0030 || &#039;c&#039; || 0x0040 ||      || 0x0050 || HOME || 0x0060 ||      || 0x0070 || MENUE&lt;br /&gt;
|-&lt;br /&gt;
| 0x0001 || &#039;^&#039; || 0x0011 || &#039;q&#039; || 0x0021 || &#039;d&#039; || 0x0031 || &#039;v&#039; || 0x0041 ||      || 0x0051 || END || 0x0061 ||      || 0x0071 || BACK&lt;br /&gt;
|-&lt;br /&gt;
| 0x0002 || &#039;1&#039; || 0x0012 || &#039;w&#039; || 0x0022 || &#039;f&#039; || 0x0032 || &#039;b&#039; || 0x0042 ||      || 0x0052 ||      || 0x0062 ||      || 0x0072 || FORWARD&lt;br /&gt;
|-&lt;br /&gt;
| 0x0003 || &#039;2&#039; || 0x0013 || &#039;e&#039; || 0x0023 || &#039;g&#039; || 0x0033 || &#039;n&#039; || 0x0043 ||      || 0x0053 || UP || 0x0063 ||      || 0x0073 || ADDRESS&lt;br /&gt;
|-&lt;br /&gt;
| 0x0004 || &#039;3&#039; || 0x0014 || &#039;r&#039; || 0x0024 || &#039;h&#039; || 0x0034 || &#039;m&#039; || 0x0044 ||      || 0x0054 || DOWN || 0x0064 ||      || 0x0074 || WINDOW&lt;br /&gt;
|-&lt;br /&gt;
| 0x0005 || &#039;4&#039; || 0x0015 || &#039;t&#039; || 0x0025 || &#039;j&#039; || 0x0035 || &#039;,&#039; || 0x0045 ||      || 0x0055 || PAGE_UP || 0x0065 ||      || 0x0075 || 1ST_PAGE&lt;br /&gt;
|-&lt;br /&gt;
| 0x0006 || &#039;5&#039; || 0x0016 || &#039;z&#039; || 0x0026 || &#039;k&#039; || 0x0036 || &#039;.&#039; || 0x0046 ||      || 0x0056 || PAGE_DOWN || 0x0066 ||      || 0x0076 || STOP&lt;br /&gt;
|-&lt;br /&gt;
| 0x0007 || &#039;6&#039; || 0x0017 || &#039;u&#039; || 0x0027 || &#039;l&#039; || 0x0037 || &#039;-&#039; || 0x0047 ||      || 0x0057 ||      || 0x0067 ||      || 0x0077 || MAIL&lt;br /&gt;
|-&lt;br /&gt;
| 0x0008 || &#039;7&#039; || 0x0018 || &#039;i&#039; || 0x0028 || &#039;ö&#039; || 0x0038 ||      || 0x0048 ||      || 0x0058 ||      || 0x0068 ||      || 0x0078 || FAVORITES&lt;br /&gt;
|-&lt;br /&gt;
| 0x0009 || &#039;8&#039; || 0x0019 || &#039;o&#039; || 0x0029 || &#039;ä&#039; || 0x0039 || SHIFT_RIGHT || 0x0049 ||      || 0x0059 || RIGHT || 0x0069 ||      || 0x0079 || NEW_PAGE&lt;br /&gt;
|-&lt;br /&gt;
| 0x000A || &#039;9&#039; || 0x001A || &#039;p&#039; || 0x002A || &#039;#&#039; || 0x003A || CTRL || 0x004A ||      || 0x005A ||      || 0x006A ||      || 0x007A || SETUP&lt;br /&gt;
|-&lt;br /&gt;
| 0x000B || &#039;0&#039; || 0x001B || &#039;ü&#039; || 0x002B || CR || 0x003B ||      || 0x004B || INSERT || 0x005B ||      || 0x006B ||      || 0x007B || FONT&lt;br /&gt;
|-&lt;br /&gt;
| 0x000C || &#039;ß&#039; || 0x001C || &#039;+&#039; || 0x002C || SHIFT_LEFT || 0x003C || ALT_LEFT || 0x004C || DELETE || 0x005C ||      || 0x006C ||      || 0x007C || PRINT&lt;br /&gt;
|-&lt;br /&gt;
| 0x000D || &#039;´&#039; || 0x001D ||      || 0x002D || &#039;&amp;lt;&#039; || 0x003D || SPACE || 0x004D ||      || 0x005D ||      || 0x006D ||      || 0x007D ||&lt;br /&gt;
|-&lt;br /&gt;
| 0x000E ||      || 0x001E || CAPSLOCK || 0x002E || &#039;y&#039; || 0x003E || ALT_RIGHT || 0x004E ||      || 0x005E ||      || 0x006E || ESCAPE || 0x007E || ON_OFF&lt;br /&gt;
|-&lt;br /&gt;
| 0x000F || BACKSPACE || 0x001F || &#039;a&#039; || 0x002F || &#039;x&#039; || 0x003F ||      || 0x004F || LEFT || 0x005F ||      || 0x006F ||      || 0x007F ||&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Zusatztasten links:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Code || Taste&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
| 0x0400 || KEY_MOUSE_1&lt;br /&gt;
|-&lt;br /&gt;
| 0x0800 || KEY_MOUSE_2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Dabei gelten die obigen Werte für das Drücken einer Taste. Wird die Taste wieder losgelassen, setzt [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] zusätzlich das 8. Bit im Kommando.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
      Taste &#039;a&#039; drücken:   0x001F&lt;br /&gt;
      Taste &#039;a&#039; loslassen: 0x009F&lt;br /&gt;
&lt;br /&gt;
Ausnahme ist die EIN/AUS-Taste: Diese sendet nur beim Drücken einen Code, nicht beim Loslassen.&lt;br /&gt;
&lt;br /&gt;
Wird eine Taste länger gedrückt, wird das in irmp_data.flag angezeigt.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
                           command   flag&lt;br /&gt;
      Taste &#039;a&#039; drücken:   0x001F    0x00&lt;br /&gt;
      Taste &#039;a&#039; drücken:   0x001F    0x01&lt;br /&gt;
      Taste &#039;a&#039; drücken:   0x001F    0x01&lt;br /&gt;
      Taste &#039;a&#039; drücken:   0x001F    0x01&lt;br /&gt;
      ....&lt;br /&gt;
      Taste &#039;a&#039; loslassen: 0x009F    0x00&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Werden Tastenkombinationen (zum Beispiel für ein großes &#039;A&#039;) gedrückt, dann sind die Rückgabewerte von [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] in folgendem Ablauf zu sehen:&lt;br /&gt;
&lt;br /&gt;
      Linke SHIFT-Taste drücken:   0x0002&lt;br /&gt;
      Taste &#039;a&#039; drücken:           0x001F&lt;br /&gt;
      Taste &#039;a&#039; loslassen:         0x009F&lt;br /&gt;
      Linke SHIFT-Taste loslassen: 0x0082&lt;br /&gt;
&lt;br /&gt;
In [http://www.mikrocontroller.net/svnbrowser/irmp/irmp.c?view=markup irmp.c] findet man für die LINUX-Version eine Funktion get_fdc_key(), welche als Vorlage dienen mag, die Keycodes einer FDC-Tastatur in die entsprechenden ASCII-Codes umzuwandeln. Diese Funktion kann man entweder lokal auf dem µC nutzen, um die Keycodes zu decodieren, oder auf einem Hostsystem (z.B. PC), an welches die IRMP-Data-Struktur gesandt wird. Dafür sollte man die Funktion incl. der dazugehörenden Preprozessor-Konstanten in seinen Applikations-Quelltext kopieren.&lt;br /&gt;
&lt;br /&gt;
Hier der entsprechende Auszug:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define STATE_LEFT_SHIFT    0x01&lt;br /&gt;
#define STATE_RIGHT_SHIFT   0x02&lt;br /&gt;
#define STATE_LEFT_CTRL     0x04&lt;br /&gt;
#define STATE_LEFT_ALT      0x08&lt;br /&gt;
#define STATE_RIGHT_ALT     0x10&lt;br /&gt;
&lt;br /&gt;
#define KEY_ESCAPE          0x1B            // keycode = 0x006e&lt;br /&gt;
#define KEY_MENUE           0x80            // keycode = 0x0070&lt;br /&gt;
#define KEY_BACK            0x81            // keycode = 0x0071&lt;br /&gt;
#define KEY_FORWARD         0x82            // keycode = 0x0072&lt;br /&gt;
#define KEY_ADDRESS         0x83            // keycode = 0x0073&lt;br /&gt;
#define KEY_WINDOW          0x84            // keycode = 0x0074&lt;br /&gt;
#define KEY_1ST_PAGE        0x85            // keycode = 0x0075&lt;br /&gt;
#define KEY_STOP            0x86            // keycode = 0x0076&lt;br /&gt;
#define KEY_MAIL            0x87            // keycode = 0x0077&lt;br /&gt;
#define KEY_FAVORITES       0x88            // keycode = 0x0078&lt;br /&gt;
#define KEY_NEW_PAGE        0x89            // keycode = 0x0079&lt;br /&gt;
#define KEY_SETUP           0x8A            // keycode = 0x007a&lt;br /&gt;
#define KEY_FONT            0x8B            // keycode = 0x007b&lt;br /&gt;
#define KEY_PRINT           0x8C            // keycode = 0x007c&lt;br /&gt;
#define KEY_ON_OFF          0x8E            // keycode = 0x007c&lt;br /&gt;
&lt;br /&gt;
#define KEY_INSERT          0x90            // keycode = 0x004b&lt;br /&gt;
#define KEY_DELETE          0x91            // keycode = 0x004c&lt;br /&gt;
#define KEY_LEFT            0x92            // keycode = 0x004f&lt;br /&gt;
#define KEY_HOME            0x93            // keycode = 0x0050&lt;br /&gt;
#define KEY_END             0x94            // keycode = 0x0051&lt;br /&gt;
#define KEY_UP              0x95            // keycode = 0x0053&lt;br /&gt;
#define KEY_DOWN            0x96            // keycode = 0x0054&lt;br /&gt;
#define KEY_PAGE_UP         0x97            // keycode = 0x0055&lt;br /&gt;
#define KEY_PAGE_DOWN       0x98            // keycode = 0x0056&lt;br /&gt;
#define KEY_RIGHT           0x99            // keycode = 0x0059&lt;br /&gt;
#define KEY_MOUSE_1         0x9E            // keycode = 0x0400&lt;br /&gt;
#define KEY_MOUSE_2         0x9F            // keycode = 0x0800&lt;br /&gt;
&lt;br /&gt;
static uint8_t&lt;br /&gt;
get_fdc_key (uint16_t cmd)&lt;br /&gt;
{&lt;br /&gt;
    static uint8_t key_table[128] =&lt;br /&gt;
    {&lt;br /&gt;
     // 0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F&lt;br /&gt;
        0,  &#039;^&#039;, &#039;1&#039;, &#039;2&#039;, &#039;3&#039;, &#039;4&#039;, &#039;5&#039;, &#039;6&#039;, &#039;7&#039;, &#039;8&#039;, &#039;9&#039;, &#039;0&#039;, &#039;ß&#039;, &#039;´&#039;,  0,  &#039;\b&#039;,&lt;br /&gt;
       &#039;\t&#039;,&#039;q&#039;, &#039;w&#039;, &#039;e&#039;, &#039;r&#039;, &#039;t&#039;, &#039;z&#039;, &#039;u&#039;, &#039;i&#039;, &#039;o&#039;, &#039;p&#039;, &#039;ü&#039;, &#039;+&#039;,  0,   0,  &#039;a&#039;,&lt;br /&gt;
       &#039;s&#039;, &#039;d&#039;, &#039;f&#039;, &#039;g&#039;, &#039;h&#039;, &#039;j&#039;, &#039;k&#039;, &#039;l&#039;, &#039;ö&#039;, &#039;ä&#039;, &#039;#&#039;,  &#039;\r&#039;, 0,  &#039;&amp;lt;&#039;, &#039;y&#039;, &#039;x&#039;,&lt;br /&gt;
       &#039;c&#039;, &#039;v&#039;, &#039;b&#039;, &#039;n&#039;, &#039;m&#039;, &#039;,&#039;, &#039;.&#039;, &#039;-&#039;,  0,   0,   0,   0,   0,  &#039; &#039;,  0,   0,&lt;br /&gt;
&lt;br /&gt;
        0,  &#039;°&#039;, &#039;!&#039;, &#039;&amp;quot;&#039;, &#039;§&#039;, &#039;$&#039;, &#039;%&#039;, &#039;&amp;amp;&#039;, &#039;/&#039;, &#039;(&#039;, &#039;)&#039;, &#039;=&#039;, &#039;?&#039;, &#039;`&#039;,  0,  &#039;\b&#039;,&lt;br /&gt;
       &#039;\t&#039;,&#039;Q&#039;, &#039;W&#039;, &#039;E&#039;, &#039;R&#039;, &#039;T&#039;, &#039;Z&#039;, &#039;U&#039;, &#039;I&#039;, &#039;O&#039;, &#039;P&#039;, &#039;Ü&#039;, &#039;*&#039;,  0,   0,  &#039;A&#039;,&lt;br /&gt;
       &#039;S&#039;, &#039;D&#039;, &#039;F&#039;, &#039;G&#039;, &#039;H&#039;, &#039;J&#039;, &#039;K&#039;, &#039;L&#039;, &#039;Ö&#039;, &#039;Ä&#039;, &#039;\&#039;&#039;,&#039;\r&#039;, 0,  &#039;&amp;gt;&#039;, &#039;Y&#039;, &#039;X&#039;,&lt;br /&gt;
       &#039;C&#039;, &#039;V&#039;, &#039;B&#039;, &#039;N&#039;, &#039;M&#039;, &#039;;&#039;, &#039;:&#039;, &#039;_&#039;,  0,   0,   0,   0,   0,  &#039; &#039;,  0,   0&lt;br /&gt;
    };&lt;br /&gt;
    static uint8_t state;&lt;br /&gt;
&lt;br /&gt;
    uint8_t key = 0;&lt;br /&gt;
&lt;br /&gt;
    switch (cmd)&lt;br /&gt;
    {&lt;br /&gt;
        case 0x002C: state |=  STATE_LEFT_SHIFT;    break;              // pressed left shift&lt;br /&gt;
        case 0x00AC: state &amp;amp;= ~STATE_LEFT_SHIFT;    break;              // released left shift&lt;br /&gt;
        case 0x0039: state |=  STATE_RIGHT_SHIFT;   break;              // pressed right shift&lt;br /&gt;
        case 0x00B9: state &amp;amp;= ~STATE_RIGHT_SHIFT;   break;              // released right shift&lt;br /&gt;
        case 0x003A: state |=  STATE_LEFT_CTRL;     break;              // pressed left ctrl&lt;br /&gt;
        case 0x00BA: state &amp;amp;= ~STATE_LEFT_CTRL;     break;              // released left ctrl&lt;br /&gt;
        case 0x003C: state |=  STATE_LEFT_ALT;      break;              // pressed left alt&lt;br /&gt;
        case 0x00BC: state &amp;amp;= ~STATE_LEFT_ALT;      break;              // released left alt&lt;br /&gt;
        case 0x003E: state |=  STATE_RIGHT_ALT;     break;              // pressed left alt&lt;br /&gt;
        case 0x00BE: state &amp;amp;= ~STATE_RIGHT_ALT;     break;              // released left alt&lt;br /&gt;
&lt;br /&gt;
        case 0x006e: key = KEY_ESCAPE;              break;&lt;br /&gt;
        case 0x004b: key = KEY_INSERT;              break;&lt;br /&gt;
        case 0x004c: key = KEY_DELETE;              break;&lt;br /&gt;
        case 0x004f: key = KEY_LEFT;                break;&lt;br /&gt;
        case 0x0050: key = KEY_HOME;                break;&lt;br /&gt;
        case 0x0051: key = KEY_END;                 break;&lt;br /&gt;
        case 0x0053: key = KEY_UP;                  break;&lt;br /&gt;
        case 0x0054: key = KEY_DOWN;                break;&lt;br /&gt;
        case 0x0055: key = KEY_PAGE_UP;             break;&lt;br /&gt;
        case 0x0056: key = KEY_PAGE_DOWN;           break;&lt;br /&gt;
        case 0x0059: key = KEY_RIGHT;               break;&lt;br /&gt;
        case 0x0400: key = KEY_MOUSE_1;             break;&lt;br /&gt;
        case 0x0800: key = KEY_MOUSE_2;             break;&lt;br /&gt;
&lt;br /&gt;
        default:&lt;br /&gt;
        {&lt;br /&gt;
            if (!(cmd &amp;amp; 0x80))                      // pressed key&lt;br /&gt;
            {&lt;br /&gt;
                if (cmd &amp;gt;= 0x70 &amp;amp;&amp;amp; cmd &amp;lt;= 0x7F)     // function keys&lt;br /&gt;
                {&lt;br /&gt;
                    key = cmd + 0x10;               // 7x -&amp;gt; 8x&lt;br /&gt;
                }&lt;br /&gt;
                else if (cmd &amp;lt; 64)                  // key listed in key_table&lt;br /&gt;
                {&lt;br /&gt;
                    if (state &amp;amp; (STATE_LEFT_ALT | STATE_RIGHT_ALT))&lt;br /&gt;
                    {&lt;br /&gt;
                        switch (cmd)&lt;br /&gt;
                        {&lt;br /&gt;
                            case 0x0003: key = &#039;²&#039;;     break;&lt;br /&gt;
                            case 0x0008: key = &#039;{&#039;;     break;&lt;br /&gt;
                            case 0x0009: key = &#039;[&#039;;     break;&lt;br /&gt;
                            case 0x000A: key = &#039;]&#039;;     break;&lt;br /&gt;
                            case 0x000B: key = &#039;}&#039;;     break;&lt;br /&gt;
                            case 0x000C: key = &#039;\\&#039;;    break;&lt;br /&gt;
                            case 0x001C: key = &#039;~&#039;;     break;&lt;br /&gt;
                            case 0x002D: key = &#039;|&#039;;     break;&lt;br /&gt;
                            case 0x0034: key = &#039;µ&#039;;     break;&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (state &amp;amp; (STATE_LEFT_CTRL))&lt;br /&gt;
                    {&lt;br /&gt;
                        if (key_table[cmd] &amp;gt;= &#039;a&#039; &amp;amp;&amp;amp; key_table[cmd] &amp;lt;= &#039;z&#039;)&lt;br /&gt;
                        {&lt;br /&gt;
                            key = key_table[cmd] - &#039;a&#039; + 1;&lt;br /&gt;
                        }&lt;br /&gt;
                        else&lt;br /&gt;
                        {&lt;br /&gt;
                            key = key_table[cmd];&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        int idx = cmd + ((state &amp;amp; (STATE_LEFT_SHIFT | STATE_RIGHT_SHIFT)) ? 64 : 0);&lt;br /&gt;
&lt;br /&gt;
                        if (key_table[idx])&lt;br /&gt;
                        {&lt;br /&gt;
                            key = key_table[idx];&lt;br /&gt;
                        }&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return (key);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Als letztes noch ein Beispiel einer Anwendung der Funktion get_fdc_key():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    if (irmp_get_data (&amp;amp;irmp_data))&lt;br /&gt;
    {&lt;br /&gt;
        uint8_t key;&lt;br /&gt;
&lt;br /&gt;
        if (irmp_data.protocol == IRMP_FDC_PROTOCOL &amp;amp;&amp;amp;&lt;br /&gt;
            (key = get_fdc_key (irmp_data.command)) != 0)&lt;br /&gt;
        {&lt;br /&gt;
            if ((key &amp;gt;= 0x20 &amp;amp;&amp;amp; key &amp;lt; 0x7F) || key &amp;gt;= 0xA0) // show only printable characters&lt;br /&gt;
            {&lt;br /&gt;
                printf (&amp;quot;ascii-code = 0x%02x, character = &#039;%c&#039;\n&amp;quot;, key, key);&lt;br /&gt;
            }&lt;br /&gt;
            else // it&#039;s a non-printable key&lt;br /&gt;
            {&lt;br /&gt;
                printf (&amp;quot;ascii-code = 0x%02x\n&amp;quot;, key);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle nicht-druckbaren Zeichen werden dabei folgendermaßen codiert:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Taste             || Konstante                || Wert&lt;br /&gt;
|-&lt;br /&gt;
| ESC               || KEY_ESCAPE              || 0x1B&lt;br /&gt;
|-&lt;br /&gt;
| Menü              || KEY_MENUE               || 0x80&lt;br /&gt;
|-&lt;br /&gt;
| Zurück            || KEY_BACK                || 0x81&lt;br /&gt;
|-&lt;br /&gt;
| Vorw.             || KEY_FORWARD             || 0x82&lt;br /&gt;
|-&lt;br /&gt;
| Adresse           || KEY_ADDRESS             || 0x83&lt;br /&gt;
|-&lt;br /&gt;
| Fenster           || KEY_WINDOW              || 0x84&lt;br /&gt;
|-&lt;br /&gt;
| 1. Seite          || KEY_1ST_PAGE            || 0x85&lt;br /&gt;
|-&lt;br /&gt;
| Stop              || KEY_STOP                || 0x86&lt;br /&gt;
|-&lt;br /&gt;
| Mail              || KEY_MAIL                || 0x87&lt;br /&gt;
|-&lt;br /&gt;
| Fav.              || KEY_FAVORITES           || 0x88&lt;br /&gt;
|-&lt;br /&gt;
| Neue Seite        || KEY_NEW_PAGE            || 0x89&lt;br /&gt;
|-&lt;br /&gt;
| Setup             || KEY_SETUP               || 0x8A&lt;br /&gt;
|-&lt;br /&gt;
| Schrift           || KEY_FONT                || 0x8B&lt;br /&gt;
|-&lt;br /&gt;
| Druck             || KEY_PRINT               || 0x8C&lt;br /&gt;
|-&lt;br /&gt;
| Ein/Aus           || KEY_ON_OFF              || 0x8E&lt;br /&gt;
|-&lt;br /&gt;
| Backspace         || &#039;\b&#039;                    || 0x08&lt;br /&gt;
|-&lt;br /&gt;
| CR/ENTER          || &#039;\r&#039;                    || 0x0C&lt;br /&gt;
|-&lt;br /&gt;
| TAB               || &#039;\t&#039;                    || 0x09&lt;br /&gt;
|-&lt;br /&gt;
| Einfg             || KEY_INSERT              || 0x90&lt;br /&gt;
|-&lt;br /&gt;
| Entf              || KEY_DELETE              || 0x91&lt;br /&gt;
|-&lt;br /&gt;
| Cursor links      || KEY_LEFT                || 0x92&lt;br /&gt;
|-&lt;br /&gt;
| Pos1              || KEY_HOME                || 0x93&lt;br /&gt;
|-&lt;br /&gt;
| Ende              || KEY_END                 || 0x94&lt;br /&gt;
|-&lt;br /&gt;
| Cursor rechts     || KEY_UP                  || 0x95&lt;br /&gt;
|-&lt;br /&gt;
| Cursor runter     || KEY_DOWN                || 0x96&lt;br /&gt;
|-&lt;br /&gt;
| Bild hoch         || KEY_PAGE_UP             || 0x97&lt;br /&gt;
|-&lt;br /&gt;
| Bild runter       || KEY_PAGE_DOWN           || 0x98&lt;br /&gt;
|-&lt;br /&gt;
| Cursor links      || KEY_RIGHT               || 0x99&lt;br /&gt;
|-&lt;br /&gt;
| Linke Maustaste   || KEY_MOUSE_1             || 0x9E&lt;br /&gt;
|-&lt;br /&gt;
| Rechte Maustaste  || KEY_MOUSE_2             || 0x9F&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Die Funktion get_fdc_key berücksichtigt das Gedrückthalten der Shift-, Strg- und ALT-Tasten. Damit funktioniert nicht nur das Schreiben von Großbuchstaben, sondern auch das Auswählen der Sonderzeichen mit der Tastenkombination  ALT + Taste, z.B. ALT + m = µ oder ALT + q = @. Ebenso kann man mit der Strg-Taste die Control-Zeichen CTRL-A bis CTRL-Z senden. Die CapsLock-Taste wird ignoriert, da ich sie sowieso für die überflüssigste Taste überhaupt halte ;-)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= IRSND - Infrarot-Multiprotokoll-Encoder =&lt;br /&gt;
&lt;br /&gt;
[[Datei:irmp-title.png| |Scan eines NEC-kompatiblen Fernbedienungssignals]]&lt;br /&gt;
&lt;br /&gt;
== Einleitung IRSND ==&lt;br /&gt;
&lt;br /&gt;
[[Datei:ir-sender.png|miniatur|Anschluß eines einfachen IR-Senders an µC. 1k als Basiswiderstand sollte die Reichweite beträchtlich erhöhen.]]&lt;br /&gt;
&lt;br /&gt;
[[IRMP#IRSND_-_Infrarot-Multiprotokoll-Encoder|IRSND]] ist das Gegenstück zu IRMP: es reproduziert aus den Daten, die mit [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] empfangen wurden, wieder den Original Frame, der dann über eine Infrarot-Diode ausgegeben werden kann.&lt;br /&gt;
&lt;br /&gt;
=== Von IRSND unterstützte µCs ===&lt;br /&gt;
&lt;br /&gt;
[[IRMP#IRSND_-_Infrarot-Multiprotokoll-Encoder|IRSND]] ist lauffähig auf folgenden AVR µCs:&lt;br /&gt;
&lt;br /&gt;
* ATtiny87,  ATtiny167&lt;br /&gt;
* ATtiny45,  ATtiny85&lt;br /&gt;
* ATtiny44,  ATtiny84&lt;br /&gt;
* ATmega8,   ATmega16,  ATmega32&lt;br /&gt;
* ATmega162&lt;br /&gt;
* ATmega164, ATmega324, ATmega644,  ATmega644P, ATmega1284&lt;br /&gt;
* ATmega88,  ATmega88P, ATmega168,  ATmega168P, ATmega328P&lt;br /&gt;
&lt;br /&gt;
Es gibt aber auch Portierungen auf diverse PIC µCs - für den CCS- und C18-Compiler. Auch ist [[IRMP#IRSND_-_Infrarot-Multiprotokoll-Encoder|IRSND]] mittlerweile auf ARM STM32 lauffähig.&lt;br /&gt;
&lt;br /&gt;
=== Von IRSND unterstützte Protokolle ===&lt;br /&gt;
&lt;br /&gt;
[[IRMP#IRSND_-_Infrarot-Multiprotokoll-Encoder|IRSND]] unterstützt die folgenden Protokolle:&lt;br /&gt;
&lt;br /&gt;
* [[IRMP#SIRCS|SIRCS]]&lt;br /&gt;
* [[IRMP#NEC_+_extended_NEC|NEC]]&lt;br /&gt;
* [[IRMP#SAMSUNG|SAMSUNG]]&lt;br /&gt;
* [[IRMP#SAMSUNG32|SAMSUNG32]]&lt;br /&gt;
* [[IRMP#MATSUSHITA|MATSUSHITA]]&lt;br /&gt;
* [[IRMP#RC5_+_RC5X|RC5]]&lt;br /&gt;
* [[IRMP#KASEIKYO|KASEIKYO]]&lt;br /&gt;
* [[IRMP#DENON|DENON]]&lt;br /&gt;
* [[IRMP#JVC|JVC]]&lt;br /&gt;
* [[IRMP#APPLE|APPLE]]&lt;br /&gt;
* [[IRMP#NUBERT|NUBERT]]&lt;br /&gt;
* [[IRMP#B&amp;amp;O|BANG_OLUFSON]]&lt;br /&gt;
* [[IRMP#GRUNDIG_+_NOKIA|GRUNDIG]]&lt;br /&gt;
* [[IRMP#GRUNDIG_+_NOKIA|NOKIA]]&lt;br /&gt;
* [[IRMP#SIEMENS_+_RUWIDO|SIEMENS]] (bei mind. ~15kHz)&lt;br /&gt;
* [[IRMP#FDC|FDC]] (bei mind. ~15kHz)&lt;br /&gt;
* [[IRMP#RCCAR|RCCAR]] (bei mind. ~15kHz)&lt;br /&gt;
* [[IRMP#RECS80|RECS80]] (bei mind. ~20kHz)&lt;br /&gt;
* [[IRMP#RECS80EXT|RECS80EXT]] (bei mind. ~20kHz)&lt;br /&gt;
* [[IRMP#NIKON|NIKON]]&lt;br /&gt;
* [[IRMP#RC6_+_RC6A|RC6]]&lt;br /&gt;
* [[IRMP#RC6_+_RC6A|RC6A]]&lt;br /&gt;
* [[IRMP#THOMSON|THOMSON]]&lt;br /&gt;
* [[IRMP#NEC16|NEC16]]&lt;br /&gt;
* [[IRMP#NEC42|NEC42]]&lt;br /&gt;
* [[IRMP#LEGO|LEGO]]&lt;br /&gt;
* [[IRMP#IR60 (SDA2008)|IR60 (SDA2008)]]&lt;br /&gt;
* [[IRMP#A1TVBOX|A1TVBOX]]&lt;br /&gt;
* [[IRMP#ROOMBA|ROOMBA]] &#039;&#039;&#039;(NEU, nur im SVN!)&#039;&#039;&#039;&lt;br /&gt;
* [[IRMP#SPEAKER|SPEAKER]] &#039;&#039;&#039;(NEU, nur im SVN!)&#039;&#039;&#039;&lt;br /&gt;
* [[IRMP#TELEFUNKEN|TELEFUNKEN]] &#039;&#039;&#039;(NEU, nur im SVN!)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[IRMP#IRSND_-_Infrarot-Multiprotokoll-Encoder|IRSND]] unterstützt die folgenden Protokolle derzeit (noch) &#039;&#039;&#039;NICHT&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
* [[IRMP#KATHREIN|KATHREIN]]&lt;br /&gt;
* [[IRMP#NETBOX|NETBOX]]&lt;br /&gt;
* [[IRMP#ORTEK|ORTEK]]&lt;br /&gt;
* [[IRMP#RCMM|RCMM]]&lt;br /&gt;
* [[IRMP#LGAIR|LGAIR]]&lt;br /&gt;
&lt;br /&gt;
== Download IRSND ==&lt;br /&gt;
&lt;br /&gt;
Version 2.4.0, Stand vom 20.02.2014&lt;br /&gt;
&lt;br /&gt;
Download Release-Version: [http://www.mikrocontroller.net/wikifiles/c/c7/Irsnd.zip Irsnd.zip] &lt;br /&gt;
&lt;br /&gt;
[[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] &amp;amp; [[IRMP#IRSND_-_Infrarot-Multiprotokoll-Encoder|IRSND]] sind nun auch über SVN abrufbar: [http://www.mikrocontroller.net/svnbrowser/irmp/ IRMP im SVN]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achtung:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Die Version im SVN kann eine Zwischen- oder Test-Version sein, die nicht den hier dokumentierten Stand widerspiegelt! Im Zweifel verwendet man besser den obigen Download auf Irsnd.zip.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Die Software-Änderungen kann man sich hier anschauen: [http://www.mikrocontroller.net/articles/IRMP#Software-Historie_IRSND Software-Historie IRSND]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Source-Code IRSND ==&lt;br /&gt;
&lt;br /&gt;
Der Source-Code lässt sich einfach übersetzen, indem man unter Windows die Projekt-Datei irsnd.aps in das AVRStudio 4 lädt.&lt;br /&gt;
&lt;br /&gt;
Auch für andere Entwicklungsumgebungen lässt sich leicht ein Projekt bzw. Makefile zusammenstellen. Zum IRSND-Source gehören folgende Dateien:&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irsnd.c?view=markup irsnd.c] - Der eigentliche IR-Encoder&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irmpprotocols.h?view=markup irmpprotocols.h] - Sämtliche Definitionen zu den IR-Protokollen&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irmpsystem.h?view=markup irmpsystem.h] - Vom Zielsystem abhängige Definitionen für AVR/PIC/STM32&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irsnd.h?view=markup irsnd.h] - Include-Datei für die Applikation&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irsndconfig.h?view=markup irsndconfig.h] - Anzupassende Konfigurationsdatei&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/svnbrowser/irmp/irsndmain.c?view=markup irsndmain.c] - Beispiel Anwendung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;WICHTIG:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Im Applikations-Source sollte nur [http://www.mikrocontroller.net/svnbrowser/irmp/irsnd.h?view=markup irsnd.h] per include eingefügt werden, also lediglich:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;irsnd.h&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alle anderen Include-Dateien werden automatisch über [http://www.mikrocontroller.net/svnbrowser/irmp/irsnd.h?view=markup irsnd.h] &amp;quot;eingefügt&amp;quot;. Siehe dazu auch die Beispieldatei [http://www.mikrocontroller.net/svnbrowser/irmp/irsndmain.c?view=markup irsndmain.c].&lt;br /&gt;
&lt;br /&gt;
[[IRMP#IRSND_-_Infrarot-Multiprotokoll-Encoder|IRSND]] encodiert sämtliche oben aufgelisteten Protokolle in einer ISR, siehe [http://www.mikrocontroller.net/svnbrowser/irmp/irsnd.c?view=markup irsnd.c].&lt;br /&gt;
&lt;br /&gt;
=== Einstellungen in irsndconfig.h ===&lt;br /&gt;
&lt;br /&gt;
==== F_INTERRUPTS ====&lt;br /&gt;
&lt;br /&gt;
Anzahl der Interrupts pro Sekunde. Der Wert kann zwischen 10000 und 20000 eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
Standardwert:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define F_INTERRUPTS                            15000      // interrupts per second&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== IRSND_SUPPORT_xxx_PROTOCOL ====&lt;br /&gt;
&lt;br /&gt;
Hier lässt sich einstellen, welche Protokolle von [[IRMP#IRSND_-_Infrarot-Multiprotokoll-Encoder|IRSND]] unterstützt werden sollen. Die Standardprotokolle sind bereits aktiv. Möchte man weitere Protokolle einschalten bzw. einige aus Speicherplatzgründen deaktivieren, sind die entsprechenden Werte in [http://www.mikrocontroller.net/svnbrowser/irmp/irsndconfig.h?view=markup irsndconfig.h] anzupassen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// typical protocols, disable here!             Enable  Remarks                 F_INTERRUPTS            Program Space&lt;br /&gt;
#define IRSND_SUPPORT_SIRCS_PROTOCOL            1       // Sony SIRCS           &amp;gt;= 10000                 ~200 bytes&lt;br /&gt;
#define IRSND_SUPPORT_NEC_PROTOCOL              1       // NEC + APPLE          &amp;gt;= 10000                 ~100 bytes&lt;br /&gt;
#define IRSND_SUPPORT_SAMSUNG_PROTOCOL          1       // Samsung + Samsung32  &amp;gt;= 10000                 ~300 bytes&lt;br /&gt;
#define IRSND_SUPPORT_MATSUSHITA_PROTOCOL       1       // Matsushita           &amp;gt;= 10000                 ~200 bytes&lt;br /&gt;
#define IRSND_SUPPORT_KASEIKYO_PROTOCOL         1       // Kaseikyo             &amp;gt;= 10000                 ~300 bytes&lt;br /&gt;
&lt;br /&gt;
// more protocols, enable here!                 Enable  Remarks                 F_INTERRUPTS            Program Space&lt;br /&gt;
#define IRSND_SUPPORT_DENON_PROTOCOL            0       // DENON, Sharp         &amp;gt;= 10000                 ~200 bytes&lt;br /&gt;
#define IRSND_SUPPORT_RC5_PROTOCOL              0       // RC5                  &amp;gt;= 10000                 ~150 bytes&lt;br /&gt;
#define IRSND_SUPPORT_RC6_PROTOCOL              0       // RC6                  &amp;gt;= 10000                 ~250 bytes&lt;br /&gt;
#define IRSND_SUPPORT_RC6A_PROTOCOL             0       // RC6A                 &amp;gt;= 10000                 ~250 bytes&lt;br /&gt;
#define IRSND_SUPPORT_JVC_PROTOCOL              0       // JVC                  &amp;gt;= 10000                 ~150 bytes&lt;br /&gt;
#define IRSND_SUPPORT_NEC16_PROTOCOL            0       // NEC16                &amp;gt;= 10000                 ~150 bytes&lt;br /&gt;
#define IRSND_SUPPORT_NEC42_PROTOCOL            0       // NEC42                &amp;gt;= 10000                 ~150 bytes&lt;br /&gt;
#define IRSND_SUPPORT_IR60_PROTOCOL             0       // IR60 (SDA2008)       &amp;gt;= 10000                 ~250 bytes&lt;br /&gt;
#define IRSND_SUPPORT_GRUNDIG_PROTOCOL          0       // Grundig              &amp;gt;= 10000                 ~300 bytes&lt;br /&gt;
#define IRSND_SUPPORT_SIEMENS_PROTOCOL          0       // Siemens, Gigaset     &amp;gt;= 15000                 ~150 bytes&lt;br /&gt;
#define IRSND_SUPPORT_NOKIA_PROTOCOL            0       // Nokia                &amp;gt;= 10000                 ~400 bytes&lt;br /&gt;
&lt;br /&gt;
// exotic protocols, enable here!               Enable  Remarks                 F_INTERRUPTS            Program Space&lt;br /&gt;
#define IRSND_SUPPORT_KATHREIN_PROTOCOL         0       // Kathrein             &amp;gt;= 10000                 DON&#039;T CHANGE, NOT SUPPORTED YET!&lt;br /&gt;
#define IRSND_SUPPORT_NUBERT_PROTOCOL           0       // NUBERT               &amp;gt;= 10000                 ~100 bytes&lt;br /&gt;
#define IRSND_SUPPORT_BANG_OLUFSEN_PROTOCOL     0       // Bang&amp;amp;Olufsen         &amp;gt;= 10000                 ~250 bytes&lt;br /&gt;
#define IRSND_SUPPORT_RECS80_PROTOCOL           0       // RECS80               &amp;gt;= 15000                 ~100 bytes&lt;br /&gt;
#define IRSND_SUPPORT_RECS80EXT_PROTOCOL        0       // RECS80EXT            &amp;gt;= 15000                 ~100 bytes&lt;br /&gt;
#define IRSND_SUPPORT_THOMSON_PROTOCOL          0       // Thomson              &amp;gt;= 10000                 ~250 bytes&lt;br /&gt;
#define IRSND_SUPPORT_NIKON_PROTOCOL            0       // NIKON                &amp;gt;= 10000                 ~150 bytes&lt;br /&gt;
#define IRSND_SUPPORT_NETBOX_PROTOCOL           0       // Netbox keyboard      &amp;gt;= 10000                 DON&#039;T CHANGE, NOT SUPPORTED YET!&lt;br /&gt;
#define IRSND_SUPPORT_FDC_PROTOCOL              0       // FDC IR keyboard      &amp;gt;= 10000 (better 15000)  ~150 bytes&lt;br /&gt;
#define IRSND_SUPPORT_RCCAR_PROTOCOL            0       // RC CAR               &amp;gt;= 10000 (better 15000)  ~150 bytes&lt;br /&gt;
#define IRSND_SUPPORT_ROOMBA_PROTOCOL           0       // iRobot Roomba        &amp;gt;= 10000                 ~150 bytes&lt;br /&gt;
#define IRSND_SUPPORT_RUWIDO_PROTOCOL           0       // RUWIDO, T-Home       &amp;gt;= 15000                 ~250 bytes&lt;br /&gt;
#define IRSND_SUPPORT_A1TVBOX_PROTOCOL          0       // A1 TV BOX            &amp;gt;= 15000 (better 20000)  ~200 bytes&lt;br /&gt;
#define IRSND_SUPPORT_LEGO_PROTOCOL             0       // LEGO Power RC        &amp;gt;= 20000                 ~150 bytes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit Setzen auf 0 wird das Protokoll deaktiviert, mit Setzen auf 1 wird es aktiviert. Die deaktivierten Protokolle werden dann nicht mitübersetzt. Das spart Speicherplatz im Flash, siehe Angaben in obigen Kommentaren. Wenn man unbedingt Speicherplatz sparen muss, gelten natürlich hier dieselben Tipps wie für IRMP.&lt;br /&gt;
&lt;br /&gt;
Um das [[IRMP#APPLE|APPLE]]-Protokoll zu unterstützen, ist IRSND_SUPPORT_NEC_PROTOCOL auf 1 zu setzen, da es sich hier lediglich um einen Spezialfall vom [[IRMP#NEC_+_extended_NEC|NEC]]-Protokoll handelt.&lt;br /&gt;
&lt;br /&gt;
==== IRSND_OCx ====&lt;br /&gt;
&lt;br /&gt;
Für das Senden der IR-Signale benötigt [[IRMP#IRSND_-_Infrarot-Multiprotokoll-Encoder|IRSND]] einen PWM-fähigen Output-Pin, da das Signal moduliert werden muss. Möglich sind eine der folgenden Einstellungen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define IRSND_OCx                               IRSND_OC2  // OC2  on ATmegas         supporting OC2,  e.g. ATmega8&lt;br /&gt;
#define IRSND_OCx                               IRSND_OC2A // OC2A on ATmegas         supporting OC2A, e.g. ATmega88&lt;br /&gt;
#define IRSND_OCx                               IRSND_OC2B // OC2B on ATmegas         supporting OC2B, e.g. ATmega88&lt;br /&gt;
#define IRSND_OCx                               IRSND_OC0  // OC0  on ATmegas         supporting OC0,  e.g. ATmega162&lt;br /&gt;
#define IRSND_OCx                               IRSND_OC0A // OC0A on ATmegas/ATtinys supporting OC0A, e.g. ATtiny84, ATtiny85&lt;br /&gt;
#define IRSND_OCx                               IRSND_OC0B // OC0B on ATmegas/ATtinys supporting OC0B, e.g. ATtiny84, ATtiny85&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Standardwert:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define IRSND_OCx                               IRSND_OC2B&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für die PIC- und STM32-µCs sind entsprechende Werte anzupassen, siehe Kommentare in [http://www.mikrocontroller.net/svnbrowser/irmp/irsndconfig.h?view=markup irsndconfig.h].&lt;br /&gt;
&lt;br /&gt;
==== IRSND_USE_CALLBACK ====&lt;br /&gt;
&lt;br /&gt;
Standardwert:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define IRSND_USE_CALLBACK                      0       // flag: 0 = don&#039;t use callbacks, 1 = use callbacks, default is 0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn man Callbacks einschaltet, wird bei jeder Änderung des Signals (IR-Modulation ein/aus) eine Callback-Funktion aufgerufen. Dies kann zum Beispiel dafür verwendet werden, ein unmoduliertes Signal an einem weiteren Pin auszugeben.&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define LED_PORT PORTD                                  // LED at PD6&lt;br /&gt;
#define LED_DDR  DDRD&lt;br /&gt;
#define LED_PIN  6&lt;br /&gt;
&lt;br /&gt;
/*-----------------------------------------------------------------------------------------------------------------------&lt;br /&gt;
 * Called (back) from IRSND module&lt;br /&gt;
 * This example switches a LED (which is connected to Vcc)&lt;br /&gt;
 *-----------------------------------------------------------------------------------------------------------------------&lt;br /&gt;
 */&lt;br /&gt;
void&lt;br /&gt;
led_callback (uint8_t on)&lt;br /&gt;
{&lt;br /&gt;
    if (on)&lt;br /&gt;
    {&lt;br /&gt;
       LED_PORT &amp;amp;= ~(1 &amp;lt;&amp;lt; LED_PIN);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
       LED_PORT |= (1 &amp;lt;&amp;lt; LED_PIN);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int&lt;br /&gt;
main ()&lt;br /&gt;
{&lt;br /&gt;
    ...&lt;br /&gt;
    LED_DDR |= (1 &amp;lt;&amp;lt; LED_PIN);         // LED pin to output&lt;br /&gt;
    LED_PORT |= (1 &amp;lt;&amp;lt; LED_PIN);        // switch LED off (active low)&lt;br /&gt;
    irsnd_init ();&lt;br /&gt;
    irsnd_set_callback_ptr (led_callback);&lt;br /&gt;
    sei ();&lt;br /&gt;
    ...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Anwendung von IRSND ===&lt;br /&gt;
&lt;br /&gt;
[[IRMP#IRSND_-_Infrarot-Multiprotokoll-Encoder|IRSND]] baut den zu sendenden Frame &amp;quot;on-the-fly&amp;quot; aus der IRMP-Datenstruktur wieder zusammen. Dazu zählen:&lt;br /&gt;
&lt;br /&gt;
 1. ID für verwendetes Protokoll&lt;br /&gt;
 2. Adresse bzw. Herstellercode&lt;br /&gt;
 3. Kommando&lt;br /&gt;
&lt;br /&gt;
Mittels der Funktion&lt;br /&gt;
&lt;br /&gt;
   irsnd_send_data (IRMP_DATA * irmp_data_p)&lt;br /&gt;
&lt;br /&gt;
kann man ein zu encodierendes Telegramm versenden. Der Return-Wert ist 1, wenn das Telegramm versendet werden kann, sonst 0. Im ersten Fall werden die Struct-Members&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    irmp_data_p-&amp;gt;protocol&lt;br /&gt;
    irmp_data_p-&amp;gt;address&lt;br /&gt;
    irmp_data_p-&amp;gt;command&lt;br /&gt;
    irmp_data_p-&amp;gt;flags&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ausgelesen und dann als Frame im jeweils gewünschten Protokoll gesendet.&lt;br /&gt;
&lt;br /&gt;
irmp_data_p-&amp;gt;flags gibt die Anzahl der Wiederholungen an, z.B.&lt;br /&gt;
&lt;br /&gt;
  irmp_data_p-&amp;gt;flags = 0: keine Wiederholung&lt;br /&gt;
  irmp_data_p-&amp;gt;flags = 1: 1 Wiederholung&lt;br /&gt;
  irmp_data_p-&amp;gt;flags = 2: 2 Wiederholungen&lt;br /&gt;
  usw.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Zu beachten: Es ist unbedingt darauf zu achten, dass irmp_data_p-&amp;gt;flags vor dem Aufruf von irsnd_send_data() einen definierten Wert hat!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Hier ein Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
   IRMP_DATA irmp_data;&lt;br /&gt;
&lt;br /&gt;
   irmp_data.protocol = IRMP_NEC_PROTOCOL;       // sende im NEC-Protokoll&lt;br /&gt;
   irmp_data.address  = 0x00FF;                  // verwende Adresse 0x00FF&lt;br /&gt;
   irmp_data.command  = 0x0001;                  // sende Kommando 0001&lt;br /&gt;
   irmp_data.flags    = 0;                       // keine Wiederholung!&lt;br /&gt;
&lt;br /&gt;
   (void) irsnd_send_data (&amp;amp;irmp_data, FALSE);   // versende ohne Prüfung und ohne Warten&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Frame wird asynchron über die Interrupt-Routine irsnd_ISR() verschickt, so dass die Funktion irsnd_send_data() sofort zurückkommt.&lt;br /&gt;
&lt;br /&gt;
Sind Wiederholungen angegeben, wird entweder der Frame nach einer Pause (protokollabhängig) neu ausgegeben oder ein protokollspezifischer Wiederholungsframe (z.B. für NEC) gesendet.&lt;br /&gt;
&lt;br /&gt;
Wird erneut irsnd_send_data() aufgerufen, wartet diese, bis der vorhergenhende Frame vollständig verschickt wurde. Man kann aber auch selbst prüfen, ob [[IRMP#IRSND_-_Infrarot-Multiprotokoll-Encoder|IRSND]] gerade &amp;quot;busy&amp;quot; ist oder nicht:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
   while (irsnd_is_busy ())&lt;br /&gt;
   {&lt;br /&gt;
      ;                                          // selber warten oder was anderes tun...&lt;br /&gt;
   }&lt;br /&gt;
   (void) irsnd_send_data (&amp;amp;irmp_data, FALSE);   // versende ohne Prüfung und ohne Warten&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wird irsnd_send_data() mit dem 2. Argument TRUE aufgerufen, kommt diese Funktion erst zurück, wenn der Frame komplett ausgesendet wurde.&lt;br /&gt;
&lt;br /&gt;
Im Beispiel-Source irsndmain.c findet man neben der Verwendung von irsnd_send_data() auch den [[AVR-GCC-Tutorial/Die_Timer_und_Zähler_des_AVR|Timer]]-Aufruf:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
  irsnd_ISR())          // call irsnd ISR&lt;br /&gt;
  // call other timer interrupt routines...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Paralleles Betreiben von IRMP und IRSND ===&lt;br /&gt;
&lt;br /&gt;
Möchte man [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] und [[IRMP#IRSND_-_Infrarot-Multiprotokoll-Encoder|IRSND]] parallel verwenden (also als Sender und Empfänger) schreibt man die ISR folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
  if (! irsnd_ISR())          // call irsnd ISR&lt;br /&gt;
  {                           // if not busy...&lt;br /&gt;
      irmp_ISR();             // call irmp ISR&lt;br /&gt;
  }&lt;br /&gt;
  // call other timer interrupt routines...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das heisst: Nur wenn irsnd_ISR() nichts zu tun hat, dann rufe die ISR des Empfängers auf. Damit ist der Empfänger solange abgeschaltet, während irsnd_ISR() noch Daten sendet. Die [[AVR-GCC-Tutorial/Die_Timer_und_Zähler_des_AVR|Timer]]-Initialisierungsroutine ist für [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] und [[IRMP#IRSND_-_Infrarot-Multiprotokoll-Encoder|IRSND]] dann natürlich dieselbe.&lt;br /&gt;
&lt;br /&gt;
Eine gemeinsame main-Funktion könnte dann zum Beispiel folgendermaßen aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int&lt;br /&gt;
main (void)&lt;br /&gt;
{&lt;br /&gt;
  IRMP_DATA irmp_data;&lt;br /&gt;
&lt;br /&gt;
  irmp_init();                // initialize irmp&lt;br /&gt;
  irsnd_init();               // initialize irsnd&lt;br /&gt;
  timer_init();               // initialize timer&lt;br /&gt;
  sei ();                     // enable interrupts&lt;br /&gt;
&lt;br /&gt;
  for (;;)&lt;br /&gt;
  {&lt;br /&gt;
    if (irmp_get_data (&amp;amp;irmp_data))&lt;br /&gt;
    {&lt;br /&gt;
      irmp_data.flags = 0;    // reset flags!&lt;br /&gt;
      irsnd_send_data (&amp;amp;irmp_data);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion des obigen Sources ist offensichtlich: Ein empfangenes Telegramm wird nach vollständiger Decodierung wieder encodiert und dann wieder über die IR-Diode ausgesandt. Somit können dann zum Beispiel Signale &amp;quot;um die Ecke&amp;quot; oder streckenweise drahtgebunden übertragen werden.&lt;br /&gt;
&lt;br /&gt;
Desweiteren könnte man auch Protokolle transformieren, zum Beispiel NEC-Telegramme in RC5 umwandeln, wenn man seine Original-RC5-FB zu seinem Philips-Gerät verlegt hat...&lt;br /&gt;
&lt;br /&gt;
Der Rest bleibt der Phantasie des geneigten Lesers überlassen ;-)&lt;br /&gt;
&lt;br /&gt;
Hier noch die möglichen Werte für irmp_data.protocol, siehe auch [http://www.mikrocontroller.net/svnbrowser/irmp/irmpprotocols.h?view=markup irmpprotocols.h]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define IRMP_SIRCS_PROTOCOL                      1              // Sony&lt;br /&gt;
#define IRMP_NEC_PROTOCOL                        2              // NEC, Pioneer, JVC, Toshiba, NoName etc.&lt;br /&gt;
#define IRMP_SAMSUNG_PROTOCOL                    3              // Samsung&lt;br /&gt;
#define IRMP_MATSUSHITA_PROTOCOL                 4              // Matsushita&lt;br /&gt;
#define IRMP_KASEIKYO_PROTOCOL                   5              // Kaseikyo (Panasonic etc)&lt;br /&gt;
#define IRMP_RECS80_PROTOCOL                     6              // Philips, Thomson, Nordmende, Telefunken, Saba&lt;br /&gt;
#define IRMP_RC5_PROTOCOL                        7              // Philips etc&lt;br /&gt;
#define IRMP_DENON_PROTOCOL                      8              // Denon, Sharp&lt;br /&gt;
#define IRMP_RC6_PROTOCOL                        9              // Philips etc&lt;br /&gt;
#define IRMP_SAMSUNG32_PROTOCOL                 10              // Samsung32: no sync pulse at bit 16, length 32 instead of 37&lt;br /&gt;
#define IRMP_APPLE_PROTOCOL                     11              // Apple, very similar to NEC&lt;br /&gt;
#define IRMP_RECS80EXT_PROTOCOL                 12              // Philips, Technisat, Thomson, Nordmende, Telefunken, Saba&lt;br /&gt;
#define IRMP_NUBERT_PROTOCOL                    13              // Nubert&lt;br /&gt;
#define IRMP_BANG_OLUFSEN_PROTOCOL              14              // Bang &amp;amp; Olufsen&lt;br /&gt;
#define IRMP_GRUNDIG_PROTOCOL                   15              // Grundig&lt;br /&gt;
#define IRMP_NOKIA_PROTOCOL                     16              // Nokia&lt;br /&gt;
#define IRMP_SIEMENS_PROTOCOL                   17              // Siemens, e.g. Gigaset&lt;br /&gt;
#define IRMP_FDC_PROTOCOL                       18              // FDC keyboard&lt;br /&gt;
#define IRMP_RCCAR_PROTOCOL                     19              // RC Car&lt;br /&gt;
#define IRMP_JVC_PROTOCOL                       20              // JVC (NEC with 16 bits)&lt;br /&gt;
#define IRMP_RC6A_PROTOCOL                      21              // RC6A, e.g. Kathrein, XBOX&lt;br /&gt;
#define IRMP_NIKON_PROTOCOL                     22              // Nikon&lt;br /&gt;
#define IRMP_RUWIDO_PROTOCOL                    23              // Ruwido, e.g. T-Home Mediareceiver&lt;br /&gt;
#define IRMP_IR60_PROTOCOL                      24              // IR60 (SDA2008)&lt;br /&gt;
#define IRMP_KATHREIN_PROTOCOL                  25              // Kathrein&lt;br /&gt;
#define IRMP_NETBOX_PROTOCOL                    26              // Netbox keyboard (bitserial)&lt;br /&gt;
#define IRMP_NEC16_PROTOCOL                     27              // NEC with 16 bits (incl. sync)&lt;br /&gt;
#define IRMP_NEC42_PROTOCOL                     28              // NEC with 42 bits&lt;br /&gt;
#define IRMP_LEGO_PROTOCOL                      29              // LEGO Power Functions RC&lt;br /&gt;
#define IRMP_THOMSON_PROTOCOL                   30              // Thomson&lt;br /&gt;
#define IRMP_BOSE_PROTOCOL                      31              // BOSE&lt;br /&gt;
#define IRMP_A1TVBOX_PROTOCOL                   32              // A1 TV Box&lt;br /&gt;
#define IRMP_ORTEK_PROTOCOL                     33              // ORTEK - Hama&lt;br /&gt;
#define IRMP_TELEFUNKEN_PROTOCOL                34              // Telefunken (1560)&lt;br /&gt;
#define IRMP_ROOMBA_PROTOCOL                    35              // iRobot Roomba vacuum cleaner&lt;br /&gt;
#define IRMP_RCMM32_PROTOCOL                    36              // Fujitsu-Siemens (Activy remote control)&lt;br /&gt;
#define IRMP_RCMM24_PROTOCOL                    37              // Fujitsu-Siemens (Activy keyboard)&lt;br /&gt;
#define IRMP_RCMM12_PROTOCOL                    38              // Fujitsu-Siemens (Activy keyboard)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Daten für die Adresse und das Kommando ermittelt man am besten über IRMP, siehe weiter oben ;-)&lt;br /&gt;
&lt;br /&gt;
== IRSND unter Linux und Windows ==&lt;br /&gt;
&lt;br /&gt;
=== Übersetzen von IRSND ===&lt;br /&gt;
&lt;br /&gt;
[http://www.mikrocontroller.net/svnbrowser/irmp/irsnd.c?view=markup irsnd.c] lässt sich auch unter Linux direkt kompilieren, um damit Telegramme in Form von IRMP-Scan-Dateien zu erzeugen. Das geht folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
    make -f makefile.unx&lt;br /&gt;
&lt;br /&gt;
=== Aufruf von IRSND ===&lt;br /&gt;
&lt;br /&gt;
Der Aufruf geht dann folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
    ./irsnd protocol-number hex-address hex-command [repeat] &amp;gt; filename.txt&lt;br /&gt;
&lt;br /&gt;
also zum Beispiel für das NEC-Protokoll, Adresse 0x00FF, Kommando 0x0001&lt;br /&gt;
&lt;br /&gt;
    ./irsnd 2 00FF 0001 &amp;gt; nec.txt                   # irsnd ausführen&lt;br /&gt;
&lt;br /&gt;
=== IRSND unter Windows ===&lt;br /&gt;
&lt;br /&gt;
[[IRMP#IRSND_-_Infrarot-Multiprotokoll-Encoder|IRSND]] kann man auch unter Windows nutzen, nämlich folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
* Eingabeaufforderung starten&lt;br /&gt;
* In das Verzeichnis von irsnd wechseln&lt;br /&gt;
* Aufruf von:&lt;br /&gt;
&lt;br /&gt;
            irsnd.exe 2 00FF 0001 &amp;gt; nec.txt&lt;br /&gt;
&lt;br /&gt;
Nun kann man direkt mit [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] anschließend testen, ob das erzeugte Telegramm auch korrekt ist:&lt;br /&gt;
&lt;br /&gt;
            ./irmp &amp;lt; nec.txt&lt;br /&gt;
&lt;br /&gt;
bzw. unter Windows:&lt;br /&gt;
&lt;br /&gt;
            irmp.exe &amp;lt; nec.txt&lt;br /&gt;
&lt;br /&gt;
Das Ganze geht auch ohne Zwischendatei, nämlich:&lt;br /&gt;
&lt;br /&gt;
            ./irsnd 2 00FF 0001 | ./irmp&lt;br /&gt;
&lt;br /&gt;
bzw. unter Windows:&lt;br /&gt;
&lt;br /&gt;
            irsnd.exe 2 00FF 0001 | irmp.exe&lt;br /&gt;
&lt;br /&gt;
[[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] gibt dann als Ergebnis folgendes aus:&lt;br /&gt;
&lt;br /&gt;
            11111111000000001000000001111111 p =  2, a = 0x00ff, c = 0x0001, f = 0x00&lt;br /&gt;
&lt;br /&gt;
[[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] konnte also aus dem von [[IRMP#IRSND_-_Infrarot-Multiprotokoll-Encoder|IRSND]] generierten Frame wieder das Protokoll 2, Adresse 0x00FF und Kommando 0x0001 decodieren.&lt;br /&gt;
&lt;br /&gt;
Bitte beachten: Je nach benutztem Protokoll sind die Bit-Breiten der Adressen bzw. Kommandos verschieden, siehe obige Tabelle [http://www.mikrocontroller.net/articles/IRMP#Protokolle].&lt;br /&gt;
&lt;br /&gt;
Man kann also nicht mit jedem IR-Protokoll komplett 16-Bit breite Adressen oder Kommandos transparent übertragen.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
= Anhang =&lt;br /&gt;
&lt;br /&gt;
== Die IR-Protokolle im Detail ==&lt;br /&gt;
&lt;br /&gt;
=== Pulse Distance Protokolle ===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Pulse-Distance.png|miniatur|Pulse Distance Coding]]&lt;br /&gt;
&lt;br /&gt;
==== NEC + extended NEC ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;[[IRMP#NEC-Protokoll|NEC + extended NEC]]&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 36 kHz / 38 kHz&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 32 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten NEC || 8 Adress-Bits + 8 invertierte Adress-Bits + 8 Kommando-Bits + 8 invertierte Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Daten ext. NEC || 16 Adress-Bits + 8 Kommando-Bits + 8 invertierte Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 9000µs Puls, 4500µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 560µs Puls,  560µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 560µs Puls, 1690µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 560µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || 9000µs Puls, 2250µs Pause, 560µs Puls, ~100ms Pause&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || LSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== JVC ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;[[IRMP#NEC16-Protokoll (JVC)|JVC]]&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 16 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 4 Adress-Bits + 12 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 9000µs Puls, 4500µs Pause, 6000µs Pause bei Tasten-Wiederholung&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 560µs Puls,  560µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 560µs Puls, 1690µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 560µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || Wiederholung nach Pause von 25ms&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || LSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== NEC16 ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;NEC16&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 8 Adress-Bits + 1 Sync-Bit + 8 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 9000µs Puls, 4500µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Sync-Bit || 560µs Puls, 4500µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 560µs Puls,  560µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 560µs Puls, 1690µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 560µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine/eine/zwei nach 25ms?&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || Wiederholung nach Pause von 25ms?&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || LSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== NEC42 ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;NEC42&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz?&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 42 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 13 Adress-Bits + 13 invertierte Adress-Bits + 8 Kommando-Bits + 8 invertierte Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 9000µs Puls, 4500µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 560µs Puls,  560µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 560µs Puls, 1690µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 560µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || nach 110ms (ab Start-Bit), 9000µs Puls, 2250µs Pause, 560µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || LSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== LGAIR ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;[[IRMP#LGAIR-Protokoll|LGAIR]]&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 28 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 8 Adress-Bits + 16 Kommando-Bits + 4 Checksum-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 9000µs Puls, 4500µs Pause (identisch mit [[IRMP#NEC_.2B_extended_NEC|NEC]])&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 560µs Puls,  560µs Pause (identisch mit [[IRMP#NEC_.2B_extended_NEC|NEC]])&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 560µs Puls, 1690µs Pause (identisch mit [[IRMP#NEC_.2B_extended_NEC|NEC]])&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 560µs Puls (identisch mit [[IRMP#NEC_.2B_extended_NEC|NEC]])&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || unbekannt&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || MSB first (&#039;&#039;&#039;abweichend&#039;&#039;&#039; zu [[IRMP#NEC_.2B_extended_NEC|NEC]])&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== SAMSUNG ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;[[IRMP#SAMSUNG-Protokoll|SAMSUNG]]&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || ?? kHz&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 16 Daten(1)-Bits + 1 Sync-Bit + 20 Daten(2)-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten(1) || 16 Adress-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Daten(2) || 4 ID-Bits + 8 Kommando-Bits + 8 invertierte Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 4500µs Puls, 4500µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 550µs Puls,  550µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 550µs Puls, 1650µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Sync-Bit || 550µs Puls, 4500µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 550µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || N-fache Wiederholung des Original-Frames innerhalb von 100ms&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || LSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== SAMSUNG32 ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;SAMSUNG32&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 32 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 16 Adress-Bits + 16 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 4500µs Puls, 4500µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 550µs Puls,  550µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 550µs Puls, 1650µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 550µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || dritter, fünfter, siebter usw. identischer Frame&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || LSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== MATSUSHITA ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;[[IRMP#MATSUHITA-Protokoll|MATSUSHITA]]&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 36 kHz&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 24 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 6 Hersteller-Bits + 6 Kommando-Bits + 12 Adress-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 3488µs Puls, 3488µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 872µs Puls,  872µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 872µs Puls, 2616µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 872µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || N-fache Wiederholung des Original-Frames nach 40ms Pause&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || LSB first?&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== KASEIKYO ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;[[IRMP#KASEIKYO-Protokoll (auch &amp;quot;Japan-Protokoll&amp;quot;)|KASEIKYO]]&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 48 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 16 Hersteller-Bits + 4 Parity-Bits + 4 Genre1-Bits + 4 Genre2-Bits + 10 Kommando-Bits + 2 ID-Bits + 8 Parity-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 3380µs Puls, 1690µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 423µs Puls,  423µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 423µs Puls, 1269µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 423µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || einmalig nach 74ms Pause&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || N-fache Wiederholung des 1. Original-Frames nach ca. 80ms Pause&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || LSB first?&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== RECS80 ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;[[IRMP#RECS80- und RECS80-Extended-Protokoll|RECS80]]&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bits + 10 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 1 Toggle-Bit + 3 Adress-Bits + 6 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 158µs Puls, 7432µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 158µs Puls, 4902µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 158µs Puls, 7432µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 158µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || N-fache Wiederholung des Original-Frames innerhalb von 100ms&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || MSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== RECS80EXT ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;[[IRMP#RECS80- und RECS80-Extended-Protokoll|RECS80EXT]]&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 2 Start-Bits + 11 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 1 Toggle-Bit + 4 Adress-Bits + 6 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 158µs Puls, 3637µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 158µs Puls, 4902µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 158µs Puls, 7432µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 158µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || N-fache Wiederholung des Original-Frames innerhalb von 100ms&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || MSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== DENON ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;[[IRMP#Denon-Protokoll|DENON]]&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz (in der Praxis, lt. Dokumentation: 32 kHz)&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 0 Start-Bits + 15 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 5 Address-Bits + 10 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Kommando || 6 Datenbits + 2 Extension Bits + 2 Data Construction Bits (normal: 00, invertiert: 11)&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || kein Start-Bit&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 310µs Puls, 745µs Pause (in der Praxis, lt. Doku: 275µs Puls, 775µs Pause)&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 310µs Puls, 1780µs Pause (in der Praxis, lt. Doku: 275µs Puls, 1900µs Pause)&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 310µs Puls (310µs Puls, 745µs Pause (in der Praxis, lt. Doku: 275µs Puls)&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || Nach 65ms Wiederholung des Frames mit invertieren Kommando-Bits (Data Construction Bits = 11)&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || N-fache Wiederholung der beiden Original-Frames nach 65ms&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || MSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== APPLE ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;APPLE&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz?&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 32 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 16 Adress-Bits + 11100000 + 8 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || siehe [[IRMP#NEC_+_extended_NEC|NEC]]&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || siehe [[IRMP#NEC_+_extended_NEC|NEC]]&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || siehe [[IRMP#NEC_+_extended_NEC|NEC]]&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || siehe [[IRMP#NEC_+_extended_NEC|NEC]]&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || N-fache Wiederholung des Original-Frames innerhalb von 100ms&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || LSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== BOSE ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;BOSE&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz?&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 16 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 0 Adress-Bits + 8 Kommando-Bits + 8 invertierte Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 1060µs Puls, 1425µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 550µs Puls,  437µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 550µs Puls, 1425µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 550µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || noch ungeklärt&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || LSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== B&amp;amp;O ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;[[IRMP#Bang &amp;amp; Olufsen|B&amp;amp;O]]&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 455 kHz&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 4 Start-Bits + 16 Daten-Bits + 1 Trailer-Bit + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 0 Adress-Bits + 16 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit 1 || 200µs Puls, 2925µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit 2 || 200µs Puls, 2925µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit 3 || 200µs Puls, 15425µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit 4 || 200µs Puls, 2925µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 200µs Puls, 2925µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 200µs Puls, 9175µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| R-Bit || 200µs Puls, 6050µs Pause, wiederholt das letzte Bit (repetition)&lt;br /&gt;
|-&lt;br /&gt;
| Trailer-Bit || 200µs Puls, 12300µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 200µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || N-fache Wiederholung des Original-Frames innerhalb von 100ms&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || MSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== FDC ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;FDC&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 40 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 8 Adress-Bits + 12 x 0-Bits + 4 Press/Release-Bits + 8 Kommando-Bits + 8 invertierte Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 2085µs Puls, 966µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 300µs Puls,  220µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 300µs Puls, 715µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 300µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Drücken || Press/Release-Bits = 0000&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Loslassen || Press/Release-Bits = 1111&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || Wiederholung nach Pause von 60ms&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || LSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== NIKON ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;NIKON&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz?&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 2 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 2 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 2200µs Puls, 27100µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 500µs Puls,  1500µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 500µs Puls, 3500µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 500µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || unbekannt&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || MSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== KATHREIN ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;KATHREIN&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz?&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 11 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 4 Adress-Bits + 7 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 210µs Puls, 6218µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 210µs Puls,  1400µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 210µs Puls, 3000µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 210µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || nach 35ms?&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || MSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== LEGO ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;[[IRMP#LEGO Power Functions RC|LEGO]]&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz?&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 16 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 16 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 158µs Puls, 1026µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 158µs Puls,  263µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 158µs Puls, 553µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 158µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || unbekannt&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || MSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== THOMSON ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;THOMSON&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 33 kHz&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 0 Start-Bits + 12 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 4 Adress-Bits + 1 Toggle-Bit + 7 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 550µs Puls,  2000µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 550µs Puls, 4500µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 550µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || Framewiederholung nach 35ms&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || vermutlich MSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== TELEFUNKEN ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;TELEFUNKEN&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz?&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 15 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 0 Adress-Bits + 15 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 600µs Puls, 1500µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 600µs Puls, 600µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 600µs Puls, 1500µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 600µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || unbekannt&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || vermutlich MSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== RCCAR ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;RCCAR&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz?&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 13 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 13 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 2000µs Puls, 2000µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 600µs Puls,  900µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 600µs Puls, 450µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 600µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || nach 40ms?&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || LSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== RCMM ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;[[IRMP#RCMM-Protokoll|RCMM]]&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 36 kHz&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance&lt;br /&gt;
|-&lt;br /&gt;
| Frame RCMM32 || 1 Start-Bit + 32 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Frame RCMM24 || 1 Start-Bit + 24 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Frame RCMM12 || 1 Start-Bit + 12 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten RCMM32 || 16 Adress-Bits (= 4 Mode-Bits + 12 Device-Bits) + 1 Toggle-Bit + 15 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Daten RCMM24 || 16 Adress-Bits (= 4 Mode-Bits + 12 Device-Bits) + 1 Toggle-Bit + 7 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Daten RCMM12 || 4 Adress-Bits (= 2 Mode-Bits + 2 Device-Bits) + 8 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 500µs Puls, 220µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 00-Bits || 230µs Puls, 220µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 01-Bits || 230µs Puls, 380µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 10-Bits || 230µs Puls, 550µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 11-Bits || 230µs Puls, 720µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 230µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || nach 80ms&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || LSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pulse Width Protokolle ===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Pulse-Width.png|miniatur|Pulse Width Coding]]&lt;br /&gt;
&lt;br /&gt;
==== SIRCS ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;[[IRMP#SIRCS-Protokoll|SIRCS]]&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
|Frequenz ||40 kHz&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Width&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 12-20 Daten-Bits, kein Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 7 Kommando-Bits + 5 Adress-Bits + bis zu 8 zusätzliche Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 2400µs Puls, 600µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 600µs Puls, 600µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 1200µs Puls, 600µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || zweimalig nach ca. 25ms, d.h. 2. und 3. Frame&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || ab dem 4. identischen Frame, Abstand ca. 25ms&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || LSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pulse Distance Width Protokolle ===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Pulse-Distance-Width.png|miniatur|Pulse Distance Width Coding]]&lt;br /&gt;
&lt;br /&gt;
==== NUBERT ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;NUBERT&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 36 kHz?&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance Width&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 10 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 0 Adress-Bits + 10 Kommando-Bits ?&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 1340µs Puls, 340µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 500µs Puls, 1300µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 1340µs Puls, 340µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 500µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || einmalig nach 35ms&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || dritter, fünfter, siebter usw. identischer Frame&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || MSB first?&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== SPEAKER ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;SPEAKER&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz?&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance Width&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 10 Daten-Bits + 1 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 0 Adress-Bits + 10 Kommando-Bits ?&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 440µs Puls, 1250µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 440µs Puls, 1250µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 1250µs Puls, 440µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || 440µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || einmalig nach ca. 38ms&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || dritter, fünfter, siebter usw. identischer Frame&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || MSB first?&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ROOMBA ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;ROOMBA&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz?&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Distance Width&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 7 Daten-Bits + 0 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 0 Adress-Bits + 7 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 2790µs Puls, 930µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 930µs Puls, 2790µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 2790µs Puls, 930µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || kein Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || dreimalig nach jeweils 18ms?&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || noch unbekannt&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || MSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Biphase Protokolle ===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Biphase-Coding.png|miniatur|Biphase Coding]]&lt;br /&gt;
&lt;br /&gt;
==== RC5 + RC5X ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;[[IRMP#RC5- und RC5x-Protokoll|RC5 + RC5X]]&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 36 kHz&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Biphase (Manchester)&lt;br /&gt;
|-&lt;br /&gt;
| Frame RC5 || 2 Start-Bits + 12 Daten-Bits + 0 Stop-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Daten RC5 || 1 Toggle-Bit + 5 Adress-Bits + 6 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Frame RC5X || 1 Start-Bit + 13 Daten-Bits + 0 Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten RC5X || 1 invertiertes Kommando-Bit + 1 Toggle-Bit + 5 Adress-Bits + 6 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 889µs Pause, 889µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 889µs Puls, 889µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 889µs Pause, 889µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || kein Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || N-fache Wiederholung des Original-Frames innerhalb von 100ms&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || MSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== RC6 + RC6A ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;[[IRMP#RC6 und RC6A-Protokoll|RC6 + RC6A]]&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 36 kHz&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Biphase (Manchester)&lt;br /&gt;
|-&lt;br /&gt;
| Frame RC6 || 1 Start-Bit + 1 Bit &amp;quot;1&amp;quot; + 3 Mode-Bits (000) + 1 Toggle-Bit + 16 Daten-Bits + 2666µs pause&lt;br /&gt;
|-&lt;br /&gt;
| Frame RC6A || 1 Start-Bit + 1 Bit &amp;quot;1&amp;quot; + 3 Mode-Bits (110) + 1 Toggle-Bit + 31 Daten-Bits + 2666µs pause&lt;br /&gt;
|-&lt;br /&gt;
| Daten RC6 || 8 Adress-Bits + 8 Kommando Bits&lt;br /&gt;
|-&lt;br /&gt;
| Daten RC6A || &amp;quot;1&amp;quot; + 14 Hersteller-Bits + 8 System-Bits + 8 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Daten RC6A Pace (Sky) || &amp;quot;1&amp;quot; + 3 Mode-Bits (&amp;quot;110&amp;quot;) + 1 Toggle-Bit(UNUSED &amp;quot;0&amp;quot;) + 16 Bit + 1 Toggle(!) + 15 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 2666µs Puls, 889µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Toggle 0-Bit || 889µs Pause, 889µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| Toggle 1-Bit || 889µs Puls, 889µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 444µs Pause, 444µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 444µs Puls, 444µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || kein Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || N-fache Wiederholung des Original-Frames innerhalb von 100ms&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || MSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GRUNDIG + NOKIA ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;[[IRMP#Grundig-Protokoll|GRUNDIG + NOKIA]]&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz (?)&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Biphase (Manchester)&lt;br /&gt;
|-&lt;br /&gt;
| Frame-Paket || 1 Start-Frame + 19,968ms Pause + N Info-Frames + 117,76ms Pause + 1 Stop-Frame&lt;br /&gt;
|-&lt;br /&gt;
| Start-Frame || 1 Pre-Bit + 1 Start-Bit + 9 Daten-Bits (alle 1) + 0 Stop-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Info-Frame || 1 Pre-Bit + 1 Start-Bit + 9 Daten-Bits + 0 Stop-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Frame || 1 Pre-Bit + 1 Start-Bit + 9 Daten-Bits (alle 1) + 0 Stop-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Daten Grundig || 9 Kommando-Bits + 0 Adress-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Daten Nokia || 8 Kommando-Bits + 8 Adress-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Pre-Bit || 528µs Puls, 2639µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 528µs Puls, 528µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 528µs Pause, 528µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 528µs Puls, 528µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || kein Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || N-fache Wiederholung des Info-Frames mit einem Pausenabstand von 117,76ms&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || LSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== IR60 (SDA2008) ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;[[IRMP#IR60 (SDA2008 bzw. MC14497P)|IR60 (SDA2008)]]&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 30 kHz&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Biphase (Manchester)&lt;br /&gt;
|-&lt;br /&gt;
| Start Frame || 1 Start-Bit + 101111 + 0 Stop-Bits + 22ms Pause&lt;br /&gt;
|-&lt;br /&gt;
| Daten Frame || 1 Start-Bit + 7 Daten-Bits + 0 Stop-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 0 Adress-Bits + 7 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 528µs Puls, 2639µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 528µs Pause, 528µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 528µs Puls, 528µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || kein Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || N-fache Wiederholung des Info-Frames mit einem Pausenabstand von 117,76ms&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || LSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== SIEMENS + RUWIDO ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;SIEMENS + RUWIDO&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 36 kHz? (Merlin-Tastatur mit Ruwido-Protokoll: 56 kHz)&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Biphase (Manchester)&lt;br /&gt;
|-&lt;br /&gt;
| Frame Siemens || 1 Start-Bit + 22 Daten-Bits + 0 Stop-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Frame Ruwido || 1 Start-Bit + 17 Daten-Bits + 0 Stop-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Daten Siemens || 11 Adress-Bits + 10 Kommando-Bits + 1 invertiertes Bit (letztes Bit davor nochmal invertiert)&lt;br /&gt;
|-&lt;br /&gt;
| Daten Ruwido || 9 Adress-Bits + 7 Kommando-Bits + 1 invertiertes Bit (letztes Bit davor nochmal invertiert)&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 275µs Puls, 275µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 275µs Pause, 275µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 275µs Puls, 275µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || kein Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || 1-malige Wiederholung mit gesetztem Repeat-Bit (?)&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || N-fache Wiederholung des Original-Frames innerhalb von 100ms (?)&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || MSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== A1TVBOX ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;A1TVBOX&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz?&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Biphase (Manchester) asymmetrisch&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 2 Start-Bits + 16 Daten-Bits + 0 Stop-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 8 Adress-Bits + 8 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bits || &amp;quot;10&amp;quot;, also 250µs Puls, 150µs + 150µs Pause, 250µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 150µs Pause, 250µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 250µs Puls, 150µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || kein Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || unbekannt&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || MSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ORTEK ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;ORTEK&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz?&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Biphase (Manchester) symmetrisch&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 2 Start-Bits + 18 Daten-Bits + 0 Stop-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 6 Adress-Bits + 2 Spezial-Bits +  6 Kommando-Bits + 4 Spezial-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 2000µs Puls, 1000µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| 0-Bit || 500µs Pause, 500µs Puls&lt;br /&gt;
|-&lt;br /&gt;
| 1-Bit || 500µs Puls, 500µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Stop-Bit || kein Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || 2 zusätzliche Frames mit gesetzten Spezial-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || N-fache Wiederholung des 2. Frames&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || MSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pulse Position Protokolle ===&lt;br /&gt;
&lt;br /&gt;
==== NETBOX ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! &#039;&#039;&#039;NETBOX&#039;&#039;&#039; || Wert&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;width: 15em&amp;quot;|&lt;br /&gt;
|style=&amp;quot;width: 50em&amp;quot;|&lt;br /&gt;
|-&lt;br /&gt;
| Frequenz || 38 kHz?&lt;br /&gt;
|-&lt;br /&gt;
| Kodierung || Pulse Position&lt;br /&gt;
|-&lt;br /&gt;
| Frame || 1 Start-Bit + 16 Daten-Bits, kein Stop-Bit&lt;br /&gt;
|-&lt;br /&gt;
| Daten || 3 Adress-Bits + 13 Kommando-Bits&lt;br /&gt;
|-&lt;br /&gt;
| Start-Bit || 2400µs Puls, 800µs Pause&lt;br /&gt;
|-&lt;br /&gt;
| Bitlänge || 800µs&lt;br /&gt;
|-&lt;br /&gt;
| Wiederholung || keine&lt;br /&gt;
|-&lt;br /&gt;
| Tasten-Wiederholung || Abstand ca. 35ms?&lt;br /&gt;
|-&lt;br /&gt;
| Bit-Order || LSB first&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Software-Historie IRMP ==&lt;br /&gt;
&lt;br /&gt;
Änderungen IRMP:&lt;br /&gt;
&lt;br /&gt;
Version 2.5.3:&lt;br /&gt;
&lt;br /&gt;
* 05.06.2014: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#LGAIR|LGAIR]]&lt;br /&gt;
&lt;br /&gt;
Version 2.5.0:&lt;br /&gt;
&lt;br /&gt;
* 30.05.2014: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#SPEAKER|SPEAKER]]&lt;br /&gt;
&lt;br /&gt;
Version 2.4.1:&lt;br /&gt;
&lt;br /&gt;
* 30.05.2014: Timings für [[IRMP#SAMSUNG|SAMSUNG]]-Protokolle optimiert&lt;br /&gt;
&lt;br /&gt;
Version 2.4.0:&lt;br /&gt;
&lt;br /&gt;
* 20.02.2014: Fehlerhaftes Decodieren des [[IRMP#SIEMENS_+_RUWIDO|SIEMENS]]-Protokolls korrigiert&lt;br /&gt;
* 19.02.2014: &#039;&#039;&#039;Neue Protokolle&#039;&#039;&#039;: [[IRMP#RCMM|RCMM32, RCMM24 und RCMM12]]&lt;br /&gt;
* 17.09.2014: Timing für [[IRMP#ROOMBA|ROOMBA]] verbessert&lt;br /&gt;
&lt;br /&gt;
Ältere Versionen:&lt;br /&gt;
&lt;br /&gt;
* 09.04.2013: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#ROOMBA|ROOMBA]] (nur im SVN!)&lt;br /&gt;
* 09.04.2013: Verbesserte Frame-Erkennung für [[IRMP#ORTEK|ORTEK (Hama)]]&lt;br /&gt;
* 19.03.2013: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#ORTEK|ORTEK (Hama)]]&lt;br /&gt;
* 19.03.2013: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#TELEFUNKEN|TELEFUNKEN]]&lt;br /&gt;
* 12.03.2013: Geänderte Timing-Toleranzen für [[IRMP#RECS80|RECS80]]- und  [[IRMP#RECS80EXT|RECS80EXT]]-Protokoll&lt;br /&gt;
* 21.01.2013: Korrekturen Erkennung des Wiederholungsframes beim [[IRMP#DENON|DENON]]-Protokoll&lt;br /&gt;
* 17.01.2013: Korrekturen Frame-Erkennung beim [[IRMP#DENON|DENON]]-Protokoll&lt;br /&gt;
* 11.12.2012: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#A1TVBOX|A1TVBOX]]&lt;br /&gt;
* 07.12.2012: Verbesserte Erkennung von [[IRMP#DENON|DENON]]-Wiederholungsframes&lt;br /&gt;
* 19.11.2012: Portierung auf Stellaris LM4F120 Launchpad von TI (ARM Cortex M4)&lt;br /&gt;
* 06.11.2012: Korrektur [[IRMP#DENON|DENON]]-Frame-Erkennung&lt;br /&gt;
* 26.10.2012: Einige Timer-Korrekturen, Anpassungen an Arduino&lt;br /&gt;
* 11.07.2012: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#BOSE|BOSE]]&lt;br /&gt;
* 18.06.2012: Unterstützung für ATtiny87/167 hinzugefügt&lt;br /&gt;
* 05.06.2012: Kleinere Korrekturen Portierung auf ARM STM32&lt;br /&gt;
* 05.06.2012: Include-Korrektur in [http://www.mikrocontroller.net/svnbrowser/irmp/irmpextlog.c?view=markup irmpextlog.c]&lt;br /&gt;
* 05.06.2012: Bugfix, wenn nur [[IRMP#NEC_+_extended_NEC|NEC]] und [[IRMP#NEC42|NEC42]] aktiviert&lt;br /&gt;
* 23.05.2012: Portierung auf ARM STM32&lt;br /&gt;
* 23.05.2012: Bugfix Frame-Erkennung beim [[IRMP#DENON|DENON]]-Protokoll&lt;br /&gt;
* 27.02.2012: Bug in IR60-Decoder behoben&lt;br /&gt;
* 27.02.2012: Bug in CRC-Berechnung von [[IRMP#KASEIKYO|KASEIKYO]]-Frames behoben&lt;br /&gt;
* 27.02.2012: Portierung auf C18 Compiler für PIC-Mikroprozessoren&lt;br /&gt;
* 13.02.2012: Bugfix: oberstes Bit in Adresse falsch bei [[IRMP#NEC_+_extended_NEC|NEC]]-Protokoll, wenn auch [[IRMP#NEC42|NEC42]]-Protokoll eingeschaltet ist.&lt;br /&gt;
* 13.02.2012: Timing von [[IRMP#SAMSUNG|SAMSUNG]]- und [[IRMP#SAMSUNG32|SAMSUNG32]]-Protokoll korrigiert&lt;br /&gt;
* 13.02.2012: [[IRMP#KASEIKYO|KASEIKYO]]: Genre2-Bits werden nun im oberen Nibble von flags gespeichert.&lt;br /&gt;
* 20.09.2011: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#KATHREIN|KATHREIN]]&lt;br /&gt;
* 20.09.2011: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#SIEMENS_+_RUWIDO|RUWIDO]]&lt;br /&gt;
* 20.09.2011: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#THOMSON|THOMSON]]&lt;br /&gt;
* 20.09.2011: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#IR60 (SDA2008)|IR60 (SDA2008)]]&lt;br /&gt;
* 20.09.2011: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#LEGO|LEGO]]&lt;br /&gt;
* 20.09.2011: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#NEC16|NEC16]]&lt;br /&gt;
* 20.09.2011: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#NEC42|NEC42]]&lt;br /&gt;
* 20.09.2011: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#NETBOX|NETBOX]]&lt;br /&gt;
* 20.09.2011: Portierung auf ATtiny84 und ATtiny85&lt;br /&gt;
* 20.09.2011: Verbesserung von Tastenwiederholungen bei [[IRMP#RC5_+_RC5X|RC5]]&lt;br /&gt;
* 20.09.2011: Verbessertes Decodieren von [[IRMP#Biphase|Biphase]]-Protokollen&lt;br /&gt;
* 20.09.2011: Korrekturen am [[IRMP#RECS80|RECS80]]-Decoder&lt;br /&gt;
* 20.09.2011: Korrekturen beim Erkennen von zusätzlichen Bits im SIRCS-Protocol&lt;br /&gt;
* 18.01.2011: Korrekturen für [[IRMP#SIEMENS_+_RUWIDO|SIEMENS]]-Protokoll&lt;br /&gt;
* 18.01.2011: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#NIKON|NIKON]]&lt;br /&gt;
* 18.01.2011: Speichern der zusätzlichen Bits (&amp;gt;12) im [[IRMP#SIRCS|SIRCS]]-Protokoll in der Adresse&lt;br /&gt;
* 18.01.2011: Timing-Korrekturen für [[IRMP#DENON|DENON]]-Protokoll&lt;br /&gt;
&lt;br /&gt;
* 04.09.2010: Bugfix für F_INTERRUPTS &amp;gt;= 16000&lt;br /&gt;
&lt;br /&gt;
* 02.09.2010: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#RC6_+_RC6A|RC6A]]&lt;br /&gt;
&lt;br /&gt;
* 29.08.2010: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#JVC|JVC]]&lt;br /&gt;
* 29.08.2010: [[IRMP#KASEIKYO|KASEIKYO]]-Protokoll: Berücksichtigung der Genre-Bits. &#039;&#039;&#039;ACHTUNG: dadurch neue Command-Codes!&#039;&#039;&#039;&lt;br /&gt;
* 29.08.2010: [[IRMP#KASEIKYO|KASEIKYO]]-Protokoll: Verbesserte Behandlung von Wiederholungs-Frames&lt;br /&gt;
* 29.08.2010: Verbesserte Unterstützung des [[IRMP#APPLE|APPLE]]-Protokolls. &#039;&#039;&#039;ACHTUNG: dadurch neue Adress-Codes!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* 01.07.2010: Bugfix: Einführen eines Timeouts für [[IRMP#NEC_+_extended_NEC|NEC]]-Repetition-Frames, um &amp;quot;Geisterkommandos&amp;quot; zu verhindern.&lt;br /&gt;
&lt;br /&gt;
* 26.06.2010: Bugfix: Deaktivieren von [[IRMP#RECS80|RECS80]], [[IRMP#RECS80EXT|RECS80EXT]] &amp;amp; [[IRMP#SIEMENS_+_RUWIDO|SIEMENS]] bei geringer Interrupt-Rate&lt;br /&gt;
&lt;br /&gt;
* 25.06.2010: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#RCCAR|RCCAR]]&lt;br /&gt;
* 25.06.2010: Tastenerkennung für [[IRMP#FDC|FDC]]-Protokoll (IR-keyboard) erweitert&lt;br /&gt;
* 25.06.2010: Interrupt-Frequenz nun bis zu 20kHz möglich&lt;br /&gt;
&lt;br /&gt;
* 09.06.2010: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#FDC|FDC]] (IR-keyboard)&lt;br /&gt;
* 09.06.2010: Timing für [[IRMP#DENON|DENON]]-Protokoll korrigiert&lt;br /&gt;
&lt;br /&gt;
* 02.06.2010: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#SIEMENS_+_RUWIDO|SIEMENS]] (Gigaset)&lt;br /&gt;
&lt;br /&gt;
* 26.05.2010: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#GRUNDIG_+_NOKIA|NOKIA]]&lt;br /&gt;
* 26.05.2010: Bugfix Auswertung von langen Tastendrücken bei [[IRMP#GRUNDIG_+_NOKIA|GRUNDIG]]-Protokoll&lt;br /&gt;
&lt;br /&gt;
* 17.05.2010: Bugfix [[IRMP#SAMSUNG32|SAMSUNG32]]-Protokoll: Kommando-Bit-Maske korrigiert&lt;br /&gt;
&lt;br /&gt;
* 16.05.2010: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#GRUNDIG_+_NOKIA|GRUNDIG]]&lt;br /&gt;
* 16.05.2010: Behandlung von automatischen Frame-Wiederholungen beim [[IRMP#SIRCS|SIRCS]]-, [[IRMP#SAMSUNG32|SAMSUNG32]]- und [[IRMP#NUBERT|NUBERT]]-Protokoll verbessert.&lt;br /&gt;
&lt;br /&gt;
* 28.04.2010: Nur einige kosmetische Code-Optimierungen&lt;br /&gt;
&lt;br /&gt;
* 16.04.2010: Sämtliche Timing-Toleranzen angepasst/optimiert&lt;br /&gt;
&lt;br /&gt;
* 12.04.2010: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#B&amp;amp;O|Bang &amp;amp; Olufsen]]&lt;br /&gt;
&lt;br /&gt;
* 29.03.2010: Bugfix beim Erkennen von mehrfachen [[IRMP#NEC_+_extended_NEC|NEC]]-Repetition-Frames&lt;br /&gt;
* 29.03.2010: Konfiguration in [http://www.mikrocontroller.net/svnbrowser/irmp/irmpconfig.h?view=markup irmpconfig.h] ausgelagert&lt;br /&gt;
* 29.03.2010: Einführung einer Programmversion in README.txt: Version 1.0&lt;br /&gt;
&lt;br /&gt;
* 17.03.2010: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#NUBERT|NUBERT]]&lt;br /&gt;
&lt;br /&gt;
* 16.03.2010: Korrektur der RECS80-Startbit-Timings&lt;br /&gt;
* 16.03.2010: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#RECS80EXT|RECS80 Extended]]&lt;br /&gt;
&lt;br /&gt;
* 15.03.2010: Codeoptimierung&lt;br /&gt;
&lt;br /&gt;
* 14.03.2010: Portierung auf PIC&lt;br /&gt;
&lt;br /&gt;
* 11.03.2010: Anpassungen an verschiedene ATMega-Typen durchgeführt&lt;br /&gt;
&lt;br /&gt;
* 07.03.2010: Bugfix: Zurücksetzen der Statemachine nach einem unvollständigen [[IRMP#RC5_+_RC5X|RC5]]-Frame&lt;br /&gt;
&lt;br /&gt;
* 05.03.2010: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#APPLE|APPLE]]&lt;br /&gt;
* 05.03.2010: Die Daten irmp_data.addr + irmp_data.command werden nun in der jeweiligen Bit-Order des verwendeten Protokolls gespeichert&lt;br /&gt;
&lt;br /&gt;
* 04.03.2010: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#SAMSUNG32|SAMSUNG32]] (Mix aus [[IRMP#SAMSUNG|SAMSUNG]] &amp;amp; [[IRMP#NEC_+_extended_NEC|NEC]]-Protokoll)&lt;br /&gt;
* 04.03.2010: Änderung der [[IRMP#SIRCS|SIRCS]]- und [[IRMP#KASEIKYO|KASEIKYO]]-Toleranzen&lt;br /&gt;
&lt;br /&gt;
* 02.03.2010: [[IRMP#SIRCS|SIRCS]]: Korrekte Erkennung und Unterdrückung von automatischen Frame-Wiederholungen&lt;br /&gt;
* 02.03.2010: [[IRMP#SIRCS|SIRCS]]: Device-ID-Bits werden nun in irmp_data.command und nicht mehr in irmp_data.address gespeichert&lt;br /&gt;
* 02.03.2010: Vergrößerung des Scan Buffers (zwecks Protokollierung)&lt;br /&gt;
&lt;br /&gt;
* 24.02.2010: Neue Variable flags in IRMP_DATA zur Erkennung von langen Tastendrücken&lt;br /&gt;
&lt;br /&gt;
* 20.02.2010: Bugfix [[IRMP#DENON|DENON]]-Protokoll: Wiederholungsframe grundsätzlich invertiert&lt;br /&gt;
&lt;br /&gt;
* 19.02.2010: Erkennung von [[IRMP#NEC_+_extended_NEC|NEC]]-Protokoll-Varianten, z.&amp;amp;nbsp;B. [[IRMP#APPLE|APPLE]]-Fernbedienung&lt;br /&gt;
* 19.02.2010: Erkennung von [[IRMP#RC6_+_RC6A|RC6]]- und [[IRMP#DENON|DENON]]-Protokoll&lt;br /&gt;
* 19.02.2010: Verbesserung des [[IRMP#RC5_+_RC5X|RC5]]-Decoders (Bugfixes)&lt;br /&gt;
&lt;br /&gt;
* 13.02.2010: Bugfix: Puls/Pausen-Counter um 1 zu niedrig, nun bessere Erkennung bei Protokollen mit sehr kurzen Pulszeiten&lt;br /&gt;
* 13.02.2010: Erkennung der [[IRMP#NEC_+_extended_NEC|NEC]]-Wiederholungssequenz&lt;br /&gt;
&lt;br /&gt;
* 12.02.2010: [[IRMP#RC5_+_RC5X|RC5]]-Protokoll-Decoder hinzugefügt&lt;br /&gt;
&lt;br /&gt;
* 05.02.2010: Konflikt zwischen [[IRMP#SAMSUNG|SAMSUNG]]- und [[IRMP#MATSUSHITA|MATSUSHITA]]-Protokoll beseitigt&lt;br /&gt;
&lt;br /&gt;
* 07.01.2010: Erste Version&lt;br /&gt;
&lt;br /&gt;
== Software-Historie IRSND ==&lt;br /&gt;
&lt;br /&gt;
Änderungen IRSND:&lt;br /&gt;
&lt;br /&gt;
Version 2.5.2:&lt;br /&gt;
&lt;br /&gt;
* 03.06.2014: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#TELEFUNKEN|TELEFUNKEN]]&lt;br /&gt;
&lt;br /&gt;
Version 2.5.1:&lt;br /&gt;
&lt;br /&gt;
* 30.05.2014: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#SPEAKER|SPEAKER]]&lt;br /&gt;
&lt;br /&gt;
Version 2.4.1:&lt;br /&gt;
&lt;br /&gt;
* 30.05.2014: Timings für [[IRMP#SAMSUNG|SAMSUNG]]-Protokolle optimiert&lt;br /&gt;
&lt;br /&gt;
Version 2.4.0&lt;br /&gt;
&lt;br /&gt;
* 20.02.2014: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#SIEMENS_+_RUWIDO|RUWIDO]]&lt;br /&gt;
&lt;br /&gt;
Ältere Versionen:&lt;br /&gt;
&lt;br /&gt;
* 09.04.2013: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#ROOMBA|ROOMBA]] (&#039;&#039;&#039;nur im SVN!&#039;&#039;&#039;)&lt;br /&gt;
* 12.03.2013: 15kHz für [[IRMP#RECS80|RECS80]]- und  [[IRMP#RECS80EXT|RECS80EXT]]-Protokoll ist nun auch erlaubt&lt;br /&gt;
* 17.01.2013: Unterstützung für ATtiny44 hinzugefügt&lt;br /&gt;
* 12.12.2012: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#A1TVBOX|A1TVBOX]]&lt;br /&gt;
* 07.12.2012: Korrektur Timing beim [[IRMP#NIKON|NIKON]]-Protokoll&lt;br /&gt;
* 26.10.2012: Einige Timer-Korrekturen, Anpassungen an Arduino&lt;br /&gt;
* 18.06.2012: Unterstützung für ATtiny87/167 hinzugefügt&lt;br /&gt;
* 05.06.2012: Korrekturen Portierung auf ARM STM32 - nun getestet&lt;br /&gt;
* 23.05.2012: Portierung auf ARM STM32 (ungetestet!)&lt;br /&gt;
* 23.05.2012: Bugfix Timing für 2. Frame beim Denon-Protokoll&lt;br /&gt;
* 27.02.2012: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#IR60 (SDA2008)|IR60 (SDA2008)]]&lt;br /&gt;
* 27.02.2012: Bug beim Senden von [[IRMP#Biphase|Biphase]]-Frames (Manchester) behoben&lt;br /&gt;
* 27.02.2012: Portierung auf C18 Compiler für PIC-Mikroprozessoren&lt;br /&gt;
* 15.02.2012: Bugfix: Nur der 1. Frame wurde gesendet&lt;br /&gt;
* 13.02.2012: Timing von [[IRMP#SAMSUNG|SAMSUNG]]- und [[IRMP#SAMSUNG32|SAMSUNG32]]-Protokoll korrigiert&lt;br /&gt;
* 13.02.2012: [[IRMP#KASEIKYO|KASEIKYO]]: Genre2-Bits werden nun im oberen Nibble von flags gespeichert.&lt;br /&gt;
* 13.02.2012: Zusätzliche Pause nach dem Senden des letzten Frames&lt;br /&gt;
* 20.09.2011: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#THOMSON|THOMSON]]&lt;br /&gt;
* 20.09.2011: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#LEGO|LEGO]]&lt;br /&gt;
* 20.09.2011: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#NEC16|NEC16]]&lt;br /&gt;
* 20.09.2011: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#NEC42|NEC42]]&lt;br /&gt;
* 20.09.2011: Portierung auf ATtiny84 und ATtiny85&lt;br /&gt;
* 20.09.2011: Korrektur von Pausenlängen&lt;br /&gt;
* 20.09.2011: Korrekturen von irsnd_stop()&lt;br /&gt;
* 20.09.2011: Korrektur des [[IRMP#SIEMENS_+_RUWIDO|SIEMENS]]-Timings&lt;br /&gt;
* 20.09.2011: Umstellung auf 36kHz Modulationsfrequenz für [[IRMP#DENON|DENON]]-Protokoll&lt;br /&gt;
* 20.09.2011: Korrektur Behandlung zusätzlicher Bits im [[IRMP#SIRCS|SIRCS]]-Protokoll&lt;br /&gt;
* 18.01.2011: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#RC6_+_RC6A|RC6A]]&lt;br /&gt;
* 18.01.2011: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#RC6_+_RC6A|RC6]]&lt;br /&gt;
* 18.01.2011: &#039;&#039;&#039;Neues Protokoll&#039;&#039;&#039;: [[IRMP#NIKON|NIKON]]&lt;br /&gt;
* 18.01.2011: Beachten der zusätzlichen Bits (&amp;gt;12) im [[IRMP#SIRCS|SIRCS]]-Protokoll&lt;br /&gt;
* 18.01.2011: Korrektur der Pausenlängen&lt;br /&gt;
* 18.01.2011: Timing-Korrekturen für [[IRMP#DENON|DENON]]-Protokoll&lt;br /&gt;
&lt;br /&gt;
* 02.09.2010: Neues Protokoll: [[IRMP#JVC|JVC]]&lt;br /&gt;
* 02.09.2010: Anpassung des [[IRMP#APPLE|APPLE]]-Encoders an IRMP-Version 1.7.3.&lt;br /&gt;
&lt;br /&gt;
* 29.08.2010: Neues Protokoll: [[IRMP#KASEIKYO|KASEIKYO]] (Panasonic u.a.)&lt;br /&gt;
&lt;br /&gt;
* 01.07.2010: Bugfix: Deaktivieren von [[IRMP#RECS80|RECS80]], [[IRMP#RECS80EXT|RECS80EXT]] &amp;amp; [[IRMP#SIEMENS_+_RUWIDO|SIEMENS]] bei geringer Interrupt-Rate&lt;br /&gt;
&lt;br /&gt;
* 25.06.2010: Neues Protokoll: [[IRMP#RCCAR|RCCAR]]&lt;br /&gt;
&lt;br /&gt;
* 09.06.2010: Neues Protokoll: [[IRMP#FDC|FDC]] (IR-keyboard)&lt;br /&gt;
* 09.06.2010: Timing für [[IRMP#DENON|DENON]]-Protokoll korrigiert&lt;br /&gt;
&lt;br /&gt;
* 02.06.2010: Neues Protokoll: [[IRMP#SIEMENS_+_RUWIDO|SIEMENS]] (Gigaset)&lt;br /&gt;
* 02.06.2010: Simulation von langen Tastendrücken&lt;br /&gt;
&lt;br /&gt;
* 26.05.2010: Neues Protokoll: [[IRMP#GRUNDIG_+_NOKIA|NOKIA]]&lt;br /&gt;
&lt;br /&gt;
* 17.05.2010: Neues Protokoll: [[IRMP#GRUNDIG_+_NOKIA|GRUNDIG]]&lt;br /&gt;
* 17.05.2010: Behandlung von Frame-Wiederholungen für [[IRMP#SIRCS|SIRCS]], [[IRMP#SAMSUNG32|SAMSUNG32]] und [[IRMP#NUBERT|NUBERT]] korrigiert&lt;br /&gt;
&lt;br /&gt;
* 28.04.2010: Unterstützung des [[IRMP#APPLE|APPLE]]-Protokolls&lt;br /&gt;
* 28.04.2010: Konfiguration über [http://www.mikrocontroller.net/svnbrowser/irmp/irsndconfig.h?view=markup irsndconfig.h]&lt;br /&gt;
&lt;br /&gt;
* 16.04.2010: Sämtliche Timing-Toleranzen angepasst/optimiert&lt;br /&gt;
&lt;br /&gt;
* 14.04.2010: Neues Protokoll: [[IRMP#B&amp;amp;O|Bang &amp;amp; Olufsen]]&lt;br /&gt;
&lt;br /&gt;
* 17.03.2010: Neues Protokoll: [[IRMP#NUBERT|NUBERT]]&lt;br /&gt;
* 17.03.2010: Korrektur der Pausen zwischen Frame-Wiederholungen&lt;br /&gt;
&lt;br /&gt;
* 16.03.2010: Korrektur des Timer-Registers TCCR2&lt;br /&gt;
* 16.03.2010: Korrektur der [[IRMP#RECS80|RECS80]]-Startbit-Timings&lt;br /&gt;
* 16.03.2010: Neues Protokoll: [[IRMP#RECS80EXT|RECS80 Extended]]&lt;br /&gt;
&lt;br /&gt;
* 11.03.2010: Anpassungen an verschiedene ATMega-Typen durchgeführt&lt;br /&gt;
&lt;br /&gt;
* 07.03.2010: Alpha-Version&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
&lt;br /&gt;
=== IR-Übersicht ===&lt;br /&gt;
&lt;br /&gt;
* http://www.sbprojects.com/knowledge/ir/index.php&lt;br /&gt;
* http://www.epanorama.net/links/irremote.html&lt;br /&gt;
* http://www.elektor.de/jahrgang/2008/juni/cc2-avr-projekt-%283%29-unsichtbare-kommandos.497184.lynkx?tab=4 (IR Übersicht &amp;amp; RC5)&lt;br /&gt;
&lt;br /&gt;
=== SIRCS-Protokoll ===&lt;br /&gt;
&lt;br /&gt;
* http://www.sbprojects.com/knowledge/ir/sirc.php&lt;br /&gt;
* http://www.ustr.net/infrared/sony.shtml&lt;br /&gt;
* http://users.telenet.be/davshomepage/sony.htm&lt;br /&gt;
* http://picprojects.org.uk/projects/sirc/&lt;br /&gt;
* http://www.celadon.com/infrared_protocol/infrared_protocols_samples.pdf&lt;br /&gt;
&lt;br /&gt;
=== NEC-Protokoll ===&lt;br /&gt;
&lt;br /&gt;
* http://www.sbprojects.com/knowledge/ir/nec.php&lt;br /&gt;
* http://www.ustr.net/infrared/nec.shtml&lt;br /&gt;
* http://www.celadon.com/infrared_protocol/infrared_protocols_samples.pdf&lt;br /&gt;
&lt;br /&gt;
=== LGAIR-Protokoll ===&lt;br /&gt;
&lt;br /&gt;
Der LG Air Conditioner ist eine Klimaanlage, die durch eine &amp;quot;intelligente&amp;quot; Fernbedienung gesteuert wird.&lt;br /&gt;
Dies sind die &amp;quot;entschlüsselten&amp;quot; Daten:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    Befehl                  AAAAAAAA  PW  Z  S  T  mmm  tttt  vvvv  PPPP&lt;br /&gt;
    --------------------------------------------------------------------&lt;br /&gt;
    ON 23C                  10001000  00  0  0  0  000  1000  0100  1100&lt;br /&gt;
    ON 26C                  10001000  00  0  0  0  000  1011  0100  1111&lt;br /&gt;
&lt;br /&gt;
    OFF                     10001000  11  0  0  0  000  0000  0101  0001&lt;br /&gt;
    TURN OFF                10001000  11  0  0  0  000  0000  0101  0001  (18C currently, identical with off)&lt;br /&gt;
&lt;br /&gt;
    TEMP DOWN 23C           10001000  00  0  0  1  000  1000  0100  0100&lt;br /&gt;
    MODE (to mode0, 23C)    10001000  00  0  0  1  000  1000  0100  0100&lt;br /&gt;
&lt;br /&gt;
    TEMP UP (24C)           10001000  00  0  0  1  000  1001  0100  0101&lt;br /&gt;
    TEMP DOWN 24C           10001000  00  0  0  1  000  1001  0100  0101&lt;br /&gt;
&lt;br /&gt;
    TEMP UP (25C)           10001000  00  0  0  1  000  1010  0100  0110&lt;br /&gt;
    TEMP DOWN 25C           10001000  00  0  0  1  000  1010  0100  0110&lt;br /&gt;
&lt;br /&gt;
    TEMP UP (26C)           10001000  00  0  0  1  000  1011  0100  0111&lt;br /&gt;
&lt;br /&gt;
    MODE                    10001000  00  0  0  1  011  0111  0100  0110  (to mode1, 22C - when switching to mode1 temp automaticall sets to 22C)&lt;br /&gt;
    ON (mode1, 22C)         10001000  00  0  0  0  011  0111  0100  1110&lt;br /&gt;
&lt;br /&gt;
    MODE                    10001000  00  0  0  1  001  1000  0100  0101  (to mode2, no temperature displayed)&lt;br /&gt;
    ON (mode2)              10001000  00  0  0  0  001  1000  0100  1101&lt;br /&gt;
    MODE (to mode3, 23C)    10001000  00  0  0  1  100  1000  0100  1000&lt;br /&gt;
    ON (mode3, 23C)         10001000  00  0  0  0  100  1000  0100  0000&lt;br /&gt;
&lt;br /&gt;
    VENTILATION SLOW        10001000  00  0  0  1  000  0011  0000  1011&lt;br /&gt;
    VENTILATION MEDIUM      10001000  00  0  0  1  000  0011  0010  1101&lt;br /&gt;
    VENTILATION HIGH        10001000  00  0  0  1  000  0011  0100  1111&lt;br /&gt;
    VENTILATION LIGHT       10001000  00  0  0  1  000  0011  0101  0000&lt;br /&gt;
&lt;br /&gt;
    SWING ON/OFF            10001000  00  0  1  0  000  0000  0000  0001&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    Format:     1 start bit + 8 address bits + 16 data bits + 4 checksum bits + 1 stop bit&lt;br /&gt;
&lt;br /&gt;
    Address:    AAAAAAAA = 0x88 (8 bits)&lt;br /&gt;
&lt;br /&gt;
    Data:       PW Z S T MMM tttt vvvv PPPP (16 bits)&lt;br /&gt;
&lt;br /&gt;
                PW:         Power:     00 = On, 11 = Off&lt;br /&gt;
&lt;br /&gt;
                Z:          N/A:       Always 0&lt;br /&gt;
&lt;br /&gt;
                S:          Swing:     1 = Toggle swing, all other data bits are zeros.&lt;br /&gt;
&lt;br /&gt;
                T:          Temp/Vent: 1 = Set temperature and ventilation&lt;br /&gt;
&lt;br /&gt;
                MMM:        Mode, can be combined with temperature&lt;br /&gt;
                            000=Mode 0&lt;br /&gt;
                            001=Mode 2&lt;br /&gt;
                            010=????&lt;br /&gt;
                            011=Mode 1&lt;br /&gt;
                            100=Mode 3&lt;br /&gt;
                            101=???&lt;br /&gt;
                            111=???&lt;br /&gt;
&lt;br /&gt;
                tttt:       Temperature:&lt;br /&gt;
                            0000=used by OFF command&lt;br /&gt;
                            0001=????&lt;br /&gt;
                            0010=????&lt;br /&gt;
                            0011=18°C&lt;br /&gt;
                            0100=19°C&lt;br /&gt;
                            0101=20°C&lt;br /&gt;
                            0110=21°C&lt;br /&gt;
                            0111=22°C&lt;br /&gt;
                            1000=23°C&lt;br /&gt;
                            1001=24°C&lt;br /&gt;
                            1010=25°C&lt;br /&gt;
                            1011=26°C&lt;br /&gt;
                            1011=27°C&lt;br /&gt;
                            1100=28°C&lt;br /&gt;
                            1101=29°C&lt;br /&gt;
                            1111=30°C&lt;br /&gt;
&lt;br /&gt;
                vvvv:       Ventilation:&lt;br /&gt;
                            0000=slow&lt;br /&gt;
                            0010=medium&lt;br /&gt;
                            0011=????&lt;br /&gt;
                            0100=high&lt;br /&gt;
                            0101=light&lt;br /&gt;
                            0110=????&lt;br /&gt;
                            0111=????&lt;br /&gt;
                            ...&lt;br /&gt;
                            1111=????&lt;br /&gt;
&lt;br /&gt;
    Checksum:   PPPP = (DataNibble1 + DataNibble2 + DataNibble3 + DataNibble4) &amp;amp; 0x0F&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== NEC16-Protokoll (JVC) ===&lt;br /&gt;
&lt;br /&gt;
* http://www.sbprojects.com/knowledge/ir/jvc.php&lt;br /&gt;
* http://www.ustr.net/infrared/jvc.shtml&lt;br /&gt;
&lt;br /&gt;
=== SAMSUNG-Protokoll ===&lt;br /&gt;
&lt;br /&gt;
(wurde aus diversen Protokollen (Daewoo u.ä.) zusammengereimt, daher kein direkter Link auf irgendwelche SAMSUNG-Dokumentation verfügbar)&lt;br /&gt;
&lt;br /&gt;
Hier ein Link zum Daewoo-Protokoll, welches dasselbe Prinzip des Sync-Bits in der Mitte eines Frames nutzt, jedoch mit anderen Timing-Werten arbeitet:&lt;br /&gt;
&lt;br /&gt;
* http://users.telenet.be/davshomepage/daewoo.htm&lt;br /&gt;
&lt;br /&gt;
=== MATSUHITA-Protokoll ===&lt;br /&gt;
&lt;br /&gt;
* http://www.celadon.com/infrared_protocol/infrared_protocols_samples.pdf&lt;br /&gt;
&lt;br /&gt;
=== KASEIKYO-Protokoll (auch &amp;quot;Japan-Protokoll&amp;quot;) ===&lt;br /&gt;
&lt;br /&gt;
* http://www.mikrocontroller.net/attachment/4246/IR-Protokolle_Diplomarbeit.pdf&lt;br /&gt;
* http://www.roboternetz.de/phpBB2/files/entwicklung_und_realisierung_einer_universalinfrarotfernbedienung_mit_timerfunktionen.pdf&lt;br /&gt;
&lt;br /&gt;
=== RECS80- und RECS80-Extended-Protokoll ===&lt;br /&gt;
&lt;br /&gt;
* http://www.sbprojects.com/knowledge/ir/recs80.php&lt;br /&gt;
&lt;br /&gt;
=== RC5- und RC5x-Protokoll ===&lt;br /&gt;
&lt;br /&gt;
* http://www.sbprojects.com/knowledge/ir/rc5.php&lt;br /&gt;
* http://users.telenet.be/davshomepage/rc5.htm&lt;br /&gt;
* http://www.celadon.com/infrared_protocol/infrared_protocols_samples.pdf&lt;br /&gt;
* http://www.opendcc.de/info/rc5/rc5.html&lt;br /&gt;
&lt;br /&gt;
=== Denon-Protokoll ===&lt;br /&gt;
&lt;br /&gt;
* http://www.mikrocontroller.com/de/IR-Protokolle.php#DENON&lt;br /&gt;
* http://www.manualowl.com/m/Denon/AVR-3803/Manual/170243&lt;br /&gt;
&lt;br /&gt;
=== RC6 und RC6A-Protokoll ===&lt;br /&gt;
&lt;br /&gt;
* http://www.sbprojects.com/knowledge/ir/rc6.php&lt;br /&gt;
* http://www.picbasic.nl/info_rc6_uk.htm&lt;br /&gt;
&lt;br /&gt;
=== Bang &amp;amp; Olufsen ===&lt;br /&gt;
&lt;br /&gt;
* http://www.mikrocontroller.net/attachment/33137/datalink.pdf&lt;br /&gt;
&lt;br /&gt;
=== Grundig-Protokoll ===&lt;br /&gt;
&lt;br /&gt;
* http://www.see-solutions.de/sonstiges/Grundig_10bit.pdf&lt;br /&gt;
&lt;br /&gt;
=== Nokia-Protokoll ===&lt;br /&gt;
&lt;br /&gt;
* http://www.sbprojects.com/knowledge/ir/nrc17.php&lt;br /&gt;
&lt;br /&gt;
=== IR60 (SDA2008 bzw. MC14497P) ===&lt;br /&gt;
&lt;br /&gt;
* http://www.datasheetcatalog.org/datasheet/motorola/MC14497P.pdf&lt;br /&gt;
&lt;br /&gt;
=== LEGO Power Functions RC ===&lt;br /&gt;
&lt;br /&gt;
* http://www.philohome.com/pf/LEGO_Power_Functions_RC_v110.pdf&lt;br /&gt;
&lt;br /&gt;
=== RCMM-Protokoll ===&lt;br /&gt;
&lt;br /&gt;
* http://www.sbprojects.com/knowledge/ir/rcmm.php&lt;br /&gt;
&lt;br /&gt;
=== Diverse Protokolle ===&lt;br /&gt;
&lt;br /&gt;
* http://www.mikrocontroller.net/attachment/4246/IR-Protokolle_Diplomarbeit.pdf&lt;br /&gt;
* http://www.celadon.com/infrared_protocol/infrared_protocols_samples.pdf&lt;br /&gt;
* http://www.roboternetz.de/phpBB2/files/entwicklung_und_realisierung_einer_universalinfrarotfernbedienung_mit_timerfunktionen.pdf&lt;br /&gt;
&lt;br /&gt;
== IRMP auf Youtube ==&lt;br /&gt;
&lt;br /&gt;
Einige Videos zu [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] habe ich auf Youtube gefunden:&lt;br /&gt;
&lt;br /&gt;
* http://www.youtube.com/watch?v=Q7DJvLIyTEI&lt;br /&gt;
&lt;br /&gt;
* http://www.youtube.com/watch?v=1tQ_aqayWZk&lt;br /&gt;
&lt;br /&gt;
* http://www.youtube.com/watch?v=W4tI2axR3-w&lt;br /&gt;
&lt;br /&gt;
* http://www.youtube.com/watch?v=SRs98dIe2WE&lt;br /&gt;
&lt;br /&gt;
== Weitere Artikel zu IRMP ==&lt;br /&gt;
&lt;br /&gt;
[http://www.infineon.com/dgdl/RF2ir+WhitePaper+V1.0.pdf?folderId=db3a3043191a246301192dd3ee2c2ae4&amp;amp;fileId=db3a30432b57a660012b5c16272c2e81 Whitepaper von Martin Gotschlich, Infineon Technologies AG]&lt;br /&gt;
&lt;br /&gt;
== Hardware / IRMP-Projekte ==&lt;br /&gt;
&lt;br /&gt;
=== IR-Tester ===&lt;br /&gt;
&lt;br /&gt;
Eine Implementierung auf Basis [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] und [[IRMP#IRSND_-_Infrarot-Multiprotokoll-Encoder|IRSND]] als Multiprotokoll Dekoder mit LCD&lt;br /&gt;
von Klaus Leidinger: &lt;br /&gt;
* http://www.mikrocontroller-projekte.de/Mikrocontroller/index.html&lt;br /&gt;
&lt;br /&gt;
=== IR-Tester mit AVR-NET-IO ===&lt;br /&gt;
&lt;br /&gt;
Ähnliche Implementierung wie von Klaus Leidinger für Pollin AVR-NET-IO mit Pollin ADD-ON Board:&lt;br /&gt;
* http://son.ffdf-clan.de/include.php?path=forumsthread&amp;amp;threadid=703&lt;br /&gt;
&lt;br /&gt;
=== USB IR Remote Receiver ===&lt;br /&gt;
&lt;br /&gt;
USB IR Remote Receiver von Hugo Portisch:&lt;br /&gt;
* http://www.mikrocontroller.net/articles/USB_IR_Remote_Receiver&lt;br /&gt;
&lt;br /&gt;
=== Servo-gesteuerter IR-Sender  ===&lt;br /&gt;
&lt;br /&gt;
Servo-gesteuerter IR-Sender mit Anlernfunktion von Stefan Pendsa:&lt;br /&gt;
* http://forum.mikrokopter.de/topic-21060.html&lt;br /&gt;
* [http://svn.mikrokopter.de/listing.php?repname=Projects&amp;amp;path=%2FServo-Controlled+IR-Transmitter%2F&amp;amp;#Ad2417800d6aa14bf08c571a896e9def7 SVN]&lt;br /&gt;
&lt;br /&gt;
=== Lernfähige IR-Fernbedienung ===&lt;br /&gt;
&lt;br /&gt;
Lernfähige IR-Fernbedienung von Robert und Frank M.&lt;br /&gt;
* http://www.mikrocontroller.net/articles/DIY_Lernfähige_Fernbedienung_mit_IRMP&lt;br /&gt;
&lt;br /&gt;
=== AVR Moodlight ===&lt;br /&gt;
&lt;br /&gt;
AVR Moodlight von Axel Schwenke&lt;br /&gt;
* http://www.mikrocontroller.net/topic/244768&lt;br /&gt;
&lt;br /&gt;
=== Kinosteuerung ===&lt;br /&gt;
&lt;br /&gt;
Kinosteuerung von Owagner&lt;br /&gt;
* http://ccc.zerties.org/index.php/Benutzer:Owagner&lt;br /&gt;
&lt;br /&gt;
=== Phasenanschnittsdimmer ===&lt;br /&gt;
&lt;br /&gt;
Phasenanschnittsdimmer - steuerbar über IR-Fernbedienung:&lt;br /&gt;
&lt;br /&gt;
* http://flosserver.dyndns.org/phasenanschnittsdimmer.php&lt;br /&gt;
&lt;br /&gt;
=== IRDioder – Ikea Dioder Hack ===&lt;br /&gt;
&lt;br /&gt;
Ikea Dioder Hack mit Atmel und Infrarotempfaenger:&lt;br /&gt;
&lt;br /&gt;
* http://marco-difeo.de/tag/infrared/&lt;br /&gt;
&lt;br /&gt;
=== Arduino als IR-Empfänger ===&lt;br /&gt;
&lt;br /&gt;
Arduino als IR-Empfänger:&lt;br /&gt;
&lt;br /&gt;
* http://www.vdr-portal.de/board18-vdr-hardware/board13-fernbedienungen/110918-arduino-als-ir-empf%C3%A4nger-einsetzen/&lt;br /&gt;
&lt;br /&gt;
=== IR-Lautstärkesteuerung mit Stellaris Launchpad ===&lt;br /&gt;
&lt;br /&gt;
IR-Lautstärkesteuerung mit Stellaris Launchpad (ARM Cortex-M4F):&lt;br /&gt;
&lt;br /&gt;
* http://www.anthonyvh.com/2013/03/31/ir-volume-control/&lt;br /&gt;
&lt;br /&gt;
== Danksagung ==&lt;br /&gt;
&lt;br /&gt;
Ganz herzlich bedanken möchte ich mich bei Vlad Tepesch, Klaus Leidinger und Peter K., die mich mit Scan-Dateien ihrer Infrarot-Fernbedienungen versorgt haben. Dank auch an Klaus für seine nächtelangen Tests von [[IRMP#IRMP_-_Infrarot-Multiprotokoll-Decoder|IRMP]] &amp;amp; [[IRMP#IRSND_-_Infrarot-Multiprotokoll-Encoder|IRSND]].&lt;br /&gt;
&lt;br /&gt;
Ebenso bedanken möchte ich mich bei Christian F. für seine Tipps zur PIC-Portierung. Vielen Dank auch an gera für die Portierung auf den PIC-C18 Compiler. Für die Portierung auf ARM STM32 bedanke ich mich herzlich bei kichi (Michael K.). Vielen Dank auch an Markus Schuster für die Portierung auf Stellaris LM4F120 Launchpad von TI (ARM Cortex M4).&lt;br /&gt;
&lt;br /&gt;
== Diskussion ==&lt;br /&gt;
&lt;br /&gt;
Meinungen, Verbesserungsvorschläge, harsche Kritik und ähnliches kann im [http://www.mikrocontroller.net/topic/162119 Beitrag: Infrared Multi Protocol Decoder] geäussert werden.&lt;br /&gt;
&lt;br /&gt;
Viel Spaß mit IRMP!&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Infrarot]]&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Fehlersuche&amp;diff=83143</id>
		<title>Fehlersuche</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Fehlersuche&amp;diff=83143"/>
		<updated>2014-05-25T12:05:20Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Auf neudeutsch [http://de.wikipedia.org/wiki/Debugger Debugging] genannt (engl. bug = Wanze). Die Fehlersuche in Geräten, welche defekt sind oder die man sogar selber gebaut hat, ist eine der Hauptbeschäftigungen beim Umgang mit Elektronik, egal ob Hardware oder Software. Deshalb sollte man sie möglichst effizient betreiben.&lt;br /&gt;
&lt;br /&gt;
== Grundlagen ==&lt;br /&gt;
&lt;br /&gt;
=== Vorgehen ===&lt;br /&gt;
&lt;br /&gt;
Am Anfang kann man von unzähligen Fehlermöglichkeiten förmlich erschlagen werden. Und dann weiß man manchmal nicht so recht, wo man anfangen soll. Aber auch dafür gibt es Konzepte, welche sich dem individuellen Problem anpassen lassen.&lt;br /&gt;
&lt;br /&gt;
* Einfach zu prüfende, grundlegend wichtige Dinge zuerst prüfen. Wenn ein Auto stehen bleibt, prüft man erstmal, ob noch Treibstoff im Tank ist und nicht, ob die Kurbelwelle gebrochen ist. Grundlegende Dinge sind&lt;br /&gt;
** Stromversorgung&lt;br /&gt;
** wichtige Eingangssignale&lt;br /&gt;
** wichtigen Zwischensignale&lt;br /&gt;
* Sind meine Messgeräte OK?&lt;br /&gt;
**Batterie im [[Multimeter]] noch halbwegs voll?&lt;br /&gt;
**Kalibrierung stimmt?&lt;br /&gt;
**Tastköpfe am Oszilloskop richtig kompensiert?&lt;br /&gt;
* Messe ich am richtigen IC und am richtigen Pin? Je nach Bauteil zeigt das Datenblatt die Pinbelegung von oben (top view) oder unten (bottom view).&lt;br /&gt;
* Keine voreiligen Schlüsse. Man sollte Fehlerursachen nur dann wirklich ausschließen, wenn man sie eindeutig geprüft und gemessen hat.&lt;br /&gt;
* Den Testaufbau schrittweise einschränken und vereinfachen. Nach Möglichkeit Schaltungs/- oder Softwareteile deaktivieren bzw. abklemmen oder austauschen (ICs, Module, Kabel, Programmteile, Funktionen, etc.).&lt;br /&gt;
* Teile und herrsche. Wenn in einer langen Signalkette das Ausgangssignal nicht stimmt, sollte man sich sich nicht Schritt für Schritt durchhangeln sondern immer erst die Mitte der Kette prüfen. Beispiel. In einer Kette von 10 Verstärkerstufen prüft man zuerst die 5. Stufe. Ist das Signal dort OK, liegt der Fehler zwischen Stufe 5 und 10, also prüft man danach Stufe 7 oder 8. Im anderen Fall, wenn Stufe 5 schon kein gutes Siganl mehr ausgibt, liegt der Fehler zwischen 1 bis 5, man prüft somit im nächsten Schritt Stufe 2 oder 3. Somit findet man in einer Kette bzw. Reihenschaltung von sehr vielen Elementen sehr schnell das Problem.&lt;br /&gt;
&lt;br /&gt;
=== Hilfsmittel ===&lt;br /&gt;
&lt;br /&gt;
Für die Fehlersuche in  Hardware braucht man je nach Art der Schaltung&lt;br /&gt;
&lt;br /&gt;
* ein oder mehrere [[Multimeter]]&lt;br /&gt;
* Labornetzteil mit Strombegrenzung&lt;br /&gt;
* Status-[[LED]]s&lt;br /&gt;
* [[Oszilloskop]]&lt;br /&gt;
* Logikanalysator&lt;br /&gt;
* Funktionsgenerator&lt;br /&gt;
* Netzwerkanalysator&lt;br /&gt;
* Trenntrafo&lt;br /&gt;
&lt;br /&gt;
Typische Werkzeuge für das Softwaredebuggen sind&lt;br /&gt;
&lt;br /&gt;
* Simulator: Damit wird der Code nur auf dem PC simuliert&lt;br /&gt;
* In Circuit Debugger: Er kann das echte Programm auf der echten Hardware debuggt werden, man kann Haltepunkte (engl. break points) im Programm setzen, Variablen anschauen und vieles mehr&lt;br /&gt;
* [[UART]] für Debugausgaben&lt;br /&gt;
* Status-[[LED]]s&lt;br /&gt;
* Testpins&lt;br /&gt;
&lt;br /&gt;
=== Allgemeine Hinweise ===&lt;br /&gt;
&lt;br /&gt;
*Wenn ein Fehler konstant vorliegt oder reproduzierbar ist, hat man in gewisser Weise Glück. Diese Fehler sind eher leicht zu finden und zu beheben. Ziel der Fehlersuche ist es, einen Fehler reproduzierbar zu machen.&lt;br /&gt;
*Sporadische Fehler sind sehr gefährlich und sehr schwer lokalisierbar, wie z.B. Hardwarefehler&lt;br /&gt;
**Wackelkontakte&lt;br /&gt;
**Haarrisse&lt;br /&gt;
**Risse durch mechanische oder thermische Spannungen&lt;br /&gt;
*oder Softwarefehler wie&lt;br /&gt;
**Zugriffsfehler auf Variablen in [[Interrupt]]s&lt;br /&gt;
**Variablenüberläufe, welche erst nach Stunden oder Tagen auftreten (Echtzeituhr, Datum, Ereigniszähler)&lt;br /&gt;
**Pufferüberläufe in Strings und Arrays&lt;br /&gt;
Gerade die sporadischen Fehler sollte man vermeiden, indem man möglichst solide arbeitet. D.h.&lt;br /&gt;
*Hardware&lt;br /&gt;
** gutes Konzept, d.h. die Schaltung sollte möglichst unempfindlich gegenüber Bauteiltoleranzen und Störungen sein&lt;br /&gt;
** sauber löten&lt;br /&gt;
** Bauteilkennwerte nicht überschreiten, Reserven einplanen&lt;br /&gt;
** Toleranzen und Temperaturverhalten der Bauteile beachten&lt;br /&gt;
*Software&lt;br /&gt;
** gutes Konzept&lt;br /&gt;
** [[Strukturierte Programmierung auf Mikrocontrollern | sauber programmieren]], keine Hackertricks&lt;br /&gt;
** defensiv programmieren, umfangreiche Fehlerbehandlung&lt;br /&gt;
&lt;br /&gt;
== Fehlersuche in Hardware ==&lt;br /&gt;
&lt;br /&gt;
* Stromversorgung&lt;br /&gt;
** Ist das Gerät ans Netz(teil) angeschlossen? Korrekte Polung?&lt;br /&gt;
** Ist die Sicherung OK?&lt;br /&gt;
** Liefert der Spannungsregler die korrekte Spannung?&lt;br /&gt;
** Ist mein Messgerät auf die richtige Spannungsform eingestellt (AC oder DC)?&lt;br /&gt;
** Liegt die Spannung an allen wichtigen ICs an?&lt;br /&gt;
** Liegt die Stromaufnahme im erwarteten Bereich?&lt;br /&gt;
* Signalpfade&lt;br /&gt;
** Wie sieht das Eingangssignal aus?&lt;br /&gt;
** Liegen die richtigen Ruhesignale (Arbeitspunkt, Ruhestrom) an den wichtigen Punkten der Schaltung an?&lt;br /&gt;
** Liegen die richtigen Signale an den Zwischenpunkten der Schaltung an?&lt;br /&gt;
** Sind Logikpegel sauber LOW und HIGH? Wenn nein, dann sind oft mehrere Ausgänge gleichzeitig auf einem [[Bus]] aktiv und ziehen in verschiedene Richtungen (Low und High). Oder Die Ausgänge sind zu schwach, um die Lasten zu treiben.&lt;br /&gt;
** Sind Taktsignale sauber ohne Überschwinger und Zacken in den Flanken? Falsche [[Wellenwiderstand | Terminierung]], schleche Leitungsführung (Masse) oder EMV-Probleme können die Ursache sein.&lt;br /&gt;
**Dabei sollte man aber auch sauber messen, um nicht einem Phantom hinterher zu jagen (Bandbreite des [[Oszilloskop#Tastköpfe richtig benutzen| Tastkopfes]] und [[Oszilloskop]]s, kurze Masseverbindung ([http://www.mikrocontroller.net/topic/81049#677911 ground spring]), möglichst keine Erdschleifen).&lt;br /&gt;
** Wenn Signale ganz fehlen oder sich nicht ändern? Kurzschlüsse? Unterbrechungen? Wackelkontakte?&lt;br /&gt;
*Fehlfunktionen&lt;br /&gt;
** Werden ICs ungewöhnlich heiß? Einfache Logik-ICs und Operationsverstärker werden normalerweise kaum warm, Endstufen, [[Treiber]], Leistungstransistoren, Linearregler und große ICs ([[FPGA]]s, Tranceiver etc.) dagegen schon.&lt;br /&gt;
** Schwingen Quarze und Oszillatoren korrekt? Vorsicht beim direkten Messen an Quarzen, die reagieren bisweilen empfindlich auf zusätzliche Lastkapazitäten, hier auf jeden Fall mit einem 10:1 Tastkopf messen&lt;br /&gt;
** &amp;quot;Hello World!&amp;quot; Minimaltest für Mikrocontroller. Eine LED im 1s Rhytmus blinken lassen. Damit kann man viele einfache Dinge erstmal prüfen, das sollte man am Anfang immer erst einmal machen.&lt;br /&gt;
*** Compiler funktioniert und erzeugt ein gültiges Hex-File&lt;br /&gt;
*** Programmierung funktioniert&lt;br /&gt;
*** Mikrocontroller kann das Programm ausführen, Spannung und Takt liegen an&lt;br /&gt;
&lt;br /&gt;
=== Tips zum Hardwaredebugging ===&lt;br /&gt;
&lt;br /&gt;
* Freie Pins an Mikrocontrollern, [[FPGA]]s, [[CPLD]]s auf Testpads legen, das ist vor allem bei kleinen Gehäusen wie TQFP, MLF oder gar [[BGA]]s notwendig, um dort mit Testspitzen und Drähten ranzukommen.&lt;br /&gt;
* In wichtige Punkte der Stromverteilung Null Ohm Widerstände einfügen, dort kann man später ein Messgerät einschleifen; alternativ wenigstens die Leiterbahn gut zugänglich auf der Ober- oder Unterseite layouten, damit man sie im Testfall mit dem Skalpell auftrennen kann.&lt;br /&gt;
* Viele Vorgänge in Mikrocontrollerschaltungen sind nicht periodisch. Um sie zu messen braucht man meist ein [[Oszilloskop | Digitaloszilloskop]]. Hat man sowas nicht zur Verfügung, muss man versuchen, die Vorgänge periodisch zu machen, indem man z.B. eine Datenausgabe per [[UART]] oder [[SPI]] in einer Schleife immer wieder ausführt. Damit kann man sie auch mit einem Analogoszilloskop darstellen.&lt;br /&gt;
* Testpins sind sehr nützlich, um Zeitverhalten von Software zu messen, z.B. Interruptroutinen. Zum Begin setzt man ein Pin auf HIGH, am Ende auf LOW, das kann man dann sehr einfach mit einem Oszilloskop messen&lt;br /&gt;
* Ebenfalls kann man mit so einem Testpin den Anfang eines speziellen Programmablaufs signalisieren, um ein Oszilloskop zu triggern, was sonst in einem komplexen Signalspiel nur sehr schwer möglich wäre&lt;br /&gt;
*Treten Fehler erst bei hohen oder niedrigen Temperaturen auf? Mit Kältespray und Heißluftpistole kann man sie provozieren.&lt;br /&gt;
*Einfache Logikschaltungen wie z.B. den [[SPI]]-[[Bus]] kann man auch ohne [[Oszilloskop]] anschauen, indem man das Timing der Steuersignale extrem verlangsamt. Das schafft man, indem man im Programm hinter jedem Portzugriff eine Pause von ca. 1s macht (avr gcc -&amp;gt; _delay_ms(1000)). Damit kann man an jedes Signal eine [[LED]] mit Vorwiderstand anschließen und das Signalspiel sichtbar machen. Das Gleiche gilt für [[I2C]], da auch dieser ein synchroner Bus ist und damit beliebig langsam getaktet werden kann. Man muss nur beachten, dass dadurch die Busleitungen mit den Open Drain Ausgängen nicht zu sehr belastet werden. Am Besten schließt man diese Test-LEDs ebenfalls invertiert an, parallel zu den Pull Up Widerständen, d.h. Anode über Vorwiderstand an VCC und die Kathode jeweils an die beiden Siganle SCL und SDA. Beim [[UART]] geht das leider nicht, dieser ist asynchron und auf ein genaues Timing angewiesen.&lt;br /&gt;
&lt;br /&gt;
=== FPGAs und CPLDs ===&lt;br /&gt;
&lt;br /&gt;
* In komplexeren FPGA-Schaltungen, welche z.B. Videodaten mittels [[AD-Wandler]] aufnehmen und verarbeiten, kann man den AD-Wandler zu Testzwecken durch ein synthetisches Modul im FPGA ersetzen, welches definierte Datenströme erzeugt, sozusagen ein digitaler Funktionsgenerator&lt;br /&gt;
* In FPGAs kann man auch virtuelle Logikanalysatoren einbauen, welche Datenströme im FPGA aufzeichnen; Die Steuerung erfolgt oft über [[JTAG]] oder spezielle Schnittstellen&lt;br /&gt;
  &lt;br /&gt;
=== Kurzschlüsse finden ===&lt;br /&gt;
&lt;br /&gt;
In der Entwicklung von Schaltungen geht immer mal was kaputt. Bauteile brennen durch. Doch wie findet man sie, wenn sie zwar defekt, aber nicht äusserlich zerstört sind? Wie findet man einen defekten IC an einem [[SPI]]-[[Bus]] mit 10 angeschlossenen ICs?&lt;br /&gt;
&lt;br /&gt;
* Verpolte Elektrolytkondensatoren findet man meist recht schnell, wenn man mit einem strombegrenzten Netzteil die Schaltung speist. Sie werden warm bis heiß, das findet man schnell.&lt;br /&gt;
*Kurzschlüsse auf verzweigten Netzen findet man per Milliohmmessung nach dem [http://de.wikipedia.org/wiki/Vierdrahtmessung Vierleiterprinzip].&lt;br /&gt;
**Schaltung ausschalten&lt;br /&gt;
**Über ein strombegrenztes Netzteil oder eine Spannungsquelle mit großem Vorwiderstand einen Konstantstrom in das fehlerhafte Netz einspeisen. Dabei richtet sich dessen Höhe nach der Art des elektrischen Netzes. Für ein Signal auf einer Platine reichen meist 100mA, für Stromversorgungsleitungen oder Verkabelung in einem Gerät können es schon mal 1-10A sein.&lt;br /&gt;
**Mit dem Multimeter im Millivolt-Messbereich die Spannung vom Einspeisepunkt zu den verschiedensten Punkten im Netz messen. Dort wo die größte Spannung abfällt, ist der Kurzschluss.&lt;br /&gt;
*Feine Kurzschlüsse auf Leiterbahnen, welche z.B. durch Fehler beim Ätzen entstehen, weil Dreck, Haare oder ähliches zur sehr feinen Kurzschlüssen geführt haben, kann man teilweise durch einen starken Strompuls aus einem großen Kondensator oder Netzteil freibrennen, der Kurzschluss verdampft dabei das Kupfer. Aber Vorsicht! Wenn man Pech hat verdampft auch gleich ein guter Teil der Leiterbahn!  &lt;br /&gt;
&lt;br /&gt;
=== Erstmaliges Einschalten einer Schaltung ===&lt;br /&gt;
&lt;br /&gt;
Schaltet man eine Schaltung das erste Mal ein, sollte man einiges beachten, um im Fehlerfall nicht vor einem Haufen Asche zu sitzen. Das gilt vor allem für Schaltungen, die größere Leistungen beinhalten (Netzteile, Motorendstufen, Wechselrichter, etc.) oder aus sehr kräftigen Quellen gespeist werden (Stromstarke Netzteile, Akkumulatoren).&lt;br /&gt;
* Vor dem Einschalten die Platine noch einmal kontrollieren&lt;br /&gt;
** Sind alle Bauteile richtig bestückt?&lt;br /&gt;
** Polarität von Dioden und Kondensatoren stimmt?&lt;br /&gt;
** ICs nicht verdreht?&lt;br /&gt;
** Keine Kurzschlüsse durch Lötzinn?&lt;br /&gt;
** Ist alles um die Platine herum richtig angeschlossen? &lt;br /&gt;
*Schaltungen mit Kleinspannung aus einem Netzteil mit Strombegrenzung speisen, die Strombegrenzung nur wenig höher einstellen als das Gerät schätzungsweise benötigt.&lt;br /&gt;
*Schaltungen mit größerer Leistung bzw. Netzanschluss mit einem Sicherungsautomaten absichern.&lt;br /&gt;
*Nach dem Einschalten die wichtigsten Ströme und Spannungen messen und prüfen, ob sie wie erwartet sind&lt;br /&gt;
*Wichtige Zwischensignale messen und prüfen&lt;br /&gt;
*Wärmeentwicklung prüfen&lt;br /&gt;
*Belastung von Netzteilen und Verstärkern langsam steigern&lt;br /&gt;
&lt;br /&gt;
== Fehlersuche in Software ==&lt;br /&gt;
&lt;br /&gt;
=== Tips zum Softwaredebugging ===&lt;br /&gt;
&lt;br /&gt;
* Eine Ausgabe von Debuginformationen per [[UART]] ist oft sehr nützlich, auch wenn das Gerät im Normalbetrieb keinerlei UART nutzt&lt;br /&gt;
* Im [[EEPROM]] kann man auch Debuginformationen ablegen und später wieder auslesen&lt;br /&gt;
* Wenn man fremde Projeke übernimmt, sollte man schrittweise vorgehen.&lt;br /&gt;
** Zuerst das Projekt, welches meist ein Beispiel enthält, ohne jegliche Änderungen/Anpassungen komplett kompilieren. Wenn das funktioniert, weiß man erstmal, dass der Compiler soweit funktioniert.&lt;br /&gt;
** Danach nur minimale Änderungen, z.b. Pinzuordungen, Konfigurationen vornehmen und testen.&lt;br /&gt;
** Nach erfolgreichem Test des Beispiels mit minimalen Änderungen kann man das Projekt in größerem Maße umbauen bzw. in sein Projekt integrieren. Aber auch hier sollte man eher kleine Schritte machen und zwischendurch immer wieder die Funktion testen. Das ist einfacher als sehr viele Änderungen auf einmal durchzuführen und danach zu testen.&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[AVR Checkliste]]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/299061?goto=3206880#3206853 Forumsbeitrag]: Protokoll eines unbekannt Display mittels Chaosangriff entziffern&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* Analog Circuits (World Class Designs) ISBN 978-0750686273, eine Zusammenstellung von verschiedensten Schaltungen mit ausführlichen Erklärungen; Filter, AD-Wandler, Lasertreiber, U-F Wandler, Mikrocontroller etc.&lt;br /&gt;
* Troubleshooting Analog Circuits, ISBN 978-0750694995, eine umfangreiche Mischung von Praxistips zur Entwicklung und Fehlersuche in analogen Schaltungen, viele Informationen über Bauteile und Konzepte, geschrieben von der Analoglegende [http://www.ti.com/ww/en/bobpease/index.html Bob Peace]&lt;br /&gt;
* http://www.repairfaq.org Seite mit umfangreichen Tips zur Fehlersuche, Reperatur diverser Elektronik, Laser und mehr (engl.)&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
* [http://www.analog.com/library/analogdialogue/archives/43-09/linear_circuit_design_handbook.html Basic Linear Design seminar notes] - fundiertes eBook / PDFs mit nützlichen Infos zu Schaltungsdesign, parasitären Effekten und Fehlersuche&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Motoransteuerung_mit_PWM&amp;diff=83063</id>
		<title>Motoransteuerung mit PWM</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Motoransteuerung_mit_PWM&amp;diff=83063"/>
		<updated>2014-05-19T19:33:27Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Allgemeines==&lt;br /&gt;
&lt;br /&gt;
Bei der Dimensionierung der Strombelastbarkeit der Bauteile muss man vor allem 2 Werte betrachten:&lt;br /&gt;
* Stromaufnahme des Motors im normalen Betrieb (also mit der Last)&lt;br /&gt;
* Stromaufnahme bei blockiertem Motor, bzw. Anlaufstrom. Hier wird der Strom nur durch den ohmschen Widerstand im Stromkreis begrenzt, er kann also je nach Motor schnell den 2-3 stelligen Amperebereich erreichen.&lt;br /&gt;
&lt;br /&gt;
Die übliche Dimensionierung richtet sich vor allem nach dem ersten Wert und plant entsprechende Reserven ein (für ein paar Sekunden Faktor 2-5 des Stromes), da der zweite Wert in der Praxis aus Kostengründen meist nur schwer realisierbar und unnötig ist. Daher umgeht man das Problem entweder über eine schnelle Strombegrenzung oder über einen Sanftanlauf indem man die [[PWM]] langsam hoch fährt. Dadurch wird der maximale Strom auf einen deutlich niedrigeren Wert begrenzt, so dass die Bauteile schwächer und kostengünstiger ausfallen können. &lt;br /&gt;
&lt;br /&gt;
Die Spannung am Motor und somit näherungsweise die Leerlaufdrehzahl ist proportional zu dem Tastverhältnis:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;\text{Motorspannung} = \text{Betriebsspannung} \cdot \mathrm{Tastverh\ddot{a}ltnis}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Schaltungsvarianten==&lt;br /&gt;
&lt;br /&gt;
===Mosfet mit Freilaufdiode, 1-Quadrantensteller===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Motor_PWM_1.gif|thumb|300px|1-Quadrantensteller]]&lt;br /&gt;
Die einfachste Schaltung besteht nur aus Transistor T1, dem Motor, der Freilaufdiode D1, dem Kondensator C1, sowie der eigentlichen [[PWM]]-Erzeugung und dem [[MOSFET-Übersicht#Mosfet-Treiber | Mosfettreiber]].&lt;br /&gt;
&lt;br /&gt;
In der Einschaltphase von T1 liegt am Motor die gesamte Betriebsspannung an. Die Differenz zwischen der vom sich drehenden Motor erzeugten Generatorspannung und der Betriebsspannung fällt am Wicklungswiderstand sowie der Wicklungsinduktivität ab. Man hat es also mit einer RL Reihenschaltung zu tun. Da der Wicklungswiderstand recht klein ist, steigt der Strom näherungsweise linear an, bis T1 abschaltet. Dann übernimmt D1 den Stromfluss und schließt den Stromkreis solange, bis T1 den Strom wieder übernimmt (oder der Strom abgeklungen ist = lückender Betrieb). Obwohl keine Energie mehr von außen zugeführt wird, wird der Motor weiterhin durch die in der Wicklung gespeicherten Energie versorgt. Der Strom fällt nun wieder linear ab, bis T1 wieder durchsteuert und wieder Energie zuführt.&lt;br /&gt;
&lt;br /&gt;
Der Strom durch die Diode D1 ist von der Amplitude her genauso groß wie der Strom durch T1, je nach Tastverhältnis ist der Effektivwert aber kleiner als der durch T1 (bei über 50% Tastverhältnis), gleich (bei 50% Tastverhältnis) oder sogar größer (bei einem Tastverhältnis kleiner 50%). Daher muss die Diode genauso stark dimensioniert werden wie der Transistor (möglichst eine schnelle Schaltdiode (z.B. Schottky) verwenden, keine langsamen Gleichrichterdioden wie 1N400x). Der Kondensator C1 ist notwendig, um den durch die PWM gepulsten Strom zu glätten, da aufgrund der steilen Flanken ansonsten in den Zuleitungen ein Spannungsabfall bzw. Spannungsspitzen auftreten würden (am besten 2 oder mehrere Kondensatoren unterschiedlicher Kapazität und Bauart verwenden, meistens ein Folienkondensator mit einigen Mikrofarad parallel zu einem Aluminiumelektrolytkondensator).&lt;br /&gt;
&lt;br /&gt;
Der Transistor, die Diode und der Kondensator sollen möglichst nahe zusammen plaziert werden (kürzeste Verbindungen). Wenn die Diode am Motor angebracht wird, strahlt die Zuleitung massiv Störungen ab. Die Leitungen sollten am besten verdrillt werden.&lt;br /&gt;
&lt;br /&gt;
===Synchrongleichrichtung, 2-Quadrantensteller===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Motor_PWM_2.gif|thumb|300px|2-Quadrantensteller]]&lt;br /&gt;
Um die Verluste in der Freilaufdiode zu verringern kann man diese durch einen zweiten Mosfet ersetzen, der immer dann eingeschaltet wird, wenn der andere abgeschaltet ist.&lt;br /&gt;
&lt;br /&gt;
Da dieser Mosfet im Gegensatz zu einer Diode in beide Richtungen Strom leitet, ist es damit möglich den Motor kurzzuschließen und so den Motor zu bremsen. Allgemein kann man sagen: Ist die durch die PWM erzeugte mittlere Spannung größer als die Generatorspannung des Motors, wird dieser beschleunigt. Ist die Spannung kleiner, wird der Motor abgebremst. Durch T2 wird der Motor dabei kurzgeschlossen, so dass sich durch die Generatorspannung zunächst der Strom in der Motorwicklung ab- und dann in umgekehrter Richtung wieder aufbaut. Beim Abschalten von T2 und Einschalten von T1 fließt dieser Strom über T1 in C1 und somit die Spannungsquelle zurück. Die Energie wird beim Bremsen also nicht vernichtet, sondern wieder in elektrische Energie zurückverwandelt. Dies sollte man bedenken wenn man eine große Masse abbremst, denn die Spannungsquelle muss die Energie aufnehmen können. Sollte die Spannungsquelle z.&amp;amp;nbsp;B. aus einem Transformator mit Gleichrichter bestehen, kann dieser die Energie nicht aufnehmen sondern nur C1, was dazu führt, dass die Betriebsspannung ansteigt bis eventuell einer der Transistoren zerstört wird. Um dies zu verhindern ist eine Überspannungsbegrenzung in Form eines Bremswiderstands vorzusehen (Bremschopper). In einfachen Fällen reicht auch eine Leistung-Z-Diode oder ein passende Nachbildung aus Z-Diode und Leistungstransistor. Besteht die Spannungsquelle z.&amp;amp;nbsp;B. aus einem Akku dann nimmt dieser die Energie auf und wird beim Bremsen wieder etwas geladen.&lt;br /&gt;
Dies funktioniert allerdings nur, wenn das Tastverhältnis nicht 0% beträgt, also T2 und T1 abwechselnd schalten, so dass nicht die gesamte Energie in der Motorwicklung sowie T2 verheizt wird. Man sollte es daher vermeiden das Tastverhältnis schnell in eine der beiden Richtungen zu ändern, da dies zu einem hohen Strom führt.&lt;br /&gt;
&lt;br /&gt;
Die Ansteuerschaltung muss weiterhin verhindern, dass T1 und T2 gleichzeitig leitend werden können, denn dies würde zu einem Kurzschluss der Betriebsspannung führen. Ein fertig aufgebauter Mosfet-Treiber verhindert dies.&lt;br /&gt;
&lt;br /&gt;
===H-Brücke, 4-Quadrantensteller===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Motor_PWM_3.gif|thumb|300px|4-Quadrantensteller]]&lt;br /&gt;
Die H-Brücke, bzw. der 4-Quadrantensteller ist eine Erweiterung des 2-Quadrantenstellers durch eine zweite Halbbrücke. Diese ermöglicht neben dem Beschleunigen und Bremsen des Motors auch eine Umkehr der Drehrichtung. Dafür gibt es mehrere Ansteuerverfahren&lt;br /&gt;
#Das effizienteste ist, eine Hälfte wie beim 2-Quadrantensteller zu betreiben und mit der anderen den zweiten Motoranschluss an die Betriebsspannung zu legen. Für die andere Drehrichtung wechselt man einfach die Hälften, legt also den anderen Anschluss an die Betriebsspannung und verwendet die andere Hälfte als 2-Quadrantensteller.&lt;br /&gt;
&lt;br /&gt;
#Das andere Verfahren steuert abwechselnd T1 und T4 oder T2 und T3 durch, legt also immer eine Spannung an den Motor. Ist das Tastverhältnis 50% fließt im Mittel ein Strom von 0A, da der Motor für jeweils die Hälfte der Zeit eine positive und eine negative Spannung erhält, der Motor steht also. Je nachdem ob man das Tastverhältnis darüber oder darunter wählt, legt man die Drehrichtung fest. Dieses Verfahren ist Ansteuertechnisch einfacher, erzeugt aber auch im Stillstand Schaltverluste in den Transistoren und Verluste im Motor.&lt;br /&gt;
&lt;br /&gt;
==Beispielschaltungen==&lt;br /&gt;
&lt;br /&gt;
===1-Quadrantensteller mit diskretem Mosfettreiber===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Motor_PWM1_real.gif|thumb|300px|Einfacher 1-Quadrantensteller]]&lt;br /&gt;
Diese Schaltung eignet sich für Motoren bis etwa 35V und 10A Dauerstrom.&lt;br /&gt;
Q1 und Q2 zusammen mit deren Beschaltung dienen als [[Pegelwandler]] von 3,3 oder 5V Digitalsignalen auf 12V für das Mosfet Gate. Die Schaltung arbeitet dabei invertierend, der Mosfet schaltet also bei einem Low am Eingang ein.&lt;br /&gt;
Sperrt Q1, wird Q2 über R1 durchgesteuert und liefert etwa 11-11,5V ans Gate des Mosfets. R2 begrenzt dabei den Strom.&lt;br /&gt;
Das Abschalten des Mosfets geschieht über den Pfad Q1 und D1. Gleichzeitig wird Q2 die Basisspannung weggenommen, so dass dieser sperrt.&lt;br /&gt;
D2 zwischen Basis und Kollektor von Q1 verhindert, dass dieser in die Sättigung kommt, so dass dieser nahezu verzögerungsfrei sperrt, sobald der Eingang auf Low wechselt. Ab ein paar Ampere benötigt die Freilaufdiode D3 einen kleinen [[Kühlkörper]], ebenso Q3. Sollte die Betriebsspannung V+ des Motors bei etwa 10-16V liegen, dann kann diese Spannung auch für die Mosfetansteuerung verwendet werden. Ansonsten sollte dafür eine getrennte Spannung mit etwa 12-15V verwendet werden.&lt;br /&gt;
&lt;br /&gt;
===1-Quadrantensteller mit diskretem Highside-Mosfettreiber===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Motor_PWM1b_real.gif|thumb|300px|Einfacher 1-Quadrantensteller mit P-Kanal Mosfet]]&lt;br /&gt;
&lt;br /&gt;
Diese Schaltung eignet sich für Motoren mit etwa 15-40V Betriebsspannung und mit bis zu 10A Dauerstrom. Schaltungen mit P-Kanal Mosfets sollte man wenn möglich vermeiden, da N-Kanal Mosfets prinzipbedingt um Faktor 3 bessere Werte aufweisen als P-Kanal Mosfets. Allerdings wird manchmal ein auf Masse bezogener Ausgang gefordert, dann ist diese Schaltung hier die richtige. Das Problem bei der Highsideansteuerung ist, dass man die Gate-Sourcespannung irgendwie auf max. 20V begrenzen muss, was hier durch eine zusätzliche Hilfsspannung von 12V wie bei der vorigen Schaltung, nicht so einfach geht. Daher wird hier ein anderer Weg eingeschlagen. Q1 und R2 bilden eine [[Konstantstromquelle]]. Dadurch, dass an der Basis eine feste Logikspannung ansteht, steuert Q1 so stark durch, bis er sich durch den Spannungsabfall an R2 selbst die Basisspannung reduziert. Der fließende Strom beträgt dabei (Logikpegel am Eingang - 0,6V Basis-Emitterspannung)/R2. Ein guter Wert für den Strom sind etwa 10-15mA. Bei der Dimensionierung sollte man auch die Verlustleistung beachten: 40V * 15mA = 0,6W. Dies ist für einen Transistor im TO92 Gehäuse deutlich zu viel. Dadurch, dass Q1 im Linearbetrieb arbeitet, kommt er nicht in die Sättigung, und es kann auf die Diode wie in der vorherigen Schaltung verzichtet werden. Ebenso ist ein Basiswiderstand unnötig bzw. sogar hier fehl am Platz. Da nun bekannt ist, dass im durchgesteuerten Zustand von Q1 bei 5V Logikspannung (5V-0,6V)/330Ω= 13,3mA fließen, kann man damit den Spannungsabfall an R1 berechnen, bzw. aus der gewünschten Spannung R1:&lt;br /&gt;
U(R1)=13,3mA*1kOhm=13,3V. Im eingeschalteten Zustand ist die Spannung am Kollektor von Q1 also um 13,3V negativer als V+ und das unabhängig von der Betriebsspannung! Da diese Spannung durch die als Emitterfolger geschalteten Transistor Q2 und Q3 gepuffert auch an das Gate des Mosfets gelegt werden, bekommt dieser also rund 13V Gatespannung im eingeschalteten Zustand. Dies passt gut, denn für die meisten Mosfets sollte man einen Wert zwischen 10 und 15V verwenden. Durch den Spannungsteiler aus R1 und R2 ergibt sich allerdings auch eine untere Grenze der Betriebsspannung, damit die Schaltung sauber funktioniert: Um die 13,3V über R2 zu erhalten, bzw. die 4,4V über R1 sind mindestens 17,7V für V+ notwendig.&lt;br /&gt;
&lt;br /&gt;
===2-Quadrantensteller mit Halbbrücken Mosfettreiber===&lt;br /&gt;
&lt;br /&gt;
[[Datei:Motor_PWM2_real.gif|thumb|300px|Einfacher 2-Quadrantensteller]]&lt;br /&gt;
&lt;br /&gt;
Diese Schaltung eignet sich für Motoren bis etwa 35V und 20A Dauerstrom.&lt;br /&gt;
Um den Aufwand zu minimieren wird für die Halbbrücke ein fertiger Halbbrückentreiber IR2184 verwendet. Dieser besitzt eine integrierte Totzeit (engl. dead time) von 500ns zwischen dem Umschalten der Mosfets, so dass ein gleichzeitiges Einschalten beider Mosfets ausgeschlossen ist. Da der Mosfet gegen V+ angeschlossen ist, arbeitet auch diese Schaltung invertierend. Der Grund, warum der Motor nicht gegenüber GND angeschlossen ist, ist folgender:&lt;br /&gt;
Für die Ansteuerung des Highside Mosfets Q2 ist eine Spannung von etwa 10V mehr als die Betriebsspannung V+ notwendig. Diese wird über die Bootstrapschaltung aus C2 und D1 erzeugt. Ist Q1 durchgesteuert, läd sich C2 über D1 auf. Schaltet anschließend Q1 ab und Q2 ein, wird dessen Ansteuerspannung aus C2 entnommen. Da Q2 nun VS mit V+ verbindet, steigt auch das Potential an C2 an. An dem VB Pin stehen nun etwa V+ + 12V-0,7V (12V Betriebsspannung-Flusspannung von D1) an. Aufgrund von Leckströmen, entläd sich C2 allerdings innerhalb einiger Millisekunden. Daher ist die maximale Einschaltdauer von Q2 begrenzt. 100% Einschaltdauer wären daher nicht möglich. Um dieses Problem zu umgehen ist der Motor gegen V+ geschaltet, so dass für 100% Einschaltdauer Q1 eingeschaltet werden muss, was kein Problem ist, denn dessen Treiber wird direkt auf den 12V versorgt. Ist Q1 dagegen dauerhaft aus, Q2 also an, bremst der Motor, bzw. er steht, so dass kein Strom durch die Mosfets fließt. Daher ist es auch nicht weiter schlimm, wenn Q2 nach einer kurzen Zeit wieder abschaltet. Das einzige was nicht möglich ist, ist ein dauerhaftes Bremsen des Motors mittels Q2, aber dies wird in der Praxis auch nur in den seltensten Fällen benötigt. Über den IN Pin, wird das invertierte PWM Signal mit Logikpegeln eingespeist. Über den SD\ Pin, lassen sich beide Mosfets gemeinsam abschalten. Damit ist ein ungebremstes Auslaufen lassen des Motors möglich (Freilauf). Ab etwa 5Ampere benötigen die Mosfets einen kleinen [[Kühlkörper]].&lt;br /&gt;
&lt;br /&gt;
==Wahl der PWM-Frequenz==&lt;br /&gt;
&lt;br /&gt;
Bei der Wahl der PWM Frequenz muss man mehrere Faktoren berücksichtigen und einen Kompromiss eingehen:&lt;br /&gt;
* Die Motorinduktivität L glättet den Strom, der Wicklungswiderstand R führt zu einem Abfallen des Stromes, daraus ergibt sich die elektrische Zeitkonstante des Motors &amp;lt;math&amp;gt;t=\frac{L}{R}&amp;lt;/math&amp;gt;. Bei vielen Motoren liegt diese um 1ms. Bei hochwertigen Motoren sollte diese Angabe im Datenblatt zu finden sein. Um den Stromripple gering, also das Drehmoment konstant zu halten, sollte die Periodendauer der PWM diese Zeit nicht überschreiten. Vor allem im 2 bzw. 4-Quadratentebetrieb ist dies wichtig, denn dort kann der Strom auch seine Richtung ändern, was zu einem Abbremsen, somit zu einem deutlichen Ruckeln und zu Vibrationen des Motors und zu unnötigen Verlusten führt. &lt;br /&gt;
* Frequenzen zwischen  100Hz und 10kHz erzeugen hörbare Pfeifgeräusche im Motor&lt;br /&gt;
* Mit zunehmender Frequenz steigen die Schaltverluste in den Transistoren sowie die Verluste in der Ankerwicklung sowie in deren Kern.&lt;br /&gt;
&lt;br /&gt;
Die aus elektrischer Sicht ideale PWM Frequenz liegt daher meist bei 1-2kHz. Allerdings ist dies genau der Bereich, in dem das Gehör am empfindlichsten ist. Wenn das Pfeifen des Motors nicht stört, ist dies also der ideale Bereich.&lt;br /&gt;
Da die untere Frequenz durch die elektrische Zeitkonstante des Motors begrenzt ist, kann man nur nach oben ausweichen. Ein Kompromiss ist daher der Bereich 5-15kHz in dem das Gehör deutlich unempfindlicher ist, sich die Verluste noch in Grenzen halten. Verwendet man die einfache Schaltung mit der Freilaufdiode und legt keinen Wert auf einen runden Lauf, bzw. hat eine hohe Masse am Motor, so dass dieser träge ist, dann kann man als Alternative zu den &amp;gt;5kHz die PWM Frequenz auch bis auf 200Hz reduzieren um das Geräusch erträglicher zu machen. Allerdings reduziert sich dann der Wirkungsgrad aufgrund des hohen Stromripples.&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
*[[PWM]]&lt;br /&gt;
*[[Treiber]]&lt;br /&gt;
*[[MOSFET-Übersicht#MOSFET-Treiber | Mosfet-Treiber]]&lt;br /&gt;
*[[H-Brücken Übersicht]]&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/103116#900247 Forumsbeitrag]: Highside Mosfetansteuerung mit diskretem Treiber&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/191616#1870643 Forumsbeitrag]: Zur Erklärung der PWM Steuerung, Bremsen und Unterschied zum Relais&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/280480#2960070 Forumsbeitrag]: Clevere MOSFET-Treiber mit kleinsten Trafos&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
&lt;br /&gt;
*[http://de.wikipedia.org/wiki/Zweiquadrantensteller Zweiquadrantensteller bei Wikipedia]&lt;br /&gt;
*[http://de.wikipedia.org/wiki/Vierquadrantensteller Vierquadrantensteller bei Wikipedia]&lt;br /&gt;
*[http://homepages.which.net/~paul.hills/SpeedControl/SpeedControllersBody.html Grundlagen zum Thema Motoransteuerung (englisch)]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Leistungselektronik]]&lt;br /&gt;
[[Kategorie:Motoren]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR-GCC-Tutorial/LCD-Ansteuerung&amp;diff=81766</id>
		<title>AVR-GCC-Tutorial/LCD-Ansteuerung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR-GCC-Tutorial/LCD-Ansteuerung&amp;diff=81766"/>
		<updated>2014-02-23T08:59:25Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Änderung 81760 von 2.205.104.107 (Diskussion) rückgängig gemacht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Das LCD und sein Controller==&lt;br /&gt;
&lt;br /&gt;
Die meisten Text-LCDs verwenden den Controller [[HD44780]] oder einen kompatiblen (z.&amp;amp;nbsp;B. KS0070) und haben 14 oder 16 Pins. Hier ist die häufigste Anschluss-Belegung angegeben. &lt;br /&gt;
&lt;br /&gt;
;Achtung: Es gibt Displays mit abweichender Anschluss-Belegung, z.B. TC1602E (Pollin 120420). Falscher Anschluss kann zur Zerstörung führen! Daher immer das zugehörige Datenblatt zu Rate ziehen. Einzelheiten unter Artikel zum Controller [[HD44780]].&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Pin # || Bezeichnung || Funktion&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| Vss  || GND (beim TC1602E Vdd=Vcc)&lt;br /&gt;
|-&lt;br /&gt;
! 2&lt;br /&gt;
| Vdd/Vcc  || 5V  (beim TC1602E Vss=Gnd)&lt;br /&gt;
|-&lt;br /&gt;
! 3&lt;br /&gt;
| Vee  || Kontrastspannung (0V bis 5V)&lt;br /&gt;
|-&lt;br /&gt;
! 4&lt;br /&gt;
| RS   || Register Select (Befehle/Daten)&lt;br /&gt;
|-&lt;br /&gt;
! 5&lt;br /&gt;
| RW   || Read/Write&lt;br /&gt;
|-&lt;br /&gt;
! 6&lt;br /&gt;
| E&lt;br /&gt;
| Enable&lt;br /&gt;
|-&lt;br /&gt;
! 7&lt;br /&gt;
| DB0  ||rowspan=&amp;quot;8&amp;quot;| Datenbits 0&amp;amp;minus;7&lt;br /&gt;
|-&lt;br /&gt;
! 8&lt;br /&gt;
| DB1&lt;br /&gt;
|-&lt;br /&gt;
! 9&lt;br /&gt;
| DB2&lt;br /&gt;
|-&lt;br /&gt;
! 10&lt;br /&gt;
| DB3&lt;br /&gt;
|-&lt;br /&gt;
! 11&lt;br /&gt;
| DB4&lt;br /&gt;
|-&lt;br /&gt;
! 12&lt;br /&gt;
| DB5&lt;br /&gt;
|-&lt;br /&gt;
! 13&lt;br /&gt;
| DB6&lt;br /&gt;
|-&lt;br /&gt;
! 14&lt;br /&gt;
| DB7&lt;br /&gt;
|-&lt;br /&gt;
! 15&lt;br /&gt;
| A   || LED-Beleuchtung, Anode&lt;br /&gt;
|-&lt;br /&gt;
! 16&lt;br /&gt;
| K   || LED-Beleuchtung, Kathode&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Warnung|&lt;br /&gt;
;Achtung: Unbedingt von der richtigen Seite zu zählen anfangen! Meistens ist neben Pin 1 eine kleine 1 auf der LCD-Platine. Ansonsten im Datenblatt nachschauen! Oft ist Pin 1 auch durch ein rechteckiges statt rundes Pad gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
:Bei LCDs mit 16-poligem Anschluss sind die beiden letzten Pins für die Hintergrundbeleuchtung reserviert. Hier unbedingt das Datenblatt zu Rate ziehen, die beiden Anschlüsse sind je nach Hersteller oft anders beschaltet. Falls kein Datenblatt vorliegt, kann man mit einem Durchgangsprüfer feststellen, welcher Anschluss mit Masse (GND) verbunden ist.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Vss wird ganz einfach an GND angeschlossen und Vcc an 5V. Vee kann man testweise auch an GND legen. Wenn das LCD dann zu dunkel sein sollte muss man ein 10k-Potentiometer zwischen GND und 5V schalten, mit dem Schleifer an Vee: &lt;br /&gt;
&lt;br /&gt;
[[Bild:LCD_Vee.gif]]&lt;br /&gt;
&lt;br /&gt;
Es gibt zwei verschiedene Möglichkeiten zur Ansteuerung eines solchen Displays: den &#039;&#039;&#039;8-bit-&#039;&#039;&#039; und den &#039;&#039;&#039;4-bit-&#039;&#039;&#039;Modus.&lt;br /&gt;
* Für den &#039;&#039;&#039;8-bit-Modus&#039;&#039;&#039; werden (wie der Name schon sagt) alle acht Datenleitungen zur Ansteuerung verwendet, somit kann durch einen Zugriff immer ein ganzes Byte übertragen werden.&lt;br /&gt;
* Der &#039;&#039;&#039;4-bit-Modus&#039;&#039;&#039; verwendet nur die oberen vier Datenleitungen (&#039;&#039;&#039;DB4-DB7&#039;&#039;&#039;). Um ein Byte zu übertragen braucht man somit zwei Zugriffe, wobei zuerst das höherwertige &#039;&#039;&#039;&amp;quot;Nibble&amp;quot;&#039;&#039;&#039; (= 4 Bits), also Bit 4 bis Bit 7 übertragen wird und dann das niederwertige, also Bit 0 bis Bit 3. Die unteren Datenleitungen des LCDs, die beim Lesezyklus Ausgänge sind, lässt man offen (siehe Datasheets, z.&amp;amp;nbsp;B. vom KS0070).&lt;br /&gt;
&lt;br /&gt;
Der 4-bit-Modus hat den Vorteil, dass man 4 IO-Pins weniger benötigt als beim 8-bit-Modus, weshalb ich mich hier für eine Ansteuerung mit 4bit entschieden habe. &lt;br /&gt;
&lt;br /&gt;
Neben den vier Datenleitungen (DB4, DB5, DB6 und DB7) werden noch die Anschlüsse &#039;&#039;&#039;RS&#039;&#039;&#039;, &#039;&#039;&#039;RW&#039;&#039;&#039; und &#039;&#039;&#039;E&#039;&#039;&#039; (ist in manchen Unterlagen auch &#039;&#039;&#039;EN&#039;&#039;&#039;  für &#039;&#039;Enable&#039;&#039; abgekürzt) benötigt. &lt;br /&gt;
&lt;br /&gt;
* Über &#039;&#039;&#039;RS&#039;&#039;&#039; wird ausgewählt, ob man einen Befehl oder ein Datenbyte an das LCD schicken möchte. Ist RS Low, dann wird das ankommende Byte als Befehl interpretiert, ist RS high, dann wird das Byte auf dem LCD angezeigt. &lt;br /&gt;
* &#039;&#039;&#039;RW&#039;&#039;&#039; legt fest, ob geschrieben oder gelesen werden soll. High bedeutet lesen, low bedeutet schreiben. Wenn man RW auf lesen einstellt und RS auf Befehl, dann kann man das &#039;&#039;&#039;Busy-Flag&#039;&#039;&#039; an DB7 lesen, das anzeigt, ob das LCD den vorhergehenden Befehl fertig verarbeitetet hat (diese Methode u.a. in der LCD-Library von Peter Fleury verwendet). Ist RS auf Daten eingestellt, dann kann man z.&amp;amp;nbsp;B. den Inhalt des Displays lesen - was jedoch nur in den wenigsten Fällen Sinn macht. Deshalb kann man RW dauerhaft auf low lassen (= an GND anschließen), so dass man noch ein IO-Pin am Controller einspart. Der Nachteil ist, dass man dann das Busy-Flag nicht lesen kann, weswegen man nach jedem Befehl vorsichtshalber ein paar Mikrosekunden warten sollte, um dem LCD Zeit zum Ausführen des Befehls zu geben. Dummerweise schwankt die Ausführungszeit von Display zu Display und ist auch von der Betriebsspannung abhängig. Für professionellere Sachen also lieber den IO-Pin opfern und Busy abfragen.&lt;br /&gt;
* Der &#039;&#039;&#039;E&#039;&#039;&#039; Anschluss schließlich signalisiert dem LCD, dass die übrigen Datenleitungen jetzt korrekte Pegel angenommen haben und es die gewünschten Daten von den Datenleitungen bzw. Kommandos von den Datenleitungen übernehmen kann.&lt;br /&gt;
&lt;br /&gt;
== Anschluss an den Controller ==&lt;br /&gt;
&lt;br /&gt;
Jetzt da wir wissen, welche Anschlüsse das LCDs benötigt, können wir das LCD mit dem Mikrocontroller verbinden: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;ACHTUNG: Es gibt Displays mit abweichender Anschluss-Belegung, falscher Anschluss kann zur Zerstörung führen! Daher immer das zugehörige Datenblatt zu Rate ziehen.&amp;lt;/span&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Einzelheiten unter [http://www.mikrocontroller.net/articles/HD44780 Artikel zum Controller HD44780]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Pin #-LCD  || Bezeichnung-LCD || Pin-µC&lt;br /&gt;
|-&lt;br /&gt;
!1&lt;br /&gt;
| Vss || GND&lt;br /&gt;
|-&lt;br /&gt;
!2&lt;br /&gt;
| Vcc || 5V&lt;br /&gt;
|-&lt;br /&gt;
!3&lt;br /&gt;
| Vee || GND oder Poti (siehe oben)&lt;br /&gt;
|-&lt;br /&gt;
!4&lt;br /&gt;
| RS  || PD4 am AVR&lt;br /&gt;
|-&lt;br /&gt;
!5&lt;br /&gt;
| RW  || GND&lt;br /&gt;
|-&lt;br /&gt;
!6&lt;br /&gt;
| E   || PD5 am AVR&lt;br /&gt;
|-&lt;br /&gt;
!7&lt;br /&gt;
| DB0 ||rowspan=&amp;quot;4&amp;quot;| offen (unbenutzt)&lt;br /&gt;
|-&lt;br /&gt;
!8&lt;br /&gt;
| DB1&lt;br /&gt;
|-&lt;br /&gt;
!9&lt;br /&gt;
| DB2&lt;br /&gt;
|-&lt;br /&gt;
!10&lt;br /&gt;
| DB3&lt;br /&gt;
|-&lt;br /&gt;
!11&lt;br /&gt;
| DB4 || PD0 am AVR&lt;br /&gt;
|-&lt;br /&gt;
!12&lt;br /&gt;
| DB5 || PD1 am AVR&lt;br /&gt;
|-&lt;br /&gt;
!13&lt;br /&gt;
| DB6 || PD2 am AVR&lt;br /&gt;
|-&lt;br /&gt;
!14&lt;br /&gt;
| DB7 || PD3 am AVR&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Wenn man die Steuerleitungen EN und RS auf Pins an einem anderen Port legen möchte, kann man so wie in diesem [http://www.mikrocontroller.net/topic/88543#751982 Forumsbeitrag] oder wie im Artikel [[Erweiterte LCD-Ansteuerung]] vorgehen.&lt;br /&gt;
&lt;br /&gt;
Ok, alles ist verbunden, wenn man jetzt den Strom einschaltet sollten ein oder zwei schwarze Balken auf dem Display angezeigt werden. Erscheint trotz korrektem Anschluss nichts auf dem Display, so kann das auch am Kontrast des LCDs liegen. Die Balken werden dann zwar theoretisch angezeigt, sind aber nicht sichtbar, weil die Kontrastspannung zu hoch ist. Abhilfe schafft es hier, wenn man die Spannung am Schleifer des Potis nachmisst und in Richtung 0V verstellt. Zwischen 1V und 0V treten die Balken dann meist hervor.&lt;br /&gt;
Doch wie bekommt man jetzt die Befehle und Daten in das Display?&lt;br /&gt;
&lt;br /&gt;
== Programmierung ==&lt;br /&gt;
&lt;br /&gt;
=== Die LCD Routinen ===&lt;br /&gt;
&lt;br /&gt;
Der folgende Satz von Ansteuerroutinen für ein Text-LCD ist in der Datei &#039;&#039;&#039;lcd-routines.c&#039;&#039;&#039; zusammengefasst. Diese Datei muss man beim Einrichten zusätzlich zum eigenen Hauptprogramm in sein Projekt aufnehmen. Dies geschieht beim AVR Studio unter Source Files im Fenster AVR GCC oder bei WinAVR im Makefile (z.&amp;amp;nbsp;B. durch SRC += lcd-routines.c). &lt;br /&gt;
&lt;br /&gt;
Wichtig ist außerdem, dass die Optimierung bei der Compilierung eingeschaltet ist, sonst stimmen die Zeiten der Funktionen _delay_us() und _delay_ms() nicht und der Code wird wesentlich länger (Siehe Dokumentation der libc im WinAVR).&lt;br /&gt;
&lt;br /&gt;
Als weitere Datei ist die Includedatei &#039;&#039;&#039;lcd-routines.h&#039;&#039;&#039; notwendig, die im Hauptprogramm und in &#039;&#039;&#039;lcd-routines.c&#039;&#039;&#039; eingebunden wird. Die Anpassung der Pinbelegung etc. macht man in dieser Datei.&lt;br /&gt;
&lt;br /&gt;
==== Datei &#039;&#039;&#039;lcd-routines.h&#039;&#039;&#039; ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus&lt;br /&gt;
// http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung&lt;br /&gt;
//&lt;br /&gt;
 &lt;br /&gt;
#ifndef LCD_ROUTINES_H&lt;br /&gt;
#define LCD_ROUTINES_H&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Hier die verwendete Taktfrequenz in Hz eintragen, wichtig!&lt;br /&gt;
 &lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
#define F_CPU 3686400&lt;br /&gt;
#endif&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Pinbelegung für das LCD, an verwendete Pins anpassen&lt;br /&gt;
// Alle LCD Pins müssen an einem Port angeschlossen sein und die 4&lt;br /&gt;
// Datenleitungen müssen auf aufeinanderfolgenden Pins liegen&lt;br /&gt;
 &lt;br /&gt;
//  LCD DB4-DB7 &amp;lt;--&amp;gt;  PORTD Bit PD0-PD3&lt;br /&gt;
#define LCD_PORT      PORTD&lt;br /&gt;
#define LCD_DDR       DDRD&lt;br /&gt;
#define LCD_DB        PD0&lt;br /&gt;
 &lt;br /&gt;
//  LCD RS      &amp;lt;--&amp;gt;  PORTD Bit PD4     (RS: 1=Data, 0=Command)&lt;br /&gt;
#define LCD_RS        PD4&lt;br /&gt;
 &lt;br /&gt;
//  LCD EN      &amp;lt;--&amp;gt;  PORTD Bit PD5     (EN: 1-Impuls für Daten)&lt;br /&gt;
#define LCD_EN        PD5&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// LCD Ausführungszeiten (MS=Millisekunden, US=Mikrosekunden)&lt;br /&gt;
 &lt;br /&gt;
#define LCD_BOOTUP_MS           15&lt;br /&gt;
#define LCD_ENABLE_US           20&lt;br /&gt;
#define LCD_WRITEDATA_US        46&lt;br /&gt;
#define LCD_COMMAND_US          42&lt;br /&gt;
 &lt;br /&gt;
#define LCD_SOFT_RESET_MS1      5&lt;br /&gt;
#define LCD_SOFT_RESET_MS2      1&lt;br /&gt;
#define LCD_SOFT_RESET_MS3      1&lt;br /&gt;
#define LCD_SET_4BITMODE_MS     5&lt;br /&gt;
 &lt;br /&gt;
#define LCD_CLEAR_DISPLAY_MS    2&lt;br /&gt;
#define LCD_CURSOR_HOME_MS      2&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Zeilendefinitionen des verwendeten LCD&lt;br /&gt;
// Die Einträge hier sollten für ein LCD mit einer Zeilenlänge von 16 Zeichen passen&lt;br /&gt;
// Bei anderen Zeilenlängen müssen diese Einträge angepasst werden&lt;br /&gt;
 &lt;br /&gt;
#define LCD_DDADR_LINE1         0x00&lt;br /&gt;
#define LCD_DDADR_LINE2         0x40&lt;br /&gt;
#define LCD_DDADR_LINE3         0x10&lt;br /&gt;
#define LCD_DDADR_LINE4         0x50&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Initialisierung: muss ganz am Anfang des Programms aufgerufen werden.&lt;br /&gt;
void lcd_init( void );&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// LCD löschen&lt;br /&gt;
void lcd_clear( void );&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Cursor in die 1. Zeile, 0-te Spalte&lt;br /&gt;
void lcd_home( void );&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Cursor an eine beliebige Position &lt;br /&gt;
void lcd_setcursor( uint8_t spalte, uint8_t zeile );&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Ausgabe eines einzelnen Zeichens an der aktuellen Cursorposition &lt;br /&gt;
void lcd_data( uint8_t data );&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Ausgabe eines Strings an der aktuellen Cursorposition &lt;br /&gt;
void lcd_string( const char *data );&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Definition eines benutzerdefinierten Sonderzeichens.&lt;br /&gt;
// data muss auf ein Array[8] mit den Zeilencodes des zu definierenden Zeichens&lt;br /&gt;
// zeigen&lt;br /&gt;
void lcd_generatechar( uint8_t code, const uint8_t *data );&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Ausgabe eines Kommandos an das LCD.&lt;br /&gt;
void lcd_command( uint8_t data );&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// LCD Befehle und Argumente.&lt;br /&gt;
// Zur Verwendung in lcd_command&lt;br /&gt;
 &lt;br /&gt;
// Clear Display -------------- 0b00000001&lt;br /&gt;
#define LCD_CLEAR_DISPLAY       0x01&lt;br /&gt;
 &lt;br /&gt;
// Cursor Home ---------------- 0b0000001x&lt;br /&gt;
#define LCD_CURSOR_HOME         0x02&lt;br /&gt;
 &lt;br /&gt;
// Set Entry Mode ------------- 0b000001xx&lt;br /&gt;
#define LCD_SET_ENTRY           0x04&lt;br /&gt;
 &lt;br /&gt;
#define LCD_ENTRY_DECREASE      0x00&lt;br /&gt;
#define LCD_ENTRY_INCREASE      0x02&lt;br /&gt;
#define LCD_ENTRY_NOSHIFT       0x00&lt;br /&gt;
#define LCD_ENTRY_SHIFT         0x01&lt;br /&gt;
 &lt;br /&gt;
// Set Display ---------------- 0b00001xxx&lt;br /&gt;
#define LCD_SET_DISPLAY         0x08&lt;br /&gt;
 &lt;br /&gt;
#define LCD_DISPLAY_OFF         0x00&lt;br /&gt;
#define LCD_DISPLAY_ON          0x04&lt;br /&gt;
#define LCD_CURSOR_OFF          0x00&lt;br /&gt;
#define LCD_CURSOR_ON           0x02&lt;br /&gt;
#define LCD_BLINKING_OFF        0x00&lt;br /&gt;
#define LCD_BLINKING_ON         0x01&lt;br /&gt;
 &lt;br /&gt;
// Set Shift ------------------ 0b0001xxxx&lt;br /&gt;
#define LCD_SET_SHIFT           0x10&lt;br /&gt;
 &lt;br /&gt;
#define LCD_CURSOR_MOVE         0x00&lt;br /&gt;
#define LCD_DISPLAY_SHIFT       0x08&lt;br /&gt;
#define LCD_SHIFT_LEFT          0x00&lt;br /&gt;
#define LCD_SHIFT_RIGHT         0x04&lt;br /&gt;
 &lt;br /&gt;
// Set Function --------------- 0b001xxxxx&lt;br /&gt;
#define LCD_SET_FUNCTION        0x20&lt;br /&gt;
 &lt;br /&gt;
#define LCD_FUNCTION_4BIT       0x00&lt;br /&gt;
#define LCD_FUNCTION_8BIT       0x10&lt;br /&gt;
#define LCD_FUNCTION_1LINE      0x00&lt;br /&gt;
#define LCD_FUNCTION_2LINE      0x08&lt;br /&gt;
#define LCD_FUNCTION_5X7        0x00&lt;br /&gt;
#define LCD_FUNCTION_5X10       0x04&lt;br /&gt;
 &lt;br /&gt;
#define LCD_SOFT_RESET          0x30&lt;br /&gt;
 &lt;br /&gt;
// Set CG RAM Address --------- 0b01xxxxxx  (Character Generator RAM)&lt;br /&gt;
#define LCD_SET_CGADR           0x40&lt;br /&gt;
 &lt;br /&gt;
#define LCD_GC_CHAR0            0&lt;br /&gt;
#define LCD_GC_CHAR1            1&lt;br /&gt;
#define LCD_GC_CHAR2            2&lt;br /&gt;
#define LCD_GC_CHAR3            3&lt;br /&gt;
#define LCD_GC_CHAR4            4&lt;br /&gt;
#define LCD_GC_CHAR5            5&lt;br /&gt;
#define LCD_GC_CHAR6            6&lt;br /&gt;
#define LCD_GC_CHAR7            7&lt;br /&gt;
 &lt;br /&gt;
// Set DD RAM Address --------- 0b1xxxxxxx  (Display Data RAM)&lt;br /&gt;
#define LCD_SET_DDADR           0x80&lt;br /&gt;
 &lt;br /&gt;
#endif &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Datei &#039;&#039;&#039;lcd-routines.c&#039;&#039;&#039;: ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus&lt;br /&gt;
// http://www.mikrocontroller.net/articles/HD44780&lt;br /&gt;
// http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung&lt;br /&gt;
//&lt;br /&gt;
// Die Pinbelegung ist über defines in lcd-routines.h einstellbar&lt;br /&gt;
 &lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;quot;lcd-routines.h&amp;quot;&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Erzeugt einen Enable-Puls&lt;br /&gt;
static void lcd_enable( void )&lt;br /&gt;
{&lt;br /&gt;
    LCD_PORT |= (1&amp;lt;&amp;lt;LCD_EN);     // Enable auf 1 setzen&lt;br /&gt;
    _delay_us( LCD_ENABLE_US );  // kurze Pause&lt;br /&gt;
    LCD_PORT &amp;amp;= ~(1&amp;lt;&amp;lt;LCD_EN);    // Enable auf 0 setzen&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Sendet eine 4-bit Ausgabeoperation an das LCD&lt;br /&gt;
static void lcd_out( uint8_t data )&lt;br /&gt;
{&lt;br /&gt;
    data &amp;amp;= 0xF0;                       // obere 4 Bit maskieren&lt;br /&gt;
 &lt;br /&gt;
    LCD_PORT &amp;amp;= ~(0xF0&amp;gt;&amp;gt;(4-LCD_DB));    // Maske löschen&lt;br /&gt;
    LCD_PORT |= (data&amp;gt;&amp;gt;(4-LCD_DB));     // Bits setzen&lt;br /&gt;
    lcd_enable();&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Initialisierung: muss ganz am Anfang des Programms aufgerufen werden.&lt;br /&gt;
void lcd_init( void )&lt;br /&gt;
{&lt;br /&gt;
    // verwendete Pins auf Ausgang schalten&lt;br /&gt;
    uint8_t pins = (0x0F &amp;lt;&amp;lt; LCD_DB) |           // 4 Datenleitungen&lt;br /&gt;
                   (1&amp;lt;&amp;lt;LCD_RS) |                // R/S Leitung&lt;br /&gt;
                   (1&amp;lt;&amp;lt;LCD_EN);                 // Enable Leitung&lt;br /&gt;
    LCD_DDR |= pins;&lt;br /&gt;
 &lt;br /&gt;
    // initial alle Ausgänge auf Null&lt;br /&gt;
    LCD_PORT &amp;amp;= ~pins;&lt;br /&gt;
 &lt;br /&gt;
    // warten auf die Bereitschaft des LCD&lt;br /&gt;
    _delay_ms( LCD_BOOTUP_MS );&lt;br /&gt;
    &lt;br /&gt;
    // Soft-Reset muss 3mal hintereinander gesendet werden zur Initialisierung&lt;br /&gt;
    lcd_out( LCD_SOFT_RESET );&lt;br /&gt;
    _delay_ms( LCD_SOFT_RESET_MS1 );&lt;br /&gt;
 &lt;br /&gt;
    lcd_enable();&lt;br /&gt;
    _delay_ms( LCD_SOFT_RESET_MS2 );&lt;br /&gt;
 &lt;br /&gt;
    lcd_enable();&lt;br /&gt;
    _delay_ms( LCD_SOFT_RESET_MS3 );&lt;br /&gt;
 &lt;br /&gt;
    // 4-bit Modus aktivieren &lt;br /&gt;
    lcd_out( LCD_SET_FUNCTION |&lt;br /&gt;
             LCD_FUNCTION_4BIT );&lt;br /&gt;
    _delay_ms( LCD_SET_4BITMODE_MS );&lt;br /&gt;
 &lt;br /&gt;
    // 4-bit Modus / 2 Zeilen / 5x7&lt;br /&gt;
    lcd_command( LCD_SET_FUNCTION |&lt;br /&gt;
                 LCD_FUNCTION_4BIT |&lt;br /&gt;
                 LCD_FUNCTION_2LINE |&lt;br /&gt;
                 LCD_FUNCTION_5X7 );&lt;br /&gt;
 &lt;br /&gt;
    // Display ein / Cursor aus / Blinken aus&lt;br /&gt;
    lcd_command( LCD_SET_DISPLAY |&lt;br /&gt;
                 LCD_DISPLAY_ON |&lt;br /&gt;
                 LCD_CURSOR_OFF |&lt;br /&gt;
                 LCD_BLINKING_OFF); &lt;br /&gt;
 &lt;br /&gt;
    // Cursor inkrement / kein Scrollen&lt;br /&gt;
    lcd_command( LCD_SET_ENTRY |&lt;br /&gt;
                 LCD_ENTRY_INCREASE |&lt;br /&gt;
                 LCD_ENTRY_NOSHIFT );&lt;br /&gt;
 &lt;br /&gt;
    lcd_clear();&lt;br /&gt;
}&lt;br /&gt;
  &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Sendet ein Datenbyte an das LCD&lt;br /&gt;
void lcd_data( uint8_t data )&lt;br /&gt;
{&lt;br /&gt;
    LCD_PORT |= (1&amp;lt;&amp;lt;LCD_RS);    // RS auf 1 setzen&lt;br /&gt;
 &lt;br /&gt;
    lcd_out( data );            // zuerst die oberen, &lt;br /&gt;
    lcd_out( data&amp;lt;&amp;lt;4 );         // dann die unteren 4 Bit senden&lt;br /&gt;
 &lt;br /&gt;
    _delay_us( LCD_WRITEDATA_US );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Sendet einen Befehl an das LCD&lt;br /&gt;
void lcd_command( uint8_t data )&lt;br /&gt;
{&lt;br /&gt;
    LCD_PORT &amp;amp;= ~(1&amp;lt;&amp;lt;LCD_RS);    // RS auf 0 setzen&lt;br /&gt;
 &lt;br /&gt;
    lcd_out( data );             // zuerst die oberen, &lt;br /&gt;
    lcd_out( data&amp;lt;&amp;lt;4 );           // dann die unteren 4 Bit senden&lt;br /&gt;
 &lt;br /&gt;
    _delay_us( LCD_COMMAND_US );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Sendet den Befehl zur Löschung des Displays&lt;br /&gt;
void lcd_clear( void )&lt;br /&gt;
{&lt;br /&gt;
    lcd_command( LCD_CLEAR_DISPLAY );&lt;br /&gt;
    _delay_ms( LCD_CLEAR_DISPLAY_MS );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Sendet den Befehl: Cursor Home&lt;br /&gt;
void lcd_home( void )&lt;br /&gt;
{&lt;br /&gt;
    lcd_command( LCD_CURSOR_HOME );&lt;br /&gt;
    _delay_ms( LCD_CURSOR_HOME_MS );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Setzt den Cursor in Spalte x (0..15) Zeile y (1..4) &lt;br /&gt;
 &lt;br /&gt;
void lcd_setcursor( uint8_t x, uint8_t y )&lt;br /&gt;
{&lt;br /&gt;
    uint8_t data;&lt;br /&gt;
 &lt;br /&gt;
    switch (y)&lt;br /&gt;
    {&lt;br /&gt;
        case 1:    // 1. Zeile&lt;br /&gt;
            data = LCD_SET_DDADR + LCD_DDADR_LINE1 + x;&lt;br /&gt;
            break;&lt;br /&gt;
 &lt;br /&gt;
        case 2:    // 2. Zeile&lt;br /&gt;
            data = LCD_SET_DDADR + LCD_DDADR_LINE2 + x;&lt;br /&gt;
            break;&lt;br /&gt;
 &lt;br /&gt;
        case 3:    // 3. Zeile&lt;br /&gt;
            data = LCD_SET_DDADR + LCD_DDADR_LINE3 + x;&lt;br /&gt;
            break;&lt;br /&gt;
 &lt;br /&gt;
        case 4:    // 4. Zeile&lt;br /&gt;
            data = LCD_SET_DDADR + LCD_DDADR_LINE4 + x;&lt;br /&gt;
            break;&lt;br /&gt;
 &lt;br /&gt;
        default:&lt;br /&gt;
            return;                                   // für den Fall einer falschen Zeile&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    lcd_command( data );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Schreibt einen String auf das LCD&lt;br /&gt;
 &lt;br /&gt;
void lcd_string( const char *data )&lt;br /&gt;
{&lt;br /&gt;
    while( *data != &#039;\0&#039; )&lt;br /&gt;
        lcd_data( *data++ );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Schreibt ein Zeichen in den Character Generator RAM&lt;br /&gt;
 &lt;br /&gt;
void lcd_generatechar( uint8_t code, const uint8_t *data )&lt;br /&gt;
{&lt;br /&gt;
    // Startposition des Zeichens einstellen&lt;br /&gt;
    lcd_command( LCD_SET_CGADR | (code&amp;lt;&amp;lt;3) );&lt;br /&gt;
 &lt;br /&gt;
    // Bitmuster übertragen&lt;br /&gt;
    for ( uint8_t i=0; i&amp;lt;8; i++ )&lt;br /&gt;
    {&lt;br /&gt;
        lcd_data( data[i] );&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LCD Beispiel 1 ===&lt;br /&gt;
Ein Hauptprogramm, welches die LCD Funktionen benutzt, sieht zb. so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// &lt;br /&gt;
// Anpassungen im makefile:&lt;br /&gt;
//    ATMega8 =&amp;gt; MCU=atmega8 im makefile einstellen&lt;br /&gt;
//    lcd-routines.c in SRC = ... Zeile anhängen&lt;br /&gt;
// &lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;quot;lcd-routines.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  // Initialisierung des LCD&lt;br /&gt;
  // Nach der Initialisierung müssen auf dem LCD vorhandene schwarze Balken&lt;br /&gt;
  // verschwunden sein&lt;br /&gt;
  lcd_init();&lt;br /&gt;
&lt;br /&gt;
  // Text in einzelnen Zeichen ausgeben&lt;br /&gt;
  lcd_data( &#039;T&#039; );&lt;br /&gt;
  lcd_data( &#039;e&#039; );&lt;br /&gt;
  lcd_data( &#039;s&#039; );&lt;br /&gt;
  lcd_data( &#039;t&#039; );&lt;br /&gt;
&lt;br /&gt;
  // Die Ausgabemarke in die 2te Zeile setzen&lt;br /&gt;
  lcd_setcursor( 0, 2 );&lt;br /&gt;
&lt;br /&gt;
  // erneut Text ausgeben, aber diesmal komfortabler als String&lt;br /&gt;
  lcd_string(&amp;quot;Hello World!&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  while(1)&lt;br /&gt;
  {&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== LCD Beispiel 2 ===&lt;br /&gt;
Ein Hauptprogramm, welches eine Variable ausgibt, sieht zb. so aus.&lt;br /&gt;
Mittels der itoa() Funktion (itoa = &amp;lt;b&amp;gt;I&amp;lt;/b&amp;gt;nteger &amp;lt;b&amp;gt;To&amp;lt;/b&amp;gt; &amp;lt;b&amp;gt;A&amp;lt;/b&amp;gt;scii ) wird von einem Zahlenwert eine textuelle Repräsentierung ermittelt (sprich: ein String erzeugt) und dieser String mit der bereits vorhandenen Funktion lcd_string ausgegeben. Das Einrichten des Projekts ist wie in Beispiel 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// &lt;br /&gt;
// Anpassungen im makefile:&lt;br /&gt;
//    ATMega8 =&amp;gt; MCU=atmega8 im makefile einstellen&lt;br /&gt;
//    lcd-routines.c in SRC = ... Zeile anhängen &lt;br /&gt;
// &lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;quot;lcd-routines.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
// Beispiel&lt;br /&gt;
int variable = 42;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  lcd_init();&lt;br /&gt;
&lt;br /&gt;
  // Ausgabe des Zeichens dessen ASCII-Code gleich dem Variablenwert ist&lt;br /&gt;
  // (Im Beispiel entspricht der ASCII-Code 42 dem Zeichen *)&lt;br /&gt;
  // http://www.code-knacker.de/ascii.htm&lt;br /&gt;
  lcd_data( variable );&lt;br /&gt;
&lt;br /&gt;
  lcd_setcursor( 0, 2 );&lt;br /&gt;
 &lt;br /&gt;
  // Ausgabe der Variable als Text in dezimaler Schreibweise&lt;br /&gt;
  {&lt;br /&gt;
     // ... umwandeln siehe FAQ Artikel bei http://www.mikrocontroller.net/articles/FAQ&lt;br /&gt;
     // WinAVR hat eine itoa()-Funktion, das erfordert obiges #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
     char Buffer[20]; // in diesem {} lokal&lt;br /&gt;
     itoa( variable, Buffer, 10 ); &lt;br /&gt;
&lt;br /&gt;
     // ... ausgeben  &lt;br /&gt;
     lcd_string( Buffer );&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  while(1)&lt;br /&gt;
  {&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Erweiterte LCD-Ansteuerung]]&lt;br /&gt;
* [[Pseudo-Graphische LCD-Ansteuerung]]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/316826#3431235 Ermittlung der Startadresse der einzelnen Zeilen]&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
* [http://homepage.hispeed.ch/peterfleury/avr-software.html#libs Lib zur HD44780 Ansteuerung (AVR)]&lt;br /&gt;
* [http://pic-projekte.de/wordpress/?p=908 Lib zur HD44780 Ansteuerung (PIC)]&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/group__stdiodemo.html Using the standard IO facilities] - Demoprojekt zur Text-LCD Ansteuerung (HD44780 komp.) in der avr-libc&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Avr-gcc Tutorial]]&lt;br /&gt;
[[Kategorie:LCD]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=MOSFET-%C3%9Cbersicht&amp;diff=75400</id>
		<title>MOSFET-Übersicht</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=MOSFET-%C3%9Cbersicht&amp;diff=75400"/>
		<updated>2013-04-26T23:10:55Z</updated>

		<summary type="html">&lt;p&gt;Maybee: /* P-Kanal MOSFET */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Im Forum wird immer wieder gefragt, welchen Mosfet-Transistor man für ein Projekt einsetzen sollte. Und wo man die herbekommt. Deshalb soll hier eine Übersicht mit gängigen Mosfet-Transistoren entstehen, wo auch die Bezugsquellen angegeben sind. Bezugsquellen sollten nach Möglichkeit solche sein, die auch für den privaten Bastler in Frage kommen.&lt;br /&gt;
&lt;br /&gt;
Der Thread zum Thema: http://www.mikrocontroller.net/topic/41588&lt;br /&gt;
&lt;br /&gt;
siehe auch : [[Transistor-Übersicht]] - [[Dioden-Übersicht]] - [[Standardbauelemente]]&lt;br /&gt;
&lt;br /&gt;
== P-Kanal MOSFET==&lt;br /&gt;
&lt;br /&gt;
{| {{Tabelle}} border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;pkanalmosfets&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#eeeeee&amp;quot;&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Package&lt;br /&gt;
! Hersteller&lt;br /&gt;
! U&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;/V&lt;br /&gt;
! U&amp;lt;sub&amp;gt;DS&amp;lt;/sub&amp;gt;/V&lt;br /&gt;
! I&amp;lt;sub&amp;gt;D&amp;lt;/sub&amp;gt;/A&lt;br /&gt;
! P/W&lt;br /&gt;
! R&amp;lt;sub&amp;gt;DS,on&amp;lt;/sub&amp;gt;/mOhm&lt;br /&gt;
! Bemerkung&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Einzelpreis&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BS250 BS250]&lt;br /&gt;
| TO-92/SOT-23&lt;br /&gt;
| Siliconix&lt;br /&gt;
| 4,0&lt;br /&gt;
| 60&lt;br /&gt;
| 0,12&lt;br /&gt;
| 0,35&lt;br /&gt;
| 10000&lt;br /&gt;
| -&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Buerklin|Bü]]&lt;br /&gt;
| 0,32 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BSH205 BSH205]&lt;br /&gt;
| SOT23&lt;br /&gt;
| Phi&lt;br /&gt;
| 1,0&lt;br /&gt;
| 12&lt;br /&gt;
| 0,75&lt;br /&gt;
| 0,4&lt;br /&gt;
| 500&lt;br /&gt;
| kleine Gatekapazität (3.8nC)&lt;br /&gt;
| [[Elektronikversender#csd-electronics|csd]] (a.A.)&lt;br /&gt;
| 0,30 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/SI2301 SI2301]&lt;br /&gt;
| SOT23&lt;br /&gt;
| Vishay&lt;br /&gt;
| 1,5&lt;br /&gt;
| 20&lt;br /&gt;
| 2,0&lt;br /&gt;
| 0,7&lt;br /&gt;
| 150&lt;br /&gt;
| kleine Gatekapazität (typ 4.5nC)&lt;br /&gt;
| [[Elektronikversender#farnell|farnell]]&lt;br /&gt;
| 0,30 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRLML6402  IRLML6402PBF]&lt;br /&gt;
| SOT23&lt;br /&gt;
| IRF&lt;br /&gt;
| 1,2&lt;br /&gt;
| 20&lt;br /&gt;
| 3,7&lt;br /&gt;
| 1,3&lt;br /&gt;
| 65&lt;br /&gt;
| Ultra-Low On-Resistance, Logic-level&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#csd-electronics|csd]],[[Elektronikversender#Buerklin|Bü]]&lt;br /&gt;
| 0,15 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRLML6302  IRLML6302PBF]&lt;br /&gt;
| SOT23&lt;br /&gt;
| IRF&lt;br /&gt;
| 1,5&lt;br /&gt;
| 20&lt;br /&gt;
| 0,75&lt;br /&gt;
| 0,54&lt;br /&gt;
| 600&lt;br /&gt;
| ähnlich BSH205&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#csd-electronics|csd]],[[Elektronikversender#Buerklin|Bü]]&lt;br /&gt;
| 0,18 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BSS83 BSS83P]&lt;br /&gt;
| SOT143&lt;br /&gt;
| Inf&lt;br /&gt;
| 3,0&lt;br /&gt;
| 60&lt;br /&gt;
| 0,33&lt;br /&gt;
| 0,35&lt;br /&gt;
| 2000&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,11 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BSS84 BSS84]&lt;br /&gt;
| SOT23&lt;br /&gt;
| Fairchild,NXP&lt;br /&gt;
| 2,0&lt;br /&gt;
| 50&lt;br /&gt;
| 0,13&lt;br /&gt;
| 0,35&lt;br /&gt;
| 10000&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Farnell|Fa]]&lt;br /&gt;
| 0,28 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BSS83 BSS83]&lt;br /&gt;
| TO-97, SOT23&lt;br /&gt;
| Phi&lt;br /&gt;
| 3,0&lt;br /&gt;
| 50&lt;br /&gt;
| 0,13&lt;br /&gt;
| 0,35&lt;br /&gt;
| 10000&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]],[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,07 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BSS110 BSS110]&lt;br /&gt;
| TO-97, SOT23&lt;br /&gt;
| Phi&lt;br /&gt;
| 3,0&lt;br /&gt;
| 50&lt;br /&gt;
| 0,17&lt;br /&gt;
| 0,35&lt;br /&gt;
| 10000&lt;br /&gt;
| -&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/PMV65XP PMV65XP]&lt;br /&gt;
| SOT23&lt;br /&gt;
| Phi&lt;br /&gt;
| 1,4&lt;br /&gt;
| 20&lt;br /&gt;
| 3,9&lt;br /&gt;
| ?&lt;br /&gt;
| 76&lt;br /&gt;
| grosser ID für Bauform&lt;br /&gt;
| [[Elektronikversender#Spoerle|Spo]], [[Elektronikversender#RS_Components|RS]]&lt;br /&gt;
| 0,10 € (3000er-Rolle)&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF4905S IRF4905S]&lt;br /&gt;
| D2Pack&lt;br /&gt;
| irf&lt;br /&gt;
| 4,0&lt;br /&gt;
| 55&lt;br /&gt;
| 64&lt;br /&gt;
| 3,8&lt;br /&gt;
| 20&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]], [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 1,10 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF4905 IRF4905]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 4,0&lt;br /&gt;
| 55&lt;br /&gt;
| 74&lt;br /&gt;
| 3,8&lt;br /&gt;
| 20&lt;br /&gt;
| -&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,93 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF5210S IRF5210S]&lt;br /&gt;
| D2Pack&lt;br /&gt;
| irf&lt;br /&gt;
| 10,0&lt;br /&gt;
| 100&lt;br /&gt;
| 40&lt;br /&gt;
| ?&lt;br /&gt;
| 60&lt;br /&gt;
| -&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1,25 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7104 IRF7104]&lt;br /&gt;
| SO-8&lt;br /&gt;
| irf&lt;br /&gt;
| 3,0&lt;br /&gt;
| 20&lt;br /&gt;
| 2,3&lt;br /&gt;
| 2,0&lt;br /&gt;
| 250&lt;br /&gt;
| 2 FETs im Gehäuse&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,36 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7205 IRF7205]&lt;br /&gt;
| SO-8&lt;br /&gt;
| irf&lt;br /&gt;
| 3,0&lt;br /&gt;
| 30&lt;br /&gt;
| 4,6&lt;br /&gt;
| 2,5&lt;br /&gt;
| 70&lt;br /&gt;
| ?&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]] &lt;br /&gt;
| 0,34 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/FDC604P FDC604P]&lt;br /&gt;
| SuperSOT-6&lt;br /&gt;
| Fairchild&lt;br /&gt;
| 1,5&lt;br /&gt;
| 20&lt;br /&gt;
| 5,5&lt;br /&gt;
| 0,8-1,6&lt;br /&gt;
| 33&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#csd-electronics|csd]] (a.A.)&lt;br /&gt;
| 0,70 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/NDS0610 NDS0610]&lt;br /&gt;
| SOT-23&lt;br /&gt;
| Fairchild&lt;br /&gt;
| 1,8&lt;br /&gt;
| 60&lt;br /&gt;
| 0,12&lt;br /&gt;
| 0,36&lt;br /&gt;
| 10000&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#csd-electronics|csd]]&lt;br /&gt;
| 0,07 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF5305 IRF5305]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 3,0&lt;br /&gt;
| 55&lt;br /&gt;
| 31&lt;br /&gt;
| 110&lt;br /&gt;
| 60&lt;br /&gt;
| -&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,59 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/NDS352P NDS352P]&lt;br /&gt;
| SOT23&lt;br /&gt;
| Fairchild&lt;br /&gt;
| 4,5&lt;br /&gt;
| 20&lt;br /&gt;
| 0,85&lt;br /&gt;
| 0,5&lt;br /&gt;
| 500&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0,76 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BSP171 BSP171]&lt;br /&gt;
| SOT-223&lt;br /&gt;
| Siemens&lt;br /&gt;
| 1,4&lt;br /&gt;
| 60&lt;br /&gt;
| 1,7&lt;br /&gt;
| 1,8&lt;br /&gt;
| 350&lt;br /&gt;
| -&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,51 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRFD9014 IRFD9014]&lt;br /&gt;
| HEXDIP/DIP4&lt;br /&gt;
| irf&lt;br /&gt;
| 2,0&lt;br /&gt;
| 60&lt;br /&gt;
| 1,1&lt;br /&gt;
| 1,3&lt;br /&gt;
| 500&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0,65 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRFD9024 IRFD9024]&lt;br /&gt;
| HEXDIP/DIP4&lt;br /&gt;
| irf&lt;br /&gt;
| 2,0&lt;br /&gt;
| 60&lt;br /&gt;
| 1,6&lt;br /&gt;
| 1,3&lt;br /&gt;
| 280&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]],[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,50 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7416 IRF7416]&lt;br /&gt;
| SO-8&lt;br /&gt;
| irf&lt;br /&gt;
| 1,0&lt;br /&gt;
| 30&lt;br /&gt;
| 10&lt;br /&gt;
| 2,5&lt;br /&gt;
| 20&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]],[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,60 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/SUP75P03 SUP75P03-007]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| VISHAY&lt;br /&gt;
| 3,0&lt;br /&gt;
| 30&lt;br /&gt;
| 75&lt;br /&gt;
| 187&lt;br /&gt;
| 7&lt;br /&gt;
| -&lt;br /&gt;
| nessel-elektronik.de&lt;br /&gt;
| 2,30 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7220 IRF7220]&lt;br /&gt;
| SO-8&lt;br /&gt;
| irf&lt;br /&gt;
| 0,6&lt;br /&gt;
| 14&lt;br /&gt;
| 11&lt;br /&gt;
| 2,5&lt;br /&gt;
| 8,2&lt;br /&gt;
| spezifiziert ab 2,5V Vgs, Qg=84nC&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]], [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,58 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7410 IRF7410]&lt;br /&gt;
| SO-8&lt;br /&gt;
| irf&lt;br /&gt;
| 0,4...0,9&lt;br /&gt;
| 12&lt;br /&gt;
| 16&lt;br /&gt;
| 2,5&lt;br /&gt;
| 7&lt;br /&gt;
| spezifiziert ab 1,8V Vgs, Qg=91nC &lt;br /&gt;
| distrelec.de&amp;lt;br/&amp;gt;[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1,80 €&amp;lt;br/&amp;gt;0,85 €&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
(Tabelle mit Click im Kopfbereich sortierbar; a.A. = Auf Anfrage)&lt;br /&gt;
&lt;br /&gt;
== N-Kanal MOSFET==&lt;br /&gt;
&lt;br /&gt;
{| {{Tabelle}} class=&amp;quot;sortable&amp;quot; id=&amp;quot;nkanalmosfets&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#eeeeee&amp;quot;&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Package&lt;br /&gt;
! Hersteller&lt;br /&gt;
! U&amp;lt;sub&amp;gt;GS(th)&amp;lt;/sub&amp;gt;/V&lt;br /&gt;
! U&amp;lt;sub&amp;gt;DS&amp;lt;/sub&amp;gt;/V&lt;br /&gt;
! I&amp;lt;sub&amp;gt;D&amp;lt;/sub&amp;gt;/A&lt;br /&gt;
! P/W&lt;br /&gt;
! R&amp;lt;sub&amp;gt;DS,on&amp;lt;/sub&amp;gt;/mOhm&lt;br /&gt;
! Bemerkung&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Preis/EUR&lt;br /&gt;
|-&lt;br /&gt;
| IRFP 4310Z &lt;br /&gt;
| TO-247AC&lt;br /&gt;
| irf&lt;br /&gt;
| 2-4&lt;br /&gt;
| 100&lt;br /&gt;
| 120&lt;br /&gt;
| 280&lt;br /&gt;
| 4.8&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRFP450 IRFP450]&lt;br /&gt;
| TO-247&lt;br /&gt;
| irf&lt;br /&gt;
| 3&lt;br /&gt;
| 500&lt;br /&gt;
| 14&lt;br /&gt;
| 190&lt;br /&gt;
| 400&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1.20&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF530 IRF530]&lt;br /&gt;
| TO-220&lt;br /&gt;
| irf&lt;br /&gt;
| 2.9&lt;br /&gt;
| 100&lt;br /&gt;
| 16&lt;br /&gt;
| 94&lt;br /&gt;
| 160&lt;br /&gt;
| Linearbetrieb möglich&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.44&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRL3103 IRL3103]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 1.0&lt;br /&gt;
| 30&lt;br /&gt;
| 64&lt;br /&gt;
| 94&lt;br /&gt;
| 12&lt;br /&gt;
| Qg=33nC (!)&lt;br /&gt;
| [[Elektronikversender#Segor-electronics|Seg]]&lt;br /&gt;
| 0.95&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF730A IRF730A]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0&lt;br /&gt;
| 400&lt;br /&gt;
| 5.5&lt;br /&gt;
| 74&lt;br /&gt;
| 1000&lt;br /&gt;
| Qg=22nC (!)&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.54&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRFP064 IRFP064]&lt;br /&gt;
| TO-247AC&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0&lt;br /&gt;
| 60&lt;br /&gt;
| 70&lt;br /&gt;
| 300&lt;br /&gt;
| 9&lt;br /&gt;
| Qg=190 nC&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1.65&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF3205 IRF3205]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0&lt;br /&gt;
| 55&lt;br /&gt;
| 110&lt;br /&gt;
| 200&lt;br /&gt;
| 8&lt;br /&gt;
|&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.86&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRL3803 IRL3803]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 1.0&lt;br /&gt;
| 30&lt;br /&gt;
| 140&lt;br /&gt;
| 200&lt;br /&gt;
| 6&lt;br /&gt;
| Qg=140nC&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.96&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF540 IRF540]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 3&lt;br /&gt;
| 100&lt;br /&gt;
| 28&lt;br /&gt;
| 150&lt;br /&gt;
| 77&lt;br /&gt;
| Linearbetrieb möglich&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Kessler|Kes]]&lt;br /&gt;
| 0.52&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7401 IRF7401]&lt;br /&gt;
| SO-8&lt;br /&gt;
| irf&lt;br /&gt;
| 2.7&lt;br /&gt;
| 20&lt;br /&gt;
| 8.7&lt;br /&gt;
| 2.0&lt;br /&gt;
| 22&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.72&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7403 IRF7403]&lt;br /&gt;
| SO-8&lt;br /&gt;
| irf&lt;br /&gt;
| 4.85&lt;br /&gt;
| 30&lt;br /&gt;
| 8.5&lt;br /&gt;
| 2.5&lt;br /&gt;
| 22&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.42&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7413 IRF7413]&lt;br /&gt;
| SO-8&lt;br /&gt;
| irf&lt;br /&gt;
| 3.0&lt;br /&gt;
| 30&lt;br /&gt;
| 13.0&lt;br /&gt;
| 2.5&lt;br /&gt;
| 11&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Kessler|Kes]]&lt;br /&gt;
| 0.41&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BUZ11 BUZ11]&lt;br /&gt;
| TO-220&lt;br /&gt;
| ST&lt;br /&gt;
| 5.0&lt;br /&gt;
| 50&lt;br /&gt;
| 33.0&lt;br /&gt;
| 90.0&lt;br /&gt;
| 30&lt;br /&gt;
| Linearbetrieb möglich, Achtung! Der BUZ11 von STM hat deutlich niedrigere SOA-Grenzen als von anderen Herstellern!&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.50&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BS170 BS170]&lt;br /&gt;
| TO-92&lt;br /&gt;
| gs&lt;br /&gt;
| 2.0&lt;br /&gt;
| 60&lt;br /&gt;
| 0.3&lt;br /&gt;
| 0.83&lt;br /&gt;
| 5000&lt;br /&gt;
| Linearbetrieb möglich&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.13&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BSN20 BSN20]&lt;br /&gt;
| SOT-23&lt;br /&gt;
| gs&lt;br /&gt;
| 1.8&lt;br /&gt;
| 50&lt;br /&gt;
| 0.18&lt;br /&gt;
| 0.35&lt;br /&gt;
| 6000&lt;br /&gt;
| Linearbetrieb möglich&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.092&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BSS138 BSS138]&lt;br /&gt;
| SOT-23&lt;br /&gt;
| div&lt;br /&gt;
| 0.8-1.6&lt;br /&gt;
| 50&lt;br /&gt;
| 0.22&lt;br /&gt;
| 0.36&lt;br /&gt;
| 2000&lt;br /&gt;
| Linearbetrieb möglich&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.06&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BSS123 BSS123]&lt;br /&gt;
| SOT-23&lt;br /&gt;
| div&lt;br /&gt;
| 0.8-1.6&lt;br /&gt;
| 100&lt;br /&gt;
| 0.17&lt;br /&gt;
| 0.36&lt;br /&gt;
| 10000 @ 4,5V, &lt;br /&gt;
| Linearbetrieb möglich&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.06&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRFP2907 IRFP2907]&lt;br /&gt;
| TO-247AC&lt;br /&gt;
| irf&lt;br /&gt;
| 4.0&lt;br /&gt;
| 75&lt;br /&gt;
| 209&lt;br /&gt;
| 470&lt;br /&gt;
| 4.5&lt;br /&gt;
|&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 4.70&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/2N7000 2N7000]&lt;br /&gt;
| TO-92&lt;br /&gt;
| ON&lt;br /&gt;
| 3.0&lt;br /&gt;
| 60&lt;br /&gt;
| 0.2&lt;br /&gt;
| 0.35&lt;br /&gt;
| 5000&lt;br /&gt;
| Linearbetrieb möglich&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Kessler|Kes]]&lt;br /&gt;
| 0.13&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BS107 BS107]&lt;br /&gt;
| TO-92&lt;br /&gt;
| ON, Phi&lt;br /&gt;
| 3.0&lt;br /&gt;
| 200&lt;br /&gt;
| 0.25&lt;br /&gt;
| 0.35&lt;br /&gt;
| 6400/14000&lt;br /&gt;
| Linearbetrieb möglich&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.18&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BS108 BS108]&lt;br /&gt;
| TO-92&lt;br /&gt;
| ON, Phi&lt;br /&gt;
| 2.0&lt;br /&gt;
| 200&lt;br /&gt;
| 0.25&lt;br /&gt;
| 0.35&lt;br /&gt;
| 8000&lt;br /&gt;
| Linearbetrieb möglich&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.14&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BUK100 BUK100]&lt;br /&gt;
| TO-220&lt;br /&gt;
| Phi&lt;br /&gt;
| 3.0&lt;br /&gt;
| 50&lt;br /&gt;
| 13.5&lt;br /&gt;
| 40&lt;br /&gt;
| 125&lt;br /&gt;
| Overload-Protection, ESD-Protection&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1.40&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRL3705N IRL3705N]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0&lt;br /&gt;
| 55&lt;br /&gt;
| 89&lt;br /&gt;
| 170&lt;br /&gt;
| 10&lt;br /&gt;
| Qg=98nC&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1.20&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BUZ72 BUZ72A]&lt;br /&gt;
| TO-220&lt;br /&gt;
| Infineon&lt;br /&gt;
| 4.0&lt;br /&gt;
| 100&lt;br /&gt;
| 9.0&lt;br /&gt;
| 40&lt;br /&gt;
| 250&lt;br /&gt;
| Linearbetrieb möglich&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.45&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRLZ34N IRLZ34N]&lt;br /&gt;
| TO-220&lt;br /&gt;
| irf&lt;br /&gt;
| 2.5&lt;br /&gt;
| 55&lt;br /&gt;
| 30&lt;br /&gt;
| 68&lt;br /&gt;
| 35&lt;br /&gt;
| 5V Logic-Level, Linearbetrieb möglich&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Farnell|Far]],[[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 0.45&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRLML2502 IRLML2502]&lt;br /&gt;
| SOT23&lt;br /&gt;
| irf&lt;br /&gt;
| 1.2&lt;br /&gt;
| 20&lt;br /&gt;
| 4.2&lt;br /&gt;
| 1&lt;br /&gt;
| 45&lt;br /&gt;
| Logic-Level&lt;br /&gt;
| [[Elektronikversender#csd-electronics|csd]] [[Elektronikversender#Reichelt|Rei (neu)]]&lt;br /&gt;
| 0.21&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF1404 IRF1404]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 4.0&lt;br /&gt;
| 40&lt;br /&gt;
| 202&lt;br /&gt;
| 333&lt;br /&gt;
| 4&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1.10&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRL1004 IRL1004]&lt;br /&gt;
| TO-220&lt;br /&gt;
| irf&lt;br /&gt;
| 2.7&lt;br /&gt;
| 40&lt;br /&gt;
| 130&lt;br /&gt;
| 200&lt;br /&gt;
| 6.5&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1.25&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRL530 IRL530]&lt;br /&gt;
| TO220, D2Pack&lt;br /&gt;
| irf&lt;br /&gt;
| 2&lt;br /&gt;
| 100&lt;br /&gt;
| 15.0&lt;br /&gt;
| 88&lt;br /&gt;
| 160&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.57/0.78&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF830 IRF830]&lt;br /&gt;
| TO220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0-4.5   &lt;br /&gt;
| 500&lt;br /&gt;
| 5.0&lt;br /&gt;
| 74&lt;br /&gt;
| 1400&lt;br /&gt;
| Linearbetrieb möglich&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Kessler|Kes]]&lt;br /&gt;
| 0.57&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF840 IRF840]&lt;br /&gt;
| TO220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0-4.0   &lt;br /&gt;
| 500&lt;br /&gt;
| 8.0&lt;br /&gt;
| 125&lt;br /&gt;
| 850&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.57&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/FDC645N FDC645N]&lt;br /&gt;
| SuperSOT-6&lt;br /&gt;
| Fairchild&lt;br /&gt;
| 1.5&lt;br /&gt;
| 30&lt;br /&gt;
| 5.5&lt;br /&gt;
| 0.8/1.6&lt;br /&gt;
| 30&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#csd-electronics|csd]] (a.A.), Far&lt;br /&gt;
| 0.7&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BSP297 BSP297]&lt;br /&gt;
| SOT-223&lt;br /&gt;
| Siemens/Infineon&lt;br /&gt;
| 0.8-2.4&lt;br /&gt;
| 200&lt;br /&gt;
| 0.65&lt;br /&gt;
| 1.8&lt;br /&gt;
| 6000&lt;br /&gt;
| 200V &amp;lt;math&amp;gt;U_{DS}&amp;lt;/math&amp;gt;, SMD und Logic Level (seltene Kombinaton), Linearbetrieb möglich&lt;br /&gt;
| [[Elektronikversender#Farnell|Far]], [[Elektronikversender#Schuricht|Schu]], [[Elektronikversender#RS_Components|RS]]&lt;br /&gt;
| 0.56&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7455 IRF7455]&lt;br /&gt;
| SO-8&lt;br /&gt;
| irf&lt;br /&gt;
| 4.5&lt;br /&gt;
| 30&lt;br /&gt;
| 15&lt;br /&gt;
| 2.5&lt;br /&gt;
| 7.5&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Kessler|Kes]]&lt;br /&gt;
| 1.04&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/SI4442DY SI4442DY]&lt;br /&gt;
| SO-8&lt;br /&gt;
| vis&lt;br /&gt;
| 2.5&lt;br /&gt;
| 30&lt;br /&gt;
| 22&lt;br /&gt;
| 2.5&lt;br /&gt;
| 5/4.5V&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Kessler|Kes]]&lt;br /&gt;
| 1.64&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRLU2905 IRLU2905]&lt;br /&gt;
| TO251, DPack&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0&lt;br /&gt;
| 55&lt;br /&gt;
| 42&lt;br /&gt;
| 110&lt;br /&gt;
| 27&lt;br /&gt;
| Logic-Level&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Farnell|Far]]&lt;br /&gt;
| 1.89&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRFD014 IRFD014]&lt;br /&gt;
| HEXDIP/DIP4&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0-4.0&lt;br /&gt;
| 60&lt;br /&gt;
| 1.7&lt;br /&gt;
| 1.3&lt;br /&gt;
| 200&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Conrad|Con]],[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.52&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRFD024 IRFD024]&lt;br /&gt;
| HEXDIP/DIP4&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0-4.0&lt;br /&gt;
| 60&lt;br /&gt;
| 2.5&lt;br /&gt;
| 1.3&lt;br /&gt;
| 100&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Conrad|Con]],[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.54&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRLD024 IRLD024]&lt;br /&gt;
| HEXDIP/DIP4&lt;br /&gt;
| irf&lt;br /&gt;
| 1.0-2.0&lt;br /&gt;
| 60&lt;br /&gt;
| 2.5&lt;br /&gt;
| 1.3&lt;br /&gt;
| 100&lt;br /&gt;
| Logic-Level&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]],[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.47&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRLU3717 IRLU3717]&lt;br /&gt;
| I-Pak&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0&lt;br /&gt;
| 20&lt;br /&gt;
| 120&lt;br /&gt;
| 1.5/89&lt;br /&gt;
| 4&lt;br /&gt;
| Qg=21nC&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]],[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1.15&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRFP3703 IRFP3703]&lt;br /&gt;
| TO-247AC&lt;br /&gt;
| irf&lt;br /&gt;
| 4.0&lt;br /&gt;
| 30&lt;br /&gt;
| 210&lt;br /&gt;
| 230&lt;br /&gt;
| 2.8&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 5.08&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF3710 IRF3710]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 5&lt;br /&gt;
| 100&lt;br /&gt;
| 57&lt;br /&gt;
| 200&lt;br /&gt;
| 23&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0.83&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRLR7843 IRLR7843]&lt;br /&gt;
| D-Pack&lt;br /&gt;
| irf&lt;br /&gt;
| 2.3&lt;br /&gt;
| 30&lt;br /&gt;
| 164&lt;br /&gt;
| 140&lt;br /&gt;
| 3.3&lt;br /&gt;
| Qg: 34nC, Rds_on bei GS=4.5V: max. 4.0mOhm&lt;br /&gt;
| [http://www.flymotec.de/]&lt;br /&gt;
| 0.70&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF1010N IRF1010N]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 4&lt;br /&gt;
| 55&lt;br /&gt;
| 85&lt;br /&gt;
| 180&lt;br /&gt;
| 11&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Farnell|Far]]&lt;br /&gt;
| 1.99&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF1010Z IRF1010Z]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 4&lt;br /&gt;
| 55&lt;br /&gt;
| 75&lt;br /&gt;
| 140&lt;br /&gt;
| 7.5&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Conrad|Con]], [[Elektronikversender#Farnell|Far]]&lt;br /&gt;
| 1.99&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRLIZ44N IRLIZ44N]&lt;br /&gt;
| TO-220-Fullpak &lt;br /&gt;
| irf&lt;br /&gt;
| 1.0 - 2.0&lt;br /&gt;
| 55&lt;br /&gt;
| 30&lt;br /&gt;
| 45&lt;br /&gt;
| 25&lt;br /&gt;
| Logic Level&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0.80&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRLU024N IRLU024N]&lt;br /&gt;
| TO-251AA&lt;br /&gt;
| irf&lt;br /&gt;
| 1.0 - 2.0&lt;br /&gt;
| 55&lt;br /&gt;
| 17&lt;br /&gt;
| 45&lt;br /&gt;
| 80&lt;br /&gt;
| Logic Level, Q&amp;lt;sub&amp;gt;g&amp;lt;/sub&amp;gt;=15 nC (!)&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0.40&lt;br /&gt;
|-&lt;br /&gt;
| IRFZ48N&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 3&lt;br /&gt;
| 55&lt;br /&gt;
| 64&lt;br /&gt;
| 130&lt;br /&gt;
| 14&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0.60&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.irf.com/product-info/datasheets/data/irl2505.pdf IRL2505]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 2,5&lt;br /&gt;
| 55&lt;br /&gt;
| 104&lt;br /&gt;
| &lt;br /&gt;
| 8&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Farnell|Far]]&lt;br /&gt;
| 3.99&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.irf.com/product-info/datasheets/data/irf7607.pdf IRF7607]&lt;br /&gt;
| Micro8&lt;br /&gt;
| irf&lt;br /&gt;
| 12&lt;br /&gt;
| 20&lt;br /&gt;
| 6.5&lt;br /&gt;
| 1.8&lt;br /&gt;
| 3&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 1.89&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.irf.com/product-info/datasheets/data/irf3708.pdf IRF3708]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 12&lt;br /&gt;
| 30&lt;br /&gt;
| 62&lt;br /&gt;
| 87&lt;br /&gt;
| 8&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 1.49&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/GF2304 GF2304]&lt;br /&gt;
| SOT-23&lt;br /&gt;
| gs&lt;br /&gt;
| 1.0&lt;br /&gt;
| 30&lt;br /&gt;
| 2.5&lt;br /&gt;
| 1.25&lt;br /&gt;
| 135&lt;br /&gt;
| Qg=3.7nC&lt;br /&gt;
| [[Elektronikversender#Pollin_Electronic|Pol]]&lt;br /&gt;
| 0.05&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
(Tabelle mit Click im Kopfbereich sortierbar, a.A.=Auf Anfrage)&lt;br /&gt;
&lt;br /&gt;
== N-Kanal J-FET==&lt;br /&gt;
&lt;br /&gt;
{| {{Tabelle}} border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;fetpaare&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#eeeeee&amp;quot;&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Package&lt;br /&gt;
! Hersteller&lt;br /&gt;
! U&amp;lt;sub&amp;gt;GS(co)&amp;lt;/sub&amp;gt;/V&lt;br /&gt;
! U&amp;lt;sub&amp;gt;DS&amp;lt;/sub&amp;gt;/V&lt;br /&gt;
! I&amp;lt;sub&amp;gt;D(max)&amp;lt;/sub&amp;gt;/mA&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Einzelpreis&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BF245 BF245A]&lt;br /&gt;
| TO-92&lt;br /&gt;
| diverse&lt;br /&gt;
| -2,2&lt;br /&gt;
| 30&lt;br /&gt;
| 6,5&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,15 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BF245 BF245B]&lt;br /&gt;
| TO-92&lt;br /&gt;
| diverse&lt;br /&gt;
| -3,8&lt;br /&gt;
| 30&lt;br /&gt;
| 15&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,15 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BF245 BF245C]&lt;br /&gt;
| TO-92&lt;br /&gt;
| diverse&lt;br /&gt;
| -7,5&lt;br /&gt;
| 30&lt;br /&gt;
| 25&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,15 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BF246 BF246A]&lt;br /&gt;
| TO-92&lt;br /&gt;
| diverse&lt;br /&gt;
| -4&lt;br /&gt;
| 25&lt;br /&gt;
| 80&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,15 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BF246 BF246B]&lt;br /&gt;
| TO-92&lt;br /&gt;
| diverse&lt;br /&gt;
| -7&lt;br /&gt;
| 25&lt;br /&gt;
| 140&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,17 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BF246 BF246C]&lt;br /&gt;
| TO-92&lt;br /&gt;
| diverse&lt;br /&gt;
| -12&lt;br /&gt;
| 25&lt;br /&gt;
| 250&lt;br /&gt;
| ??&lt;br /&gt;
| ??&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BF511 BF511]&lt;br /&gt;
| SOT-23&lt;br /&gt;
| diverse&lt;br /&gt;
| -1,5&lt;br /&gt;
| 20&lt;br /&gt;
| 7&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,36 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BFR30 BFR30]&lt;br /&gt;
| SOT-23&lt;br /&gt;
| diverse&lt;br /&gt;
| -4&lt;br /&gt;
| 25&lt;br /&gt;
| 10&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BFR31 BFR31]&lt;br /&gt;
| SOT-23&lt;br /&gt;
| diverse&lt;br /&gt;
| -2&lt;br /&gt;
| 25&lt;br /&gt;
| 5&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/MMBF4416 MMBF4416]&lt;br /&gt;
| SOT-23&lt;br /&gt;
| Fairchild&lt;br /&gt;
| -5,5&lt;br /&gt;
| 15&lt;br /&gt;
| 5&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0,52 €&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
(Tabelle mit Click im Kopfbereich sortierbar)&lt;br /&gt;
&lt;br /&gt;
== FET-Paare ==&lt;br /&gt;
&lt;br /&gt;
{| {{Tabelle}} border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;fetpaare&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#eeeeee&amp;quot;&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Package&lt;br /&gt;
! Hersteller&lt;br /&gt;
! UGS/V&lt;br /&gt;
! UDS/V&lt;br /&gt;
! ID/A&lt;br /&gt;
! P/W&lt;br /&gt;
! RDSon/mOhm&lt;br /&gt;
! Bemerkung&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Einzelpreis&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7389 IRF7389]&lt;br /&gt;
| SO-8&lt;br /&gt;
| IRF&lt;br /&gt;
| 3,0&lt;br /&gt;
| 30&lt;br /&gt;
| 7,3/-5,3&lt;br /&gt;
| 2,0&lt;br /&gt;
| 29/58&lt;br /&gt;
| P+N&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,56 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7501 IRF7501]&lt;br /&gt;
| micro8&lt;br /&gt;
| IRF&lt;br /&gt;
| 2,7&lt;br /&gt;
| 20&lt;br /&gt;
| 2,4&lt;br /&gt;
| ?&lt;br /&gt;
| 135 @4,5V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;&lt;br /&gt;
| 2*N&lt;br /&gt;
| [[Elektronikversender#Kessler|Kessler]], [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 1,64 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7506 IRF7506]&lt;br /&gt;
| micro8&lt;br /&gt;
| IRF&lt;br /&gt;
| 4,5&lt;br /&gt;
| 30&lt;br /&gt;
| 1,7&lt;br /&gt;
| ?&lt;br /&gt;
| 270 @10V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;&lt;br /&gt;
| 2*P&lt;br /&gt;
| [[Elektronikversender#Kessler|Kessler]], [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0,56 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7103 IRF7103]&lt;br /&gt;
| SO-8&lt;br /&gt;
| IRF&lt;br /&gt;
| 4,5&lt;br /&gt;
| 50&lt;br /&gt;
| 2,3&lt;br /&gt;
| 2&lt;br /&gt;
| 130 @10V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;&lt;br /&gt;
| 2*N&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]], [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0,32 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7104 IRF7104]&lt;br /&gt;
| SO-8&lt;br /&gt;
| IRF&lt;br /&gt;
| 4,5&lt;br /&gt;
| 20&lt;br /&gt;
| 2,3&lt;br /&gt;
| 2&lt;br /&gt;
| 250 @10V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;&lt;br /&gt;
| 2*P&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,32 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7316 IRF7316]&lt;br /&gt;
| SO-8&lt;br /&gt;
| IRF&lt;br /&gt;
| 4,5&lt;br /&gt;
| 30&lt;br /&gt;
| 4,9&lt;br /&gt;
| ?&lt;br /&gt;
| 58 @10V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;&lt;br /&gt;
| 2*P&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,49 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7313 IRF7313]&lt;br /&gt;
| SO-8&lt;br /&gt;
| IRF&lt;br /&gt;
| 4,5&lt;br /&gt;
| 30&lt;br /&gt;
| 6,5&lt;br /&gt;
| ?&lt;br /&gt;
| 46 @4.5V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;&lt;br /&gt;
| 2*N&lt;br /&gt;
| [[Elektronikversender#Kessler|Kessler]], [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0,66 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/FDD8424H FDD8424H]&lt;br /&gt;
| Dual DPAK4L&lt;br /&gt;
| Fairchild&lt;br /&gt;
| &lt;br /&gt;
| 40&lt;br /&gt;
| 9/-6,5&lt;br /&gt;
| 3&lt;br /&gt;
| 24/54 @10V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt; &amp;lt;br&amp;gt; 30/70 @4,5V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;&lt;br /&gt;
| P+N&lt;br /&gt;
| [[Elektronikversender#Digi-Key|Digi-Key]] &lt;br /&gt;
| 0,73 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/SUD50NP04-94 SUD50NP04-94]&lt;br /&gt;
| TO252-4L DPAK4L&lt;br /&gt;
| Vishay&lt;br /&gt;
| 2&lt;br /&gt;
| 40 &lt;br /&gt;
| 8&lt;br /&gt;
| 8?&lt;br /&gt;
| 41/53 @10V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt; &amp;lt;br&amp;gt; 45/72 @4,5V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;&lt;br /&gt;
| P+N&lt;br /&gt;
| [[Elektronikversender#Farnell|Farnell]]&lt;br /&gt;
| 0,56 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRFI4024H-117P IRFI4024H-117P]&lt;br /&gt;
| TO-220-5&lt;br /&gt;
| IRF&lt;br /&gt;
| 2&lt;br /&gt;
| 55&lt;br /&gt;
| 11&lt;br /&gt;
| 14&lt;br /&gt;
| 50 @10V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;&lt;br /&gt;
| 2*N&lt;br /&gt;
| [[Elektronikversender#Reichelt|Reichelt]]&lt;br /&gt;
| 2,10 €&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
(Tabelle mit Click im Kopfbereich sortierbar)&lt;br /&gt;
&lt;br /&gt;
== MOSFET-Treiber ==&lt;br /&gt;
* Detaillierte [[Treiber]]-Dimensionierung&lt;br /&gt;
{| {{Tabelle}} border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;fettreiber&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#eeeeee&amp;quot;&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Low / High-Side&lt;br /&gt;
! Strom&lt;br /&gt;
! Spannung&lt;br /&gt;
! Logikeingang&lt;br /&gt;
! Sockel&lt;br /&gt;
! Lieferant / Datenblatt&lt;br /&gt;
! Einzelpreis&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2101 IR2101]&lt;br /&gt;
| High &amp;amp; Low-Side Driver&lt;br /&gt;
| 130/270mA&lt;br /&gt;
| 600V&lt;br /&gt;
| 3,3V&lt;br /&gt;
| DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 2,30 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2104 IR2104]&lt;br /&gt;
| Half Bridge Driver&lt;br /&gt;
| 130/270mA&lt;br /&gt;
| 600V&lt;br /&gt;
| 3,3V&lt;br /&gt;
| DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 2,00 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2110 IR2110]&lt;br /&gt;
| High &amp;amp; Low-Side Driver&lt;br /&gt;
| 2A&lt;br /&gt;
| 500V&lt;br /&gt;
| 3,3V&lt;br /&gt;
| DIL14/SO16&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 1,55 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2111 IR2111]&lt;br /&gt;
| Half Bridge Driver&lt;br /&gt;
| 200/430mA&lt;br /&gt;
| 600V&lt;br /&gt;
| 10-20V CMOS Eingang&lt;br /&gt;
| DIL8/SO8, maximale Kriechwege&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 1,10 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2112 IR2112]&lt;br /&gt;
| High &amp;amp; Low-Side Driver&lt;br /&gt;
| 200/420mA&lt;br /&gt;
| 600V&lt;br /&gt;
| 3,3V&lt;br /&gt;
| DIL14/SO16&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 1,45 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2113 IR2113]&lt;br /&gt;
| High &amp;amp; Low-Side Driver&lt;br /&gt;
| 2A&lt;br /&gt;
| 600V&lt;br /&gt;
| 3,3V&lt;br /&gt;
| DIL14/SO16&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 1,85 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2117 IR2117]&lt;br /&gt;
| Single High Side Driver&lt;br /&gt;
| 200/420mA&lt;br /&gt;
| 600V&lt;br /&gt;
| 10-20V CMOS Eingang&lt;br /&gt;
| DIL8/SO8, maximale Kriechwege&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 1,20 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2121 IR2121]&lt;br /&gt;
| Low Side Driver&lt;br /&gt;
| 1A/2A&lt;br /&gt;
| ?&lt;br /&gt;
| 2,5V&lt;br /&gt;
| DIL8/SO8, Strombegrenzung&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 2,15 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2125 IR2125]&lt;br /&gt;
| Single Channel High Side Driver&lt;br /&gt;
| 1A/2A&lt;br /&gt;
| 500V&lt;br /&gt;
| 2,5V&lt;br /&gt;
| DIL8/SO8, Strombegrenzung, maximale Kriechwege&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 4,20 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2127 IR2127]&lt;br /&gt;
| Single Channel High Side Driver&lt;br /&gt;
| 200/420mA&lt;br /&gt;
| ?&lt;br /&gt;
| 3,3V&lt;br /&gt;
| DIL8/SO8, maximale Kriechwege, Fehlerausgang&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 2,40 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2130 IR2130]&lt;br /&gt;
| 3-Phase Bridge Driver&lt;br /&gt;
| 200/420mA&lt;br /&gt;
| 600V&lt;br /&gt;
| 2,5V&lt;br /&gt;
| DIL28/SO28&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 2,50 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2151 IR2151]&lt;br /&gt;
| Self Oscillating Half Bridge Driver&lt;br /&gt;
| 100/210mA&lt;br /&gt;
| 600V&lt;br /&gt;
| ?&lt;br /&gt;
| DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 2,50 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2153 IR2153]&lt;br /&gt;
| Self Oscillating Half Bridge Driver&lt;br /&gt;
| 100/210mA&lt;br /&gt;
| 600V&lt;br /&gt;
| n/a&lt;br /&gt;
| DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 1,20 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2155 IR2155]&lt;br /&gt;
| Self Oscillating Half Bridge Driver&lt;br /&gt;
| 210/420mA&lt;br /&gt;
| 600V&lt;br /&gt;
| n/a&lt;br /&gt;
| DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 3,50 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2181 IR2181]&lt;br /&gt;
| High &amp;amp; Low-Side Driver&lt;br /&gt;
| 1.4A/1.8A&lt;br /&gt;
| 600V&lt;br /&gt;
| 3,3V&lt;br /&gt;
| DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 2,10 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2183 IR2183]&lt;br /&gt;
| Half Bridge Driver&lt;br /&gt;
| 1.4A/1.8A&lt;br /&gt;
| 600V&lt;br /&gt;
| 3,3V&lt;br /&gt;
| DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 4,00 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2184 IR2184]&lt;br /&gt;
| Half Bridge Driver&lt;br /&gt;
| 1.4A/1.8A&lt;br /&gt;
| 600V&lt;br /&gt;
| 3,3V/5V&lt;br /&gt;
| DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 3,20 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2136 IR2136]&lt;br /&gt;
| 3 Phase Driver&lt;br /&gt;
| 120/250mA&lt;br /&gt;
| 600V&lt;br /&gt;
| 3,3V&lt;br /&gt;
| DIP28/SOIC28,&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 1,80 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/ICL7667 ICL7667]&lt;br /&gt;
| Dual Power MOSFET Driver&lt;br /&gt;
| ?&lt;br /&gt;
| 4.5-15V, 7Ω&lt;br /&gt;
| 3,3V&lt;br /&gt;
| DIL8/SO8 &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 2,00 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/HIP4081A HIP4081A]&lt;br /&gt;
| Full Bridge Driver&lt;br /&gt;
| 2,5A&lt;br /&gt;
| 80V&lt;br /&gt;
| ?&lt;br /&gt;
| DIP20/SOIC20&lt;br /&gt;
| [[Elektronikversender#Farnell|Far]]&lt;br /&gt;
| 8,00 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/HIP4082 HIP4082]&lt;br /&gt;
| Full Bridge Driver&lt;br /&gt;
| 1,2A&lt;br /&gt;
| 80V&lt;br /&gt;
| ?&lt;br /&gt;
| DIP16/SOIC16&lt;br /&gt;
| [[Elektronikversender#Farnell|Far]] [[Elektronikversender#Farnell|Far]]&lt;br /&gt;
| 6,20 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/HIP4083 HIP4083]&lt;br /&gt;
| 3 Phase High side N-channel MOSFET driver&lt;br /&gt;
| 0,3A&lt;br /&gt;
| 80V&lt;br /&gt;
| ?&lt;br /&gt;
| DIP16/SOIC16&lt;br /&gt;
| [[Elektronikversender#Farnell|Far]]&lt;br /&gt;
| 4,80 €&lt;br /&gt;
&amp;lt;!-- ohne Preis und Lieferant&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/HIP4084 HIP4084]&lt;br /&gt;
| 4 Phase Driver&lt;br /&gt;
| 0,5A&lt;br /&gt;
| 80V&lt;br /&gt;
| ?&lt;br /&gt;
| DIP28/SOIC28&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/HIP4086 HIP4086]&lt;br /&gt;
| 3 Phase Driver&lt;br /&gt;
| 0.5A&lt;br /&gt;
| 80V&lt;br /&gt;
| ?&lt;br /&gt;
| DIP24/SOIC24&lt;br /&gt;
| [[Elektronikversender#Farnell|Far]]&lt;br /&gt;
| 8,00 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/TC4451 TC4451/TC4452]&lt;br /&gt;
| High Speed MOSFET Driver&lt;br /&gt;
| 12A peak, 2,5A DC&lt;br /&gt;
| ?&lt;br /&gt;
| 4,5-18V&lt;br /&gt;
| DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Farnell|Far]]&lt;br /&gt;
| 3,00 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/LM5104 LM5104]&lt;br /&gt;
| Half Bridge Driver&lt;br /&gt;
| 1,6/1,8A&lt;br /&gt;
| 100V&lt;br /&gt;
| 2,5V&lt;br /&gt;
| SO8/LLP10 &lt;br /&gt;
| [[Elektronikversender#RS_Components|RS]]&lt;br /&gt;
| 3,20 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/MCP1407 MCP1407-E/P]&lt;br /&gt;
| High Speed MOSFET Driver&lt;br /&gt;
| 6A peak, 1,3A DC&lt;br /&gt;
| ?&lt;br /&gt;
| 4,5-18V&lt;br /&gt;
| DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,95 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/MAX626 MAX626]&lt;br /&gt;
| Dual Power MOSFET drivers, inverting&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| 4,5-18 V&lt;br /&gt;
| DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 3,40 €&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Anmerkungen ==&lt;br /&gt;
* U&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt; - minimale Gatespannung, bei welcher der MOSFET zu leiten anfängt (100µA..1mA, nicht genormt). Zur vollständigen Durchschaltung bei maximalem Strom braucht es höhere Spannungen.&lt;br /&gt;
* Logic Level - FET schaltet bei niedrigen Gatespannungen von typisch 4,5V (z.&amp;amp;nbsp;B. CMOS Logikpegel) hinreichend durch. Normale MOSFETs brauchen hierfür typisch 10V.&lt;br /&gt;
* U&amp;lt;sub&amp;gt;GS(co)&amp;lt;/sub&amp;gt; - Gate Source Cut Off Spannung, bei welcher der Drainstrom I&amp;lt;sub&amp;gt;D&amp;lt;/sub&amp;gt; eines JFETs praktisch Null ist. Die Messbedingung ist jedoch nicht genormt (0,5nA..200µA).&lt;br /&gt;
* N-Kanal MOSFETs mit niedrigem R&amp;lt;sub&amp;gt;DS,On&amp;lt;/sub&amp;gt; sind technologisch einfacher herzustellen als P-Kanal MOSFETs. Deshalb gibt es bei P-Kanal keine so große Auswahl und oft werden Schaltungen angestrebt, in denen ausschließlich N-Kanal MOSFETs verwendet werden. Es gibt spezielle Treiberbausteine, die über eine Ladungspumpe für entsprechend hohe Gatespannung auch für die High-Side N-Fets sorgen (&amp;quot;Bootstrap Circuits&amp;quot;, siehe Artikel [[Treiber]]).&lt;br /&gt;
* Bei der Dimensionierung ist zu beachten, dass die Stromangabe im allgemeinen für 25°C gilt. Geht man davon aus, dass der MOSFET mit maximal zulässigem Strom betrieben wird und mit passend dimensioniertem [[Kühlkörper]] ausgestattet ist, so beträgt die Sperrschichttemperatur bis zu 150°C, folglich gilt z.&amp;amp;nbsp;B. für den IRF540 nicht mehr 28A, sondern nur noch ca. 12-15A.&lt;br /&gt;
* Restströme sind auch stark von der Temperatur abhängig. Bei höherer Temperatur nehmen die Restströme exponentiell zu. So können bei 100°C durchaus 100 µA zwischen Source und Drain auch im gesperrten Zustand fließen. Bei 25°C ist dieser Reststrom meist bei 1µA spezifiziert. Real sind es meist weniger.&lt;br /&gt;
* Der Gate-Charge-Wert Qg (s. Datenblatt) bestimmt, wie schnell das Gate beim Schalten umgeladen werden kann. Auch wenn MOSFETs stromlos den durchgeschalteten Zustand halten können, braucht man während des Umschaltvorganges einen Strom, der das Gate umlädt (ähnlich wie ein Kondensator). Je höher dieser Strom, um so schneller ist der Umschaltvorgang und um so geringer die Verlustleistung während dieser Phase. Leistungs-MOSFETs können bei höheren Frequenzen (&amp;gt;1KHz) oft nur mit höheren Gateströmen von 0,1A-2A sinnvoll geschaltet werden. Man kann das Gate also nicht direkt an einen Digitalpin anschließen. Man braucht einen [[MOSFET-Übersicht#MOSFET-Treiber | MOSFET-Treiber]]. Manche MOSFETs haben eine sehr geringe Total Gate Charge (z.&amp;amp;nbsp;B. 4-10nC). Diese können in gewissen Grenzen recht gut direkt an digitalen [[Ausgangsstufen Logik-ICs | Logikausgängen]] betrieben werden. Zur Abschätzung kann man sich merken: Wenn man das Gate eines MOSFETs mit einer Eingangskapazität von 1nF (~10nC) in 100ns auf 10V aufladen will, braucht man dazu 100mA.&lt;br /&gt;
&lt;br /&gt;
== Lieferantenübersicht ==&lt;br /&gt;
* [[Elektronikversender#Reichelt|Rei]]&amp;lt;nowiki&amp;gt;chelt&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* [[Elektronikversender#Conrad|Con]]&amp;lt;nowiki&amp;gt;rad&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* [[Elektronikversender#Kessler|Kes]]&amp;lt;nowiki&amp;gt;sler&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* [[Elektronikversender#csd-electronics|csd]]&amp;lt;nowiki&amp;gt;-electronics&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* [[Elektronikversender#Farnell|Far]]&amp;lt;nowiki&amp;gt;nell&amp;lt;/nowiki&amp;gt; (nur gewerbliche Kunden oder Studenten)&lt;br /&gt;
* HBE-Shop (FARNELL-Fachhändler, auch als nichtgewerblicher Kunde)&lt;br /&gt;
* [[Elektronikversender#Schuricht|Schu]]&amp;lt;nowiki&amp;gt;richt&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* [[Elektronikversender#RS_Components|RS]]&lt;br /&gt;
* [[Elektronikversender#Spoerle|Spo]]&amp;lt;nowiki&amp;gt;erle&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Herstellerübersicht ==&lt;br /&gt;
* [irf] [http://www.irf.com International Rectifier]&lt;br /&gt;
* [Siliconix] [http://www.vishay.com/company/brands/siliconix/ Vishay Siliconix]&lt;br /&gt;
* [st] [http://www.st.com/web/en/home.html STMicroelectronics]&lt;br /&gt;
&lt;br /&gt;
== IRF MOSFET-Codierung ==&lt;br /&gt;
* IRF: Alle &amp;quot;Standardtransistoren&amp;quot;, also TO-220-Gehäuse&lt;br /&gt;
* IRFB: Hochspannungs-MosFETs&lt;br /&gt;
* IRFD: MosFETs im Dip-4-Gehäuse&lt;br /&gt;
* IRFI: MosFETs im isolierten TO-220-Gehäuse&lt;br /&gt;
* IRFP: MosFETs im TO-247AC-Gehäuse&lt;br /&gt;
* IRFR: MosFETs im D-Pak&lt;br /&gt;
* IRFU: MosFETs im I-Pak&lt;br /&gt;
* IRFZ: Also die die ich kenne liegen alle so bei 50-60V mit relativ niedrigem Rds(on), also so für mittlere Leistungen&lt;br /&gt;
* IRG:  Afaik sind das IGBTs&lt;br /&gt;
* IRL:  Logic-Level MosFETs&lt;br /&gt;
* IRLD: Logic-Level MosFETs im Dip-4 Gehäuse&lt;br /&gt;
* IRLI: Logic-Level MosFETs im isolierten TO-220-Gehäuse&lt;br /&gt;
* IRLR: Logic-Level MosFETs im D-Pak&lt;br /&gt;
* IRLU: Logic-Level MosFETs im I-Pak&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* [[FET]]&lt;br /&gt;
* [[IGBT]]&lt;br /&gt;
* [[Treiber]]&lt;br /&gt;
* [[H-Brücken Übersicht]]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/280480#2960070 Forumsbeitrag]: Clevere MOSFET-Treiber mit kleinsten Trafos&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/283585#3004839 Forumsbeitrag]: Galvanisch getrennte Ansteuerung eines MOSFETs mittels Übertrager und 100% Tastverhältnis&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://www.sprut.de/electronic/switch/nkanal/nkanal.html N-Kanal MOSFET leicht erklärt bei sprut.de]&lt;br /&gt;
* [http://www.sprut.de/electronic/switch/pkanal/pkanal.html P-Kanal MOSFET leicht erklärt bei sprut.de]&lt;br /&gt;
* [http://elektronik-kompendium.de/sites/bau/0510161.htm MOSFET im ElKo]&lt;br /&gt;
* [http://elektronik-kompendium.de/public/schaerer/battoff.htm Abschaltverzögerung beim ElKo]&lt;br /&gt;
* [http://elektronik-kompendium.de/sites/bau/0207011.htm FET beim ElKo]&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Mosfet MOSFET bei Wikipedia]&lt;br /&gt;
&amp;lt;!-- * [http://www.irf.com/product-info/auto/autogdic.html IR21xx Familienvergleich] --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Parametrische Suche beim Hersteller ==&lt;br /&gt;
* [http://www.infineon.com/cms/de/product/channel.html?channel=db3a304319c6f18c011a14e5341b25f1 Infineon]&lt;br /&gt;
* [http://www.nxp.com/#/ps/ps=%5Bi%3D48014%5D%7Cpp%3D%5Bt%3Dpfp%2Ci%3D48014%5D NXP standard Mosfets]&lt;br /&gt;
* [http://www.onsemi.com/PowerSolutions/parametrics.do?id=809&amp;amp;lctn=home ONsemi]&lt;br /&gt;
* [http://www.diodes.com/zetex/?ztx=3.0/3-3-1@tcatid~7 Diodes (vormals Zetex)]&lt;br /&gt;
* [http://www.irf.com/product-info/hexfet/ IRF]&lt;br /&gt;
* [http://www.vishay.com/mosfets/ Vishay]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Liste mit Bauteilen]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=ATxMega_Stick_-_First_Steps&amp;diff=69354</id>
		<title>ATxMega Stick - First Steps</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=ATxMega_Stick_-_First_Steps&amp;diff=69354"/>
		<updated>2012-11-29T18:45:23Z</updated>

		<summary type="html">&lt;p&gt;Maybee: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Datei:ATxMegaStick-1.jpg|thumb|Platine des ATxMega Stick]]&lt;br /&gt;
[[Datei:ATxMegaStick_revC-p1.png|thumb|Schaltplan - Seite 1]]&lt;br /&gt;
[[Datei:ATxMegaStick_revC-p2.png|thumb|Schaltplan - Seite 2]]&lt;br /&gt;
Der ATxMega Stick ist eine kleine Platine (27 mm x 80 mm) mit ATxmega128A3, USB-Device-Anschluss und Micro-SD-Kartenslot.&lt;br /&gt;
&lt;br /&gt;
== Eigenschaften ==&lt;br /&gt;
&lt;br /&gt;
* Mikrocontroller ATxmega128A3&lt;br /&gt;
* USB-Baustein [http://kweb/wiki/images/b/ba/MCP2200_22228A.pdf MCP2200]&lt;br /&gt;
* Mini-USB-B-Device-Anschluss&lt;br /&gt;
* Micro-SD-Kartenslot&lt;br /&gt;
* Programmierung via PDI (z.B. AVRISP mkII)&lt;br /&gt;
* Reset-Taster&lt;br /&gt;
* 2 LEDs zur Signalisierung von USB-Transfers&lt;br /&gt;
* 2 frei verwendbare LEDs&lt;br /&gt;
* On-board-Spannungsregler (3.3 V, Versorgung über USB oder extern)&lt;br /&gt;
* 6 x 8-Bit-Ports auf Stiftleisten verfügbar, davon ist ein Port belegt (2-mal LED, RX und TX zum USB-Baustein, SPI zum Micro-SD-Kartenslot)&lt;br /&gt;
&lt;br /&gt;
== Hinweise zum Aufbau ==&lt;br /&gt;
&lt;br /&gt;
=== Anmerkungen zum Schaltplan vom 15.09.2011 23:08:38 ===&lt;br /&gt;
&lt;br /&gt;
* Seite 1: C1 hat 22µF&amp;lt;br&amp;gt;&lt;br /&gt;
* Seite 1: C14, C15 haben 3.3µF&lt;br /&gt;
* Seite 2: Verbindungsbezeichnung bei &amp;quot;&amp;lt;tt&amp;gt;I/Os&amp;lt;/tt&amp;gt;&amp;quot; µC Pin 27 und JP4 Pin 4 und bei &amp;quot;&amp;lt;tt&amp;gt;LEDs&amp;lt;/tt&amp;gt;&amp;quot; muss &amp;lt;tt&amp;gt;LED3&amp;lt;/tt&amp;gt; lauten statt &amp;lt;tt&amp;gt;LED1&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Seite 2: Verbindungsbezeichnung bei &amp;quot;&amp;lt;tt&amp;gt;I/Os&amp;lt;/tt&amp;gt;&amp;quot; µC Pin 26 und JP4 Pin 3 und bei &amp;quot;&amp;lt;tt&amp;gt;LEDs&amp;lt;/tt&amp;gt;&amp;quot; muss &amp;lt;tt&amp;gt;LED4&amp;lt;/tt&amp;gt; lauten statt &amp;lt;tt&amp;gt;LED2&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stromversorgung ===&lt;br /&gt;
&lt;br /&gt;
Auf JP1 muss ein Jumper bestückt werden:&lt;br /&gt;
* zum Platinenrand hin für Versorgung über USB&lt;br /&gt;
* zur Platinenmitte hin für externe Versorgung&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Hinweis:&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Jumper sollte unbedingt gesteckt sein, wenn USB verwendet wird. Steht dieser auf externer Versorung, muss diese dabei auch anliegen. Wird der MCP2200 per USB versorgt, ohne dass am ATxMega Versorgungsspannung anliegt, kommt es über die UART-Leitung zu einem Stromfluss über das entsprechende I/O-Pin des ATxMega, da dieser sich ohne Spannung intern in einem undefinierten Zustand befindet. Auf VCC liegen dann etwa 2.8 V an. Durch den Stromfluss erwärmt sich der MCP2200 deutlich, was zur eventuellen Beschädigung des ICs führen kann.&lt;br /&gt;
&lt;br /&gt;
=== Löten des SD-Halters ===&lt;br /&gt;
&lt;br /&gt;
* Zuerst muss man den Halten ausrichen und einen Punkt am Rand festlöten.&lt;br /&gt;
* Dann muss man alle 4 Ecken festlöten&lt;br /&gt;
* Jetzt kann man mit der Lötspitze oben durch die Aussparungen und führt den Zinn durch die Öffnung für die SD-Karte.&lt;br /&gt;
* So lötet man dann alle 8 Kontakte.&lt;br /&gt;
* Lötbrücken sind hier nicht schön, lässt sich aber dann noch mit Entlötlitze entfernen (Entlötlitze statt Zinn durch die Öffnung führen)&lt;br /&gt;
&lt;br /&gt;
== Betrieb unter Linux ==&lt;br /&gt;
&lt;br /&gt;
Damit man als User auf den Stick zugreifen kann, empfiehlt es sich, einen UDEV-Eintrag für den Stick anzulegen, z.B. neue Datei /etc/udev/rules.d/15_USB_uC.rules anlegen:&lt;br /&gt;
&lt;br /&gt;
 ATTRS{idVendor}==&amp;quot;04d8&amp;quot;, ATTRS{idProduct}==&amp;quot;00df&amp;quot;, GROUP=&amp;quot;MeineGruppe&amp;quot;, MODE=&amp;quot;0660&amp;quot;, SYMLINK+=&amp;quot;ATxMegaStick%n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Für &amp;quot;MeineGruppe&amp;quot; einen geeigneten Werte verwenden, d.h. eine Gruppe, der man selbst angehört.&lt;br /&gt;
&lt;br /&gt;
Jetzt kann man nach dem Anschließen folgende Links sehen:&lt;br /&gt;
&lt;br /&gt;
 ls -l /dev/ATxMegaStick*&lt;br /&gt;
 lrwxrwxrwx 1 root root  7 2011-10-17 00:04 /dev/ATxMegaStick0 -&amp;gt; ttyACM0&lt;br /&gt;
 lrwxrwxrwx 1 root root 11 2011-10-17 00:04 /dev/ATxMegaStick1 -&amp;gt; usb/hiddev1&lt;br /&gt;
 lrwxrwxrwx 1 root root  7 2011-10-17 00:04 /dev/ATxMegaStick2 -&amp;gt; hidraw2&lt;br /&gt;
 lrwxrwxrwx 1 root root 15 2011-10-17 00:04 /dev/ATxMegaStick3 -&amp;gt; bus/usb/001/042&lt;br /&gt;
&lt;br /&gt;
Und die Zugriffrechte sehen so aus:&lt;br /&gt;
&lt;br /&gt;
 ls -lL /dev/ATxMegaStick*&lt;br /&gt;
 crw-rw---- 1 root dialout 166,  0 2011-10-17 00:04 /dev/ATxMegaStick0&lt;br /&gt;
 crw-rw---- 1 root mgr     180, 97 2011-10-17 00:04 /dev/ATxMegaStick1&lt;br /&gt;
 crw-rw---- 1 root mgr     251,  2 2011-10-17 00:04 /dev/ATxMegaStick2&lt;br /&gt;
 crw-rw-r-- 1 root mgr     189, 41 2011-10-17 00:04 /dev/ATxMegaStick3&lt;br /&gt;
&lt;br /&gt;
== Fuses ==&lt;br /&gt;
&lt;br /&gt;
Default-Werte der Fuses:&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;signature&amp;lt;/tt&amp;gt;: Signatur ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U signature:r:-:h&lt;br /&gt;
 0x1e,0x97,0x42&lt;br /&gt;
:0x1e9742 = ATxmega128A3&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse0&amp;lt;/tt&amp;gt;: JTAG User ID ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse0:r:-:h&lt;br /&gt;
 0xff&lt;br /&gt;
:JTAG User ID (JTAGUID) = 0xff &#039;&#039;&#039;(das Manual sagt: 0x00)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse1&amp;lt;/tt&amp;gt;: Watchdog Configuration ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse1:r:-:h&lt;br /&gt;
 0x0&lt;br /&gt;
:Watchdog Window Timeout Period (WDWPER) = n.a.&lt;br /&gt;
:Watchdog Timeout Period (WDPER) = n.a.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse2&amp;lt;/tt&amp;gt;: Reset Configuration ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse2:r:-:h&lt;br /&gt;
 0xff&lt;br /&gt;
:Reset Vector (BOOTRST) = Application Reset&lt;br /&gt;
:BOD operation in power-down mode (BODPD) = BOD disabled&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse4&amp;lt;/tt&amp;gt;: Start-up Configuration ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse4:r:-:h&lt;br /&gt;
 0xfe&lt;br /&gt;
:External Reset Disable (RSTDISBL) = no&lt;br /&gt;
:Start-up time (STARTUPTIME) = 0&lt;br /&gt;
:Watchdog Timer lock (WDLOCK) = no&lt;br /&gt;
:JTAG enabled (JTAGEN) = yes&lt;br /&gt;
&lt;br /&gt;
Bei Bedarf ändern:&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse4:w:0xff:m&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse4:r:-:h&lt;br /&gt;
 0xff&lt;br /&gt;
:JTAG enabled (JTAGEN) = no&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse5&amp;lt;/tt&amp;gt;: BODACT, BODLEVEL, EESAVE ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse5:r:-:h&lt;br /&gt;
 0xff&lt;br /&gt;
:BOD operation in active mode (BODACT) = BOD disabled&lt;br /&gt;
:EEPROM memory is preserved through the Chip Erase (EESAVE) = no&lt;br /&gt;
:BOD voltage level (BODLEVEL) = 1.6V&lt;br /&gt;
&lt;br /&gt;
Bei Bedarf ändern:&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse5:w:0xf7:m&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse5:r:-:h&lt;br /&gt;
 0xf7&lt;br /&gt;
:EEPROM memory is preserved through the Chip Erase (EESAVE) = yes&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
=== Clock System ===&lt;br /&gt;
&lt;br /&gt;
Takt zu Testzwecken auf Port C Pin 7 (d.h. JP3 Pin 3) ausgeben.&lt;br /&gt;
 PORTC.DIRSET = 0x80;&lt;br /&gt;
 PORTCFG.CLKEVOUT = 0x01;&lt;br /&gt;
&lt;br /&gt;
==== 32 MHz mit dem externen Quarz ====&lt;br /&gt;
&lt;br /&gt;
Unter Verwendung der Software zu AVR1003 (-&amp;gt; Siehe auch) kann man den Takt auf 32 MHz einstellen:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;quot;clksys_driver.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 void init_clock( void )&lt;br /&gt;
 {&lt;br /&gt;
    CLKSYS_XOSC_Config( OSC_FRQRANGE_12TO16_gc, false, OSC_XOSCSEL_XTAL_16KCLK_gc );&lt;br /&gt;
    CLKSYS_Enable( OSC_XOSCEN_bm );&lt;br /&gt;
    CLKSYS_PLL_Config( OSC_PLLSRC_XOSC_gc, 2 );&lt;br /&gt;
    CLKSYS_Enable( OSC_PLLEN_bm );&lt;br /&gt;
    CLKSYS_Prescalers_Config( CLK_PSADIV_1_gc, CLK_PSBCDIV_1_1_gc );&lt;br /&gt;
    do {} while ( CLKSYS_IsReady( OSC_PLLRDY_bm ) == 0 );&lt;br /&gt;
    CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_PLL_gc );&lt;br /&gt;
    CLKSYS_Disable( OSC_XOSCEN_bm );&lt;br /&gt;
 } /* init_clock() */&lt;br /&gt;
&lt;br /&gt;
=== USART ===&lt;br /&gt;
&lt;br /&gt;
==== USART über USB ====&lt;br /&gt;
&lt;br /&gt;
So stellt man unter Verwendung der Software zu AVR1307 (-&amp;gt; Siehe auch) bei 32 MHz Takt den USART für die Übertragung per USB ein:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;quot;usart_driver.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #define USART USARTD0&lt;br /&gt;
 &lt;br /&gt;
 void init_usart( void )&lt;br /&gt;
 {&lt;br /&gt;
    PORTD.DIRSET = PIN3_bm;&lt;br /&gt;
    PORTD.DIRCLR = PIN2_bm;&lt;br /&gt;
    USART_Format_Set( &amp;amp;USART, USART_CHSIZE_8BIT_gc, USART_PMODE_DISABLED_gc, false );&lt;br /&gt;
    /*&lt;br /&gt;
     * BSEL[11:0]-Wert bei 32MHz Takt und BSCALE[3:0]==0:&lt;br /&gt;
     *   207 :   9600&lt;br /&gt;
     *   103 :  19200&lt;br /&gt;
     *    51 :  38400&lt;br /&gt;
     *    34 :  57600&lt;br /&gt;
     *    16 : 115200&lt;br /&gt;
     */&lt;br /&gt;
    USART_Baudrate_Set( &amp;amp;USART, 34 , 0 );&lt;br /&gt;
    USART_Rx_Enable( &amp;amp;USART );&lt;br /&gt;
    USART_Tx_Enable( &amp;amp;USART );&lt;br /&gt;
 } /* init_usart() */&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/227310 Ursprungsbeitrag im Forum]&lt;br /&gt;
* [http://www.jtronics.de/avr-projekte/xmega-tutorial.html XMEGA Tutorial in C] - Tutorial ATxmega (ATxmega128A3U)&lt;br /&gt;
* [http://www.atxmega-board.de/stick Die Seite des Sticks] mit Schaltplan und Stückliste&lt;br /&gt;
* &amp;lt;del&amp;gt;[http://www.stromflo.de/dokuwiki/doku.php?id=xmega-c-tutorial XMEGA-C-Tutorial auf stromflo.de]&amp;lt;/del&amp;gt; :-(&lt;br /&gt;
* [http://www.atmel.com/dyn/products/product_card.asp?part_id=4302 Produktseite des ATxmega128A3] mit jeder Menge an Dokumentation und Application Notes&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc8072.pdf AVR1003: Using the XMEGA Clock System] (PDF) und [http://www.atmel.com/dyn/resources/prod_documents/AVR1003.zip Software] (ZIP)&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc8049.pdf AVR1307: Using the XMEGA USART] (PDF) und [http://www.atmel.com/dyn/resources/prod_documents/AVR1307.zip Software] (ZIP)&lt;br /&gt;
* [http://www.microchip.com/wwwproducts/devices.aspx?dDocName=en546923 Produktseite des MCP2200] mit Dokumentation und Tools&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=ATxMega_Stick_-_First_Steps&amp;diff=69353</id>
		<title>ATxMega Stick - First Steps</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=ATxMega_Stick_-_First_Steps&amp;diff=69353"/>
		<updated>2012-11-29T18:40:19Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Schaltplan&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Datei:ATxMegaStick-1.jpg|thumb|Platine des ATxMega Stick]]&lt;br /&gt;
[[Datei:ATxMegaStick_revC-p1.png|thumb|Schaltplan - Seite 1]]&lt;br /&gt;
[[Datei:ATxMegaStick_revC-p2.png|thumb|Schaltplan - Seite 1]]&lt;br /&gt;
Der ATxMega Stick ist eine kleine Platine (27 mm x 80 mm) mit ATxmega128A3, USB-Device-Anschluss und Micro-SD-Kartenslot.&lt;br /&gt;
&lt;br /&gt;
== Eigenschaften ==&lt;br /&gt;
&lt;br /&gt;
* Mikrocontroller ATxmega128A3&lt;br /&gt;
* USB-Baustein [http://kweb/wiki/images/b/ba/MCP2200_22228A.pdf MCP2200]&lt;br /&gt;
* Mini-USB-B-Device-Anschluss&lt;br /&gt;
* Micro-SD-Kartenslot&lt;br /&gt;
* Programmierung via PDI (z.B. AVRISP mkII)&lt;br /&gt;
* Reset-Taster&lt;br /&gt;
* 2 LEDs zur Signalisierung von USB-Transfers&lt;br /&gt;
* 2 frei verwendbare LEDs&lt;br /&gt;
* On-board-Spannungsregler (3.3 V, Versorgung über USB oder extern)&lt;br /&gt;
* 6 x 8-Bit-Ports auf Stiftleisten verfügbar, davon ist ein Port belegt (2-mal LED, RX und TX zum USB-Baustein, SPI zum Micro-SD-Kartenslot)&lt;br /&gt;
&lt;br /&gt;
== Hinweise zum Aufbau ==&lt;br /&gt;
&lt;br /&gt;
=== Anmerkungen zum Schaltplan vom 15.09.2011 23:08:38 ===&lt;br /&gt;
&lt;br /&gt;
* Seite 1: C1 hat 22µF&amp;lt;br&amp;gt;&lt;br /&gt;
* Seite 1: C14, C15 haben 3.3µF&lt;br /&gt;
* Seite 2: Verbindungsbezeichnung bei &amp;quot;&amp;lt;tt&amp;gt;I/Os&amp;lt;/tt&amp;gt;&amp;quot; µC Pin 27 und JP4 Pin 4 und bei &amp;quot;&amp;lt;tt&amp;gt;LEDs&amp;lt;/tt&amp;gt;&amp;quot; muss &amp;lt;tt&amp;gt;LED3&amp;lt;/tt&amp;gt; lauten statt &amp;lt;tt&amp;gt;LED1&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Seite 2: Verbindungsbezeichnung bei &amp;quot;&amp;lt;tt&amp;gt;I/Os&amp;lt;/tt&amp;gt;&amp;quot; µC Pin 26 und JP4 Pin 3 und bei &amp;quot;&amp;lt;tt&amp;gt;LEDs&amp;lt;/tt&amp;gt;&amp;quot; muss &amp;lt;tt&amp;gt;LED4&amp;lt;/tt&amp;gt; lauten statt &amp;lt;tt&amp;gt;LED2&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stromversorgung ===&lt;br /&gt;
&lt;br /&gt;
Auf JP1 muss ein Jumper bestückt werden:&lt;br /&gt;
* zum Platinenrand hin für Versorgung über USB&lt;br /&gt;
* zur Platinenmitte hin für externe Versorgung&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Hinweis:&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Jumper sollte unbedingt gesteckt sein, wenn USB verwendet wird. Steht dieser auf externer Versorung, muss diese dabei auch anliegen. Wird der MCP2200 per USB versorgt, ohne dass am ATxMega Versorgungsspannung anliegt, kommt es über die UART-Leitung zu einem Stromfluss über das entsprechende I/O-Pin des ATxMega, da dieser sich ohne Spannung intern in einem undefinierten Zustand befindet. Auf VCC liegen dann etwa 2.8 V an. Durch den Stromfluss erwärmt sich der MCP2200 deutlich, was zur eventuellen Beschädigung des ICs führen kann.&lt;br /&gt;
&lt;br /&gt;
=== Löten des SD-Halters ===&lt;br /&gt;
&lt;br /&gt;
* Zuerst muss man den Halten ausrichen und einen Punkt am Rand festlöten.&lt;br /&gt;
* Dann muss man alle 4 Ecken festlöten&lt;br /&gt;
* Jetzt kann man mit der Lötspitze oben durch die Aussparungen und führt den Zinn durch die Öffnung für die SD-Karte.&lt;br /&gt;
* So lötet man dann alle 8 Kontakte.&lt;br /&gt;
* Lötbrücken sind hier nicht schön, lässt sich aber dann noch mit Entlötlitze entfernen (Entlötlitze statt Zinn durch die Öffnung führen)&lt;br /&gt;
&lt;br /&gt;
== Betrieb unter Linux ==&lt;br /&gt;
&lt;br /&gt;
Damit man als User auf den Stick zugreifen kann, empfiehlt es sich, einen UDEV-Eintrag für den Stick anzulegen, z.B. neue Datei /etc/udev/rules.d/15_USB_uC.rules anlegen:&lt;br /&gt;
&lt;br /&gt;
 ATTRS{idVendor}==&amp;quot;04d8&amp;quot;, ATTRS{idProduct}==&amp;quot;00df&amp;quot;, GROUP=&amp;quot;MeineGruppe&amp;quot;, MODE=&amp;quot;0660&amp;quot;, SYMLINK+=&amp;quot;ATxMegaStick%n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Für &amp;quot;MeineGruppe&amp;quot; einen geeigneten Werte verwenden, d.h. eine Gruppe, der man selbst angehört.&lt;br /&gt;
&lt;br /&gt;
Jetzt kann man nach dem Anschließen folgende Links sehen:&lt;br /&gt;
&lt;br /&gt;
 ls -l /dev/ATxMegaStick*&lt;br /&gt;
 lrwxrwxrwx 1 root root  7 2011-10-17 00:04 /dev/ATxMegaStick0 -&amp;gt; ttyACM0&lt;br /&gt;
 lrwxrwxrwx 1 root root 11 2011-10-17 00:04 /dev/ATxMegaStick1 -&amp;gt; usb/hiddev1&lt;br /&gt;
 lrwxrwxrwx 1 root root  7 2011-10-17 00:04 /dev/ATxMegaStick2 -&amp;gt; hidraw2&lt;br /&gt;
 lrwxrwxrwx 1 root root 15 2011-10-17 00:04 /dev/ATxMegaStick3 -&amp;gt; bus/usb/001/042&lt;br /&gt;
&lt;br /&gt;
Und die Zugriffrechte sehen so aus:&lt;br /&gt;
&lt;br /&gt;
 ls -lL /dev/ATxMegaStick*&lt;br /&gt;
 crw-rw---- 1 root dialout 166,  0 2011-10-17 00:04 /dev/ATxMegaStick0&lt;br /&gt;
 crw-rw---- 1 root mgr     180, 97 2011-10-17 00:04 /dev/ATxMegaStick1&lt;br /&gt;
 crw-rw---- 1 root mgr     251,  2 2011-10-17 00:04 /dev/ATxMegaStick2&lt;br /&gt;
 crw-rw-r-- 1 root mgr     189, 41 2011-10-17 00:04 /dev/ATxMegaStick3&lt;br /&gt;
&lt;br /&gt;
== Fuses ==&lt;br /&gt;
&lt;br /&gt;
Default-Werte der Fuses:&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;signature&amp;lt;/tt&amp;gt;: Signatur ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U signature:r:-:h&lt;br /&gt;
 0x1e,0x97,0x42&lt;br /&gt;
:0x1e9742 = ATxmega128A3&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse0&amp;lt;/tt&amp;gt;: JTAG User ID ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse0:r:-:h&lt;br /&gt;
 0xff&lt;br /&gt;
:JTAG User ID (JTAGUID) = 0xff &#039;&#039;&#039;(das Manual sagt: 0x00)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse1&amp;lt;/tt&amp;gt;: Watchdog Configuration ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse1:r:-:h&lt;br /&gt;
 0x0&lt;br /&gt;
:Watchdog Window Timeout Period (WDWPER) = n.a.&lt;br /&gt;
:Watchdog Timeout Period (WDPER) = n.a.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse2&amp;lt;/tt&amp;gt;: Reset Configuration ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse2:r:-:h&lt;br /&gt;
 0xff&lt;br /&gt;
:Reset Vector (BOOTRST) = Application Reset&lt;br /&gt;
:BOD operation in power-down mode (BODPD) = BOD disabled&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse4&amp;lt;/tt&amp;gt;: Start-up Configuration ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse4:r:-:h&lt;br /&gt;
 0xfe&lt;br /&gt;
:External Reset Disable (RSTDISBL) = no&lt;br /&gt;
:Start-up time (STARTUPTIME) = 0&lt;br /&gt;
:Watchdog Timer lock (WDLOCK) = no&lt;br /&gt;
:JTAG enabled (JTAGEN) = yes&lt;br /&gt;
&lt;br /&gt;
Bei Bedarf ändern:&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse4:w:0xff:m&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse4:r:-:h&lt;br /&gt;
 0xff&lt;br /&gt;
:JTAG enabled (JTAGEN) = no&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse5&amp;lt;/tt&amp;gt;: BODACT, BODLEVEL, EESAVE ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse5:r:-:h&lt;br /&gt;
 0xff&lt;br /&gt;
:BOD operation in active mode (BODACT) = BOD disabled&lt;br /&gt;
:EEPROM memory is preserved through the Chip Erase (EESAVE) = no&lt;br /&gt;
:BOD voltage level (BODLEVEL) = 1.6V&lt;br /&gt;
&lt;br /&gt;
Bei Bedarf ändern:&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse5:w:0xf7:m&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse5:r:-:h&lt;br /&gt;
 0xf7&lt;br /&gt;
:EEPROM memory is preserved through the Chip Erase (EESAVE) = yes&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
=== Clock System ===&lt;br /&gt;
&lt;br /&gt;
Takt zu Testzwecken auf Port C Pin 7 (d.h. JP3 Pin 3) ausgeben.&lt;br /&gt;
 PORTC.DIRSET = 0x80;&lt;br /&gt;
 PORTCFG.CLKEVOUT = 0x01;&lt;br /&gt;
&lt;br /&gt;
==== 32 MHz mit dem externen Quarz ====&lt;br /&gt;
&lt;br /&gt;
Unter Verwendung der Software zu AVR1003 (-&amp;gt; Siehe auch) kann man den Takt auf 32 MHz einstellen:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;quot;clksys_driver.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 void init_clock( void )&lt;br /&gt;
 {&lt;br /&gt;
    CLKSYS_XOSC_Config( OSC_FRQRANGE_12TO16_gc, false, OSC_XOSCSEL_XTAL_16KCLK_gc );&lt;br /&gt;
    CLKSYS_Enable( OSC_XOSCEN_bm );&lt;br /&gt;
    CLKSYS_PLL_Config( OSC_PLLSRC_XOSC_gc, 2 );&lt;br /&gt;
    CLKSYS_Enable( OSC_PLLEN_bm );&lt;br /&gt;
    CLKSYS_Prescalers_Config( CLK_PSADIV_1_gc, CLK_PSBCDIV_1_1_gc );&lt;br /&gt;
    do {} while ( CLKSYS_IsReady( OSC_PLLRDY_bm ) == 0 );&lt;br /&gt;
    CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_PLL_gc );&lt;br /&gt;
    CLKSYS_Disable( OSC_XOSCEN_bm );&lt;br /&gt;
 } /* init_clock() */&lt;br /&gt;
&lt;br /&gt;
=== USART ===&lt;br /&gt;
&lt;br /&gt;
==== USART über USB ====&lt;br /&gt;
&lt;br /&gt;
So stellt man unter Verwendung der Software zu AVR1307 (-&amp;gt; Siehe auch) bei 32 MHz Takt den USART für die Übertragung per USB ein:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;quot;usart_driver.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #define USART USARTD0&lt;br /&gt;
 &lt;br /&gt;
 void init_usart( void )&lt;br /&gt;
 {&lt;br /&gt;
    PORTD.DIRSET = PIN3_bm;&lt;br /&gt;
    PORTD.DIRCLR = PIN2_bm;&lt;br /&gt;
    USART_Format_Set( &amp;amp;USART, USART_CHSIZE_8BIT_gc, USART_PMODE_DISABLED_gc, false );&lt;br /&gt;
    /*&lt;br /&gt;
     * BSEL[11:0]-Wert bei 32MHz Takt und BSCALE[3:0]==0:&lt;br /&gt;
     *   207 :   9600&lt;br /&gt;
     *   103 :  19200&lt;br /&gt;
     *    51 :  38400&lt;br /&gt;
     *    34 :  57600&lt;br /&gt;
     *    16 : 115200&lt;br /&gt;
     */&lt;br /&gt;
    USART_Baudrate_Set( &amp;amp;USART, 34 , 0 );&lt;br /&gt;
    USART_Rx_Enable( &amp;amp;USART );&lt;br /&gt;
    USART_Tx_Enable( &amp;amp;USART );&lt;br /&gt;
 } /* init_usart() */&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/227310 Ursprungsbeitrag im Forum]&lt;br /&gt;
* [http://www.jtronics.de/avr-projekte/xmega-tutorial.html XMEGA Tutorial in C] - Tutorial ATxmega (ATxmega128A3U)&lt;br /&gt;
* [http://www.atxmega-board.de/stick Die Seite des Sticks] mit Schaltplan und Stückliste&lt;br /&gt;
* &amp;lt;del&amp;gt;[http://www.stromflo.de/dokuwiki/doku.php?id=xmega-c-tutorial XMEGA-C-Tutorial auf stromflo.de]&amp;lt;/del&amp;gt; :-(&lt;br /&gt;
* [http://www.atmel.com/dyn/products/product_card.asp?part_id=4302 Produktseite des ATxmega128A3] mit jeder Menge an Dokumentation und Application Notes&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc8072.pdf AVR1003: Using the XMEGA Clock System] (PDF) und [http://www.atmel.com/dyn/resources/prod_documents/AVR1003.zip Software] (ZIP)&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc8049.pdf AVR1307: Using the XMEGA USART] (PDF) und [http://www.atmel.com/dyn/resources/prod_documents/AVR1307.zip Software] (ZIP)&lt;br /&gt;
* [http://www.microchip.com/wwwproducts/devices.aspx?dDocName=en546923 Produktseite des MCP2200] mit Dokumentation und Tools&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:ATxMegaStick_revC-p2.png&amp;diff=69352</id>
		<title>Datei:ATxMegaStick revC-p2.png</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:ATxMegaStick_revC-p2.png&amp;diff=69352"/>
		<updated>2012-11-29T18:39:23Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Schaltplan zum ATxMegaStick rev C - Seite 2 von 2&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Schaltplan zum ATxMegaStick rev C - Seite 2 von 2&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:ATxMegaStick_revC-p1.png&amp;diff=69351</id>
		<title>Datei:ATxMegaStick revC-p1.png</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:ATxMegaStick_revC-p1.png&amp;diff=69351"/>
		<updated>2012-11-29T18:37:26Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Schaltplan zum ATxMegaStick rev C - Seite 1 von 2&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Schaltplan zum ATxMegaStick rev C - Seite 1 von 2&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Entprellung&amp;diff=68536</id>
		<title>Entprellung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Entprellung&amp;diff=68536"/>
		<updated>2012-09-28T09:53:22Z</updated>

		<summary type="html">&lt;p&gt;Maybee: cli(), sei() unnötig in get_key_state()&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Mechanische Schalter prellen beim Ein- und Ausschalten, d.h sie schalten schnell aus und ein, verursacht durch mechanisches Vibrationen des Schaltkontaktes. Vereinfacht dargestellt sieht eine von einem Schalter oder Taster geschaltete Spannung beim Schalten wie folgt aus:&lt;br /&gt;
&lt;br /&gt;
[[Bild:Entprellen.png]]&lt;br /&gt;
&lt;br /&gt;
Für die Auswertung dieses unsauberen Signals gibt es verschiedene Ansätze:&lt;br /&gt;
&lt;br /&gt;
== Hardwareentprellung ==&lt;br /&gt;
&lt;br /&gt;
===Wechselschalter===&lt;br /&gt;
&lt;br /&gt;
Für die Entprellung von Wechselschaltern (engl. Double Throw Switch) kann ein klassisches RS-[[Flipflop]] genutzt werden. Bei dieser Variante werden neben zwei NAND-Gattern nur noch zwei Pull-Up Widerstände benötigt.&lt;br /&gt;
&lt;br /&gt;
[[Bild:NAND_debouncer.png|framed|left|&#039;&#039;&#039;Taster entprellen mit NAND-RS-Flipflop&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In der gezeigten Schalterstellung liegt an der Position /S der Pegel 0 an. Damit ist das Flipflop gesetzt und der Ausgang auf dem Pegel 1. Schließt der Schalter zwischen den Kontakten 2 und 3, liegt an der Postion /R der Pegel 0 an. Dies bedeutet, dass der Ausgang des Flipflops auf den Pegel 0 geht. Sobald der Schalter von einem zum anderen Kontakt wechselt, beginnt er in der Regel zu prellen. Während des Prellens wechselt der Schalter zwischen den beiden Zuständen &amp;quot;Schalter berührt Kontakt&amp;quot; und &amp;quot;Schalter ist frei in der Luft&amp;quot;. Der Ausgang des Flipflops bleibt in dieser Prellzeit aber stabil, da der Schalter während des Prellens nie den gegenüberliegenden Kontakt berührt und das RS-Flipflop seinen Zustand allein halten kann. Die Prellzeit ist stark vom Schaltertyp abhängig und liegt zwischen 0,1 und 10ms. Die Dimensionierung der Widerstände ist relativ unkritisch. Als Richtwert können hier 100kOhm verwendet werden.&lt;br /&gt;
&lt;br /&gt;
===Einfacher Taster===&lt;br /&gt;
&lt;br /&gt;
Auch wenn das RS-Flipflop sehr effektiv ist, wird diese Variante der Entprellung nur selten angewendet. Grund dafür ist, dass in Schaltungen häufiger einfache Taster eingesetzt werden. Diese sind oft kleiner und preisgünstiger. Um einfache Taster (engl. Single Throw Switch) zu entprellen, kann ein einfacher RC-Tiefpass eingesetzt werden. Hierbei wird ein Kondensator über einen Widerstand je nach Schalterstellung auf- oder entladen. Das RC-Glied bildet einen Tiefpass, sodass die Spannung über den Kondensator nicht von einen Pegel auf den anderen springen kann.&lt;br /&gt;
&lt;br /&gt;
[[Bild:RC_debouncer.png|framed|left|&#039;&#039;&#039;Taster entprellen mit RC-Entpreller&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn der Schalter geöffnet ist, lädt sich der Kondensator langsam über die beiden Widerstände R&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; und R&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; auf V&amp;lt;sub&amp;gt;cc&amp;lt;/sub&amp;gt; auf. Beim Erreichen der Umschaltschwelle springt der Ausgang auf den Pegel 0. Wird der Schalter geschlossen, entlädt sich der Kondensator langsam über den Widerstand R&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;. Demnach ändert sich der Ausgang des Inverters auf den Pegel 1. Während der Taster prellt, kann sich die Spannung über dem Kondensator nicht sprunghaft ändern, da das Auf- und Entladen eher langsam über die Widerstände erfolgt. Außerdem sind die Schaltschwellen für den Übergang LOW-&amp;gt;HIGH und HIGH-&amp;gt;LOW stark verschieden (Hysterese, siehe Artikel [[Schmitt-Trigger]]). Bei richtiger Dimensionierung der Bauelemente wird somit der Ausgang des Inverters prellfrei.&lt;br /&gt;
&lt;br /&gt;
Zu beachten ist, dass der Inverter &#039;&#039;&#039;unbedingt&#039;&#039;&#039; einer mit [[Schmitt-Trigger]] Eingängen sein muss, weil bei Standard-Logikeingängen im Bereich von üblicherweise 0,8V - 2,0V der Ausgang nicht definiert ist. Als Inverter kann zum Beispiel der 74HC14 oder der CD40106 (pinkompatibel) eingesetzt werden. Alternativ kann auch ein CD4093 eingesetzt werden. Bei dem CD4093 handelt es sich um NAND-Gatter mit Schmitt-Trigger-Eingängen. Um aus einem NAND-Gatter einen Inverter zu machen, müssen einfach nur die beiden Eingänge verbunden werden oder ein Eingang fest auf HIGH gelegt werden.&lt;br /&gt;
&lt;br /&gt;
Für eine geeignete Dimensionierung muss man etwas mit den Standardformeln für einen Kondensator jonglieren. Die Spannung über den Kondensator beim Entladen berechnet sich nach:&lt;br /&gt;
:&amp;lt;math&amp;gt;U_C(t) = U_0 \cdot e^{\frac{-t}{R_2 C_1}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit der Ausgang des Inverters stabil ist, muss die Spannung über den Kondensator und damit die Spannung am Eingang des Inverters über der Spannung bleiben, bei welcher der Inverter umschaltet. Diese Schwellwertspannung ist genau die zeitabhängige Spannung über den Kondensator.&lt;br /&gt;
:&amp;lt;math&amp;gt;U_C(t)\!\ = U_{th}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Durch Umstellen der Formel ergibt sich nun:&lt;br /&gt;
:&amp;lt;math&amp;gt;R_2=\frac{-t}{C_1 \cdot ln\left(\frac{U_{th}}{U_0} \right)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Taster prellt üblicherweise etwa 10ms. Zur Sicherheit kann bei der Berechnung der Widerstandes eine Prellzeit von 20ms angenommen werden. U_0 ist die Betriebsspannung also Vcc. Die Schwellwertspannung muss aus dem Datenblatt des eingesetzten Schmitt-Triggers abgelesen werden. Beim 74HC14 beträgt der gesuchte Wert 2,0V. Nimmt man für den Kondensator 1µF und beträgt die  Betriebsspannung 5V, ergibt sich für den Widerstand ein Wert von etwa 22kOhm.&lt;br /&gt;
&lt;br /&gt;
Wird der Schalter geöffnet, lädt sich der Kondensator nach folgender Formel auf:&lt;br /&gt;
:&amp;lt;math&amp;gt;U_C(t) = U_0 \cdot \left( 1-e^{\frac{-t}{(R_1+R_2)\cdot C_1}} \right)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit U_th=U_C ergibt das Umstellen nach (R_1+R_2):&lt;br /&gt;
:&amp;lt;math&amp;gt;R_1+R_2 = \frac{-t}{C_1 \cdot ln\left(1-\frac{U_{th}}{U_0} \right)} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für die Schwellspannung lässt sich aus dem Datenblatt ein Wert von 2,3V ablesen. Mit diesem Wert und den Annahmen von oben ergibt sich für R_1+R_2 ein Wert von 32kOhm. Somit ergibt sich für R_1 ein Wert von etwa 10kOhm.&lt;br /&gt;
&lt;br /&gt;
Anmerkung: Beim 74LS14 von Hitachi z.&amp;amp;nbsp;B. sind die oberen und unteren Schaltschwellwerte unterschiedlich. Es muss darauf geachtet werden, dass U_{th} beim Entladen die untere Schwelle und U_{th} beim Laden die obere Schwelle einnimmt.&lt;br /&gt;
&lt;br /&gt;
== Softwareentprellung ==&lt;br /&gt;
&lt;br /&gt;
Bei Verwendung eines Mikrocontrollers kann man sich die zusätzliche Hardware sparen, da die Entprellung genauso gut in Software funktioniert. Dabei ist zu beachten, dass zusätzliche Rechenleistung und je nach Umsetzung auch Hardwareressourcen benötigt werden (z. B. Timer).&lt;br /&gt;
&lt;br /&gt;
=== Flankenerkennung ===&lt;br /&gt;
Bei einem Taster gibt es insgesamt 4 Zustände:&lt;br /&gt;
&lt;br /&gt;
* 1. war nicht gedrückt und ist nicht gedrückt&lt;br /&gt;
* 2. war nicht gedrückt und ist gedrückt (steigende Flanke)&lt;br /&gt;
* 3. war gedrückt und ist immer noch gedrückt&lt;br /&gt;
* 4. war gedrückt und ist nicht mehr gedrückt (fallende Flanke)&lt;br /&gt;
&lt;br /&gt;
Diese einzelnen Zustände lassen sich jetzt bequem abfragen/durchlaufen. Die Entprellung geschieht dabei durch die ganze Laufzeit des Programms.&lt;br /&gt;
&lt;br /&gt;
Die Taster werden hierbei als Active-Low angeschlossen um die internen Pull-Ups zu nutzen.&lt;br /&gt;
&lt;br /&gt;
Diese Routine gibt für den Zustand &amp;quot;steigende Flanke&amp;quot; den Wert &amp;quot;1&amp;quot; zurück, sonst &amp;quot;0&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#define TASTERPORT PINC&lt;br /&gt;
#define TASTERBIT PINC1&lt;br /&gt;
&lt;br /&gt;
char taster(void)&lt;br /&gt;
{&lt;br /&gt;
    static unsigned char zustand;&lt;br /&gt;
    char rw = 0;&lt;br /&gt;
&lt;br /&gt;
    if(zustand == 0 &amp;amp;&amp;amp; !(TASTERPORT &amp;amp; (1&amp;lt;&amp;lt;TASTERBIT)))   //Taster wird gedrueckt (steigende Flanke)&lt;br /&gt;
    {&lt;br /&gt;
        zustand = 1;&lt;br /&gt;
        rw = 1;&lt;br /&gt;
    }&lt;br /&gt;
    else if (zustand == 1 &amp;amp;&amp;amp; !(TASTERPORT &amp;amp; (1&amp;lt;&amp;lt;TASTERBIT)))   //Taster wird gehalten&lt;br /&gt;
    {&lt;br /&gt;
         zustand = 2;&lt;br /&gt;
         rw = 0;&lt;br /&gt;
    }&lt;br /&gt;
    else if (zustand == 2 &amp;amp;&amp;amp; (TASTERPORT &amp;amp; (1&amp;lt;&amp;lt;TASTERBIT)))   //Taster wird losgelassen (fallende Flanke)&lt;br /&gt;
    {&lt;br /&gt;
        zustand = 3;&lt;br /&gt;
        rw = 0;&lt;br /&gt;
    }&lt;br /&gt;
    else if (zustand == 3 &amp;amp;&amp;amp; (TASTERPORT &amp;amp; (1&amp;lt;&amp;lt;TASTERBIT)))   //Taster losgelassen&lt;br /&gt;
    {&lt;br /&gt;
        zustand = 0;&lt;br /&gt;
        rw = 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return rw;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Warteschleifen-Verfahren ===&lt;br /&gt;
&lt;br /&gt;
Alle mechanischen Kontakte, sei es von Schaltern, Tastern oder auch von Relais, haben die unangenehme Eigenschaft zu prellen. Dies bedeutet, dass beim Schalten eines Kontaktes derselbe nicht direkt den endgültigen Zustand aufweist, sondern zwischenzeitlich möglicherweise mehrfach ein- und ausschaltet.&lt;br /&gt;
&lt;br /&gt;
Soll nun mit einem Mikrocontroller gezählt werden, wie oft ein solcher Kontakt geschaltet wird, muss das Prellen des Kontakts berücksichtigt werden, da sonst pro Schaltvorgang möglicherweise mehrfache Impulse gezählt werden. Diesem Phänomen muss beim Schreiben des Programms unbedingt Rechnung getragen werden.&lt;br /&gt;
&lt;br /&gt;
Beim folgenden einfachen Beispiel für eine Entprellung ist zu beachten, dass der AVR im Falle eines Tastendrucks 200ms wartet, also brach liegt. Bei zeitkritische Anwendungen sollte man ein anderes Verfahren nutzen (z.&amp;amp;nbsp;B. Abfrage der Tastenzustände in einer Timer-Interrupt-Service-Routine).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;inttypes.h&amp;gt;&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
#warning &amp;quot;F_CPU war noch nicht definiert, wird nun mit 3686400 definiert&amp;quot;&lt;br /&gt;
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz  */&lt;br /&gt;
#endif&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;     /* bei alter avr-libc: #include &amp;lt;avr/delay.h&amp;gt; */      &lt;br /&gt;
&lt;br /&gt;
/* Einfache Funktion zum Entprellen eines Tasters */&lt;br /&gt;
inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)&lt;br /&gt;
{&lt;br /&gt;
    if ( !(*port &amp;amp; (1 &amp;lt;&amp;lt; pin)) )&lt;br /&gt;
    {&lt;br /&gt;
        /* Pin wurde auf Masse gezogen, 100ms warten   */&lt;br /&gt;
        _delay_ms(50);   // Maximalwert des Parameters an _delay_ms &lt;br /&gt;
        _delay_ms(50);   // beachten, vgl. Dokumentation der avr-libc&lt;br /&gt;
        if ( *port &amp;amp; (1 &amp;lt;&amp;lt; pin) )&lt;br /&gt;
        {&lt;br /&gt;
            /* Anwender Zeit zum Loslassen des Tasters geben */&lt;br /&gt;
            _delay_ms(50);&lt;br /&gt;
            _delay_ms(50); &lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    DDRB &amp;amp;= ~( 1 &amp;lt;&amp;lt; PB0 );        /* PIN PB0 auf Eingang Taster)  */&lt;br /&gt;
    PORTB |= ( 1 &amp;lt;&amp;lt; PB0 );        /* Pullup-Widerstand aktivieren */&lt;br /&gt;
    ...&lt;br /&gt;
    if (debounce(&amp;amp;PINB, PB0))&lt;br /&gt;
    {&lt;br /&gt;
        /* Falls Taster an PIN PB0 gedrueckt     */&lt;br /&gt;
        /* LED an Port PD7 an- bzw. ausschalten: */&lt;br /&gt;
        PORTD = PORTD ^ ( 1 &amp;lt;&amp;lt; PD7 );&lt;br /&gt;
    }&lt;br /&gt;
    ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die obige Routine hat leider mehrere Nachteile:&lt;br /&gt;
* sie detektiert nur das Loslassen (unergonomisch)&lt;br /&gt;
* sie verzögert die Mainloop immer um 100ms bei gedrückter Taste&lt;br /&gt;
* sie verliert Tastendrücke, je mehr die Mainloop zu tun hat.&lt;br /&gt;
&lt;br /&gt;
Eine ähnlich einfach zu benutzende Routine, aber ohne all diese Nachteile findet sich im Forenthread&lt;br /&gt;
[http://www.mikrocontroller.net/topic/164194#new Entprellung für Anfänger]&lt;br /&gt;
&lt;br /&gt;
Der &#039;&#039;DEBOUNCE&#039;&#039; Befehl in dem BASIC-Dialekt BASCOM für AVR ist ebenfalls nach dem Warteschleifen-Verfahren programmiert. Die Wartezeit beträgt standardmäßig 25 ms, kann aber vom Anwender überschrieben werden. Vgl.  [http://avrhelp.mcselec.com/bascom-avr.html?DEBOUNCE BASCOM Online-Manual zu DEBOUNCE].&lt;br /&gt;
&lt;br /&gt;
Eine C-Implementierung für eine Tastenabfrage mit Warteschleife ist im Artikel [[AVR-GCC-Tutorial#IO-Register_als_Parameter_und_Variablen|AVR-GCC-Tutorial: IO-Register als Parameter und Variablen]] angeben.&lt;br /&gt;
&lt;br /&gt;
Der Nachteil dieses Verfahrens ist, dass der Controller durch die Warteschleife blockiert wird. Günstiger ist die Implementierung mit einem Timer-Interrupt.&lt;br /&gt;
&lt;br /&gt;
==== Warteschleifenvariante mit Maske und Pointer (nach Christian Riggenbach) ====&lt;br /&gt;
&lt;br /&gt;
Hier eine weitere Funktion, um Taster zu entprellen: Durch den zusätzlichen Code kann eine Entprellzeit von durchschnittlich 1-3ms (mindestens 8*150µs = 1ms) erreicht werden. Grundsätzlich prüft die Funktion den Pegel der Pins auf einem bestimmten Port. Wenn die/der Pegel 8 Mal konstant war, wird die Schleife verlassen. Diese Funktion kann sehr gut eingesetzt werden, um in einer Endlosschleife Taster anzufragen, da sie, wie erwähnt, eine kurze Wartezeit hat.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void entprellung( volatile uint8_t *port, uint8_t maske ) {&lt;br /&gt;
  uint8_t   port_puffer;&lt;br /&gt;
  uint8_t   entprellungs_puffer;&lt;br /&gt;
&lt;br /&gt;
  for( entprellungs_puffer=0 ; entprellungs_puffer!=0xff ; ) {&lt;br /&gt;
    entprellungs_puffer&amp;lt;&amp;lt;=1;&lt;br /&gt;
    port_puffer = *port;&lt;br /&gt;
    _delay_us(150);&lt;br /&gt;
    if( (*port &amp;amp; maske) == (port_puffer &amp;amp; maske) )&lt;br /&gt;
      entprellungs_puffer |= 0x01;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Die Funktion wird wie folgt aufgerufen:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  // Bugfix 20100414&lt;br /&gt;
  // http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_port_pass&lt;br /&gt;
  entprellung( &amp;amp;PINB, (1&amp;lt;&amp;lt;PINB2) ); // ggf. Prellen abwarten &lt;br /&gt;
  if( PINB &amp;amp; (1&amp;lt;&amp;lt;PINB2) )           // dann stabilen Wert einlesen&lt;br /&gt;
  {&lt;br /&gt;
    // mach was&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
    // mach was anderes&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Als Maske kann ein beliebiger Wert übergeben werden. Sie verhindert, dass nichtverwendete Taster die Entprellzeit negativ beeinflussen.&lt;br /&gt;
&lt;br /&gt;
==== Debounce-Makro von Peter Dannegger ====&lt;br /&gt;
&lt;br /&gt;
Peter Dannegger hat in [http://www.mikrocontroller.net/topic/164194#1566921 &amp;quot;Entprellen für Anfänger&amp;quot;] folgende vereinfachtes Entprellverfahren beschrieben. Das Makro arbeitet in der Originalversion mit &#039;&#039;active low&#039;&#039; geschalteten Tastern, kann aber einfach für  &#039;&#039;active high&#039;&#039; geschaltete Taster angepasst werden ([[Pollin Funk-AVR-Evaluationsboard#Tasty Reloaded|Tasty Reloaded]]). &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/************************************************************************/&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/*                      Not so powerful Debouncing Example              */&lt;br /&gt;
/*                      No Interrupt needed                             */&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/*              Author: Peter Dannegger                                 */&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/************************************************************************/&lt;br /&gt;
// Target: ATtiny13&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#define F_CPU 9.6e6&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define debounce( port, pin )                                         \&lt;br /&gt;
({                                                                    \&lt;br /&gt;
  static uint8_t flag = 0;     /* new variable on every macro usage */  \&lt;br /&gt;
  uint8_t i = 0;                                                      \&lt;br /&gt;
                                                                      \&lt;br /&gt;
  if( flag ){                  /* check for key release: */           \&lt;br /&gt;
    for(;;){                   /* loop ... */                         \&lt;br /&gt;
      if( !(port &amp;amp; 1&amp;lt;&amp;lt;pin) ){  /* ... until key pressed or ... */     \&lt;br /&gt;
        i = 0;                 /* 0 = bounce */                       \&lt;br /&gt;
        break;                                                        \&lt;br /&gt;
      }                                                               \&lt;br /&gt;
      _delay_us( 98 );         /* * 256 = 25ms */                     \&lt;br /&gt;
      if( --i == 0 ){          /* ... until key &amp;gt;25ms released */     \&lt;br /&gt;
        flag = 0;              /* clear press flag */                 \&lt;br /&gt;
        i = 0;                 /* 0 = key release debounced */        \&lt;br /&gt;
        break;                                                        \&lt;br /&gt;
      }                                                               \&lt;br /&gt;
    }                                                                 \&lt;br /&gt;
  }else{                       /* else check for key press: */        \&lt;br /&gt;
    for(;;){                   /* loop ... */                         \&lt;br /&gt;
      if( (port &amp;amp; 1&amp;lt;&amp;lt;pin) ){   /* ... until key released or ... */    \&lt;br /&gt;
        i = 0;                 /* 0 = bounce */                       \&lt;br /&gt;
        break;                                                        \&lt;br /&gt;
      }                                                               \&lt;br /&gt;
      _delay_us( 98 );         /* * 256 = 25ms */                     \&lt;br /&gt;
      if( --i == 0 ){          /* ... until key &amp;gt;25ms pressed */      \&lt;br /&gt;
        flag = 1;              /* set press flag */                   \&lt;br /&gt;
        i = 1;                 /* 1 = key press debounced */          \&lt;br /&gt;
        break;                                                        \&lt;br /&gt;
      }                                                               \&lt;br /&gt;
    }                                                                 \&lt;br /&gt;
  }                                                                   \&lt;br /&gt;
  i;                           /* return value of Macro */            \&lt;br /&gt;
})&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
   Testapplication&lt;br /&gt;
 */&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  DDRB  &amp;amp;= ~(1&amp;lt;&amp;lt;PB0);&lt;br /&gt;
  PORTB |=   1&amp;lt;&amp;lt;PB0;&lt;br /&gt;
  DDRB  |=   1&amp;lt;&amp;lt;PB2;&lt;br /&gt;
  DDRB  &amp;amp;= ~(1&amp;lt;&amp;lt;PB1);&lt;br /&gt;
  PORTB |=   1&amp;lt;&amp;lt;PB1;&lt;br /&gt;
  DDRB  |=   1&amp;lt;&amp;lt;PB3;&lt;br /&gt;
  for(;;){&lt;br /&gt;
    if( debounce( PINB, PB1 ) )&lt;br /&gt;
      PORTB ^= 1&amp;lt;&amp;lt;PB2;&lt;br /&gt;
    if( debounce( PINB, PB0 ) )&lt;br /&gt;
      PORTB ^= 1&amp;lt;&amp;lt;PB3;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn das Makro für die gleiche Taste (Pin) an mehreren Stellen aufgerufen werden soll, muss eine Funktion angelegt werden, damit beide Aufrufe an die gleiche Zustandsvariable &#039;&#039;flag&#039;&#039; auswerten [http://www.mikrocontroller.net/topic/195914#1918727]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// Hilfsfunktion&lt;br /&gt;
uint8_t debounce_C1( void )&lt;br /&gt;
{&lt;br /&gt;
  return debounce(PINC, PC1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Beispielanwendung&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  DDRB  |=   1&amp;lt;&amp;lt;PB2;&lt;br /&gt;
  DDRB  |=   1&amp;lt;&amp;lt;PB3;&lt;br /&gt;
  DDRC  &amp;amp;= ~(1&amp;lt;&amp;lt;PC1);&lt;br /&gt;
  PORTC |=   1&amp;lt;&amp;lt;PC1; // Pullup für Taster&lt;br /&gt;
&lt;br /&gt;
  for(;;){&lt;br /&gt;
    if( debounce_C1() )  // nicht: debounce(PINC, PC1)&lt;br /&gt;
      PORTB ^= 1&amp;lt;&amp;lt;PB2;&lt;br /&gt;
    if( debounce_C1() )  // nicht: debounce(PINC, PC1)&lt;br /&gt;
      PORTB ^= 1&amp;lt;&amp;lt;PB3;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Timer-Verfahren (nach Peter Dannegger) ===&lt;br /&gt;
&lt;br /&gt;
==== Grundroutine (AVR Assembler) ====&lt;br /&gt;
&lt;br /&gt;
Siehe dazu: [http://www.mikrocontroller.net/forum/read-4-20435.html#new Forum] &lt;br /&gt;
&lt;br /&gt;
Vorteile&lt;br /&gt;
* besonders kurzer Code&lt;br /&gt;
* schnell&lt;br /&gt;
&lt;br /&gt;
Außerdem können 8 Tasten (aktiv low) gleichzeitig bearbeitet werden, es dürfen also&lt;br /&gt;
alle exakt zur selben Zeit gedrückt werden. Andere Routinen können z.&amp;amp;nbsp;B. nur eine Taste verarbeiten, d.h. die zuerst oder zuletzt gedrückte gewinnt, oder es kommt Unsinn heraus.&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Einlese- und Entprellroutine ist nur 8 Instruktionen&lt;br /&gt;
kurz. Der entprellte Tastenzustand ist im Register &#039;&#039;key_state&#039;&#039;. Mit nur 2 weiteren Instruktionen wird dann der Wechsel von &#039;&#039;Taste offen&#039;&#039; zu&lt;br /&gt;
&#039;&#039;Taste gedrückt&#039;&#039; erkannt und im Register &#039;&#039;key_press&#039;&#039; abgelegt. Im Beispielcode werden dann damit 8 LEDs ein- und ausgeschaltet. Jede Taste entspricht einem Bit in den Registern, d.h. die Verarbeitung erfolgt bitweise mit logischen Operationen. Zum Verständnis empfiehlt es sich daher, die Logikgleichungen mit Gattern für ein Bit = eine Taste aufzumalen. Die Register kann man sich als Flipflops denken, die mit der Entprellzeit als Takt arbeiten. D.h. man kann das auch so z.&amp;amp;nbsp;B. in einem GAL22V10 realisieren.&lt;br /&gt;
&lt;br /&gt;
Als Kommentar sind neben den einzelnen Instruktionen alle 8 möglichen&lt;br /&gt;
Kombinationen der 3 Signale dargestellt.&lt;br /&gt;
&lt;br /&gt;
Beispielcode für AVR (Assembler):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt;&lt;br /&gt;
.nolist&lt;br /&gt;
.include &amp;quot;c:\avr\inc\1200def.inc&amp;quot;&lt;br /&gt;
.list&lt;br /&gt;
.def  save_sreg         = r0&lt;br /&gt;
.def  iwr0              = r1&lt;br /&gt;
.def  iwr1              = r2&lt;br /&gt;
&lt;br /&gt;
.def  key_old           = r3&lt;br /&gt;
.def  key_state         = r4&lt;br /&gt;
.def  key_press         = r5&lt;br /&gt;
&lt;br /&gt;
.def  leds              = r16&lt;br /&gt;
.def  wr0               = r17&lt;br /&gt;
&lt;br /&gt;
.equ  key_port          = pind&lt;br /&gt;
.equ  led_port          = portb&lt;br /&gt;
&lt;br /&gt;
      rjmp   init&lt;br /&gt;
.org OVF0addr		;timer interrupt 24ms&lt;br /&gt;
      in     save_sreg, SREG&lt;br /&gt;
get8key:                               ;/old      state     iwr1      iwr0&lt;br /&gt;
      mov    iwr0, key_old             ;00110011  10101010            00110011&lt;br /&gt;
      in     key_old, key_port         ;11110000&lt;br /&gt;
      eor    iwr0, key_old             ;                              11000011&lt;br /&gt;
      com    key_old                   ;00001111&lt;br /&gt;
      mov    iwr1, key_state           ;                    10101010&lt;br /&gt;
      or     key_state, iwr0           ;          11101011&lt;br /&gt;
      and    iwr0, key_old             ;                              00000011&lt;br /&gt;
      eor    key_state, iwr0           ;          11101000&lt;br /&gt;
      and    iwr1, iwr0                ;                    00000010&lt;br /&gt;
      or     key_press, iwr1           ;store key press detect&lt;br /&gt;
;&lt;br /&gt;
;			insert other timer functions here&lt;br /&gt;
;&lt;br /&gt;
      out    SREG, save_sreg&lt;br /&gt;
      reti&lt;br /&gt;
;-------------------------------------------------------------------------&lt;br /&gt;
init:&lt;br /&gt;
      ldi    wr0, 0xFF&lt;br /&gt;
      out    ddrb, wr0&lt;br /&gt;
      ldi    wr0, 1&amp;lt;&amp;lt;CS02 | 1&amp;lt;&amp;lt;CS00    ;divide by 1024 * 256&lt;br /&gt;
      out    TCCR0, wr0&lt;br /&gt;
      ldi    wr0, 1&amp;lt;&amp;lt;TOIE0             ;enable timer interrupt&lt;br /&gt;
      out    TIMSK, wr0&lt;br /&gt;
&lt;br /&gt;
      clr    key_old&lt;br /&gt;
      clr    key_state&lt;br /&gt;
      clr    key_press&lt;br /&gt;
      ldi    leds, 0xFF&lt;br /&gt;
main: cli&lt;br /&gt;
      eor    leds, key_press           ;toggle LEDs&lt;br /&gt;
      clr    key_press                 ;clear, if key press action done&lt;br /&gt;
      sei&lt;br /&gt;
      out    led_port, leds&lt;br /&gt;
      rjmp   main&lt;br /&gt;
;-------------------------------------------------------------&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Komfortroutine (C für AVR) ====&lt;br /&gt;
&lt;br /&gt;
Siehe dazu: [http://www.mikrocontroller.net/forum/read-4-310276.html Forum]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Anmerkung&#039;&#039;&#039; Wenn statt active-low (Ruhezustand High) active-high (Ruhezustand Low) verwendet wird muss eine Zeile geändert werden siehe:&lt;br /&gt;
[http://www.mikrocontroller.net/forum/read-4-310276.html gesamter Beitrag im Forum], &lt;br /&gt;
[http://www.mikrocontroller.net/topic/48465#606555 Stelle 1 im Beitrag], ([http://www.mikrocontroller.net/topic/48465#2306398 Stelle 2 im Beitrag] muss *nicht* geändert werden, da hier die Polarität gar keinen Einfluß hat).&lt;br /&gt;
&lt;br /&gt;
Funktionsprinzip wie oben plus zusätzliche Features:  &lt;br /&gt;
* Kann Tasten sparen durch unterschiedliche Aktionen bei kurzem oder langem Drücken&lt;br /&gt;
* Wiederholfunktion, z.&amp;amp;nbsp;B. für die Eingabe von Werten&lt;br /&gt;
&lt;br /&gt;
Das Programm ist für avr-gcc/avr-libc geschrieben, kann aber mit ein paar Anpassungen auch mit anderen Compilern und Mikrocontrollern verwendet werden. Eine Portierung für den AT91SAM7 findet man [http://www.google.com/codesearch?q=show:ac2viP-2E2Y:pzkOO5QRsoc:RPICuprYy-A&amp;amp;sa=N&amp;amp;cd=1&amp;amp;ct=rc&amp;amp;cs_p=svn://mikrocontroller.net/mp3dec/trunk&amp;amp;cs_f=keys.c#a0 hier] (aus dem Projekt [[ARM MP3/AAC Player]]).&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/************************************************************************/&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/*                      Debouncing 8 Keys                               */&lt;br /&gt;
/*                      Sampling 4 Times                                */&lt;br /&gt;
/*                      With Repeat Function                            */&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/*              Author: Peter Dannegger                                 */&lt;br /&gt;
/*                      danni@specs.de                                  */&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/************************************************************************/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
#define F_CPU           1000000                   // processor clock frequency&lt;br /&gt;
#warning kein F_CPU definiert&lt;br /&gt;
#endif&lt;br /&gt;
 &lt;br /&gt;
#define KEY_DDR         DDRB&lt;br /&gt;
#define KEY_PORT        PORTB&lt;br /&gt;
#define KEY_PIN         PINB&lt;br /&gt;
#define KEY0            0&lt;br /&gt;
#define KEY1            1&lt;br /&gt;
#define KEY2            2&lt;br /&gt;
#define ALL_KEYS        (1&amp;lt;&amp;lt;KEY0 | 1&amp;lt;&amp;lt;KEY1 | 1&amp;lt;&amp;lt;KEY2)&lt;br /&gt;
 &lt;br /&gt;
#define REPEAT_MASK     (1&amp;lt;&amp;lt;KEY1 | 1&amp;lt;&amp;lt;KEY2)       // repeat: key1, key2&lt;br /&gt;
#define REPEAT_START    50                        // after 500ms&lt;br /&gt;
#define REPEAT_NEXT     20                        // every 200ms&lt;br /&gt;
&lt;br /&gt;
#define LED_DDR         DDRA&lt;br /&gt;
#define LED_PORT        PORTA&lt;br /&gt;
#define LED0            0&lt;br /&gt;
#define LED1            1&lt;br /&gt;
#define LED2            2&lt;br /&gt;
 &lt;br /&gt;
volatile uint8_t key_state;                                // debounced and inverted key state:&lt;br /&gt;
                                                  // bit = 1: key pressed&lt;br /&gt;
volatile uint8_t key_press;                                // key press detect&lt;br /&gt;
 &lt;br /&gt;
volatile uint8_t key_rpt;                                  // key long press and repeat&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
ISR( TIMER0_OVF_vect )                            // every 10ms&lt;br /&gt;
{&lt;br /&gt;
  static uint8_t ct0, ct1, rpt;&lt;br /&gt;
  uint8_t i;&lt;br /&gt;
 &lt;br /&gt;
  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms&lt;br /&gt;
 &lt;br /&gt;
  i = key_state ^ ~KEY_PIN;                       // key changed ?&lt;br /&gt;
  ct0 = ~( ct0 &amp;amp; i );                             // reset or count ct0&lt;br /&gt;
  ct1 = ct0 ^ (ct1 &amp;amp; i);                          // reset or count ct1&lt;br /&gt;
  i &amp;amp;= ct0 &amp;amp; ct1;                                 // count until roll over ?&lt;br /&gt;
  key_state ^= i;                                 // then toggle debounced state&lt;br /&gt;
  key_press |= key_state &amp;amp; i;                     // 0-&amp;gt;1: key press detect&lt;br /&gt;
 &lt;br /&gt;
  if( (key_state &amp;amp; REPEAT_MASK) == 0 )            // check repeat function&lt;br /&gt;
     rpt = REPEAT_START;                          // start delay&lt;br /&gt;
  if( --rpt == 0 ){&lt;br /&gt;
    rpt = REPEAT_NEXT;                            // repeat delay&lt;br /&gt;
    key_rpt |= key_state &amp;amp; REPEAT_MASK;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
///////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
// check if a key has been pressed. Each pressed key is reported&lt;br /&gt;
// only once&lt;br /&gt;
//&lt;br /&gt;
uint8_t get_key_press( uint8_t key_mask )&lt;br /&gt;
{&lt;br /&gt;
  cli();                                          // read and clear atomic !&lt;br /&gt;
  key_mask &amp;amp;= key_press;                          // read key(s)&lt;br /&gt;
  key_press ^= key_mask;                          // clear key(s)&lt;br /&gt;
  sei();&lt;br /&gt;
  return key_mask;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
///////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
// check if a key has been pressed long enough such that the&lt;br /&gt;
// key repeat functionality kicks in. After a small setup delay&lt;br /&gt;
// the key is reported being pressed in subsequent calls&lt;br /&gt;
// to this function. This simulates the user repeatedly&lt;br /&gt;
// pressing and releasing the key.&lt;br /&gt;
//&lt;br /&gt;
uint8_t get_key_rpt( uint8_t key_mask )&lt;br /&gt;
{&lt;br /&gt;
  cli();                                          // read and clear atomic !&lt;br /&gt;
  key_mask &amp;amp;= key_rpt;                            // read key(s)&lt;br /&gt;
  key_rpt ^= key_mask;                            // clear key(s)&lt;br /&gt;
  sei();&lt;br /&gt;
  return key_mask;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
// check if a key is pressed right now&lt;br /&gt;
//&lt;br /&gt;
uint8_t get_key_state( uint8_t key_mask )&lt;br /&gt;
&lt;br /&gt;
{&lt;br /&gt;
  key_mask &amp;amp;= key_state;&lt;br /&gt;
  return key_mask;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
uint8_t get_key_short( uint8_t key_mask )&lt;br /&gt;
{&lt;br /&gt;
  cli();                                          // read key state and key press atomic !&lt;br /&gt;
  return get_key_press( ~key_state &amp;amp; key_mask );&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
///////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
uint8_t get_key_long( uint8_t key_mask )&lt;br /&gt;
{&lt;br /&gt;
  return get_key_press( get_key_rpt( key_mask ));&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main( void )&lt;br /&gt;
{&lt;br /&gt;
  LED_PORT = 0xFF;&lt;br /&gt;
  LED_DDR = 0xFF;                     &lt;br /&gt;
&lt;br /&gt;
  // Configure debouncing routines&lt;br /&gt;
  KEY_DDR &amp;amp;= ~ALL_KEYS;                // configure key port for input&lt;br /&gt;
  KEY_PORT |= ALL_KEYS;                // and turn on pull up resistors&lt;br /&gt;
&lt;br /&gt;
  TCCR0 = (1&amp;lt;&amp;lt;CS02)|(1&amp;lt;&amp;lt;CS00);         // divide by 1024&lt;br /&gt;
  TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5);  // preload for 10ms&lt;br /&gt;
  TIMSK |= 1&amp;lt;&amp;lt;TOIE0;                   // enable timer interrupt&lt;br /&gt;
&lt;br /&gt;
  sei();&lt;br /&gt;
&lt;br /&gt;
  while(1){&lt;br /&gt;
    if( get_key_short( 1&amp;lt;&amp;lt;KEY1 ))&lt;br /&gt;
      LED_PORT ^= 1&amp;lt;&amp;lt;LED1;&lt;br /&gt;
 &lt;br /&gt;
    if( get_key_long( 1&amp;lt;&amp;lt;KEY1 ))&lt;br /&gt;
      LED_PORT ^= 1&amp;lt;&amp;lt;LED2;&lt;br /&gt;
 &lt;br /&gt;
    // single press and repeat&lt;br /&gt;
 &lt;br /&gt;
    if( get_key_press( 1&amp;lt;&amp;lt;KEY2 ) || get_key_rpt( 1&amp;lt;&amp;lt;KEY2 )){&lt;br /&gt;
      uint8_t i = LED_PORT;&lt;br /&gt;
 &lt;br /&gt;
      i = (i &amp;amp; 0x07) | ((i &amp;lt;&amp;lt; 1) &amp;amp; 0xF0);&lt;br /&gt;
      if( i &amp;lt; 0xF0 )&lt;br /&gt;
        i |= 0x08;&lt;br /&gt;
      LED_PORT = i;      &lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das single-press-und-repeat-Beispiel geht nicht in jeder Beschaltung; folgendes Beispiel sollte universeller sein (einzelne LED an/aus):&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// single press and repeat&lt;br /&gt;
if( get_key_press( 1&amp;lt;&amp;lt;KEY2 ) || get_key_rpt( 1&amp;lt;&amp;lt;KEY2 )){&lt;br /&gt;
    LED_PORT ^=0x08;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Funktionsweise =====&lt;br /&gt;
Der Code basiert auf 8 parallelen vertikalen Zählern, die über die Variablen ct0 und ct1 aufgebaut werden&lt;br /&gt;
&lt;br /&gt;
[[Bild:VertCount.png|framed|center|&#039;&#039;&#039;8 vertikale Zähler in 2 8-Bit Variablen&#039;&#039;&#039;]]&lt;br /&gt;
&lt;br /&gt;
wobei jeweils ein Bit in ct0 mit dem gleichwertigen Bit in ct1 zusammengenommen einen 2-Bit-Zähler bildet.&lt;br /&gt;
Der Code der sich um die 8 Zähler kümmert, ist so geschrieben, daß er alle 8 Zähler gemeinsam parallel behandelt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
  i = key_state ^ ~KEY_PIN;                       // key changed ?&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
i enthält an dieser Stelle für jede Taste, die sich im Vergleich mit dem vorhergehenden entprellten Zustand (keystate) verändert hat, ein 1 Bit.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
  ct0 = ~( ct0 &amp;amp; i );                             // reset or count ct0&lt;br /&gt;
  ct1 = ct0 ^ (ct1 &amp;amp; i);                          // reset or count ct1&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese beiden Anweisungen erniedrigen den 2-Bit Zähler ct0/ct1 für jedes Bit um 1, welches in i gesetzt ist. Liegt an der entsprechenden Stelle in i ein 0 Bit vor (keine Änderung des Zustands), so wird der Zähler ct0/ct1 für dieses Bit auf 1 gesetzt.&lt;br /&gt;
Der Grundzustand des Zählers ist als ct0 == 1 und ct1 == 1 (Wert 3). Der Zähler zählt daher mit jedem ISR Aufruf, bei dem die Taste im Vergleich zu keystate als verändert erkannt wurde&lt;br /&gt;
&lt;br /&gt;
   ct1   ct0&lt;br /&gt;
     1    1   // 3&lt;br /&gt;
     1    0   // 2&lt;br /&gt;
     0    1   // 1&lt;br /&gt;
     0    0   // 0&lt;br /&gt;
     1    1   // 3&lt;br /&gt;
&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
  i &amp;amp;= ct0 &amp;amp; ct1;                                 // count until roll over ?&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
in i bleibt nur dort ein 1-Bit erhalten, wo sowohl in ct1 als auch in ct0 ein 1 Bit vorgefunden wird, der betreffenede Zähler also bis 3 zählen konnte. Durch die zusätzliche Verundung mit i wird der Fall abgefangen, dass ein konstanter Zählerwert von 3 in i ein 1 Bit hinterlässt. Im Endergebnis bedeutet dass, dass nur ein Zählerwechsel von 0 auf 3 zu einem 1 Bit an der betreffenden Stelle in i führt. Das heißt, ein Tastendruck wird erkannt, wenn die Taste 4 mal hintereinander in einem anderen Zustand vorgefunden wurde als dem zuletzt bekannten entprellten Tastenzustand.&lt;br /&gt;
&lt;br /&gt;
An dieser Stelle ist i daher ein Vektor von 8 Bits, von denen jedes einzelne der Bits darüber Auskunft gibt, ob die entsprechende Taste mehrmals hintereinander im selben Zustand angetroffen wurde, der nicht mit dem zuletzt bekannten Tastenzustand übereinstimmt. Ist das der Fall, dann wird eine entsprechende Veränderung des Tastenzustands in key_state registriert&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
  key_state ^= i;                                 // then toggle debounced state&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
und wenn sich in key_state das entsprechende Bit von 0 auf 1 verändert hat, wird dieses Ereignis als &#039;Taste wurde niedergedrückt&#039; gewertet.&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
  key_press |= key_state &amp;amp; i;                     // 0-&amp;gt;1: key press detect&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit ist der Tasteneingang entprellt. Und zwar sowohl beim Drücken einer Taste als auch beim Loslassen (damit Tastenpreller beim Loslassen nicht mit dem Niederdrücken einer Taste verwechselt werden). Der weitere Code beschäftigt sich dann nur noch damit, diesen entprellten Tastenzustand weiter zu verarbeiten.&lt;br /&gt;
&lt;br /&gt;
Der Codeteil sieht durch die Verwendung der vielen bitweisen Operationen relativ komplex aus. Behält man aber im Hinterkopf, dass einige der bitweisen wie ein &#039;paralles If&#039; gleichzeitig auf allen 8 Bits eingesetzt werden, dann vereinfacht sich vieles. Ein&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
    key_press |= key_state &amp;amp; i;&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
ist nichts anderes als ein&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
    // teste ob Bit 0 sowohl in key_state als auch in i gesetzt ist&lt;br /&gt;
    // und setze Bit 0 in key_press, wenn das der Fall ist&lt;br /&gt;
    if( ( key_state &amp;amp; ( 1 &amp;lt;&amp;lt; 0 ) ) &amp;amp;&amp;amp;&lt;br /&gt;
        ( i &amp;amp; ( 1 &amp;lt;&amp;lt; 0 ) )&lt;br /&gt;
       key_press |= ( 1 &amp;lt;&amp;lt; 0 );&lt;br /&gt;
&lt;br /&gt;
    // Bit 1&lt;br /&gt;
    if( ( key_state &amp;amp; ( 1 &amp;lt;&amp;lt; 1 ) ) &amp;amp;&amp;amp;&lt;br /&gt;
        ( i &amp;amp; ( 1 &amp;lt;&amp;lt; 1 ) )&lt;br /&gt;
       key_press |= ( 1 &amp;lt;&amp;lt; 1 );&lt;br /&gt;
&lt;br /&gt;
    // Bit 2&lt;br /&gt;
    if( ( key_state &amp;amp; ( 1 &amp;lt;&amp;lt; 2 ) ) &amp;amp;&amp;amp;&lt;br /&gt;
        ( i &amp;amp; ( 1 &amp;lt;&amp;lt; 2 ) )&lt;br /&gt;
       key_press |= ( 1 &amp;lt;&amp;lt; 2 );&lt;br /&gt;
&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
nur als wesentlich kompaktere Operation ausgeführt und für alle 8 Bits gleichzeitig.&lt;br /&gt;
Die Kürze und Effizienz dieser paar Codezeilen ergibt sich aus dem Umstand, dass jedes Bit in den Variablen für eine Taste steht und alle 8 (maximal möglichen) Tasten gleichzeitig die Operationen durchlaufen.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* [[AVR-Tutorial: Tasten]]&lt;br /&gt;
* [[AVR-GCC-Tutorial#.28Tasten-.29Entprellung|AVR-GCC-Tutorial Tastenentprellung]]&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-4-20435.html Beitrag im Forum, AVR Assembler]&lt;br /&gt;
* [http://www.ganssle.com/debouncing.pdf A guide to debouncing (engl.), praktische Erläuterungen zum Entprellen in Soft- und Hardware]&lt;br /&gt;
* [http://www.pololu.com/docs/0J16/all Understanding Destructive LC Voltage Spikes]&lt;br /&gt;
&lt;br /&gt;
[[Category:AVR]]&lt;br /&gt;
[[Kategorie:Signalverarbeitung]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Pegelwandler&amp;diff=68439</id>
		<title>Pegelwandler</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Pegelwandler&amp;diff=68439"/>
		<updated>2012-09-21T19:58:31Z</updated>

		<summary type="html">&lt;p&gt;Maybee: Änderung 68438 von 88.69.135.22 (Diskussion) wurde rückgängig gemacht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Vorwort ==&lt;br /&gt;
&lt;br /&gt;
Dies ist die erste aufgeräumte Version. Sicher nicht die letzte.&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-1-375051.html &amp;quot;Stein des Anstosses&amp;quot;]&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/list-1-1.html?filter=pegelwand*+levelsh*&amp;amp;x=0&amp;amp;y=0 Suche in den Forenartikel]&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Pegelwandeln (engl. level shifting) wird oft notwendig, wenn Systeme mit unterschiedlicher Ausgangs- und Eingangsspannungen (z.&amp;amp;nbsp;B. Versorgungs- oder Logikspannungen) miteinander verbunden werden sollen. Das vielleicht bekannteste Beispiel ist die Umsetzung von 0V/5V [[TTL]] Logikpegeln auf die -12V/12V Pegel einer seriellen [[RS232]] Schnittstelle. Die Probleme beim Pegelwandeln können sein:&lt;br /&gt;
&lt;br /&gt;
# Überlastung einer oder beider Seiten&lt;br /&gt;
# Inkompatible Logikpegel und daraus resultierendes Nichtfunktionieren der Schaltung, oder noch schlimmer, sporadische Fehlfunktionen&lt;br /&gt;
# Verzögerungen der Signale durch die Pegelwandlung und daraus resultierende maximale Signalfrequenzen&lt;br /&gt;
&lt;br /&gt;
=== Überlastung ===&lt;br /&gt;
&lt;br /&gt;
Das Erzeugen von verschiedenen Versorgungsspannungen ist ziemlich einfach, aber man muss sicher gehen, daß man die Signalleitungen zwischen den Bauteilen überprüft. Wenn ein 5V Bauteil ein Signal an ein 3V Bauteil schickt, können beide Bauteile beschädigt werden. Vor allem für neue ICs ist es ein Problem mit &amp;quot;hohen&amp;quot; Spannungen wie 5V zu arbeiten. Auf Grund der immer kleineren Schaltkreisstrukturen (der aktuelle Pentium wird mit 45nm Technologie hergestellt!) werden auch die Abstände und Schichtdicken immer geringer. Das reduziert natürlich auch die Spannungsfestigkeit der Transistoren auf dem IC. Neue ICs vertragen deshalb meist nur noch 3.3V, teilweise sogar weniger! Die Überlastung erfolgt durch zu hohe Spannung und dadurch mehr oder weniger langsame Zerstörung des ICs.&lt;br /&gt;
&lt;br /&gt;
=== Schutzdioden ===&lt;br /&gt;
&lt;br /&gt;
Hauptursache Nummer zwei für Überlastung von ICs mit verschiedenen Betriebsspannungen sind die in nahezu allen ICs integrierten Schutzdioden. Deren Aufgabe ist es in Normalfall, elektrostatische Entladungen auf eine sichere, niedrige Spannung zu begrenzen. Die Entladungen geschehen durch unsachgemässe Handhabung und Transport von ICs, z.&amp;amp;nbsp;B. wenn jemand über einen Kunstfaserteppich läuft, sich dabei elektrostatisch auflädt und einen IC anfasst. Oder wenn Bauteile in einem Gerät eingebaut sind und der Anwender berührt offen liegende Kontakte (RS232 Eingang, USB-Stick, PCI-Steckkarten beim Einbau etc.). Die Schutzdioden beginnen Strom zu leiten, wenn die Eingangsspannung ca. 500mV über VCC ansteigt oder mehr als 500mV unter GND absinkt. Im Normalbetrieb sollten die Schutzdioden keinen Strom leiten. Manchmal kann man sie aber zur Spannungsbegrenzung missbrauchen, siehe [[#STEP-DOWN:_5V_-.3E_3.3V | Step Down mit Vorwiderstand]].&lt;br /&gt;
&lt;br /&gt;
[[bild:pw_schutzdioden.png]]&lt;br /&gt;
&lt;br /&gt;
=== 5 V tolerante Eingänge ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;i&amp;gt;5-Volt-tolerant&amp;lt;/i&amp;gt; bedeutet, dass 3-Volt-Bausteine ohne Probleme von einem 5-Volt-Baustein angesteuert werden dürfen.&lt;br /&gt;
&lt;br /&gt;
Viele Bauteile mit einer Betriebsspannung von 3 V verfügen über 5-V-tolerante Eingänge. Man sollte aber grundsätzlich im Datenblatt dies nachschauen, bevor die Schaltung aufgebaut wird. Sind sie es nicht, so ist ein &amp;lt;b&amp;gt;Pegelwandler&amp;lt;/b&amp;gt; auf den Verbindungsleitungen zwischen den Bauteilen notwendig. Ein Pegelwandler kann eine einfache Zener-Diode mit einem Widerstand sein, es kann aber auch ein eigens dafür vorgesehener IC sein. Sind die Signalwege bidirektional, so wird man meist die Lösung mit einem eigenen IC bevorzugen.&lt;br /&gt;
&lt;br /&gt;
[[AVR]]s sind generell &#039;&#039;&#039;nicht&#039;&#039;&#039; 5-V-tolerant, wenn sie mit 3,3 V betrieben werden! Die absolute obere Grenze für Eingangsspannungen liegt bei Vcc + 0,5 V. Zu finden in den elektrischen Spezifikationen im Datenblatt.&lt;br /&gt;
&lt;br /&gt;
Ob ein Bauteil 5-V-tolerant ist und unter welchen Betriebsbedingungen das gilt, steht im Datenblatt des betreffenden Bauteils vom betreffenden Hersteller. Wenn es auf diese Eigenschaft ankommt, lieber genau bei Lieferanten nachsehen, von welchem Hersteller die Bauteile kommen.&lt;br /&gt;
&lt;br /&gt;
Vorsicht bei:&lt;br /&gt;
&lt;br /&gt;
* 74&#039;&#039;&#039;LVX&#039;&#039;&#039;xxxx und 74&#039;&#039;&#039;LCX&#039;&#039;&#039;xxxx (245, 244, 240 ...) an Vcc = 3,3 V.&amp;lt;br&amp;gt;&amp;lt;font color=FF0000&amp;gt;Achtung&amp;lt;/font&amp;gt;: Nicht alle 74LVX sind für 5 V -&amp;gt; 3,3 V geeignet, da jeder Hersteller die ICs anders baut!&lt;br /&gt;
&lt;br /&gt;
=== Kompatibilität von Logikpegeln ===&lt;br /&gt;
&lt;br /&gt;
Siehe auch http://www.interfacebus.com/Design_Translation.html&lt;br /&gt;
&lt;br /&gt;
Verschiedene Mikroprozessoren haben eigene elektrische Kenndaten für HIGH und LOW Pegel, die abhängig von der Versorgungsspannung sind, z.&amp;amp;nbsp;B. der [[R8C]]:&lt;br /&gt;
&lt;br /&gt;
* HIGH grösser 0,8 * Vcc&lt;br /&gt;
* LOW kleiner 0,2 * Vcc&lt;br /&gt;
&lt;br /&gt;
Man muss die Spannungen der Aus- und Eingänge vergleichen. Wenn es um ein Hobbyprojekt geht, kann man einfach messen. Wenn es um eine kommerzielle Anwendung geht, die man verkaufen will, sollte man besser die Spezifikationen der ICs studieren.&lt;br /&gt;
&lt;br /&gt;
== UNIDIREKTIONAL ==&lt;br /&gt;
&lt;br /&gt;
=== 1,8 V -&amp;gt; 5 V ===&lt;br /&gt;
&lt;br /&gt;
* Die besondere Eigenschaft der alten TTL Schaltkreise, nämlich dass Strom bei LOW &#039;&#039;&#039;aus&#039;&#039;&#039; dem Eingang in den treibenden Ausgang fliesst kann man sich zu nutze machen, wie die nachfolgende Schaltung zeigt. In dieser wird der HIGH-Pegel des 1,8-V-Signals durch eine Schottkydiode um ca. 0,3 V auf 2,1 V erhöht. Damit ist man fast offiziell im HIGH-Bereich für TTL (Schaltschwelle 1,4 V, HIGH &amp;gt; 2,0 V). Der LOW-Pegel wird auf ca. 0,3 V erhöht, was voll den TTL-Richtlinien entspricht. Als Schaltkreisfamilie &#039;&#039;&#039;muss&#039;&#039;&#039; ein [[74xx|TTL-Typ]] eingesetzt werdem, also LS, F, AS oder ähnlich. CMOS-Typen wie HC, LVC etc. funktionieren &#039;&#039;&#039;nicht&#039;&#039;&#039;!&lt;br /&gt;
&lt;br /&gt;
[[bild:pw_LS.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=FF0000&amp;gt;Achtung&amp;lt;/font&amp;gt;: Diese Schaltung entspricht bei HIGH ungefähr einem offenen TTL-Eingang, was zwar meistens funktioniert, aber etwas störempfindlich sein kann. Davon wurde in der TTL-Ära stets abgeraten. Zudem ist der Pegelwechsel LOW nach HIGH durch den niedrigen Strom eher langsam. Man kann das jedoch mit einem Pullup-Widerstand absichern. Dann sind auch Gatter der 74HCT-Reihe einsetzbar.&lt;br /&gt;
&lt;br /&gt;
=== 3.3V -&amp;gt; 5V ===&lt;br /&gt;
&lt;br /&gt;
* 3.3V Pegel werden bei TTL kompatiblen Eingängen richtig erkannt (Schaltschwelle 1,4V). Es ist kein Pegelwandler erforderlich. Direkte Verbindung.&lt;br /&gt;
&lt;br /&gt;
* 5V CMOS Eingänge haben typisch eine minimale Eingangsspannug für HIGH (&amp;lt;math&amp;gt;V_{IH}&amp;lt;/math&amp;gt;) von 0.6 * VCC = 0.6 * 5V = 3V. Das kann ein 3.3V CMOS Ausgang direkt treiben, allerdings kann sich das Zeitverhalten dadurch etwas ändern weil der HIGH Pegel später erkannt wird. Vorsicht! Viele 5V CMOS ICs wollen für HIGH offiziell mindestens 0.7V * VCC = 3.5V oder manche auch 0.8 * VCC = 4.0V! Das geht dann offiziell nicht mehr mit einem 3.3V Ausgang! Für Hobbyzwecke kann man das aber ggf. probieren.&lt;br /&gt;
&lt;br /&gt;
* 3.3V [[Ausgangsstufen_Logik-ICs | Open Collector]] nach 5V (TTL oder CMOS): Einfach einen Pull-Up Widerstand hinzufügen und gut. Allerdings verbraucht der Pull-Up Widerstand bei LOW relativ viel Strom und kann bei HIGH nicht allzuviel Strom liefern. Die Schaltgeschwindigkeit von LOW nach HIGH wird durch die Grösse des Pull-Ups bestimmt.&lt;br /&gt;
&lt;br /&gt;
[[bild:pw_oc_3-5.png]]&lt;br /&gt;
&lt;br /&gt;
* 3,3V auf echte 5V (CMOS) geht am einfachsten mit einem Baustein der HCT Familie (NICHT HC !). Diese haben TTL-compatible Eingänge und echte CMOS Ausgänge&lt;br /&gt;
&lt;br /&gt;
* Man kann einen Komparator in nichtinvertierender Schaltung benutzen (LM339/393). Allerdings ist diese Lösung meist relativ langsam, abhängig vom verwendeten Komparator.&lt;br /&gt;
&lt;br /&gt;
[[bild:pw_comp_3-5.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bauteile&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* 74HCTxxx (245, 244, 240 ...)&lt;br /&gt;
* 74HCT125: OE Pins auf Masse und dann das Signal einfach anschließen.&lt;br /&gt;
* SN74LVC07AD&lt;br /&gt;
&lt;br /&gt;
=== 5V -&amp;gt; 9..15V ===&lt;br /&gt;
&lt;br /&gt;
* Am einfachsten geht das mit einem Open Collector Ausgang, einfach einen Pull-Up hinzufügen (an die hohe Spannung) und fertig.&lt;br /&gt;
&lt;br /&gt;
[[bild:pw_oc_5-12.png]]&lt;br /&gt;
&lt;br /&gt;
* Man kann einen Komparator benutzen. Allerdings ist diese Lösung meist relativ langsam, abhängig vom verwendeten Komparator. Wenn nur zwei Signale pegelgewandlet werden müssen bietet sich der LM393 an, ein Doppelkomparator mit Open Collector Ausgang, mit dem man auf einen beliebigen Pegel ausgeben kann. Der LM339 ist ein Vierfachkomparator mit den gleichen Eigenschaften. Wenn wenig Platz vorhanden ist, dann ist der TL311 im winzigen SOT-23 Gehäuse sehr empfehlenswert. Bei jedem Komparator kann auch einfach eine Invertierung gemacht werden, einfach die Eingänge + und - vertauschen. Diese Komparatoren eignen sich bis ca. 1 MHz.&lt;br /&gt;
&lt;br /&gt;
* [http://www.elektronik-kompendium.de/sites/praxis/bausatz_pegelwandler-mit-transistoren.htm Pegelwandler mit Transistor, invertierend]&lt;br /&gt;
&lt;br /&gt;
[[bild:pw_trans_inv.png]]&lt;br /&gt;
&lt;br /&gt;
* Pegelwandler mit Transistor, nicht invertierend&lt;br /&gt;
&lt;br /&gt;
[[bild:pw_trans_ni.png]]&lt;br /&gt;
&lt;br /&gt;
Die Idee ist einfach. Wenn der Ausgang des 5V Gatters auf HIGH ist dann ist der Transistor ausgeschaltet, der Pull-Up Widerstand R7 zieht den Ausgang auf +12V. Ist der Ausgang des 5V Gatters auf LOW ist, dann ist er vollkommen durchgesteuert und der Ausgang nahe 0V (je nach Typ ca. 300mV). Der Vorteil ist hier erhöhte Störsicherheit im Gegensatz zur einfachen Ansteuerung der Basis über einen Vorwiderstand. Ausserdem wird dadurch nicht die Logik invertiert. Nachteilig ist der geringe Strom, der bei HIGH zur Verfügung steht (typisch 100&amp;amp;mu;A). Diese Schaltung ist die seltene Anwendung einer Basisschaltung für digitale Signale.&lt;br /&gt;
&lt;br /&gt;
* Wenn mehr Geschwindigkeit, Ausgangsstrom und weniger Stromverbrauch nötig ist, dann muss ein spezieller Baustein her, wie z.&amp;amp;nbsp;B.&amp;lt;BR&amp;gt;&amp;lt;BR&amp;gt;&lt;br /&gt;
** [[Mosfet-Übersicht#Mosfet-Treiber|MOSFET-Treiber]] z.B. ICL7667&lt;br /&gt;
** [[H-Brücken Übersicht | Motortreiber]] ICs: (z.&amp;amp;nbsp;B. L293, L298, UCC27325 und deren Verwandte), wenns nicht zu schnell ist (einige Dutzend kHz)&lt;br /&gt;
** CD40109, bei Reichelt verfügbar&lt;br /&gt;
** HEF4104, 4fach LOW-HIGH Pegelwandler mit normalen und invertierten Augängen sowie Tristate. Um ggf. sicherzustellen, dass wie im Datenblatt beschrieben immer VDDI &amp;lt;= VDDO ist, kann man einfach eine Diode von VDDO nach VDDI schalten (z.&amp;amp;nbsp;B. Schottky SB120, aber auch 1N4148 &amp;amp; Co sollte problemlos funktionieren)&lt;br /&gt;
** CMOS 4504, 6fach LOW-HIGH/HIGH-LOW 3-20V Pegelwandler, TTL/CMOS (umschaltbar) =&amp;gt; CMOS, kein Reihenfolge von Vcc/Vee erforderlich (Bezugsquelle: CSD)&lt;br /&gt;
** MAX232, der braucht nur 5V Versorgungsspannung. Allerdings ist der Ausgangswiderstand relativ hoch (ca. 300Ω) und man kann nur ca. 5mA Ausgangstrom liefern. Die Ausgangsspannung beträgt maximal 10V.&lt;br /&gt;
&lt;br /&gt;
=== 5V -&amp;gt; 3.3V ===&lt;br /&gt;
&lt;br /&gt;
* Zuerst sollte man prüfen, ob die Eingänge 5V tolerant sind. Dann kann man die ICs direkt verbinden. Sehr schnell und billig!&lt;br /&gt;
&lt;br /&gt;
* Wenn die Eingänge nicht 5V tolerant sind und es trotzdem schnell sein soll, muss ein Gatter aus der LVC oder AHC Familie dazwischen geschaltet werden. Bei 3V Betriebsspannung kann man problemlos 5V an den Eingang anlegen. Der Baustein 74HC4050 erlaubt per Definition eine Pegelwandlung bis etwa 15V (siehe Datenblatt). Beide Anordungen verbrauchen auch sehr wenig Ruhestrom.&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&#039;Bauteile&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:* 74LVC245A (&#039;A&#039; ist wichtig, I/Os 5V-tolerant)&lt;br /&gt;
:* 74LVC245DW &lt;br /&gt;
:* 74LVT245 &lt;br /&gt;
:* 74LVXxxx (245, 244, 240 ...) an Vcc=3,3V. Achtung: Nicht alle 74LVX sind für 5V -&amp;gt; 3,3V geeignet, da jeder Hersteller die ICs anders baut!&lt;br /&gt;
:** 74LVX04 &lt;br /&gt;
:** 74LVX244 (Fairchild)&lt;br /&gt;
:** 74LVX245 (nicht von Reichelt, nicht 5V tolerant)&lt;br /&gt;
:** bei TI heissen die 74LVX... nur 74LV...&lt;br /&gt;
&lt;br /&gt;
:* 74HC4050 (bis 15V Step Down Pegelwandlung laut Datenblatt, bei Reichelt in DIP und SO erhältlich)&lt;br /&gt;
:* MAX3373/MAX3375&lt;br /&gt;
:* NC7SZ08 oder andere aus derselben Serie. CMOS-Logik mit 5V-toleranten Eingängen, recht flott und braucht dank SOT-23 auch wenig Platz auf dem Print&lt;br /&gt;
&lt;br /&gt;
* 5V Open Collector auf 3.3V Eingang. Einfach einen Pull-Up hinzufügen (Pull-Up liegt auf 3.3V). Nachteilig ist der relativ hohe Stromverbrauch bei LOW, die begrenzte Geschwindigkeit bei hochohmigen Pull-Ups und der relativ geringe Ausgangsstrom bei HIGH (abhängig vom Pull-Up).&lt;br /&gt;
&lt;br /&gt;
[[bild:pw_oc_5-3.png]]&lt;br /&gt;
&lt;br /&gt;
* Spannungsteiler mit 680Ω und 1kOhm. Der Nachteil dieser Lösung ist der relativ hohe Stromverbrauch (~3mA), der relativ geringe Ausgangsstrom (mehr als 200..300uA sollte man da nicht rausziehen) und die relativ geringe Geschwindigkeit (ca. 10 MHz).&lt;br /&gt;
&lt;br /&gt;
[[bild:pw_st_5-3.png]]&lt;br /&gt;
&lt;br /&gt;
* 1 kOhm Vorwiderstand. Dadurch wird der Strom vom 5V Ausgang in die 3.3V Versorgung durch die internen Schutzdioden auf ca. 1mA begrenzt. Diese Lösung ist auch relativ langsam (ca. 5MHz). Ggf. kann man den Vorwiderstand auf 100Ω reduzieren, das erhöht dann wieder die Geschwindigkeit. Aufpassen, einige ICs vertragen nur 1mA oder weniger durch die Schutzdioden! Ausserdem muss man aufpassen, das jetzt von der 5V Seite Strom in die 3.3V Versorgung eingespeist wird. Besonders in Schaltungen mit sehr niedrigem Stromverbrauch kann das zum Problem werden, wenn weniger Strom verbraucht wird als über die Vorwiderstände eingespeist wird. Dann nimmt es meist der Spannungsregler für 3.3V übel wenn jemand &amp;quot;schiebt&amp;quot;, sprich, Strom einspeist. Denn die allermeisten Spannungsregler können nur Strom liefern (source), aber keinen Strom aufnehmen (sink). Es gibt 4-fach-Diodennetzwerke, die die internen Schutzdioden entlasten können (Schottkydioden mit kleinerer Flusspannung von ~0,3V als die internen Silizizumdioden mit ~0,7V), außerdem ist teilweise noch eine [[Diode#Z-Diode|Zenerdiode]] enthalten, die ggf. den überschüssig eingespeisten Strom aufnehmen kann. &lt;br /&gt;
&lt;br /&gt;
[[bild:pw_vw_5-3.png]]&lt;br /&gt;
&lt;br /&gt;
Achtung: Mindestens für 74HC(T) Gatter ist dokumentiert (Philips 74HC/T High-Speed CMOS User Guide), dass auch schon geringer Strom durch die internen Schutzdioden zu einer unerwünschten Kopplung von Eingängen führen kann, d.h. der Strom fliesst zu einem anderen Eingang wieder hinaus. Sind also andere Eingänge ebenso hochohmig angeschlossen, kann dieser Querstrom zu Fehlfunktion führen.&lt;br /&gt;
&lt;br /&gt;
== BIDIREKTIONAL ==&lt;br /&gt;
&lt;br /&gt;
Für bidirektionale Busse gibt es spezielle Pegelwandler mit 2 Versorgungsspannungen. Allerdings brauchen die meist ein Signal zur Richtungsumschaltung. Auch muss man die Reihenfolge der Versorgungsspannungen beim Einschalten beachten. Aktive bidirektionale Pegelwandler OHNE Steuereingang zur Richtungsumschaltung sind mit Vorsicht zu geniessen, denn die brauchen teilweise kurzzeitig einen relativ hohen Strom, um die Eingänge zu treiben.&lt;br /&gt;
&lt;br /&gt;
=== 5V &amp;lt;-&amp;gt; 3.3V ===&lt;br /&gt;
&lt;br /&gt;
* Wenn die 5V Seite TTL-kompatible Eingänge hat kann wieder der Spannungsteiler oder Vorwiderstand wie bei der unidirektionalen Anpassung verwendet werden (mit all seinen Vor- und Nachteilen).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bauteile&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* SN74CB3T3306&lt;br /&gt;
* SN74CBTD3861 (10 Bit,flow through, Betrieb mit 5 Volt)&lt;br /&gt;
* MAX1741 &lt;br /&gt;
* MAX3378E &lt;br /&gt;
* 74AHC126 s.u.&lt;br /&gt;
* ST2378 (bei CSD erhältlich, 3.5 eur, leider TSSOP)&lt;br /&gt;
* TXS0104E (TI: 4-BIT BIDIRECTIONAL VOLTAGE-LEVEL TRANSLATOR FOR OPEN-DRAIN AND PUSH-PULL APPLICATIONS)&lt;br /&gt;
* SN74LVC07A&lt;br /&gt;
&lt;br /&gt;
=== 1,65V...5,5V &amp;lt;-&amp;gt; 1,65V...5,5V ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bauteile&#039;&#039;&#039;&lt;br /&gt;
* SN74LVC1T45&lt;br /&gt;
* SN74LVC2T45&lt;br /&gt;
* SN74LVC(H)8T245&lt;br /&gt;
* SN74LVC(H)16T245&lt;br /&gt;
&lt;br /&gt;
=== 1,2V...3,6V &amp;lt;-&amp;gt; 1,65V...5,5V ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bauteile&#039;&#039;&#039;&lt;br /&gt;
* TXB0101&lt;br /&gt;
* TXB0102&lt;br /&gt;
* TXB0104&lt;br /&gt;
* TXB0106&lt;br /&gt;
* TXB0108&lt;br /&gt;
&lt;br /&gt;
=== 1,2V...3,6V &amp;lt;-&amp;gt; 1,2V...3,6V ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bauteile&#039;&#039;&#039;&lt;br /&gt;
* SN74AVC(H)1T45&lt;br /&gt;
* SN74AVC(H)2T45&lt;br /&gt;
* SN74AVC(H)4T245&lt;br /&gt;
* SN74AVC(H)8T245&lt;br /&gt;
* SN74AVC(H)16T245&lt;br /&gt;
* SN74AVC(H)20T245&lt;br /&gt;
* SN74AVC(H)24T245&lt;br /&gt;
* SN74AVC(H)32T245&lt;br /&gt;
&lt;br /&gt;
=== 1,5V...3,6V &amp;lt;-&amp;gt; 1,5V...5,5V ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bauteile&#039;&#039;&#039;&lt;br /&gt;
* 74LVC4245A&lt;br /&gt;
&lt;br /&gt;
== Mit galvanischer Trennung ==&lt;br /&gt;
&lt;br /&gt;
* [[Optokoppler]]&lt;br /&gt;
&lt;br /&gt;
[[bild:pw_opto.png]]&lt;br /&gt;
&lt;br /&gt;
* GMR-Koppler von der Firma NVE &lt;br /&gt;
* iCoupler Technologie von der Firma Analog Devices&lt;br /&gt;
* [[Kapazitiver Koppler]]&lt;br /&gt;
&lt;br /&gt;
Lit.: &#039;&#039;Galvanische Trennung: Optokoppler, GMR-Koppler oder iCoupler?&#039;&#039;, Siegfried W. Best, Redaktion elektronik industrie, [http://www.elektronik-industrie.de/ei/11,2003/article/2f0082f824c.html elektronik industrie 11-2003, S. 22ff.]&lt;br /&gt;
&lt;br /&gt;
== Praktische Beispiele ==&lt;br /&gt;
&lt;br /&gt;
=== Einfaches RS232-Interface ===&lt;br /&gt;
&lt;br /&gt;
[http://web.archive.org/web/20050122013618/http://www.henrik-reimers.de/control/rs232interface.gif Erfolgreicher Einsatz bis 19200 Baud und bis zu 10 m Leitungslänge]&lt;br /&gt;
&lt;br /&gt;
Beschränkungen:&lt;br /&gt;
&lt;br /&gt;
* ggf. Platzbedarf&lt;br /&gt;
* Geschwindigkeit s.o.&lt;br /&gt;
&lt;br /&gt;
Beispiel: http://www.hagtech.com/pdf/translator.pdf&lt;br /&gt;
&lt;br /&gt;
=== [[I2C]]-Bus: gemeinsam 3.3V und 5V ===&lt;br /&gt;
&lt;br /&gt;
* [[MSP430]] an 3,3V/5V: http://www-s.ti.com/sc/psheets/slaa148/slaa148.pdf&lt;br /&gt;
&lt;br /&gt;
* Philips [http://www.nxp.com/documents/data_sheet/PCA9515.pdf PCA9515]: I2C Puffer mit Pegelwandlung. Der PCA9515 ist ein I2C-Bus Repeater, welcher I2C Busse mit verschiedenen Spannungen isoliert. Verfügbar bei Reichelt und DigiKey.&lt;br /&gt;
&lt;br /&gt;
* [http://ics.nxp.com/support/documents/interface/pdf/an97055.pdf Philips AN97055 Bi-directional level shifter for I²C-bus and other systems]&lt;br /&gt;
&lt;br /&gt;
* Bevor man ein Philips I2C Chip auswählt sollte man prüfen ob er verfügbar ist und auch das verfügbare Gehäuse wählen. Man sollte auch überlegen ob ein Puffer wirklich gebraucht wird. Wenn man echte I2C ICs mit 5V betreibt, dann sind die Eingänge vom Typ Schmitt Trigger CMOS (z.&amp;amp;nbsp;B. PCF8574). Dann müssen 3.3V Pegel auf 5V umgesetzt werden. Wenn man jedoch SMBUS Ics verwendet (z.&amp;amp;nbsp;B. ADT7461, Silabs 8051) dann sind die Schwellspannungen TTL kompatibel und es ist keine Anpassung notwendig. Für neue Pegelwandler sollte man hier nachschauen. http://www.bus-buffer.com&lt;br /&gt;
&lt;br /&gt;
* [http://www.edn.com/article/CA193193.html &amp;quot;Two-transistor circuit replaces IC&amp;quot;]. Für diese Anwendung kann ENABLE direkt mit 3.3V verbunden werden. Es ist eigentlich nur dazu da, den ICs &amp;quot;hot-swappable&amp;quot; zu machen (kann unter Spannung gesteckt und getrennt werden). Es geht sogar mit nur einem [[Transistor]] [http://www.mikrocontroller.net/topic/92447 siehe Forum]. Man sollte beachten, daß die Schaltung sowohl für SCL als auch SDA benötigt wird. &lt;br /&gt;
* Noch einfachere Lösungen mit nur einem MOSFET und zwei Pull-Up Widerständen pro Leitung sind in den folgenden Links zu finden. Vielleicht ist es sogar noch billiger Bipolartransistoren zu verwenden.&lt;br /&gt;
** http://www.semiconductors.philips.com/markets/mms/protocols/i2c/facts/#levelshifting&lt;br /&gt;
** http://www.semiconductors.philips.com/acrobat_download/literature/9398/39340011.pdf (Kapitel 18), bei der Berechnung der erreichbaren Geschwindigkeit dürfen die parasitären Kapazitäten der FETs nicht ignoriert werden&lt;br /&gt;
&lt;br /&gt;
=== Auswählbare Pegel ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Frage:&#039;&#039;&#039;&lt;br /&gt;
Ein CMOS Logikpegel zwischen 1,8V, 2,5V und 3,3V (abhängig von der Anwendung) muss auf 5V CMOS Logikpegel gewandelt werden. Es geht nur um diese Richtung mit maximal 8MHz. Es gibt die Stromversorgung für alle Pegel. Ein normaler Komparator wie LM311 ist nicht möglich, da er beim Betrieb mit 5V Versorgunsspannung erst ab 1V zu schalten anfängt. Meine Idee ist die Verwendung eines High Speed OPVs mit R2R Eingang, z.&amp;amp;nbsp;B. LMH6645.&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;Antworten:&#039;&#039;&#039;&lt;br /&gt;
* Man könnte einen ultra-low threshold N-Kanal MOSFET nehmen und als Open Drain mit einem Pull-Up nach 5V betreiben, BSH103 könnte passen (Schwellspannung ~0,4V).&lt;br /&gt;
* High-Speed Single Supply Komparator wie z.&amp;amp;nbsp;B. [http://www-s.ti.com/sc/ds/tl712.pdf TL712] .&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Frage:&#039;&#039;&#039;&lt;br /&gt;
Ich suchen einen IC, welcher eine Pegelwandlung von 3,3V nach 1,8V, 2,0V oder 5V ermöglicht und während des Betriebs umgeschaltet werden kann.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Antworten:&#039;&#039;&#039;&lt;br /&gt;
* So ein IC ist der Linear [http://www.linear.com/pc/productDetail.jsp?navId=H0,C1,C1007,C1071,P1601 LTC1555L-1.8] . &lt;br /&gt;
&lt;br /&gt;
=== AVR SPI (SDC/MMC)===&lt;br /&gt;
&lt;br /&gt;
Für &#039;&#039;&#039;bidirektionalen Betrieb&#039;&#039;&#039; zwischen 5V-AVR und 3,3V-Geräten und anders herum gibt es den Level-Translator &#039;&#039;&#039;MAX3378E&#039;&#039;&#039; von Maxim.&lt;br /&gt;
&lt;br /&gt;
Wenn die Datenrichtung am SPI im Zielsystem festgelegt ist, reichen &#039;&#039;&#039;unidirektionale Bausteine&#039;&#039;&#039;:&lt;br /&gt;
* 3x von 5V nach 3,3V und 1x von 3,3V nach 5V: &#039;&#039;&#039;MAX3392E&#039;&#039;&#039;&lt;br /&gt;
* 1x von 5V nach 3,3V und 3x von 3,3V nach 5V: &#039;&#039;&#039;MAX3390E&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Zum Anschließen einer SDC/MMC an einen 5V-AVR eignen sich somit der MAX3978E und der MAX3392E. Beide sind u.A. im winzigen TSSOP-14-Gehäuse verfügbar, nehmen sehr wenig Energie auf und eignen sich auch für andere Spannungen. Mit 3,3 und 5V beträgt die garantierte Übertragungsrate 8Mbps.&lt;br /&gt;
&lt;br /&gt;
* [http://datasheets.maxim-ic.com/en/ds/MAX3372E-MAX3393E.pdf Datenblatt]&lt;br /&gt;
&lt;br /&gt;
Eine weitere Möglichkeit zum Übersetzen zwischen 3,3 und 5V liegt in der Verwendung des &#039;&#039;&#039;74LVC245&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
5V-AVR an eine MMC (ohne Level-Shifter-Baustein):&lt;br /&gt;
* [http://www.microsyl.com/index.php/2010/03/24/led-sign-with-mmc-memory-card/ Projektseite] &lt;br /&gt;
* [http://www.microsyl.com/projects/ledsign/ledsign1.pdf Schaltplan]&lt;br /&gt;
&lt;br /&gt;
=== µC &amp;lt;-&amp;gt; Parallelport ([[ISP]]-Dongle, [[JTAG]] Wiggler, ...) ===&lt;br /&gt;
&lt;br /&gt;
Dieser Schaltplan funktioniert auch bei 3.3V wenn man einen 74&amp;lt;B&amp;gt;HC&amp;lt;/B&amp;gt;244 anstatt eines 74&amp;lt;B&amp;gt;LS&amp;lt;/B&amp;gt;244 verwendet: [http://www.epanorama.net/circuits/parallel_output.html Parallel port interfacing made easy: Simple circuits and programs to show how to use PC parallel port output capabilities].&lt;br /&gt;
&lt;br /&gt;
=== 2 Leitungspaare RX/TX 5V/3,3V ===&lt;br /&gt;
&lt;br /&gt;
Der [http://www.hackaday.com/2008/06/19/sparkfuns-logic-level-converter/ SparkFun&#039;s Logic Level Converter] ist eine Baugruppe mit MOSFETs [http://www.fairchildsemi.com/pf/BS/BSS138.html BSS138] für die Pegelwandlung von 5V auf 3,3V. 5V/2,8V und 5V/1,8V sind ebenfalls machbar.&lt;br /&gt;
&lt;br /&gt;
= Bauteile =&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;74ALVC164245&#039;&#039;&#039; - &#039;&#039;16bit dual supply translating transceiver&#039;&#039;. Eine Seite von 1.5V bis 3.6V, die andere von 1.5 bis 5.5V.&lt;br /&gt;
* &#039;&#039;&#039;74LVX573&#039;&#039;&#039; (unidirektional, Latch, nicht alle Hersteller bauen diesen 5V tolerant!)&lt;br /&gt;
* &#039;&#039;&#039;74LVX245&#039;&#039;&#039; (bidirektional, nicht alle Hersteller bauen diesen 5V tolerant!)&lt;br /&gt;
* &#039;&#039;&#039;74LVX125&#039;&#039;&#039; - &#039;&#039;Low Voltage Quad Buffer with 3-STATE Outputs&#039;&#039;. http://www.fairchildsemi.com/pf/74/74LVX125.html&lt;br /&gt;
* &#039;&#039;&#039;SN74LVC2T45&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;SN74LVC8T245&#039;&#039;&#039; - &#039;&#039;8-Bit Dual-Supply Bus Transceiver with Configurable Voltage Translation and Three-State Outputs&#039;&#039;. http://focus.ti.com/docs/prod/folders/print/sn74lvc8t245.html&lt;br /&gt;
* &#039;&#039;&#039;74LCX244MSA&#039;&#039;&#039; von Fairchild.&lt;br /&gt;
* &#039;&#039;&#039;MAX3377&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;MAX3000&#039;&#039;&#039; 8-Kanal bidirektioneler Pegelwandler ohne Richtungsumschaltung&lt;br /&gt;
* &#039;&#039;&#039;ADG3308&#039;&#039;&#039; 8-Kanal bi-dir. Pegelwandler ohne Richtungsumschaltung, 1,15V..5,5V, 50MBps&lt;br /&gt;
&lt;br /&gt;
Vierfachdioden im kleinen 6-poligen SMD-Gehäuse:&lt;br /&gt;
* http://www.st.com/stonline/products/literature/ds/12635/dsilc6-4xx.pdf&lt;br /&gt;
* http://www.st.com/stonline/products/literature/ds/11599.pdf&lt;br /&gt;
* http://www.st.com/stonline/products/literature/ds/6477/dalc208.pdf&lt;br /&gt;
* [http://www.diodes.com/datasheets/ds30195.pdf QSBT40, vierfach Schottky Terminator für Datenleitungen]&lt;br /&gt;
* [http://www.littlefuse.com/data/en/Data_Sheets/SP724Lead_Free.pdf SP724, Siliziumschutzarray]&lt;br /&gt;
&lt;br /&gt;
= Weblinks =&lt;br /&gt;
&lt;br /&gt;
* Gaurang Kavaiya, [http://www.edn.com/contents/images/6335309.pdf Don’t pay for level translators in systems using multiple power-supply voltages], EDN, MAY 25, 2006, 81-86 (PDF)&lt;br /&gt;
* [http://www.elektronik-kompendium.de/public/schaerer/scf3_lc.htm Einfacher Pegelwandler im ELKO]&lt;br /&gt;
* [http://www.prog-link.com/dcf77/dcf77-17.html Pegelwandler für DFC77 Module]&lt;br /&gt;
* [http://elektronik.kai-uwe-schmidt.de/index.php?page=mp3_blueschaltung Pegelwandler für [[I2C]] Bus in einem MP3 Player]&lt;br /&gt;
* [http://www.mikrocontroller.net/attachment.php/256452/levelshifter.pdf Application Note von Philips, I2C Pegelwandler]&lt;br /&gt;
* [http://www.semiconductors.philips.com/acrobat_download/literature/9398/39340011.pdf I2C Spezifikation]  &lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-1-234277.html#new Forumsbeitrag zum Thema 1,8V-5V Pegelwandler] &lt;br /&gt;
* [http://www.st.com/stonline/products/literature/ds/5186/74lcx16245.pdf 74LCX16245, 16 Bit Pegelwandler]&lt;br /&gt;
* [http://www.standardics.nxp.com/products/lvc/buffers/ LVC Logikfamilie]&lt;br /&gt;
* [http://www.standardics.nxp.com/products/lvc/transceivers/ LVC Tranceiver]&lt;br /&gt;
* [http://www.leg-gmbh.de/html/signalanpassung.html Pegelwandler für die Automatisierungstechnik]&lt;br /&gt;
* [http://www.microchip.com/stellent/groups/techpub_sg/documents/devicedoc/en026368.pdf 3V Tips ‘n Tricks] (PDF) von Microchip&lt;br /&gt;
* [http://www.ti.com/lit/an/slaa148/slaa148.pdf Interfacing the 3-V MSP430 to 5-V Circuits] (PDF) von Texas Instruments&lt;br /&gt;
&lt;br /&gt;
[[Category:Bauteile]]&lt;br /&gt;
[[Kategorie:Datenübertragung]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=ATxMega_Stick_-_First_Steps&amp;diff=68346</id>
		<title>ATxMega Stick - First Steps</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=ATxMega_Stick_-_First_Steps&amp;diff=68346"/>
		<updated>2012-09-09T22:20:41Z</updated>

		<summary type="html">&lt;p&gt;Maybee: /* Siehe auch */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Datei:ATxMegaStick-1.jpg|thumb|Platine des ATxMega Stick]]&lt;br /&gt;
Der ATxMega Stick ist eine kleine Platine (27 mm x 80 mm) mit ATxmega128A3, USB-Device-Anschluss und Micro-SD-Kartenslot.&lt;br /&gt;
&lt;br /&gt;
== Eigenschaften ==&lt;br /&gt;
&lt;br /&gt;
* Mikrocontroller ATxmega128A3&lt;br /&gt;
* USB-Baustein [http://kweb/wiki/images/b/ba/MCP2200_22228A.pdf MCP2200]&lt;br /&gt;
* Mini-USB-B-Device-Anschluss&lt;br /&gt;
* Micro-SD-Kartenslot&lt;br /&gt;
* Programmierung via PDI (z.B. AVRISP mkII)&lt;br /&gt;
* Reset-Taster&lt;br /&gt;
* 2 LEDs zur Signalisierung von USB-Transfers&lt;br /&gt;
* 2 frei verwendbare LEDs&lt;br /&gt;
* On-board-Spannungsregler (3.3 V, Versorgung über USB oder extern)&lt;br /&gt;
* 6 x 8-Bit-Ports auf Stiftleisten verfügbar, davon ist ein Port belegt (2-mal LED, RX und TX zum USB-Baustein, SPI zum Micro-SD-Kartenslot)&lt;br /&gt;
&lt;br /&gt;
== Hinweise zum Aufbau ==&lt;br /&gt;
&lt;br /&gt;
=== Anmerkungen zum Schaltplan vom 15.09.2011 23:08:38 ===&lt;br /&gt;
&lt;br /&gt;
* Seite 1: C1 hat 22µF&amp;lt;br&amp;gt;&lt;br /&gt;
* Seite 1: C14, C15 haben 3.3µF&lt;br /&gt;
* Seite 2: Verbindungsbezeichnung bei &amp;quot;&amp;lt;tt&amp;gt;I/Os&amp;lt;/tt&amp;gt;&amp;quot; µC Pin 27 und JP4 Pin 4 und bei &amp;quot;&amp;lt;tt&amp;gt;LEDs&amp;lt;/tt&amp;gt;&amp;quot; muss &amp;lt;tt&amp;gt;LED3&amp;lt;/tt&amp;gt; lauten statt &amp;lt;tt&amp;gt;LED1&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Seite 2: Verbindungsbezeichnung bei &amp;quot;&amp;lt;tt&amp;gt;I/Os&amp;lt;/tt&amp;gt;&amp;quot; µC Pin 26 und JP4 Pin 3 und bei &amp;quot;&amp;lt;tt&amp;gt;LEDs&amp;lt;/tt&amp;gt;&amp;quot; muss &amp;lt;tt&amp;gt;LED4&amp;lt;/tt&amp;gt; lauten statt &amp;lt;tt&amp;gt;LED2&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stromversorgung ===&lt;br /&gt;
&lt;br /&gt;
Auf JP1 muss ein Jumper bestückt werden:&lt;br /&gt;
* zum Platinenrand hin für Versorgung über USB&lt;br /&gt;
* zur Platinenmitte hin für externe Versorgung&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Hinweis:&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Jumper sollte unbedingt gesteckt sein, wenn USB verwendet wird. Steht dieser auf externer Versorung, muss diese dabei auch anliegen. Wird der MCP2200 per USB versorgt, ohne dass am ATxMega Versorgungsspannung anliegt, kommt es über die UART-Leitung zu einem Stromfluss über das entsprechende I/O-Pin des ATxMega, da dieser sich ohne Spannung intern in einem undefinierten Zustand befindet. Auf VCC liegen dann etwa 2.8 V an. Durch den Stromfluss erwärmt sich der MCP2200 deutlich, was zur eventuellen Beschädigung des ICs führen kann.&lt;br /&gt;
&lt;br /&gt;
=== Löten des SD-Halters ===&lt;br /&gt;
&lt;br /&gt;
* Zuerst muss man den Halten ausrichen und einen Punkt am Rand festlöten.&lt;br /&gt;
* Dann muss man alle 4 Ecken festlöten&lt;br /&gt;
* Jetzt kann man mit der Lötspitze oben durch die Aussparungen und führt den Zinn durch die Öffnung für die SD-Karte.&lt;br /&gt;
* So lötet man dann alle 8 Kontakte.&lt;br /&gt;
* Lötbrücken sind hier nicht schön, lässt sich aber dann noch mit Entlötlitze entfernen (Entlötlitze statt Zinn durch die Öffnung führen)&lt;br /&gt;
&lt;br /&gt;
== Betrieb unter Linux ==&lt;br /&gt;
&lt;br /&gt;
Damit man als User auf den Stick zugreifen kann, empfiehlt es sich, einen UDEV-Eintrag für den Stick anzulegen, z.B. neue Datei /etc/udev/rules.d/15_USB_uC.rules anlegen:&lt;br /&gt;
&lt;br /&gt;
 ATTRS{idVendor}==&amp;quot;04d8&amp;quot;, ATTRS{idProduct}==&amp;quot;00df&amp;quot;, GROUP=&amp;quot;MeineGruppe&amp;quot;, MODE=&amp;quot;0660&amp;quot;, SYMLINK+=&amp;quot;ATxMegaStick%n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Für &amp;quot;MeineGruppe&amp;quot; einen geeigneten Werte verwenden, d.h. eine Gruppe, der man selbst angehört.&lt;br /&gt;
&lt;br /&gt;
Jetzt kann man nach dem Anschließen folgende Links sehen:&lt;br /&gt;
&lt;br /&gt;
 ls -l /dev/ATxMegaStick*&lt;br /&gt;
 lrwxrwxrwx 1 root root  7 2011-10-17 00:04 /dev/ATxMegaStick0 -&amp;gt; ttyACM0&lt;br /&gt;
 lrwxrwxrwx 1 root root 11 2011-10-17 00:04 /dev/ATxMegaStick1 -&amp;gt; usb/hiddev1&lt;br /&gt;
 lrwxrwxrwx 1 root root  7 2011-10-17 00:04 /dev/ATxMegaStick2 -&amp;gt; hidraw2&lt;br /&gt;
 lrwxrwxrwx 1 root root 15 2011-10-17 00:04 /dev/ATxMegaStick3 -&amp;gt; bus/usb/001/042&lt;br /&gt;
&lt;br /&gt;
Und die Zugriffrechte sehen so aus:&lt;br /&gt;
&lt;br /&gt;
 ls -lL /dev/ATxMegaStick*&lt;br /&gt;
 crw-rw---- 1 root dialout 166,  0 2011-10-17 00:04 /dev/ATxMegaStick0&lt;br /&gt;
 crw-rw---- 1 root mgr     180, 97 2011-10-17 00:04 /dev/ATxMegaStick1&lt;br /&gt;
 crw-rw---- 1 root mgr     251,  2 2011-10-17 00:04 /dev/ATxMegaStick2&lt;br /&gt;
 crw-rw-r-- 1 root mgr     189, 41 2011-10-17 00:04 /dev/ATxMegaStick3&lt;br /&gt;
&lt;br /&gt;
== Fuses ==&lt;br /&gt;
&lt;br /&gt;
Default-Werte der Fuses:&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;signature&amp;lt;/tt&amp;gt;: Signatur ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U signature:r:-:h&lt;br /&gt;
 0x1e,0x97,0x42&lt;br /&gt;
:0x1e9742 = ATxmega128A3&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse0&amp;lt;/tt&amp;gt;: JTAG User ID ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse0:r:-:h&lt;br /&gt;
 0xff&lt;br /&gt;
:JTAG User ID (JTAGUID) = 0xff &#039;&#039;&#039;(das Manual sagt: 0x00)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse1&amp;lt;/tt&amp;gt;: Watchdog Configuration ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse1:r:-:h&lt;br /&gt;
 0x0&lt;br /&gt;
:Watchdog Window Timeout Period (WDWPER) = n.a.&lt;br /&gt;
:Watchdog Timeout Period (WDPER) = n.a.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse2&amp;lt;/tt&amp;gt;: Reset Configuration ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse2:r:-:h&lt;br /&gt;
 0xff&lt;br /&gt;
:Reset Vector (BOOTRST) = Application Reset&lt;br /&gt;
:BOD operation in power-down mode (BODPD) = BOD disabled&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse4&amp;lt;/tt&amp;gt;: Start-up Configuration ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse4:r:-:h&lt;br /&gt;
 0xfe&lt;br /&gt;
:External Reset Disable (RSTDISBL) = no&lt;br /&gt;
:Start-up time (STARTUPTIME) = 0&lt;br /&gt;
:Watchdog Timer lock (WDLOCK) = no&lt;br /&gt;
:JTAG enabled (JTAGEN) = yes&lt;br /&gt;
&lt;br /&gt;
Bei Bedarf ändern:&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse4:w:0xff:m&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse4:r:-:h&lt;br /&gt;
 0xff&lt;br /&gt;
:JTAG enabled (JTAGEN) = no&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse5&amp;lt;/tt&amp;gt;: BODACT, BODLEVEL, EESAVE ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse5:r:-:h&lt;br /&gt;
 0xff&lt;br /&gt;
:BOD operation in active mode (BODACT) = BOD disabled&lt;br /&gt;
:EEPROM memory is preserved through the Chip Erase (EESAVE) = no&lt;br /&gt;
:BOD voltage level (BODLEVEL) = 1.6V&lt;br /&gt;
&lt;br /&gt;
Bei Bedarf ändern:&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse5:w:0xf7:m&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse5:r:-:h&lt;br /&gt;
 0xf7&lt;br /&gt;
:EEPROM memory is preserved through the Chip Erase (EESAVE) = yes&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
=== Clock System ===&lt;br /&gt;
&lt;br /&gt;
Takt zu Testzwecken auf Port C Pin 7 (d.h. JP3 Pin 3) ausgeben.&lt;br /&gt;
 PORTC.DIRSET = 0x80;&lt;br /&gt;
 PORTCFG.CLKEVOUT = 0x01;&lt;br /&gt;
&lt;br /&gt;
==== 32 MHz mit dem externen Quarz ====&lt;br /&gt;
&lt;br /&gt;
Unter Verwendung der Software zu AVR1003 (-&amp;gt; Siehe auch) kann man den Takt auf 32 MHz einstellen:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;quot;clksys_driver.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 void init_clock( void )&lt;br /&gt;
 {&lt;br /&gt;
    CLKSYS_XOSC_Config( OSC_FRQRANGE_12TO16_gc, false, OSC_XOSCSEL_XTAL_16KCLK_gc );&lt;br /&gt;
    CLKSYS_Enable( OSC_XOSCEN_bm );&lt;br /&gt;
    CLKSYS_PLL_Config( OSC_PLLSRC_XOSC_gc, 2 );&lt;br /&gt;
    CLKSYS_Enable( OSC_PLLEN_bm );&lt;br /&gt;
    CLKSYS_Prescalers_Config( CLK_PSADIV_1_gc, CLK_PSBCDIV_1_1_gc );&lt;br /&gt;
    do {} while ( CLKSYS_IsReady( OSC_PLLRDY_bm ) == 0 );&lt;br /&gt;
    CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_PLL_gc );&lt;br /&gt;
    CLKSYS_Disable( OSC_XOSCEN_bm );&lt;br /&gt;
 } /* init_clock() */&lt;br /&gt;
&lt;br /&gt;
=== USART ===&lt;br /&gt;
&lt;br /&gt;
==== USART über USB ====&lt;br /&gt;
&lt;br /&gt;
So stellt man unter Verwendung der Software zu AVR1307 (-&amp;gt; Siehe auch) bei 32 MHz Takt den USART für die Übertragung per USB ein:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;quot;usart_driver.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #define USART USARTD0&lt;br /&gt;
 &lt;br /&gt;
 void init_usart( void )&lt;br /&gt;
 {&lt;br /&gt;
    PORTD.DIRSET = PIN3_bm;&lt;br /&gt;
    PORTD.DIRCLR = PIN2_bm;&lt;br /&gt;
    USART_Format_Set( &amp;amp;USART, USART_CHSIZE_8BIT_gc, USART_PMODE_DISABLED_gc, false );&lt;br /&gt;
    /*&lt;br /&gt;
     * BSEL[11:0]-Wert bei 32MHz Takt und BSCALE[3:0]==0:&lt;br /&gt;
     *   207 :   9600&lt;br /&gt;
     *   103 :  19200&lt;br /&gt;
     *    51 :  38400&lt;br /&gt;
     *    34 :  57600&lt;br /&gt;
     *    16 : 115200&lt;br /&gt;
     */&lt;br /&gt;
    USART_Baudrate_Set( &amp;amp;USART, 34 , 0 );&lt;br /&gt;
    USART_Rx_Enable( &amp;amp;USART );&lt;br /&gt;
    USART_Tx_Enable( &amp;amp;USART );&lt;br /&gt;
 } /* init_usart() */&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/227310 Ursprungsbeitrag im Forum]&lt;br /&gt;
* [http://www.jtronics.de/avr-projekte/xmega-tutorial.html XMEGA Tutorial in C] - Tutorial ATxmega (ATxmega128A3U)&lt;br /&gt;
* [http://www.atxmega-board.de/stick Die Seite des Sticks] mit Schaltplan und Stückliste&lt;br /&gt;
* &amp;lt;del&amp;gt;[http://www.stromflo.de/dokuwiki/doku.php?id=xmega-c-tutorial XMEGA-C-Tutorial auf stromflo.de]&amp;lt;/del&amp;gt; :-(&lt;br /&gt;
* [http://www.atmel.com/dyn/products/product_card.asp?part_id=4302 Produktseite des ATxmega128A3] mit jeder Menge an Dokumentation und Application Notes&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc8072.pdf AVR1003: Using the XMEGA Clock System] (PDF) und [http://www.atmel.com/dyn/resources/prod_documents/AVR1003.zip Software] (ZIP)&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc8049.pdf AVR1307: Using the XMEGA USART] (PDF) und [http://www.atmel.com/dyn/resources/prod_documents/AVR1307.zip Software] (ZIP)&lt;br /&gt;
* [http://www.microchip.com/wwwproducts/devices.aspx?dDocName=en546923 Produktseite des MCP2200] mit Dokumentation und Tools&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR-GCC-Codeoptimierung&amp;diff=67501</id>
		<title>AVR-GCC-Codeoptimierung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR-GCC-Codeoptimierung&amp;diff=67501"/>
		<updated>2012-07-24T22:39:11Z</updated>

		<summary type="html">&lt;p&gt;Maybee: /* Logische Operatoren werden auf int-Größe erweitert */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Entstanden aus diesem [http://www.mikrocontroller.net/topic/66690 Thread] sollen hier ein paar Hinweise/Erfahrungen gegeben werden, um den Quellcode in Punkto Größe und Geschwindigkeit zu optimieren. &#039;&#039;En detail&#039;&#039; ist das Thema komplex, da es stark von der Codeoptimierung des Compilers abhängt. Es ist im Einzelfall ratsam zu prüfen, ob die eigenen Maßnahmen auch erfolgreich waren. Die Diskussionen [http://www.mikrocontroller.net/topic/132624] bzw. [http://www.mikrocontroller.net/topic/180800#new] können als Anhaltspunkte dienen, wie eine solche Prüfung ablaufen kann.&lt;br /&gt;
&lt;br /&gt;
== Prinzipien der Optimierung ==&lt;br /&gt;
&lt;br /&gt;
Wie so oft sollte man nicht einfach wild drauf los optimieren und sich zunächst ein paar Dinge klar machen.&lt;br /&gt;
&lt;br /&gt;
* Warum will ich optimieren?&lt;br /&gt;
* Was kann man sinnvoll optimieren?&lt;br /&gt;
* Wieviel Rechenzeit oder Speicher soll dabei gespart werden?&lt;br /&gt;
* Wie kann optimiert werden?&lt;br /&gt;
* &amp;quot;Verfrühte Optimierung ist die Wurzel allen Übels&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Viele Optimierungen sind &amp;quot;Angst-Optimierungen&amp;quot;, die nicht wirklich nötig sind. Die Gefahr mit Optimierungen ist, den Code tot zu optimieren, sprich Lesbarkeit, Portierbarkeit und ggf. Fehlerfreiheit sinken massgeblich. Kurz und knapp in diesem [http://blogs.msdn.com/b/audiofool/archive/2007/06/14/the-rules-of-code-optimization.aspx BLOG] formuliert.&lt;br /&gt;
&lt;br /&gt;
=== Warum ===&lt;br /&gt;
&lt;br /&gt;
Optimieren sollte man nur, wenn&lt;br /&gt;
* der Speicher nicht mehr ausreicht (RAM, Flash)&lt;br /&gt;
* Die Laufzeit für bestimmte Programmteile zu groß wird und somit bestimmte (Echtzeit-)Ausgaben nicht im erforderlichen Zeitrahmen erledigt werden&lt;br /&gt;
&lt;br /&gt;
Weiter sollte man folgende Punkte gegeneinander abwägen:&lt;br /&gt;
&lt;br /&gt;
* Codeverbrauch&lt;br /&gt;
* Datenverbrauch. Statisch/Stack/Heap&lt;br /&gt;
* Mittlere Laufzeit/maximale Laufzeit&lt;br /&gt;
* Entwicklungszeit&lt;br /&gt;
* Portabilität (Compiler, Hardware, ...)&lt;br /&gt;
* Verständlichkeit der Quelle, siehe [[Strukturierte Programmierung auf Mikrocontrollern]] &lt;br /&gt;
* ABI-Konformität&lt;br /&gt;
&lt;br /&gt;
=== Was ===&lt;br /&gt;
&lt;br /&gt;
Die goldene Regle lautet: 90% der Rechenleistung werden in 10% des Codes verbraucht. Diese 10% muss man finden und zum richtigen Zeitpunkt optimieren. Der Rest muss nur sauber und lesbar geschrieben sein. Was jedoch nichts bringt, ist eine Funktion, die von 1 Minute Programmlaufzeit lediglich 1 Sekunde verbraucht, um den Faktor 10 schneller zu machen. Die Programmlaufzeit sinkt dann von 60 Sekunden auf 59.1 Sekunden. Der Aufwand, die Funktion um einen Faktor 10 schneller zu machen ist aber meistens beträchtlich!  Kann ich aber den Code, der für die 59 Sekunden verantwortlich ist um einen Faktor 10 schneller machen, dann sinkt die Gesamtlaufzeit von 60 Sekunden auf 6.9 Sekunden. Dort bringt Optimieren augenscheinlich viel mehr!&lt;br /&gt;
&lt;br /&gt;
Um die optimierungswürdigen Stellen zu finden, muss man sein Programm analysieren. Dazu gibt es verschiedene Möglichkeiten.&lt;br /&gt;
&lt;br /&gt;
====Speicherverbrauch nach Funktionen aufschlüsseln====&lt;br /&gt;
&lt;br /&gt;
;map-File:&lt;br /&gt;
:dort sind alle globalen und statischen Variablen enthalten. Eine Map-Datei kann mit den GNU-Tools während des Linkens angelegt werden:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-gcc ... -Wl,-Map,foo.map&amp;lt;/pre&amp;gt;&lt;br /&gt;
: Die Option -Wl bewirkt, daß avr-gcc die angehängen Optionen unverändert an den Linker weiterreicht. Dieser erzeugt dann das Mapfile &amp;quot;foo.map&amp;quot;, eine Textdatei.&lt;br /&gt;
;avr-size: Mit Tools wie avr-size kann die Platzbelegung einzelner Module ermittelt werden:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-size -x foo1.o foo2.o ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
:bzw. die Platzbelegung der elf-Datei:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-size foo.elf&amp;lt;/pre&amp;gt;&lt;br /&gt;
;avr-nm:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-nm --size-sort -S foo.elf&amp;lt;/pre&amp;gt;&lt;br /&gt;
:ergibt eine Liste mit der Größe aller Objekte: der erste Spalte enthälte die Adresse, die zweite Spalte die Größe, die dritte den Typ und die vierte Spalte den zugehörigen Symbolnamen. Der Typ ergibt sich aus der folgenden Zuordnung, wobei Großbuchstaben globale Symbole kennzeichnen und Kleinbuchstaben Symbole, die Modul-lokal sind:&lt;br /&gt;
:;T/t: Objekte in der text-Section: Funktionen, Daten im Flash&lt;br /&gt;
:;D/d: Objekte im data-Segment (initialisierte Daten)&lt;br /&gt;
:;B/b: Objekte im bss-Segment (Null-initialisierte Daten)&lt;br /&gt;
&lt;br /&gt;
;avr-gcc: Der Compiler hat bereits Informationen über die übersetzten Funktionen, die man direkt zur Analyse verwenden kann. Dazu lässt man avr-gcc die Assembler-Ausgabe, die ohne weiteres Zutun nur als temporäre Datei angelegt wird, abspeichern. Etwa für die Quelldatei foo.c:&lt;br /&gt;
::&amp;lt;pre&amp;gt;&amp;amp;gt; avr-gcc -save-temps foo.c -c ...&amp;lt;/pre&amp;gt;&lt;br /&gt;
:Die Assembler-Datei wird damit als foo.s angelegt und nicht gelöscht. (Das ebenfalls angelegte Präcompilat foo.i wird nicht benötigt). Für jede Funktion gibt avr-gcc 3.4.x im Prolog einen Kommentar der Form&amp;lt;ref&amp;gt;Für avr-gcc 4.x sehen die Kommentare anders aus oder fehlen je nach Compilerversion ganz&amp;lt;/ref&amp;gt;&lt;br /&gt;
::&amp;lt;pre&amp;gt;/* prologue: frame size=0 */&amp;lt;/pre&amp;gt;&lt;br /&gt;
:aus, was die Größe des aktuellen Frames angibt. Dies ist der Platz auf dem Stack, der für lokale Variablen benötigt wird. Am besten ist es, wenn die Frame-Size wie im Beispiel gleich 0 ist. Ansonsten sollte man versuchen, diese Größe auf Null zu bringen. Für Variablen, die nicht in Registern gehalten werden können, müssen Speicherzugriffe in den Stack erzeugt werden. Diese machen das Programm sowohl größer aus auch langsamer. Zudem reserviert avr-gcc bei solche Funktionen das Y-Register als Frame-Pointer; das Y-Register steht damit nicht mehr für lokale Variablen zur Verfügung was sich ebenfalls ungünstig auf die Codegüte auswirkt. Ein Grund für das Anlegen eines Frames können zu viele lokale Variablen sein (zB lokale Puffer/Arrays) oder lokale Variablen/Strukturen/Parameter mit ungünstigen Größen, etwa eine 3-Byte große Struktur. &lt;br /&gt;
&lt;br /&gt;
: Neben dieser Information gibt avr-gcc Kommentare der Gestalt&lt;br /&gt;
::&amp;lt;pre&amp;gt;/* prologue end (size=2) */&amp;lt;/pre&amp;gt;&lt;br /&gt;
:aus die darüber informieren, wie viele Register auf dem Stack gesichert wurden.&lt;br /&gt;
&lt;br /&gt;
: Zusammen mit Werkzeugen wie grep, die in jedem Linux und jeder WinAVR-Distribution enthalten sind, findet man schnell Übeltäter wie Funktionen mit Frame.&lt;br /&gt;
&lt;br /&gt;
;Assembler-Code sichten: Ein kurzer Blick auf den erzeugten Assembler-Code zeigt oft, wie gut der Compiler den Code umgesetzt hat. Den erzeugten Assembler-Code zu überfliegen ist wesentlich zeitsparender als selbst in Assembler zu programmieren. Je nach Gusto verwendet man zur Einsicht den Assembler-Code, den avr-gcc ausgibt (s.o.), Assembler-Dumps des Assemblers, List-Files oder HEX-Dumps. Siehe auch&amp;lt;ref&amp;gt;[http://rn-wissen.de/index.php/Assembler-Dump_erstellen_mit_avr-gcc roboternetz.de: Assembler-Dump erstellen mit avr-gcc]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Hilfsmittel: einkaufen oder selber bauen. Es gilt herauszufinden, welche Funktion massig Stack durch lokale Variablen verbraucht. Stacktracer können das. Wenn man keinen hat, dann muss man sich eben selber einen bauen, indem man den Stackpointer mitloggt. Zur Not einen Code-Review machen: Alle Funktionen optisch durchgehen und die identifizieren, die viele Variablen anlegen. Dann die Aufrufhierarchie der Funktion feststellen: Wirken sich die vielen Variablen überhaupt aus oder entsteht mein Problem durch eine tiefe Funktionsaufrufhierarchie, bei der zwar wenige Variablen pro Funktion im Spiel sind, aber die Menge der ineinandergeschachtelten Aufrufe &#039;das Kraut fett macht&#039;&lt;br /&gt;
;Profitools: können das alles fast auf Knopfdruck, kosten aber viel Geld&lt;br /&gt;
&lt;br /&gt;
====Laufzeit messen====&lt;br /&gt;
&lt;br /&gt;
*Simulator&lt;br /&gt;
*In Echtzeit mittels Testpin, welche an Anfang einer Funktion/Blocks gesetzt wird und am Ende wieder gelöscht wird. Mit einem [[Oszilloskop]] kann man so sehr einfach die Laufzeit messen.&lt;br /&gt;
&lt;br /&gt;
; Anmerkung: Solche Messverfahren liefern immer nur eine &#039;&#039;untere&#039;&#039; Schranke für die Laufzeit, niemals eine obere Schranke. Eine obere Schranke, wie man sie etwa in sicherheitsktitischen Systemen benötigt, liefert eine statische Codeanalyse.&lt;br /&gt;
&lt;br /&gt;
=== Wieviel ===&lt;br /&gt;
&lt;br /&gt;
Der Aufwand von Optimierungen wächst exponentiell. Die letzten paar Prozent brauchen überproportional viel Aufwand.&lt;br /&gt;
&lt;br /&gt;
=== Wie ===&lt;br /&gt;
&lt;br /&gt;
Meist muss man die Wahl treffen ob man Speicher oder Rechenzeit sparen will, beides gleichzeitg geht meist nicht. Das Konzept heißt &#039;Space for Time&#039; und kann in beide Richtungen verwendet werden. Als Beispiel soll eine komplizierte Berechnung dienen. Diese kann man relativ kompakt in eine Funktion packen, welche dann aber eher langsam ist. Oder man benutzt eine sehr große Tabelle, in welcher die Ergebnisse schon für jeden Eingangswert vorausberechnet wurden. Diese Lösung ist sehr schnell, verbraucht aber sehr viel Speicher.&lt;br /&gt;
&lt;br /&gt;
* Inlining von Funktionen erhöht den Speicherverbrauch, senkt aber die Laufzeit. Beispiel: Funktion A ist 50 Byte groß und wird 10 mal im Programm aufgerufen. Ein Aufruf kostet 10 Byte:&lt;br /&gt;
** Ohne Inline: 10 * 10Byte + 50 Byte = 150 Byte Platzverbrauch&lt;br /&gt;
** Mit Inline: 10 * 50 Byte = 500 Byte&lt;br /&gt;
* Optimierer einschalten&lt;br /&gt;
* möglichst keine Floating Point Operationen, besser ist meist [[Festkommaarithmetik]]&lt;br /&gt;
* Formeln umstellen und zusammenfassen&lt;br /&gt;
* Variablen so klein wie möglich, uint8_t wo&#039;s nur geht.&lt;br /&gt;
* Wirklich zeitkritische Funktionen und Interrupts als Assemblercode in separater Datei&lt;br /&gt;
&lt;br /&gt;
== GCC-Optionen ==&lt;br /&gt;
&lt;br /&gt;
=== Optimierungs-Level ===&lt;br /&gt;
&lt;br /&gt;
avr-gcc kennt mehrere Optimierungsstufen:&lt;br /&gt;
;&amp;lt;tt&amp;gt;-O0&amp;lt;/tt&amp;gt;: Keine Optimierung des erzeugten Codes. Diese Optimierungsstufe optimiert den Resourcenverbrauch des &#039;&#039;Hostrechners&#039;&#039; und die Nachvollziehbarkeit der erzeugten Codes anhand von Debug-Information. Alle lokalen Variablen werden auf dem Stack angelegt und nicht in Registern gehalten. Es werden keine komplexen Optimierungsalgorithmen angewandt; lediglich Konstanten wie 1+2 werden zu 3 gefaltet.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-O1&amp;lt;/tt&amp;gt;: Je höher die Optimierungsstufe, desto schwieriger ist der erzeugte Code nachvollziehbar — auch mit Debugger. Diese O-Stufe ist ein Kompromiss zwischen aggressiver Optimierung und Nachvollziehbarkeit des erzeugten Codes. Ein ehernes Gesetz in GCC ist, dass er den gleichen Code erzeugen muss unabhängig davon, ob Debug-Information erzeugt wird oder nicht. Im Umkehrschluss erlaubt volle Debug-Unterstützung nicht alle Optimierungen, wozu diese Optimierungsstufe dient.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-O2&amp;lt;/tt&amp;gt;: Optimierung auf Geschwindigkeit. Für AVR nur mässig sinnvoll, da sich der Codezuwachs nicht in einen entsprechenden Geschwindigkeitszuwachs transformiert. Dies liegt vor allem daran, daß Sprünge und Funktionsaufrufe auf AVR im Vergleich zu anderen Architekturen sehr billig sind. Es bringt also kaum einen Geschwindigkeitszuwachs, einen Block zu kopieren um einen Sprung zu sparen. Hingegen vergrößert dies den Code deutlich.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-O3&amp;lt;/tt&amp;gt;: Ditto. Auf Teufel-komm-raus Funktionen zu inlinen, Schleifen aufzurollen oder gar Funktionen mehrfach für unterschiedliche Aufruf-Szenarien zu implementieren, ist auf einem kleinen µC wie AVR der Overkill.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-Os&amp;lt;/tt&amp;gt;: Optimierung auf Codegröße. Die bevorzugte Optimierungsstufe für AVR und viele andere µC.&lt;br /&gt;
&lt;br /&gt;
Jede O-Option ist ein Sammlung von verschiedenen Schaltern, welche bestimmte Optimierungsstrategien aktivieren. Um zu sehen, welche Schalter dies genau sind, erzeugt man wie oben beschrieben mit den Schalten&lt;br /&gt;
   -save-temps -fverbose-asm&lt;br /&gt;
die Assembler-Ausgabe von gcc und schaut die Optionen im s-File nach. Einzelne Optionen lassen sich gezielt aktivieren bzw. deaktivieren und damit zum Beispiel zum &amp;lt;tt&amp;gt;-Os&amp;lt;/tt&amp;gt;-Paket hinzufügen. &lt;br /&gt;
&lt;br /&gt;
Eine Ausnahme bildet &amp;lt;tt&amp;gt;-O0&amp;lt;/tt&amp;gt;: Hier ist Code-Optimierung generell deaktiviert, und Optimierungsschalter bleiben ohne Wirkung.&lt;br /&gt;
&lt;br /&gt;
=== Feinabstimmung der Optimizer ===&lt;br /&gt;
&lt;br /&gt;
Kandidaten für Optimierungsoptionen sind folgende Schalter. &amp;lt;tt&amp;gt;-m&amp;lt;/tt&amp;gt; kennzeichnet maschinenspezifische Schalter, die nur für AVR gültig sind. &amp;lt;tt&amp;gt;-f&amp;lt;/tt&amp;gt; bzw. &amp;lt;tt&amp;gt;-fno-&amp;lt;/tt&amp;gt; sind maschinenunabhängige Schalter, die auch für andere Architekturen verfügbar sind.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-split-wide-types&amp;lt;/tt&amp;gt;: Je nach Quelle kann die Deaktivierung von &amp;lt;tt&amp;gt;-fsplit-wide-types&amp;lt;/tt&amp;gt; besseren Code ergeben.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-inline-small-functions&amp;lt;/tt&amp;gt;: Relativ kleine Funktionen /immer/ zu inlinen kann den Code unnötig vergrößern, dieser Schalter unterbindet das automatische Inlinen kleiner Funktionen.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-finline-limit=&amp;lt;/tt&amp;gt;&#039;&#039;wert&#039;&#039;: Maximalwert für automatisch geinlinte Funktionen. In einschlägigen Foren werden kleine Werte für &#039;&#039;wert&#039;&#039; vorgeschlagen, z.B.&amp;amp;nbsp;1…3&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-mcall-prologues&amp;lt;/tt&amp;gt;: Die für aufwändige Funktionen mitunter recht langen push/pop-Sequenzen werden durch Hilfsfunktionen ersetzt. Das kann vor allem bei grossen Programmen Platz sparen. Die Ausführungszeit steigt an.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-jump-tables&amp;lt;/tt&amp;gt;: Switch-Statements werden hierdurch mitunter deutlich kürzer.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-move-loop-invariants&amp;lt;br/&amp;gt;-fno-tree-loop-optimize&amp;lt;/tt&amp;gt;: Einige Schleifenoptimierungen, welche die Registerlast erhöhen und für AVR kaum zu einem Geschwindigkeitszuwachs führen, werden deaktiviert.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-tree-switch-conversion&amp;lt;/tt&amp;gt;: Neue GCC-Versionen können switch/case Anweisungen u.U. in Loopup-Tabellen umwandeln, die im RAM abgelegt werden, siehe auch [http://gcc.gnu.org/PR49857 PR49857]. Dieser Optimierung ist bei RAM-Knappheit in Betracht zu ziehen, bring aber natürlich nur dann etwas, wenn diese Optimierung auch ausgeführt wurde.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-optimize-sibling-calls&amp;lt;/tt&amp;gt;:Tailcall-Optimierung kann den Code vergrößern, wenn Epiloge mehrfach erzeugt werden. In diesem Fall deaktiviert man die Tailcall-Optimierung. Wirksam ab Version 4.7.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-maccumulate-args&amp;lt;/tt&amp;gt;: Ab 4.7: Funktionen, die mehrere printf-artige Aufrufe enthalten und viele Artumente per Stack an diese übergeben, werden u.U kleiner.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-mstrict-X&amp;lt;/tt&amp;gt;: Ab 4.7: Beeinflusst die Art und Weise, wie das X-Register zur Adressierung verwendet wird.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-mbranch-cost=&amp;lt;/tt&amp;gt;&#039;&#039;wert&#039;&#039;: Setzt die Kosten, mit der der Compiler einen bedingten Sprunge veranschlagt. Default-Wert ist &#039;&#039;wert&#039;&#039;&amp;lt;tt&amp;gt;=0&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-caller-saves&amp;lt;/tt&amp;gt;: Kann zu effizienteren Pro-/Epilogen beitragen.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fno-tree-ter&amp;lt;/tt&amp;gt;: Es gibt Fälle, in denen der Compiler die Berechnung temporärer Variablen über volatile-Zugriffe und Memory-Barriers zieht, siehe [http://gcc.gnu.org/PR53033 PR53033]. Von der  C-Spezifikation her ist dies zulässig, kann aber zu unerwünschter Umsortierung der volatile-Operation führe, z.B. wenn es sich dabei um eine &amp;lt;tt&amp;gt;SEI&amp;lt;/tt&amp;gt;-Instruktion handelt. Ohne diese Optimierung wird der Code evtl. etwas größer, aber Probleme wie im PR beschrieben können vermieden werden.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;--param case-values-threshold=&amp;lt;/tt&amp;gt;&#039;&#039;wert&#039;&#039;: Ab 4.7: Schwellwert an Einträgen in einem switch/case, ab dem anstatt eines binären if/else-Entscheidungsbaums eine Sprungtabelle zu den case-Labels erzeugt wird. Voreinstellung ab 4.7 ist &#039;&#039;wert&#039;&#039;&amp;lt;tt&amp;gt;=7&amp;lt;/tt&amp;gt;. Ältere Compilerversionen verwenden andere Werte. Siehe auch &amp;lt;tt&amp;gt;-f[no-]jump-tables&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Generell gilt für all diese Optionen, daß sie abhängig vom Projekt zu einer Codeverbesserung oder -verschlechterung führen können — dies ist i.d.R. vom Projektcode abhängig.&lt;br /&gt;
&lt;br /&gt;
=== Linker-Optionen ===&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-ffunction-sections&amp;lt;br/&amp;gt;-Wl,--gc-sections&amp;lt;/tt&amp;gt;: Der Linker wirft nicht referenzierte Sections weg, was die Codegröße günstig beeinflussen kann.  Diese Optimierung verkleinert den Code nur dann, wenn nicht verwendete Funktionen in der Anwendung rumgammeln. Weil der Linker nur auf Section-Ebene optimieren kann, muss zusätzlich der Compiler mit &amp;lt;tt&amp;gt;-ffunction-sections&amp;lt;/tt&amp;gt; aufgerufen werden, um die Anwendung auf möglichst viele Sections zu verteilen.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-Wl,--relax&amp;lt;br/&amp;gt;-mrelax&amp;lt;/tt&amp;gt;: Der Linker fasst Tail-Calls wie&lt;br /&gt;
::&amp;lt;tt&amp;gt;CALL some_function&amp;lt;br/&amp;gt;RET&amp;lt;/tt&amp;gt;&lt;br /&gt;
: zusammen als&lt;br /&gt;
::&amp;lt;tt&amp;gt;JMP some_function&amp;lt;/tt&amp;gt;&lt;br /&gt;
: Siehe auch die Compiler-Option &amp;lt;tt&amp;gt;-f[no-]optimize-sibling-calls&amp;lt;/tt&amp;gt; von oben. Zudem wird &amp;lt;tt&amp;gt;CALL&amp;lt;/tt&amp;gt; umgewandelt zur kürzeren &amp;lt;tt&amp;gt;RCALL&amp;lt;/tt&amp;gt;-Instruktion falls das Sprungziel im ±4&amp;amp;nbsp;KiB-Zielbereich von &amp;lt;tt&amp;gt;RCALL&amp;lt;/tt&amp;gt; liegt. Analog für &amp;lt;tt&amp;gt;JMP&amp;lt;/tt&amp;gt; zu &amp;lt;tt&amp;gt;RJMP&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
: Die beiden Optionen sind gleichwertig; die erste Variante veranlasst den Compiler, den Linker mit &amp;lt;tt&amp;gt;--relax&amp;lt;/tt&amp;gt; aufzurufen. Die zweite Variante verwendet den allgemeinen &amp;lt;tt&amp;gt;-Wl&amp;lt;/tt&amp;gt;-Mechanismus, um eine Option von der Compiler-Kommandozeile an den Linker durchzureichen.&lt;br /&gt;
&lt;br /&gt;
=== Weitere Optionen ===&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-mtiny-stack&amp;lt;/tt&amp;gt;: Der Compiler ändert nur das Low-Byte des Stackpointers (SP), was auf Controllern mit 16-Bit SP zu kleinerem Code führen kann.  Benötigt der Code Platz auf dem Stack, so erzeugt der Compiler u.U. Code, der den SP liest, einen Offset aufaddiert/abzieht und den SP dann zurückschreibt. Dies ist aufwändig. Für den Fall, daß sich dabei das High-Byte SP nicht ändert, kann Code eingespart werden.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;u&amp;gt;Beispiel&amp;lt;/u&amp;gt;: ATtiny44 hat RAM von &amp;lt;tt&amp;gt;0x60&amp;lt;/tt&amp;gt; bis &amp;lt;tt&amp;gt;0x15f&amp;lt;/tt&amp;gt;. Braucht die Anwendung nicht mehr als &amp;lt;tt&amp;gt;0x60&amp;lt;/tt&amp;gt;&amp;amp;nbsp;=&amp;amp;nbsp;96 Bytes an Stack, dann kann mit &amp;lt;tt&amp;gt;-mtiny-stack&amp;lt;/tt&amp;gt; compiliert werden.&lt;br /&gt;
&lt;br /&gt;
=== Änderung des Binärinterfaces per Option ===&lt;br /&gt;
&lt;br /&gt;
{{Warnung|&lt;br /&gt;
;Warnung: Im Gegensatz zu den Optionen der vorherigen Abschnitte, bei denen es sich um reine Optimierungsoptionen handelt, ändern die folgenden Optionen das Binärinterface (ABI) des vom Compiler erzeugten Codes und sind daher nur nach eingehender Prüfung anzuwenden! Wird eine Anwendung mit diesen Schaltern übersetzt, dann ist sicher zu stellen, daß &#039;&#039;alle&#039;&#039; Module inclusive Libraries damit derzeugt werden oder die ABI-Änderung sich nicht auf Code in Bibliotheken auswirkt!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Vorsicht in auch deshalb geboten, weil manche Entwicklungsumgebungen wie &amp;quot;Atmel Studio&amp;quot; das ABI &#039;&#039;per Default&#039;&#039; verändern und ohne daß der Anwender es extra anfordert.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-funsigned-char&amp;lt;/tt&amp;gt;: Anders als im avr-gcc ABI ist der Typ &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt; unsigned anstatt signed.&lt;br /&gt;
:&amp;lt;u&amp;gt;Besser&amp;lt;/u&amp;gt;: Verwende die C99-Typen wie &amp;lt;tt&amp;gt;uint8_t&amp;lt;/tt&amp;gt; aus dem C99-Header &amp;lt;tt&amp;gt;stdint.h&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-funsigned-bitfields&amp;lt;/tt&amp;gt;: Bitfelder mit Basetype &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;short&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; &amp;lt;tt&amp;gt;long&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;long long&amp;lt;/tt&amp;gt; werden als unsigned implementiert anstatt als signed wie in der avr-gcc ABI.&lt;br /&gt;
:&amp;lt;u&amp;gt;Besser&amp;lt;/u&amp;gt;: Wenn ein Bitfeld unsigned sein soll, dann mach es unsigned!&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fpack-struct&amp;lt;/tt&amp;gt;: Im Gegensatz zur avr-gcc ABI werden Strukturen und Unions per defulat gepackt.&lt;br /&gt;
:&amp;lt;u&amp;gt;Besser&amp;lt;/u&amp;gt;: Wenn ein zusammengesetzter Typ gepackt werden soll, mache ein Typedef mit explizitem &amp;lt;tt&amp;gt;__attribute__((packed))&amp;lt;/tt&amp;gt;!&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-fshort-enums&amp;lt;/tt&amp;gt;: Enum-Typen werden so kurz wie möglich implementiert anstatt als &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; gemäß avr-gcc ABI.&lt;br /&gt;
&lt;br /&gt;
;&amp;lt;tt&amp;gt;-mint8&amp;lt;/tt&amp;gt;: Ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; ist nur nocht 8 Bits breit. Dies entspricht nicht mehr dem C-Standard und wird nicht durch die C-Bibliothek wie AVR-Libc unterstützt! Die Codegröße kann sich im Vergleich zu 8-Bit Operationen ohne diese Option verkleinern, weil andere Integer-Promotion Regeln angewandt werden. Literals müssen ggf. angepasst bzw gecastet, siehe auch Makros wie &amp;lt;tt&amp;gt;UINT16_C&amp;lt;/tt&amp;gt; aus dem C99-Header &amp;lt;tt&amp;gt;stdint.h&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Anpassungen der Quelle ==&lt;br /&gt;
&lt;br /&gt;
=== Attribute noreturn, OS_main und OS_task ===&lt;br /&gt;
&lt;br /&gt;
Mikrocontroller-Programme laufen normalerweise in einer Endlosschleife, so dass die main-Routine nie verlassen wird.&lt;br /&gt;
Teilt man dies dem Compiler mit, kann er bestimmte Optimierungen durchführen.&lt;br /&gt;
So ist es zum Beispiel unnötig, Code zum Sichern und Zurücklesen von Registern zu erzeugen.&lt;br /&gt;
&lt;br /&gt;
Das Mitteilen funktioniert beim gcc über Attribute, die man der Deklaration oder bei der Implementierung einer Funktion anhängt:&lt;br /&gt;
&amp;lt;c&amp;gt;static void main_loop (void) __attribute__((noreturn));&lt;br /&gt;
void main_loop (void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
     // Hauptschleife&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/c&amp;gt;&lt;br /&gt;
oder&lt;br /&gt;
&amp;lt;c&amp;gt;static void __attribute__((noreturn))&lt;br /&gt;
main_loop (void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
     // Hauptschleife&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion &amp;lt;tt&amp;gt;main_loop&amp;lt;/tt&amp;gt; kann dann in &amp;lt;tt&amp;gt;main&amp;lt;/tt&amp;gt; aufgerufen werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;int main (void)&lt;br /&gt;
{&lt;br /&gt;
  main_loop();&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&amp;lt;/c&amp;gt;&lt;br /&gt;
Das abschließende &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; wird vom Compiler wegoptimiert und belegt keinen Speicher.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;avr-gcc&amp;lt;/tt&amp;gt; kennt weiterhin die Attribute &amp;lt;tt&amp;gt;OS_main&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;OS_task&amp;lt;/tt&amp;gt;.&lt;br /&gt;
Die Verwendung von &amp;lt;tt&amp;gt;OS_main&amp;lt;/tt&amp;gt; kann etwa aussehen wie folgt. Natürlich kann auch wie oben die Hauptschleife in einer eigenen Funktion implementiert werden, und das &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; verursacht keinen zusätzlichen Code:&lt;br /&gt;
&amp;lt;c&amp;gt;int __attribute__((OS_main))&lt;br /&gt;
main (void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
     // Hauptschleife&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Statische Variablen in einer Struktur sammeln ===&lt;br /&gt;
&lt;br /&gt;
Gibt es in einem Programm mehrere inhaltlich zusammengehörende Variablen, dann ist es sinnvoll diese in einer Struktur zu vereinigen.  Neben einer klareren Programm- bzw. Datenstruktur kann dies auch zu kleinerem Code führen.&lt;br /&gt;
&lt;br /&gt;
Beispiel ist die folgende kleine Routine, welche die Teit in der globalen &amp;lt;tt&amp;gt;time&amp;lt;/tt&amp;gt;-Strukture um eine Sekunde erhöht:&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
typedef struct &lt;br /&gt;
{&lt;br /&gt;
    uint8_t second;&lt;br /&gt;
    uint8_t minute;&lt;br /&gt;
    uint8_t hour;&lt;br /&gt;
} time_t;&lt;br /&gt;
 &lt;br /&gt;
// Globale time-Struktur enthält die Zeit&lt;br /&gt;
time_t time;&lt;br /&gt;
 &lt;br /&gt;
void next_second (void)&lt;br /&gt;
{&lt;br /&gt;
    // Zeiger auf die globale time-Struktur&lt;br /&gt;
    time_t *ptime = &amp;amp;time;&lt;br /&gt;
    &lt;br /&gt;
    // time um 1 Sekunde erhöhen&lt;br /&gt;
&lt;br /&gt;
    if (++ptime-&amp;gt;second == 60)&lt;br /&gt;
    {&lt;br /&gt;
        ptime-&amp;gt;second = 0;&lt;br /&gt;
        &lt;br /&gt;
        if (++ptime-&amp;gt;minute == 60)&lt;br /&gt;
        {&lt;br /&gt;
            ptime-&amp;gt;minute = 0;&lt;br /&gt;
            &lt;br /&gt;
            if (++ptime-&amp;gt;hour == 24)&lt;br /&gt;
                ptime-&amp;gt;hour = 0;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion enthält mehrere indirekte Zugriffe auf die &amp;lt;tt&amp;gt;time&amp;lt;/tt&amp;gt;-Struktur, und es wäre günstig, wenn &amp;lt;tt&amp;gt;avr-gcc&amp;lt;/tt&amp;gt; indirekte Adressierung für die Zugriffe verwendet: Alle Zugriffe geschehen über den Struktur-Zeiger &amp;lt;tt&amp;gt;ptime&amp;lt;/tt&amp;gt;, und ein indirekter Zugriff per &amp;lt;tt&amp;gt;LD&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;LDD&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;ST&amp;lt;/tt&amp;gt; oder &amp;lt;tt&amp;gt;STT&amp;lt;/tt&amp;gt; kostet 2&amp;amp;nbsp;Code, während die direkten Spreicherzugriffe &amp;lt;tt&amp;gt;LDS&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;STS&amp;lt;/tt&amp;gt; jeweils 4&amp;amp;nbsp;Bytes verbrauchen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;avr-gcc&amp;lt;/tt&amp;gt; erzeugt jedoch folgenden Code, wenn auf Größe optimiert wird:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
next_second:&lt;br /&gt;
    // if (++ptime-&amp;gt;second == 60)&lt;br /&gt;
    lds  r24, time&lt;br /&gt;
    subi r24, -1&lt;br /&gt;
    sts  time, r24&lt;br /&gt;
    cpi  r24, 60&lt;br /&gt;
    brne .L1&lt;br /&gt;
    // ptime-&amp;gt;second = 0;&lt;br /&gt;
    sts  time, __zero_reg__&lt;br /&gt;
    // if (++ptime-&amp;gt;minute == 60)&lt;br /&gt;
    lds  r24, time+1&lt;br /&gt;
    subi r24, -1&lt;br /&gt;
    sts  time+1, r24&lt;br /&gt;
    cpi  r24, 60&lt;br /&gt;
    brne .L1&lt;br /&gt;
    // ptime-&amp;gt;minute = 0;&lt;br /&gt;
    sts  time+1, __zero_reg__&lt;br /&gt;
    // if (++ptime-&amp;gt;hour == 24)&lt;br /&gt;
    lds  r24,time+2&lt;br /&gt;
    subi r24, -1&lt;br /&gt;
    sts  time+2, r24&lt;br /&gt;
    cpi  r24, 24&lt;br /&gt;
    brne .L1&lt;br /&gt;
    // ptime-&amp;gt;hour = 0;&lt;br /&gt;
    sts  time+2, __zero_reg__&lt;br /&gt;
.L1:&lt;br /&gt;
    ret&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
D.h. obwohl der C-Code indirekt zugreift, enthält das Compilat direkte Zugriffe und der Code belegt 56&amp;amp;nbsp;Bytes an Flash. Grund ist, daß der Compiler den Inhalt der Variablen &amp;lt;tt&amp;gt;ptime&amp;lt;/tt&amp;gt; kennt und daher die indirekten Struktur-Zugriffe in direkte umwandelt.&lt;br /&gt;
&lt;br /&gt;
Um indirekte Adressierung im erzeugten Code zu erzwingen, kann man die Struktur-Adresse als Parameter übergeben:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void next_second (time_t *ptime)&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
oder – als hässliche Lösung – dem Compiler des Wissen um den Inhalt von &amp;lt;tt&amp;gt;ptime&amp;lt;/tt&amp;gt; per Inline-Assembler nehmen:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
asm (&amp;quot;&amp;quot; : &amp;quot;+r&amp;quot; (ptime));&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dies führe denn zu folgendem Code, der um 25% kleiner ist und nur noch 42&amp;amp;nbsp;Bytes Flash belegt:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
next_second:&lt;br /&gt;
    // time_t *ptime = &amp;amp;time;&lt;br /&gt;
    // asm (&amp;quot;&amp;quot; : &amp;quot;+r&amp;quot; (ptime));&lt;br /&gt;
    ldi  r30, lo8(time)&lt;br /&gt;
    ldi  r31, hi8(time)&lt;br /&gt;
    // if (++ptime-&amp;gt;second == 60)&lt;br /&gt;
    ld   r24, Z&lt;br /&gt;
    subi r24, -1&lt;br /&gt;
    st   Z, r24&lt;br /&gt;
    cpi  r24, 60&lt;br /&gt;
    brne .L1&lt;br /&gt;
    // ptime-&amp;gt;second = 0;&lt;br /&gt;
    st   Z, __zero_reg__&lt;br /&gt;
    // if (++ptime-&amp;gt;minute == 60)&lt;br /&gt;
    ldd  r24, Z+1&lt;br /&gt;
    subi r24, -1&lt;br /&gt;
    std  Z+1, r24&lt;br /&gt;
    cpi  r24, 60&lt;br /&gt;
    brne .L1&lt;br /&gt;
    // ptime-&amp;gt;minute = 0;&lt;br /&gt;
    std  Z+1, __zero_reg__&lt;br /&gt;
    // if (++ptime-&amp;gt;hour == 24)&lt;br /&gt;
    ldd  r24, Z+2&lt;br /&gt;
    subi r24, -1&lt;br /&gt;
    std  Z+2, r24&lt;br /&gt;
    cpi  r24, 24&lt;br /&gt;
    brne .L1&lt;br /&gt;
    // ptime-&amp;gt;hour = 0;&lt;br /&gt;
    std  Z+2, __zero_reg__&lt;br /&gt;
.L1:&lt;br /&gt;
    ret&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weil AVRs nur zwei Zeiger-Register haben, die über diese Addressierungsart verfügen (Y und Z), ist diese Optimierung nur eingeschränkt anwendbar.&lt;br /&gt;
&lt;br /&gt;
Werden etwa Z oder Y für andere Zwecke benötigt – etwa für Flash-Adressierung per &amp;lt;tt&amp;gt;LPM&amp;lt;/tt&amp;gt; oder Y als Frame-Pointer gebraucht – verkleinert sich das Anwendungsfeld noch weiter. Zudem müssen genügend Struktur-Zufriffe nacheinander erfolgen, damit ein positiven Effekt auf die Codegröße zustande kommt. Immerhin muss die Adresse geladen werden, das Zeiger-Register wird belegt, und im Falle von Y kommen &amp;lt;tt&amp;gt;PUSH&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;POP&amp;lt;/tt&amp;gt; im Prolog/Epilog hinzu. Gibt es Zugriffe auf viele (&amp;quot;viele&amp;quot; relativ zu den zur Verfügung stehenden Pointer-Registern), kann die Codegröße auch ansteigen.&lt;br /&gt;
&lt;br /&gt;
=== Multiplikationen mit Konstanten ===&lt;br /&gt;
&lt;br /&gt;
Der Compiler instanziiert sofort eine teure allgemeine Bibliotheksfunktion, auch wenn es anders ginge. Ich hatte eine einzige 32-bit Multiplikation mit 10 drin, die mir ein mulsi3 beschert hat. Mit a = (b&amp;lt;&amp;lt;3) + (b&amp;lt;&amp;lt;1) geht es in dem Fall kürzer. Wie gesagt, map-File beobachten.&lt;br /&gt;
 &lt;br /&gt;
;Anmerkung: Variablen als unsigned definieren, dann sollte der Compiler das selbst machen.&lt;br /&gt;
&lt;br /&gt;
;Anmerkung: Auch Schieben ist teuer auf AVR. Schauen wir uns also mal an, was aus folgendem Code wird:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint32_t foo (uint32_t i)&lt;br /&gt;
{&lt;br /&gt;
    return i*10;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
uint32_t bar (uint32_t i)&lt;br /&gt;
{&lt;br /&gt;
    return (i &amp;lt;&amp;lt; 1) + (i &amp;lt;&amp;lt; 3);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Scrollbox|15ex;|&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
00000032 &amp;lt;foo&amp;gt;:&lt;br /&gt;
  32:	2a e0       	ldi	r18, 0x0A	; 10&lt;br /&gt;
  34:	30 e0       	ldi	r19, 0x00	; 0&lt;br /&gt;
  36:	40 e0       	ldi	r20, 0x00	; 0&lt;br /&gt;
  38:	50 e0       	ldi	r21, 0x00	; 0&lt;br /&gt;
  3a:	19 d0       	rcall	.+50     	; 0x6e &amp;lt;__mulsi3&amp;gt;&lt;br /&gt;
  3c:	08 95       	ret&lt;br /&gt;
&lt;br /&gt;
0000003e &amp;lt;bar&amp;gt;:&lt;br /&gt;
  3e:	26 2f       	mov	r18, r22&lt;br /&gt;
  40:	37 2f       	mov	r19, r23&lt;br /&gt;
  42:	48 2f       	mov	r20, r24&lt;br /&gt;
  44:	59 2f       	mov	r21, r25&lt;br /&gt;
  46:	22 0f       	add	r18, r18&lt;br /&gt;
  48:	33 1f       	adc	r19, r19&lt;br /&gt;
  4a:	44 1f       	adc	r20, r20&lt;br /&gt;
  4c:	55 1f       	adc	r21, r21&lt;br /&gt;
  4e:	e3 e0       	ldi	r30, 0x03	; 3&lt;br /&gt;
  50:	66 0f       	add	r22, r22&lt;br /&gt;
  52:	77 1f       	adc	r23, r23&lt;br /&gt;
  54:	88 1f       	adc	r24, r24&lt;br /&gt;
  56:	99 1f       	adc	r25, r25&lt;br /&gt;
  58:	ea 95       	dec	r30&lt;br /&gt;
  5a:	d1 f7       	brne	.-12     	; 0x50 &amp;lt;__SREG__+0x11&amp;gt;&lt;br /&gt;
  5c:	26 0f       	add	r18, r22&lt;br /&gt;
  5e:	37 1f       	adc	r19, r23&lt;br /&gt;
  60:	48 1f       	adc	r20, r24&lt;br /&gt;
  62:	59 1f       	adc	r21, r25&lt;br /&gt;
  64:	95 2f       	mov	r25, r21&lt;br /&gt;
  66:	84 2f       	mov	r24, r20&lt;br /&gt;
  68:	73 2f       	mov	r23, r19&lt;br /&gt;
  6a:	62 2f       	mov	r22, r18&lt;br /&gt;
  6c:	08 95       	ret&lt;br /&gt;
&lt;br /&gt;
0000006e &amp;lt;__mulsi3&amp;gt;:&lt;br /&gt;
  6e:	ff 27       	eor	r31, r31&lt;br /&gt;
  70:	ee 27       	eor	r30, r30&lt;br /&gt;
  72:	bb 27       	eor	r27, r27&lt;br /&gt;
  74:	aa 27       	eor	r26, r26&lt;br /&gt;
&lt;br /&gt;
00000076 &amp;lt;__mulsi3_loop&amp;gt;:&lt;br /&gt;
  76:	60 ff       	sbrs	r22, 0&lt;br /&gt;
  78:	04 c0       	rjmp	.+8      	; 0x82 &amp;lt;__mulsi3_skip1&amp;gt;&lt;br /&gt;
  7a:	a2 0f       	add	r26, r18&lt;br /&gt;
  7c:	b3 1f       	adc	r27, r19&lt;br /&gt;
  7e:	e4 1f       	adc	r30, r20&lt;br /&gt;
  80:	f5 1f       	adc	r31, r21&lt;br /&gt;
&lt;br /&gt;
00000082 &amp;lt;__mulsi3_skip1&amp;gt;:&lt;br /&gt;
  82:	22 0f       	add	r18, r18&lt;br /&gt;
  84:	33 1f       	adc	r19, r19&lt;br /&gt;
  86:	44 1f       	adc	r20, r20&lt;br /&gt;
  88:	55 1f       	adc	r21, r21&lt;br /&gt;
  8a:	96 95       	lsr	r25&lt;br /&gt;
  8c:	87 95       	ror	r24&lt;br /&gt;
  8e:	77 95       	ror	r23&lt;br /&gt;
  90:	67 95       	ror	r22&lt;br /&gt;
  92:	89 f7       	brne	.-30     	; 0x76 &amp;lt;__mulsi3_loop&amp;gt;&lt;br /&gt;
  94:	00 97       	sbiw	r24, 0x00	; 0&lt;br /&gt;
  96:	76 07       	cpc	r23, r22&lt;br /&gt;
  98:	71 f7       	brne	.-36     	; 0x76 &amp;lt;__mulsi3_loop&amp;gt;&lt;br /&gt;
&lt;br /&gt;
0000009a &amp;lt;__mulsi3_exit&amp;gt;:&lt;br /&gt;
  9a:	9f 2f       	mov	r25, r31&lt;br /&gt;
  9c:	8e 2f       	mov	r24, r30&lt;br /&gt;
  9e:	7b 2f       	mov	r23, r27&lt;br /&gt;
  a0:	6a 2f       	mov	r22, r26&lt;br /&gt;
  a2:	08 95       	ret&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
: Der Funktionsaufruf samt Lib-Funktion ist garnicht sooo teuer. Bereits mit zwei Multiplikationen im Programm &amp;amp;mdash; auch einer Multiplikation mit einer anderen Konstanten oder einer Variablen &amp;amp;mdash; gewinnt die lib-Version, da der Code wiederverwendet wird. Übrigens sind diese Multiplikationsroutinen und auch die in die libgcc enthaltenen Divisionen keine &amp;quot;normalen&amp;quot; Funktionen wie sie von C erzeugt werden. avr-gcc weiß genau, welche Register diese Routinen belegen und welche nicht. Damit ist der Aufruf einer solchen Funktion billiger als ein herkömmlicher Funktionsaufruf, bei dem die Funktion als Blackbox behandelt werden muss, die alle call-clobbered Register zerstört.&lt;br /&gt;
&lt;br /&gt;
=== Alle Variablen nur so breit wie nötig ===&lt;br /&gt;
&lt;br /&gt;
Hatte ich eigentlich schon, nur an einigen wenigen Stellen war ich da etwas nachlässig. Mitunter reicht ein kleinerer Typ doch, wenn man z.&amp;amp;nbsp;B. vorher geeignet skaliert. Am besten nur die skalaren Typen aus &amp;lt;stdint.h&amp;gt; verwenden, das erleichtert auch das Folgende. Bei RAM Knappheit: kann ich Strings sinnvollerweise aus dem RAM ins Flash verbannen? Kann ich es mir leisten mehrere Flag-Variablen in ein Byte zusammenzufassen, auch wenn dann die Zugriffe möglicherweise etwas langsamer werden.&lt;br /&gt;
&lt;br /&gt;
=== Logische Operatoren werden auf int-Größe erweitert ===&lt;br /&gt;
&lt;br /&gt;
Obwohl der AVR ein 8-Bit Controller ist, verlangt der C-Standard, daß ein &amp;lt;tt&amp;gt;int&amp;lt;/tt&amp;gt; mindestens 16&amp;amp;nbsp;Bits groß ist. Wegen den Promotion-Regeln von C werden 8-Bit Operanden in Operationen auf 16&amp;amp;nbsp;Bits aufgeweitet. Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
uint8_t c;&lt;br /&gt;
&lt;br /&gt;
void foo (uint8_t a, uint8_t b)&lt;br /&gt;
{&lt;br /&gt;
    if (a == ~b)&lt;br /&gt;
        c = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Den zweiten Operanden mit dem Komplement weitet der Compiler auf 16 Bit auf, wodurch alle high-Bits von &amp;lt;tt&amp;gt;~b&amp;lt;/tt&amp;gt; gesetzt werden. Der Compiler erkennt, daß der Vergleich niemals wahr ist und optimiert ihn weg:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
foo:&lt;br /&gt;
    ret&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Cast verhindert dieses:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void foo (uint8_t a, uint8_t b)&lt;br /&gt;
{&lt;br /&gt;
    if (a == (uint8_t) ~b)&lt;br /&gt;
        c = 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
was übersetzt wird zu:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
foo:&lt;br /&gt;
    // if (a == (uint8_t) ~b)&lt;br /&gt;
    com  r22&lt;br /&gt;
    cpse r24, r22   &lt;br /&gt;
    rjmp .L1&lt;br /&gt;
    // c = 0&lt;br /&gt;
    sts c, __zero_reg__&lt;br /&gt;
.L1:&lt;br /&gt;
ret&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;Achtung: Tatsächlich handelt es sich dabei nicht um ein Optimierungsproblem, sondern einen typischen Programmierfehler. Die beiden Varianten sind keineswegs identisch! Bei Variablen vom Typ &amp;lt;tt&amp;gt;uint8_t&amp;lt;/tt&amp;gt; ist der Ausdruck &amp;lt;tt&amp;gt;(a == ~b)&amp;lt;/tt&amp;gt; immer falsch!&lt;br /&gt;
&lt;br /&gt;
=== Speichern von globalen Flags ===&lt;br /&gt;
&lt;br /&gt;
Oft werden in den Programmen Flags verwendet um beispielsweise eingetroffene Interrupts in der main-Routine auszuwerten. Hierzu wird üblicherweise eine globale Variable verwendet.&lt;br /&gt;
&lt;br /&gt;
Um den Wert dieser Variable abzufragen, muss sie jedoch erst aus dem SRAM in ein Register geladen werden, und kann dann erst auf ihren Status hin überprüft werden. Eine Möglichkeit ist, der globalen Variablen ein einziges Register fest zuzuordnen:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
register uint8_t counter8_1 asm(&amp;quot;r2&amp;quot;);&lt;br /&gt;
register uint8_t counter8_2 asm(&amp;quot;r3&amp;quot;);&lt;br /&gt;
register uint16_t counter16_1 asm(&amp;quot;r4&amp;quot;); // r4:r5&lt;br /&gt;
register uint16_t counter16_2 asm(&amp;quot;r6&amp;quot;); // r6:r7&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
siehe auch: http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_regbind&lt;br /&gt;
&lt;br /&gt;
Als Alternative kann man ein nicht verwendetes Register des I/O-Bereichs verwenden. Dabei würde sich z.&amp;amp;nbsp;B. das Register eines zweiten UARTs, oder das  EEPROM-Register anbieten, falls diese nicht benötigt werden.&lt;br /&gt;
&lt;br /&gt;
Neuere AVR-Modelle besitzen für diesen Zweck 3 frei verwendbare Bytes im bitadressierbaren I/O-Bereich: GPIOR0-2.&lt;br /&gt;
&lt;br /&gt;
{{Warnung|&lt;br /&gt;
;Warnung: Dieses Vorgehen verändert das ABI! Um dieses Feature fehlerfrei anzuwenden, ist einiges an Wissen über die Interna von GCC notwendig. Auch ein korrekt funktionierendes Programm ist keine Garantie dafür, daß die globalen Register fehlerfrei implementiert wurden. Unter Umständen bringen erst spätere Codeänderungen/-erweiterung den Fehler zum Vorschein, und weil der Fehler vorher nicht akut war, sucht man sich den Wolf an der falschen Stelle im Code anstatt bei der globalen Registern. Siehe auch [[Globale Register]].}}&lt;br /&gt;
&lt;br /&gt;
=== Puffern von volatile-Variablen ===&lt;br /&gt;
&lt;br /&gt;
Der Compiler behandelt volatile-Variablen bei mehreren Manipulationen wie heiße Kartoffeln. Für jeden einzelnen Vorgang wiederholt sich das Spiel:&lt;br /&gt;
&lt;br /&gt;
* aus dem Speicher holen&lt;br /&gt;
* bearbeiten&lt;br /&gt;
* zurückspeichern&lt;br /&gt;
&lt;br /&gt;
Unter Umständen ist dieses Verhalten unsinnig. Ein Minimalbeispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
volatile char var;&lt;br /&gt;
&lt;br /&gt;
ISR()&lt;br /&gt;
{&lt;br /&gt;
    var++;&lt;br /&gt;
&lt;br /&gt;
    if (var &amp;gt; 100)&lt;br /&gt;
        var = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main (void)&lt;br /&gt;
{&lt;br /&gt;
    while (1)&lt;br /&gt;
        printf (var);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Hier wird &#039;&#039;&#039;var&#039;&#039;&#039; pro [[ISR]]-Ausführung zwei mal aus dem RAM geholt und zurückgeschrieben. Das ist überflüssig, weil die Interruptrountine nicht unterbrochen werden kann. Aus Sicht der ISR bräuchte man eigentlich kein volatile, kann es aber wegen des Zugriffs aus main heraus nicht weglassen. Eine Lösung findet sich im folgenden Schnipsel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
volatile char var;&lt;br /&gt;
&lt;br /&gt;
ISR()&lt;br /&gt;
{&lt;br /&gt;
    char temp = var;&lt;br /&gt;
&lt;br /&gt;
    if (++temp &amp;gt; 100)&lt;br /&gt;
        temp=0;&lt;br /&gt;
&lt;br /&gt;
    var = temp;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void main (void)&lt;br /&gt;
{&lt;br /&gt;
    while (1)&lt;br /&gt;
        printf (var);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Hier wird die globale Variable &#039;&#039;&#039;var&#039;&#039;&#039; in der lokalen Variable &#039;&#039;&#039;temp&#039;&#039;&#039; gepuffert. Ein Nachteil durch das Anlegen von &#039;&#039;&#039;temp&#039;&#039;&#039; ergibt sich nicht, da das dafür verwendete Register für die Manipulation sowieso benötigt wird. &lt;br /&gt;
&lt;br /&gt;
Wie alle Optimierungen kann dieses Vorgehen auch nach hinten losgehen: Wenn Laden und Zurückspeichern von &#039;&#039;&#039;var&#039;&#039;&#039; weit auseinanderliegen (extrem lange ISR), müllt man sich die Register zu. Im schlimmsten Fall wird &#039;&#039;&#039;temp&#039;&#039;&#039; sogar zwischenzeitlich auf dem Stack ausgelagert.&lt;br /&gt;
&lt;br /&gt;
=== Schleifen ===&lt;br /&gt;
&lt;br /&gt;
Bei Schleifen, die eine bestimmte Anzahl an Durchläufen ausgeführt werden sollen, ist es besser den Schleifenzähler vorher auf einen Wert zu setzen, und am Ende einer Do-While Schleife diesen zu dekrementieren.&lt;br /&gt;
So beschränkt sich die Sprungbedingung auf ein brne (branch if not equal).&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint8_t counter;	&lt;br /&gt;
counter = 100;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
    // mach irgendetwas&lt;br /&gt;
} while (--counter);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Optimierung der Ausführungsgeschwindigkeit==&lt;br /&gt;
&lt;br /&gt;
Hierzu gibt es schon eine Application-Note von Atmel. Diese AppNote bezieht sich auf den IAR-Compiler. Die darin genannten &amp;quot;Optimierungen&amp;quot; sind für avr-gcc größtenteils obsolet oder bleiben bestenfalls ohne Effekt.&lt;br /&gt;
&lt;br /&gt;
Weblinks:&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc1497.pdf AVR035]: Efficient C Coding for AVR&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Program_optimization Program optimization] auf Wikipedia, engl.&lt;br /&gt;
* [http://bleaklow.com/2012/06/20/sensor_smoothing_and_optimised_maths_on_the_arduino.html Sensor smoothing and optimised maths on the Arduino] - Multiplikation vs. Division&lt;br /&gt;
&lt;br /&gt;
== Fußnoten ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
[http://www.atmel.com/Images/doc8453.pdf Atmel AVR4027]: Tips and Tricks to Optimize Your C Code for 8-bit AVR Microcontrollers ([http://www.atmel.com/Images/AVR4027.zip Beispiel-Code])&lt;br /&gt;
&lt;br /&gt;
[[Category:avr-gcc]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=ATxMega_Stick_-_First_Steps&amp;diff=67364</id>
		<title>ATxMega Stick - First Steps</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=ATxMega_Stick_-_First_Steps&amp;diff=67364"/>
		<updated>2012-07-18T06:03:08Z</updated>

		<summary type="html">&lt;p&gt;Maybee: /* Siehe auch */  Typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Datei:ATxMegaStick-1.jpg|thumb|Platine des ATxMega Stick]]&lt;br /&gt;
Der ATxMega Stick ist eine kleine Platine (27 mm x 80 mm) mit ATxmega128A3, USB-Device-Anschluss und Micro-SD-Kartenslot.&lt;br /&gt;
&lt;br /&gt;
== Eigenschaften ==&lt;br /&gt;
&lt;br /&gt;
* Mikrocontroller ATxmega128A3&lt;br /&gt;
* USB-Baustein [http://kweb/wiki/images/b/ba/MCP2200_22228A.pdf MCP2200]&lt;br /&gt;
* Mini-USB-B-Device-Anschluss&lt;br /&gt;
* Micro-SD-Kartenslot&lt;br /&gt;
* Programmierung via PDI (z.B. AVRISP mkII)&lt;br /&gt;
* Reset-Taster&lt;br /&gt;
* 2 LEDs zur Signalisierung von USB-Transfers&lt;br /&gt;
* 2 frei verwendbare LEDs&lt;br /&gt;
* On-board-Spannungsregler (3.3 V, Versorgung über USB oder extern)&lt;br /&gt;
* 6 x 8-Bit-Ports auf Stiftleisten verfügbar, davon ist ein Port belegt (2-mal LED, RX und TX zum USB-Baustein, SPI zum Micro-SD-Kartenslot)&lt;br /&gt;
&lt;br /&gt;
== Hinweise zum Aufbau ==&lt;br /&gt;
&lt;br /&gt;
=== Anmerkungen zum Schaltplan vom 15.09.2011 23:08:38 ===&lt;br /&gt;
&lt;br /&gt;
* Seite 1: C1 hat 22µF&amp;lt;br&amp;gt;&lt;br /&gt;
* Seite 1: C14, C15 haben 3.3µF&lt;br /&gt;
* Seite 2: Verbindungsbezeichnung bei &amp;quot;&amp;lt;tt&amp;gt;I/Os&amp;lt;/tt&amp;gt;&amp;quot; µC Pin 27 und JP4 Pin 4 und bei &amp;quot;&amp;lt;tt&amp;gt;LEDs&amp;lt;/tt&amp;gt;&amp;quot; muss &amp;lt;tt&amp;gt;LED3&amp;lt;/tt&amp;gt; lauten statt &amp;lt;tt&amp;gt;LED1&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Seite 2: Verbindungsbezeichnung bei &amp;quot;&amp;lt;tt&amp;gt;I/Os&amp;lt;/tt&amp;gt;&amp;quot; µC Pin 26 und JP4 Pin 3 und bei &amp;quot;&amp;lt;tt&amp;gt;LEDs&amp;lt;/tt&amp;gt;&amp;quot; muss &amp;lt;tt&amp;gt;LED4&amp;lt;/tt&amp;gt; lauten statt &amp;lt;tt&amp;gt;LED2&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stromversorgung ===&lt;br /&gt;
&lt;br /&gt;
Auf JP1 muss ein Jumper bestückt werden:&lt;br /&gt;
* zum Platinenrand hin für Versorgung über USB&lt;br /&gt;
* zur Platinenmitte hin für externe Versorgung&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Hinweis:&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Jumper sollte unbedingt gesteckt sein, wenn USB verwendet wird. Steht dieser auf externer Versorung, muss diese dabei auch anliegen. Wird der MCP2200 per USB versorgt, ohne dass am ATxMega Versorgungsspannung anliegt, kommt es über die UART-Leitung zu einem Stromfluss über das entsprechende I/O-Pin des ATxMega, da dieser sich ohne Spannung intern in einem undefinierten Zustand befindet. Auf VCC liegen dann etwa 2.8 V an. Durch den Stromfluss erwärmt sich der MCP2200 deutlich, was zur eventuellen Beschädigung des ICs führen kann.&lt;br /&gt;
&lt;br /&gt;
=== Löten des SD-Halters ===&lt;br /&gt;
&lt;br /&gt;
* Zuerst muss man den Halten ausrichen und einen Punkt am Rand festlöten.&lt;br /&gt;
* Dann muss man alle 4 Ecken festlöten&lt;br /&gt;
* Jetzt kann man mit der Lötspitze oben durch die Aussparungen und führt den Zinn durch die Öffnung für die SD-Karte.&lt;br /&gt;
* So lötet man dann alle 8 Kontakte.&lt;br /&gt;
* Lötbrücken sind hier nicht schön, lässt sich aber dann noch mit Entlötlitze entfernen (Entlötlitze statt Zinn durch die Öffnung führen)&lt;br /&gt;
&lt;br /&gt;
== Betrieb unter Linux ==&lt;br /&gt;
&lt;br /&gt;
Damit man als User auf den Stick zugreifen kann, empfiehlt es sich, einen UDEV-Eintrag für den Stick anzulegen, z.B. neue Datei /etc/udev/rules.d/15_USB_uC.rules anlegen:&lt;br /&gt;
&lt;br /&gt;
 ATTRS{idVendor}==&amp;quot;04d8&amp;quot;, ATTRS{idProduct}==&amp;quot;00df&amp;quot;, GROUP=&amp;quot;MeineGruppe&amp;quot;, MODE=&amp;quot;0660&amp;quot;, SYMLINK+=&amp;quot;ATxMegaStick%n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Für &amp;quot;MeineGruppe&amp;quot; einen geeigneten Werte verwenden, d.h. eine Gruppe, der man selbst angehört.&lt;br /&gt;
&lt;br /&gt;
Jetzt kann man nach dem Anschließen folgende Links sehen:&lt;br /&gt;
&lt;br /&gt;
 ls -l /dev/ATxMegaStick*&lt;br /&gt;
 lrwxrwxrwx 1 root root  7 2011-10-17 00:04 /dev/ATxMegaStick0 -&amp;gt; ttyACM0&lt;br /&gt;
 lrwxrwxrwx 1 root root 11 2011-10-17 00:04 /dev/ATxMegaStick1 -&amp;gt; usb/hiddev1&lt;br /&gt;
 lrwxrwxrwx 1 root root  7 2011-10-17 00:04 /dev/ATxMegaStick2 -&amp;gt; hidraw2&lt;br /&gt;
 lrwxrwxrwx 1 root root 15 2011-10-17 00:04 /dev/ATxMegaStick3 -&amp;gt; bus/usb/001/042&lt;br /&gt;
&lt;br /&gt;
Und die Zugriffrechte sehen so aus:&lt;br /&gt;
&lt;br /&gt;
 ls -lL /dev/ATxMegaStick*&lt;br /&gt;
 crw-rw---- 1 root dialout 166,  0 2011-10-17 00:04 /dev/ATxMegaStick0&lt;br /&gt;
 crw-rw---- 1 root mgr     180, 97 2011-10-17 00:04 /dev/ATxMegaStick1&lt;br /&gt;
 crw-rw---- 1 root mgr     251,  2 2011-10-17 00:04 /dev/ATxMegaStick2&lt;br /&gt;
 crw-rw-r-- 1 root mgr     189, 41 2011-10-17 00:04 /dev/ATxMegaStick3&lt;br /&gt;
&lt;br /&gt;
== Fuses ==&lt;br /&gt;
&lt;br /&gt;
Default-Werte der Fuses:&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;signature&amp;lt;/tt&amp;gt;: Signatur ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U signature:r:-:h&lt;br /&gt;
 0x1e,0x97,0x42&lt;br /&gt;
:0x1e9742 = ATxmega128A3&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse0&amp;lt;/tt&amp;gt;: JTAG User ID ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse0:r:-:h&lt;br /&gt;
 0xff&lt;br /&gt;
:JTAG User ID (JTAGUID) = 0xff &#039;&#039;&#039;(das Manual sagt: 0x00)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse1&amp;lt;/tt&amp;gt;: Watchdog Configuration ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse1:r:-:h&lt;br /&gt;
 0x0&lt;br /&gt;
:Watchdog Window Timeout Period (WDWPER) = n.a.&lt;br /&gt;
:Watchdog Timeout Period (WDPER) = n.a.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse2&amp;lt;/tt&amp;gt;: Reset Configuration ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse2:r:-:h&lt;br /&gt;
 0xff&lt;br /&gt;
:Reset Vector (BOOTRST) = Application Reset&lt;br /&gt;
:BOD operation in power-down mode (BODPD) = BOD disabled&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse4&amp;lt;/tt&amp;gt;: Start-up Configuration ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse4:r:-:h&lt;br /&gt;
 0xfe&lt;br /&gt;
:External Reset Disable (RSTDISBL) = no&lt;br /&gt;
:Start-up time (STARTUPTIME) = 0&lt;br /&gt;
:Watchdog Timer lock (WDLOCK) = no&lt;br /&gt;
:JTAG enabled (JTAGEN) = yes&lt;br /&gt;
&lt;br /&gt;
Bei Bedarf ändern:&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse4:w:0xff:m&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse4:r:-:h&lt;br /&gt;
 0xff&lt;br /&gt;
:JTAG enabled (JTAGEN) = no&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;tt&amp;gt;fuse5&amp;lt;/tt&amp;gt;: BODACT, BODLEVEL, EESAVE ===&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse5:r:-:h&lt;br /&gt;
 0xff&lt;br /&gt;
:BOD operation in active mode (BODACT) = BOD disabled&lt;br /&gt;
:EEPROM memory is preserved through the Chip Erase (EESAVE) = no&lt;br /&gt;
:BOD voltage level (BODLEVEL) = 1.6V&lt;br /&gt;
&lt;br /&gt;
Bei Bedarf ändern:&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse5:w:0xf7:m&lt;br /&gt;
 avrdude -Pusb -cavrispmkII -px128a3 -q -q -U fuse5:r:-:h&lt;br /&gt;
 0xf7&lt;br /&gt;
:EEPROM memory is preserved through the Chip Erase (EESAVE) = yes&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
=== Clock System ===&lt;br /&gt;
&lt;br /&gt;
Takt zu Testzwecken auf Port C Pin 7 (d.h. JP3 Pin 3) ausgeben.&lt;br /&gt;
 PORTC.DIRSET = 0x80;&lt;br /&gt;
 PORTCFG.CLKEVOUT = 0x01;&lt;br /&gt;
&lt;br /&gt;
==== 32 MHz mit dem externen Quarz ====&lt;br /&gt;
&lt;br /&gt;
Unter Verwendung der Software zu AVR1003 (-&amp;gt; Siehe auch) kann man den Takt auf 32 MHz einstellen:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;quot;clksys_driver.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 void init_clock( void )&lt;br /&gt;
 {&lt;br /&gt;
    CLKSYS_XOSC_Config( OSC_FRQRANGE_12TO16_gc, false, OSC_XOSCSEL_XTAL_16KCLK_gc );&lt;br /&gt;
    CLKSYS_Enable( OSC_XOSCEN_bm );&lt;br /&gt;
    CLKSYS_PLL_Config( OSC_PLLSRC_XOSC_gc, 2 );&lt;br /&gt;
    CLKSYS_Enable( OSC_PLLEN_bm );&lt;br /&gt;
    CLKSYS_Prescalers_Config( CLK_PSADIV_1_gc, CLK_PSBCDIV_1_1_gc );&lt;br /&gt;
    do {} while ( CLKSYS_IsReady( OSC_PLLRDY_bm ) == 0 );&lt;br /&gt;
    CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_PLL_gc );&lt;br /&gt;
    CLKSYS_Disable( OSC_XOSCEN_bm );&lt;br /&gt;
 } /* init_clock() */&lt;br /&gt;
&lt;br /&gt;
=== USART ===&lt;br /&gt;
&lt;br /&gt;
==== USART über USB ====&lt;br /&gt;
&lt;br /&gt;
So stellt man unter Verwendung der Software zu AVR1307 (-&amp;gt; Siehe auch) bei 32 MHz Takt den USART für die Übertragung per USB ein:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;quot;usart_driver.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 #define USART USARTD0&lt;br /&gt;
 &lt;br /&gt;
 void init_usart( void )&lt;br /&gt;
 {&lt;br /&gt;
    PORTD.DIRSET = PIN3_bm;&lt;br /&gt;
    PORTD.DIRCLR = PIN2_bm;&lt;br /&gt;
    USART_Format_Set( &amp;amp;USART, USART_CHSIZE_8BIT_gc, USART_PMODE_DISABLED_gc, false );&lt;br /&gt;
    /*&lt;br /&gt;
     * BSEL[11:0]-Wert bei 32MHz Takt und BSCALE[3:0]==0:&lt;br /&gt;
     *   207 :   9600&lt;br /&gt;
     *   103 :  19200&lt;br /&gt;
     *    51 :  38400&lt;br /&gt;
     *    34 :  57600&lt;br /&gt;
     *    16 : 115200&lt;br /&gt;
     */&lt;br /&gt;
    USART_Baudrate_Set( &amp;amp;USART, 34 , 0 );&lt;br /&gt;
    USART_Rx_Enable( &amp;amp;USART );&lt;br /&gt;
    USART_Tx_Enable( &amp;amp;USART );&lt;br /&gt;
 } /* init_usart() */&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/227310 Ursprungsbeitrag im Forum]&lt;br /&gt;
* [http://www.atxmega-board.de/stick Die Seite des Sticks] mit Schaltplan und Stückliste&lt;br /&gt;
* [http://www.stromflo.de/dokuwiki/doku.php?id=xmega-c-tutorial XMEGA-C-Tutorial auf stromflo.de]&lt;br /&gt;
* [http://www.atmel.com/dyn/products/product_card.asp?part_id=4302 Produktseite des ATxmega128A3] mit jeder Menge an Dokumentation und Application Notes&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc8072.pdf AVR1003: Using the XMEGA Clock System] (PDF) und [http://www.atmel.com/dyn/resources/prod_documents/AVR1003.zip Software] (ZIP)&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc8049.pdf AVR1307: Using the XMEGA USART] (PDF) und [http://www.atmel.com/dyn/resources/prod_documents/AVR1307.zip Software] (ZIP)&lt;br /&gt;
* [http://www.microchip.com/wwwproducts/devices.aspx?dDocName=en546923 Produktseite des MCP2200] mit Dokumentation und Tools&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=USB_Koppelfeld_f%C3%BCr_Festplatten&amp;diff=67146</id>
		<title>USB Koppelfeld für Festplatten</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=USB_Koppelfeld_f%C3%BCr_Festplatten&amp;diff=67146"/>
		<updated>2012-07-01T08:48:33Z</updated>

		<summary type="html">&lt;p&gt;Maybee: /* Hub-Stapel &amp;amp; Vusb-Steuerung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Torsten Crull&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es entsteht ein modulares System, welches sich zu nahezu beliebig großen Quasi- [http://de.wikipedia.org/wiki/Koppelfeld Koppelfeldern] für Festplatten kaskadieren läßt. Ein Koppelfeld-Modul hat Anschlüsse für vierzehn Festplatten; das entspricht einem 19&amp;quot;-Baugruppenträger. Die Stromversorgung der Festplatten läßt sich einzeln schalten. Die Platten werden - gesteuert vom Mikrocontroller - wahlweise über USB-SATA-Bridges, USB-IDE-Bridges oder über einen eSATA Port-Multiplier mit einem Host-Computer verbunden.&lt;br /&gt;
&lt;br /&gt;
[[Bild:USBMuxBlockschaltbild.png|720px]]&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Das Projekt umfaßt:&lt;br /&gt;
* &#039;&#039;&#039;Koppelfeld-Module&#039;&#039;&#039; in mehreren Varianten, entweder mit SATA-Port-Multiplier oder mit fünf USB-HUBs. Unabhängig von der Variante werden diese Module im folgenden Text als &amp;quot;Koppelfeld&amp;quot; bezeichnet.&lt;br /&gt;
* Eine &#039;&#039;&#039;Steuerplatine&#039;&#039;&#039; für bis zu sechzehn Koppelfelder; die Steuerung von außen erfolgt über RS232, USB oder Ethernet. Die Koppelfelder werden über I²C adressiert; die übrigen Signale werden über eine [http://de.wikipedia.org/wiki/Serial_Peripheral_Interface SPI-Schnittstelle] übertragen.&lt;br /&gt;
* Eine optionale &#039;&#039;&#039;230V-Relaisbox&#039;&#039;&#039; zum ein- und ausschalten der Stromversorgung, um die Standby-Ströme zu verringern.&lt;br /&gt;
* &#039;&#039;&#039;Relaisplatinen&#039;&#039;&#039; um die Stromversorgung (5V und 12V) der Festplatten zu schalten.&lt;br /&gt;
&lt;br /&gt;
Es können &#039;&#039;&#039;handelsübliche USB-Bridges&#039;&#039;&#039; verwendet werden; diese kosten etwa fünf Euro pro Stück:&lt;br /&gt;
&lt;br /&gt;
[[Bild:UAB_SATA_Bridges_Dsc_5364.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Bild:HDDMuxBaumarkt.jpg|right]]&lt;br /&gt;
== Architektur und Mechanischer Aufbau ==&lt;br /&gt;
&lt;br /&gt;
Da in einem 19&amp;quot;-Baugruppenträger bis zu vierzehn handelsübliche 3,5&amp;quot;-Festplatten untergebracht werden können, sind die Koppelfelder auf vierzehn Festplatten ausgelegt. Pro Baugruppenträger ist also eine Koppelfeld-Platine nötig.&lt;br /&gt;
&lt;br /&gt;
Es sind wahlweise USB- und SATA-Koppelfelder vorgesehen, man kann also beliebig Baugruppenträger mit USB-SATA-Bridges und Baugruppenträger mit eSATA Port-Multiplyer vermischen. Die Anzahl von maximal sechzehn Baugruppenträgern ergibt sich aus der Adressierung über I²C.&lt;br /&gt;
&lt;br /&gt;
Jedes Koppelfeld hat eine Ansteuerung für eine 230V-Box: Um Strom zu sparen, wenn alle Festplatten im betreffenden Baugruppenträger ausgeschaltet sind, kann jedes Netzteil auf der Primärseite ausgeschaltet werden. Es können übliche Netzteile aus alten PC-Gehäusen verwendet werden (ATX-PC oder AT-PC). In der Firmware muß sicher gestellt werden, dass pro Baugruppenträger nicht mehr Festplatten eingschaltet werden, als das Netzteil versorgen kann und dass ggf. eine minimal benötigte Belastung des Netzteils für den Netzteil-Regler nicht unterschritten wird.&lt;br /&gt;
&lt;br /&gt;
Alternativ zu einem teuren Baugruppenträger kann man sich auch aus gelochten Stahlbändern vom Baumarkt einen Rahmen für die Festplatten bauen; das sieht dann aus wie aus &#039;nem Trix-Metallbaukasten (s. Bild).&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
&lt;br /&gt;
Die Hardware besteht aus den oben genannten Modulen, die im Folgenden beschrieben werden:&lt;br /&gt;
&lt;br /&gt;
=== Steuerplatine ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:USBMuxSteuerplatine.png]]&lt;br /&gt;
&lt;br /&gt;
Zentrales Element der Steuerplatine ist ein PIC32MX764F128L-I/PT von Microchip. Er enthält  bereits alle verwendeten Schnittstellen: UART (RS232), Ethernet, USB, I²C, SPI und Analogeingang.&lt;br /&gt;
&lt;br /&gt;
Für die CPU-Platine sind folgende Integrationsstufen geplant:&lt;br /&gt;
&lt;br /&gt;
1. Gefädelte Lochrasterplatine mit Adapterplatine für das TQFP-100-Gehäuse und vornehmlich DIL-Gehäusen.&lt;br /&gt;
&lt;br /&gt;
2. Aufbau mit professionell gefertigten Platinen mit Lötstopplack und vornehmlich SMD-Gehäusen.&lt;br /&gt;
&lt;br /&gt;
2. Redesign und kleinserientaugliche Lösung.&lt;br /&gt;
&lt;br /&gt;
Die Gefädelte Lochrasterplatine wird während der Entwicklung Stück für Stück erweitert. In der ersten Ausbaustufe wird der Mikrocontroller über den integrierten UART und eine USB-RS232C-Brigde mit dem Host verbunden, damit die Software noch ohne USB-Stack auskommt. In der ersten Ausbaustufe soll zunächst die praktische Nutzbarkeit des Systems gewährleistet sein, um Erfahrung mit dem System zu sammeln.&lt;br /&gt;
&lt;br /&gt;
In weiteren Ausbaustufen werden dann der Analogeingang, die Ethernet-Schnittstelle und die USB-Schnittstelle in Betrieb genommen.&lt;br /&gt;
&lt;br /&gt;
Über den Analogeingang kann der Mikrocontroller die Spannungen an den Netzteilen der angeschlossenen Baugruppenträger bestimmen und überwachen; Details sind der Beschreibung der Koppelfelder (s.u.) zu entnehmen.&lt;br /&gt;
&lt;br /&gt;
==== Stromversorgung ====&lt;br /&gt;
&lt;br /&gt;
Damit die Netzteile nicht ständig Standby-Strom verbrauchen, kann der Mikrocontroller alle Netzteile primärseitig über eine 230V-Relaisbox ausschalten, auch das Netzteil, von  dem die Steuerplatine versorgt wird. &lt;br /&gt;
&lt;br /&gt;
Wenn das Gerät über USB vom Host gesteuert wird, verhält sich das Gerät wie ein &amp;quot;self-powered USB-device&amp;quot;. Es nutzt die max. 100mA vom USB-Anschluss, um damit einen Optokoppler in der der 230V-Relaisbox für die Aktivierung des Netzteils anzusteuern und kann sich dann aus dem Netzteil mit Strom versorgen. &lt;br /&gt;
&lt;br /&gt;
Wenn das Gerät über Wakeup-on-LAN eingeschaltet werden soll, wird es bei ausgeschaltetem Netzteil von einem Handy-Akku versorgt.&lt;br /&gt;
&lt;br /&gt;
Die 230V-Relaisbox hat optional einen 230V-Ausgang für den Host-Computer, der primärseitig vom Netz getrennt werden kann, um die  Stromkosten in den Standby-Zeiten zu senken.&lt;br /&gt;
&lt;br /&gt;
==== Display-Platine ====&lt;br /&gt;
&lt;br /&gt;
Optional ist eine Display-Platine mit einem Dreh-Drück-Geber und Siebensegment LED-Anzeigen vorgesehen. Sie ist auf Steuerplatine montiert und über einen zehnpolige Steckverbindung mit der Steuerplatine verbunden.&lt;br /&gt;
&lt;br /&gt;
Das Bedienkonzept steht noch nicht im Detail fest, nur soviel: Über den Dreh-Drück-Geber läßt sich das System einschalten und der anzuzeigende Wert auswählen. Angezeigt werden die Nummern der aktiven Festplatten und die gemessenen Spannungen an den Netzteilen. Der Aufwand für eine umfangreiche Benutzerschnittstelle über die Display-Platine lohnt sich kaum, da in der Praxis die Steuerung über RS232, Ethernet oder USB erfolgen wird.&lt;br /&gt;
&lt;br /&gt;
=== USB Koppelfeld ===&lt;br /&gt;
&lt;br /&gt;
Aus der [http://www.mikrocontroller.net/topic/262844#2729270 Diskussion zu diesem Projekt] ergab sich, dass die Variante 2 mit gestapelten USB-Hubs umgesetzt wird:&lt;br /&gt;
&lt;br /&gt;
[[Bild:USBMuxVarianten.png]]&lt;br /&gt;
&lt;br /&gt;
Die ursprüngliche Idee aus einer [http://www.mikrocontroller.net/articles/Datei:FSUSB42_Matrix.png Matrix mit FSUSB42-ICs] wurde verworfen; die Vorteile der Varianten:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Variante 1: FSUSB42-Matrix&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* geringere Latenzzeiten, da die USB-Daten einen HUB weniger passieren müssen.&lt;br /&gt;
* möglicher Weise bessere Kompatibilität beim Verbinden und Trennen der USB-Verbindung, da die Datenleitungen unterbrochen werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Variante 2: USB-Hub-Stapel:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Keine Begrenzung auf drei gleichzeitig aktive Festplatten&lt;br /&gt;
* geringere Kosten&lt;br /&gt;
* weniger Bauteile; die FSUSB42-ICs sind sehr winzig und lassen sich nur schwer von Hand bestücken.&lt;br /&gt;
* geringere Störanfälligkeit, da der USB-Hub wie ein Repeater die USB-Signale auffrischt.&lt;br /&gt;
&lt;br /&gt;
==== Hub-Stapel &amp;amp; Vusb-Steuerung ====&lt;br /&gt;
&lt;br /&gt;
Das Herzstück eines USB Koppelfeldes sind die USB-Hubs und optionale USB-Power-Schalter für die 5V-Spannung &amp;quot;Vusb&amp;quot;, jeweils an Pin 1 der USB-Anschlüsse. Über Vusb werden die USB-SATA-Bridges aktiviert und deaktiviert:&lt;br /&gt;
&lt;br /&gt;
[[Bild:USBMuxModul.png]]&lt;br /&gt;
&lt;br /&gt;
Um Kosten zu sparen, kann man die USB-Power-Schalter auch weglassen, dann werden die USB-SATA-Bridges zusammen mit den 5V der Festplatten geschaltet. Diese &amp;quot;Spar-Variante&amp;quot; ist natürlich nicht konform zur USB-Spezifikation.&lt;br /&gt;
&lt;br /&gt;
Da die 5V der Festplatten auf separaten Relais-Platinen geschaltet werden, sind zwei Varianten der Verkabelung mit den Relais-Platinen vorgesehen. In der Variante 2 (s. Bild, &amp;quot;Spar-Variante&amp;quot;) werden jeweils vier Adern pro Relais-Platine angeschlossen; bei der Verwendung von USB-Power-Schalten dürfen jeweils nur zwei Adern angeschlossen sein.&lt;br /&gt;
&lt;br /&gt;
[[Bild:USBMuxFlachband.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Legende:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1 Micromatch-Steckverbinder&amp;lt;br&amp;gt;&lt;br /&gt;
2 Zwölfadriges Flachbandkabel, in Variante 1 (&amp;quot;Spar-Variante&amp;quot;) komplett&amp;lt;br&amp;gt;&lt;br /&gt;
3 Sechzehnadriges Flachbandkabel, in Variante 1 (&amp;quot;Spar-Variante&amp;quot;) komplett&amp;lt;br&amp;gt;&lt;br /&gt;
4 Vierpoliger Micromatch-Steckverbinder, einer pro Relaisplatine&amp;lt;br&amp;gt;&lt;br /&gt;
5 Flachbandkabel, in Variante 2 (spezifikationskonform) fehlen jede dritte und vierte Ader.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Von den vier Adern pro Relais-Platine werden zwei Adern zum getrennten Einschalten der Stromversorgung von zwei Festplatten verwedet; über die anderen zwei Adern werden optional die geschalteten 5V für die Versorgung der USB-Bridges zurückgeführt. Falls USB-Power-Schalter verbaut sind, müssen diese Adern abgekniffen werden.&lt;br /&gt;
&lt;br /&gt;
==== Schieberegister für Steuerungsbits ====&lt;br /&gt;
&lt;br /&gt;
Die Steuerungsbits werden mit dem [http://de.wikipedia.org/wiki/Serial_Peripheral_Interface SPI-Protokoll] von einem Microcontroller in die kaskadierten Schieberegister (daisy chain) geschrieben. Die Slave-Select-Signale für die [http://de.wikipedia.org/wiki/Serial_Peripheral_Interface SPI-Schnittstelle] werden von einem I²C-Expander (IC1, PCF8574) (s.u.) gesteuert.&lt;br /&gt;
&lt;br /&gt;
Um das Clock-Signal bei /SS = high (inaktivem Slave-Select) zu unterdrücken, ist noch ein Oder-Gatter vor den Clock-Eingang vorgesehen. (ToDo: Im Forum ansprechen)&lt;br /&gt;
&lt;br /&gt;
* Bild folgt&lt;br /&gt;
&lt;br /&gt;
==== Slave-Select per I²C ====&lt;br /&gt;
&lt;br /&gt;
Von einem I²C-Expander (IC1, PCF8574) und einem  &#039;&#039;&#039;3:8 Decoder&#039;&#039;&#039; (IC37, 74HC138) werden pro Baugruppenträger die konkreten Slave-Select-Signale für das SPI (s.o.) erzeugt. Dadurch ist es möglich, bis zu sechzen Koppelfelder per I²C-Protokoll zu adrerssieren.&lt;br /&gt;
&lt;br /&gt;
Der 74HC138 enthält kein Latch. Um unerlaubte Zustände beim Umschalten der Adresse am 3:8 Decoder zu vermeiden, muß der Mikrocontroller beim Umschalten das  globale Slave-Select-Signal &amp;quot;/SS&amp;quot; auf &amp;quot;high&amp;quot; halten. (ToDo: Schaltbild aktualisieren)&lt;br /&gt;
&lt;br /&gt;
[[Bild:USB-Koppelfeld-I2C.png|600px]]&lt;br /&gt;
&lt;br /&gt;
Die I²C-Adresse des Baugruppenträgers wird über S1 und eine Bestückungsvariante für IC1 eingestellt.&lt;br /&gt;
&lt;br /&gt;
==== Analogsignal &amp;quot;Probe&amp;quot; ====&lt;br /&gt;
&lt;br /&gt;
Von allen Baugruppenträgern wird eine gemeinsame &amp;quot;Probe&amp;quot;-Leitung verwendet, um eine zu messende Spannung an den Analogeingang des Mikrocontrollers zu geben. Über Analogschalter (IC32, s. Bild) wird die zu messende Spannung mit der &amp;quot;Probe&amp;quot;-Leitung verbunden. Die Firmware muß sicher stellen, dass immer nur ein Analogschalter auf allen Baugruppen leitend ist.&lt;br /&gt;
&lt;br /&gt;
==== Ansteuerung der Relais-Platinen ====&lt;br /&gt;
&lt;br /&gt;
Um die Festplatten-Stromversorgung über Relais oder MOSFTEs zu steuern, führen vom Koppelfeld insgesamt 56 Flachbandadern zu den Relaisplatinen. Die Belegung der Adern ist im Kapitel &amp;quot;Vusb-Steuerung&amp;quot; (s.o.) beschrieben.&lt;br /&gt;
&lt;br /&gt;
Sowohl Relais als auch die MOSFET-Transistoren werden über Open-Collector-Ausgänge eines ULN2003A angesteuert. Gegenüber einzelnen Transistoren hat ein ULN2003 keinen finanziellen Nachteil, es sind jedoch weniger Teile zu bestücken und das Platinenlayout vereinfacht sich.&lt;br /&gt;
&lt;br /&gt;
[[Bild:USB-Koppelfeld-ULN2003a.png]]&lt;br /&gt;
&lt;br /&gt;
==== USB-Versorgung der USB-SATA/PATA-Bridges ====&lt;br /&gt;
&lt;br /&gt;
Wie oben beschrieben, gibt es eine &amp;quot;Spar-Variante&amp;quot; Nr. 1 und eine spezifikationskonforme Variante Nr. 2. Bei der &amp;quot;Spar-Variante&amp;quot; werden die USB-Power-Schalter nicht bestückt und die 5V Vusb kommen über die Pins 3,4,7,8, ... von X1 und X2 von der geschalteten 5V-Stromversorgung der Festplatten.&lt;br /&gt;
&lt;br /&gt;
[[Bild:USB-Koppelfeld-HighSide.png]]&lt;br /&gt;
&lt;br /&gt;
==== Steuerung der 230V-Relaisbox ====&lt;br /&gt;
&lt;br /&gt;
Die Relais in der 230V-Relaisbox (s.u.) werden über die Open-Collector-Ausgänge eines ULN2003A geschaltet. Durch die Open-Collector-Ausgänge können entweder Relais erregt werden, MOSFETs geschaltet oder Optokoppler angesteuert werden.&lt;br /&gt;
&lt;br /&gt;
6-Pin-DIN-Stecker dienen der Verbindung zwischen der dem Koppelfeld und der Relaisbox.&lt;br /&gt;
&lt;br /&gt;
[[Bild:USB-Koppelfeld-ULN2003b.png]]&lt;br /&gt;
&lt;br /&gt;
=== eSATA Koppelfeld ===&lt;br /&gt;
&lt;br /&gt;
* Details folgen&lt;br /&gt;
&lt;br /&gt;
=== Relaisplatine ===&lt;br /&gt;
[[Bild:USBMuxRelaisModul.png]]&lt;br /&gt;
&lt;br /&gt;
Die Relaismodule schalten in Zweiergruppen die Stromversorgung der Festplatten und sind mit vier Stromschienen aus Kupferdraht miteinander verbunden:&lt;br /&gt;
&lt;br /&gt;
[[Bild:USBMuxRelaisPlatine.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Legende:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1 Relaisplatine mit Anschlussklemmen für das Netzteil, davon wird nur eine Platine pro Baugruppenträger benötigt.&amp;lt;br&amp;gt;&lt;br /&gt;
2 Anschlussklemmen (4 x 4mm²) für das Netzteil (ToDo: Alternativen klären)&amp;lt;br&amp;gt;&lt;br /&gt;
3 Anschlussklemmen (optional) für Kupferdraht (Nr. 4); der Kuperdraht kann auch flächig auf freistehendem Kupfer der Platine verlötet werden, um Kosten zu sparen.&amp;lt;br&amp;gt;&lt;br /&gt;
4 Vier &amp;quot;Stromschienen&amp;quot; aus 2,5mm² Kupferdraht (z.B. NYM-J 3x2,5 vom Baumarkt)&amp;lt;br&amp;gt;&lt;br /&gt;
5 Bohrungen zur Befestigung an der Rückseite an einem 19&amp;quot;-Baugruppenträger&amp;lt;br&amp;gt;&lt;br /&gt;
6 Relaisplatine mit Anschlussklemmen für das Netzteil&amp;lt;br&amp;gt;&lt;br /&gt;
7 Ritzung in der Platine, um Anschlussklemmen-Teil abbrechen zu können.&amp;lt;br&amp;gt;&lt;br /&gt;
8 4-Pin Micromatch-Verbinder (2 x Schalteingang, 2 x 5V-Ausgang)&amp;lt;br&amp;gt;&lt;br /&gt;
9 Durchkontaktierungen zum Anschluß eines Kabelschwanzes zur Stromversorgung einer Festplatte. Wahlweise können für aktuelle Platten SATA-Stecker oder für ältere Platten Molex-Stecker an den Kabelschwänzen sein.&amp;lt;br&amp;gt;&lt;br /&gt;
10 Zwei Relais (á zwei Wechser) oder vier MOSFETs&amp;lt;br&amp;gt;&lt;br /&gt;
11 Optionale Block-Kondensatoren, um Stromspitzen beim Einschalten der Festplatte abzublocken.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Relaismodul gibt es in zwei Varianten: Mit elektromagnetischen Schaltern und mit Halbleiter-Schaltern (MOSFETs):&lt;br /&gt;
&lt;br /&gt;
[[Bild:USBMuxRelaisModul1.png]] [[Bild:USBMuxRelaisModul2.png]]&lt;br /&gt;
&lt;br /&gt;
=== 230V-Relaisbox ===&lt;br /&gt;
[[Bild:USBMux230VBox.png]]&lt;br /&gt;
&lt;br /&gt;
Die Relaisbox kann optional über einen 6-poligen DIN-Stecker an eines der Koppelfelder angeschlossen werden, um die Netzteile für die Festplatten und für den Host-PC primärseitig vom Stromnetz zu trennen.&lt;br /&gt;
&lt;br /&gt;
Die Relaisbox muß nach VDE-Richtlinien aufgebaut sein. Damit beim Betrieb nicht ständig ein Relais angezogen (erregt) sein muß, kommen bistabile 230V-Relais zum Einsatz, die über Optokoppler (Halbleiterrelais) ein- und ausgeschaltet werden können.&lt;br /&gt;
&lt;br /&gt;
Am 230V-Anschluss hinter der Sicherung ist ein Gasableiter für einen zusätzlichen Blitzschutz vorgesehen.&lt;br /&gt;
&lt;br /&gt;
Bei Verwendung moderner Netzteile mit geringen Standby-Leistungen kann man natürlich auf die 230V-Relaisbox verzichten.&lt;br /&gt;
&lt;br /&gt;
* Details folgen&lt;br /&gt;
&lt;br /&gt;
=== Zustandsautomaten ===&lt;br /&gt;
== Software / Firmware ==&lt;br /&gt;
&lt;br /&gt;
Die Firmware wird komplet im internen EEPROM des PIC32MX764F128L-I/PT gespeichert und per In-Curcit-Debugger in den Mikrocontroller geladen.&lt;br /&gt;
&lt;br /&gt;
Die detaillierte Beschreibung der Firmware folgt, hier nur eine naheliegende Reihenfolge der Softwarestände der Integrationsstufen (s. o.):&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1.1.&#039;&#039;&#039; Unidirektionale Steuerung über UART (RS232) zur Ansteuerung der Relaisplatinen in der &amp;quot;Spar-Variante&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;1.2.&#039;&#039;&#039; Rücksendung von Status- und Messwerten über RS232&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;1.3.&#039;&#039;&#039; Ansteuerung der 230V-Box, Stromversorgung über USB bei ausgeschaltetem Netzteil&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;1.4.&#039;&#039;&#039; Implementierung der spezifikationskonformen Variante Nr. 2. der USB-Koppelfelder&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;1.5.&#039;&#039;&#039; Ansteuerung der Display-Platine zur Ausgabe der gemessenen Spannungspegel&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;1.6.&#039;&#039;&#039; Implementierung des Batteriebetriebes&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;1.7.&#039;&#039;&#039; Ansteuerung von eSATA-Koppelfeldern&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;1.8.&#039;&#039;&#039; Implementierung des Ethernet-Anschlusses zur Steuerung über HTTP/Get-Kommandos&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;2.1.&#039;&#039;&#039; Implementierung von Wakup-on-LAN&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;2.2.&#039;&#039;&#039; Implementierung der USB-Schnittstelle des Mikrocontrollers als USB-HID als Alternative zur Steuerung über die RS232-USB-Bridge&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;2.3.&#039;&#039;&#039; Unterstützung des &amp;quot;[http://www.mikrocontroller.net/topic/262844#2730914 SetPortFeature(PORT_POWER) request]&amp;quot; um die Festplatten ohne Kommunikation mit dem Mikrocontroller schalten zu können.&lt;br /&gt;
&lt;br /&gt;
=== Zustandsautomaten ===&lt;br /&gt;
Bevor die Implementierung der Software beginnt, sollten die Anforderungen klar sein. Viele Anforderungen lassen sich wie in den folgenden Kapiteln in Zustandsautomaten beschreiben:&lt;br /&gt;
&lt;br /&gt;
==== Betriebszustände ====&lt;br /&gt;
(ToDo: Kapitel vervollständigen)&lt;br /&gt;
&lt;br /&gt;
[[Bild:HDDMuxBZStateChart.png]]&lt;br /&gt;
===== Zustand &#039;&#039;&#039;off&#039;&#039;&#039; =====&lt;br /&gt;
Dieser Zustand wird&lt;br /&gt;
* bei leerer oder nicht verbauter Batterie erreicht, wenn die aktive Stromversorgung ausfällt,&lt;br /&gt;
* wenn bei leerer Batterie keine aktive Stromversorgung angeschlossen ist oder&lt;br /&gt;
* wenn der Benutzer z.B. vor einem Urlaub über eine der Benutzerschnittstellem das System komplett ausschaltet, damit der Akku nicht entladen wird.&lt;br /&gt;
&lt;br /&gt;
Ereignis &amp;quot;5V plugged 1&amp;quot;:&lt;br /&gt;
* Wenn eine Mini-USB-Buchse verbaut ist und dort ein externes USB-Steckernetzteil angeschlossen ist, wechselt das System in den Zustand &amp;quot;5V powered&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Ereignis &amp;quot;POE plugged 1&amp;quot;:&lt;br /&gt;
* Wenn die Ethernet-Schnittstelle verbaut ist und dort eine Versorgungsspannung anliegt, wechselt das System in den Zustand &amp;quot;POE powered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Ereignis &amp;quot;USB plugged 1&amp;quot;:&lt;br /&gt;
* Wenn der Stecker zum Host-PC angeschlossen ist und dort Vusb anliegt, wechselt das System in den Zustand &amp;quot;USB-powered-100&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Ereignis &amp;quot;on&amp;quot;:&lt;br /&gt;
* Falls eine Batterie verbaut ist und der Dreh-Drück-Geber gedrückt wird, wechselt das System in den Zustand &amp;quot;USB-powered-100&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Ereignis &amp;quot;230V-Set&amp;quot;:&lt;br /&gt;
* Wenn eine 230V-Relaibox verbaut ist und an der Box der On-Taster gedrückt wird oder&lt;br /&gt;
* wenn der 230V-Stecker gesteckt wird bzw. nach einem Stromausfall bei nicht verbautem oder leerem Akku&lt;br /&gt;
wechselt das System in den Zustand &amp;quot;Battery&amp;quot; und prüft den Ladezustand der Batterie; wenn der obere Wert der Batteriespannungshysterese unterschritten ist, wird im Zustand &amp;quot;Battery&amp;quot; sofort versucht, den Akku zu laden.&lt;br /&gt;
&lt;br /&gt;
===== Zustand &#039;&#039;&#039;5V powered&#039;&#039;&#039; =====&lt;br /&gt;
Falls eine Mini-USB-Buchse verbaut und dort ein externes USB-Ladegerät angeschlossen ist, kann das Sytem in diesen Zustand wechseln. Wenn eine Batterie verbaut und nicht voll geladen ist, wird sie automatisch mit bis zu maximal zulässigem Ladestrom geladen; dabei wird die Versorgungsspannung über einen Analogeingang beobachtet, um Überlastungen des Netzteils zu verhindern. Wenn der Webserver aktiv ist, ist er über Ethernet erreichbar. Am USB-Anschluss verhält sich das System als &amp;quot;self powered USB Device&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Ereignis &amp;quot;blackout 1&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;POE plugged 2&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;USB plugged 2&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;battery full 1&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;HDD on 1&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
&lt;br /&gt;
===== Zustand &#039;&#039;&#039;POE powered&#039;&#039;&#039; =====&lt;br /&gt;
Falls die Ethernet-Schnittstelle verbaut ist und dort eine Versorgungsspannung anliegt, kann das Sytem in diesen Zustand wechseln und verhält sich wie im Zustand &amp;quot;5V powered&amp;quot;. Der Akku wird ggf. mit maximal 10 Watt über die 48V geladen; dabei wird die 48V über einen Analogeingang beobachtet, um Überlastungen der POE-Versorgung zu verhindern.&lt;br /&gt;
&lt;br /&gt;
Ereignis &amp;quot;blackout 2&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;blackout 5&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;HDD on 2&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
&lt;br /&gt;
===== Zustand &#039;&#039;&#039;USB-powered-100&#039;&#039;&#039; =====&lt;br /&gt;
Falls das System über USB an ein einem Host-PC angeschlossen ist und und dort Vusb größer als 4,5V ist, kann das Sytem in diesen Zustand wechseln und wartet,&lt;br /&gt;
* bis es in einen der Zustände &amp;quot;USB-powered-500&amp;quot;, &amp;quot;5V powered&amp;quot; oder &amp;quot;POE powered&amp;quot; wechseln kann oder&lt;br /&gt;
* bis es in den Zustand &amp;quot;Power on&amp;quot; wechseln soll, um eine Festplatte einzuschalten, oder&lt;br /&gt;
* bis es in den Zustand &amp;quot;Power on&amp;quot; wechseln muss, um den Akku zu laden.&lt;br /&gt;
(ToDo: Wert von 4,5V prüfen)&lt;br /&gt;
&lt;br /&gt;
Ereignis &amp;quot;blackout 3&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;5V plugged 2&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;POE plugged 3&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;500mA available&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;USB unplugged&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;HDD on 3&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
&lt;br /&gt;
===== Zustand &#039;&#039;&#039;USB-powered-500&#039;&#039;&#039; =====&lt;br /&gt;
Falls das System über USB an ein einem Host-PC angeschlossen ist und und dort 500mA zur Verfügung stehen, kann das Sytem in diesen Zustand wechseln und verhält sich wie im Zustand &amp;quot;5V powered&amp;quot;, der Akku wird ggf. mit maximal 400mA über Vusb geladen.&lt;br /&gt;
&lt;br /&gt;
Ereignis &amp;quot;overcurrent&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;battery full 2&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;HDD on 4&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
&lt;br /&gt;
===== Zustand &#039;&#039;&#039;Battery&#039;&#039;&#039;=====&lt;br /&gt;
Ereignis &amp;quot;bat low 1&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;off&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;bat low 2&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;5V plugged 3&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;POE plugged 4&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;USB plugged 2&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;bat low 3&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;HDD on 5&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
&lt;br /&gt;
===== Zustand &#039;&#039;&#039;Power on&#039;&#039;&#039; =====&lt;br /&gt;
Ereignis &amp;quot;blackout 4&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;all HDD off 1&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;all HDD off 2&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;all HDD off 3&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;all HDD off 4&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
&lt;br /&gt;
== Downloads ==&lt;br /&gt;
&lt;br /&gt;
* Downloads (*.SCH, *.BRD, *.C) folgen&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* Diskussion zu diesem Projekt: http://www.mikrocontroller.net/topic/262844&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:PIC-Projekte]] [[Kategorie:Projekte]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=USB_Koppelfeld_f%C3%BCr_Festplatten&amp;diff=67145</id>
		<title>USB Koppelfeld für Festplatten</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=USB_Koppelfeld_f%C3%BCr_Festplatten&amp;diff=67145"/>
		<updated>2012-07-01T08:47:24Z</updated>

		<summary type="html">&lt;p&gt;Maybee: /* Zustandsautomaten */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Torsten Crull&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Es entsteht ein modulares System, welches sich zu nahezu beliebig großen Quasi- [http://de.wikipedia.org/wiki/Koppelfeld Koppelfeldern] für Festplatten kaskadieren läßt. Ein Koppelfeld-Modul hat Anschlüsse für vierzehn Festplatten; das entspricht einem 19&amp;quot;-Baugruppenträger. Die Stromversorgung der Festplatten läßt sich einzeln schalten. Die Platten werden - gesteuert vom Mikrocontroller - wahlweise über USB-SATA-Bridges, USB-IDE-Bridges oder über einen eSATA Port-Multiplier mit einem Host-Computer verbunden.&lt;br /&gt;
&lt;br /&gt;
[[Bild:USBMuxBlockschaltbild.png|720px]]&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Das Projekt umfaßt:&lt;br /&gt;
* &#039;&#039;&#039;Koppelfeld-Module&#039;&#039;&#039; in mehreren Varianten, entweder mit SATA-Port-Multiplier oder mit fünf USB-HUBs. Unabhängig von der Variante werden diese Module im folgenden Text als &amp;quot;Koppelfeld&amp;quot; bezeichnet.&lt;br /&gt;
* Eine &#039;&#039;&#039;Steuerplatine&#039;&#039;&#039; für bis zu sechzehn Koppelfelder; die Steuerung von außen erfolgt über RS232, USB oder Ethernet. Die Koppelfelder werden über I²C adressiert; die übrigen Signale werden über eine [http://de.wikipedia.org/wiki/Serial_Peripheral_Interface SPI-Schnittstelle] übertragen.&lt;br /&gt;
* Eine optionale &#039;&#039;&#039;230V-Relaisbox&#039;&#039;&#039; zum ein- und ausschalten der Stromversorgung, um die Standby-Ströme zu verringern.&lt;br /&gt;
* &#039;&#039;&#039;Relaisplatinen&#039;&#039;&#039; um die Stromversorgung (5V und 12V) der Festplatten zu schalten.&lt;br /&gt;
&lt;br /&gt;
Es können &#039;&#039;&#039;handelsübliche USB-Bridges&#039;&#039;&#039; verwendet werden; diese kosten etwa fünf Euro pro Stück:&lt;br /&gt;
&lt;br /&gt;
[[Bild:UAB_SATA_Bridges_Dsc_5364.jpg|400px]]&lt;br /&gt;
&lt;br /&gt;
[[Bild:HDDMuxBaumarkt.jpg|right]]&lt;br /&gt;
== Architektur und Mechanischer Aufbau ==&lt;br /&gt;
&lt;br /&gt;
Da in einem 19&amp;quot;-Baugruppenträger bis zu vierzehn handelsübliche 3,5&amp;quot;-Festplatten untergebracht werden können, sind die Koppelfelder auf vierzehn Festplatten ausgelegt. Pro Baugruppenträger ist also eine Koppelfeld-Platine nötig.&lt;br /&gt;
&lt;br /&gt;
Es sind wahlweise USB- und SATA-Koppelfelder vorgesehen, man kann also beliebig Baugruppenträger mit USB-SATA-Bridges und Baugruppenträger mit eSATA Port-Multiplyer vermischen. Die Anzahl von maximal sechzehn Baugruppenträgern ergibt sich aus der Adressierung über I²C.&lt;br /&gt;
&lt;br /&gt;
Jedes Koppelfeld hat eine Ansteuerung für eine 230V-Box: Um Strom zu sparen, wenn alle Festplatten im betreffenden Baugruppenträger ausgeschaltet sind, kann jedes Netzteil auf der Primärseite ausgeschaltet werden. Es können übliche Netzteile aus alten PC-Gehäusen verwendet werden (ATX-PC oder AT-PC). In der Firmware muß sicher gestellt werden, dass pro Baugruppenträger nicht mehr Festplatten eingschaltet werden, als das Netzteil versorgen kann und dass ggf. eine minimal benötigte Belastung des Netzteils für den Netzteil-Regler nicht unterschritten wird.&lt;br /&gt;
&lt;br /&gt;
Alternativ zu einem teuren Baugruppenträger kann man sich auch aus gelochten Stahlbändern vom Baumarkt einen Rahmen für die Festplatten bauen; das sieht dann aus wie aus &#039;nem Trix-Metallbaukasten (s. Bild).&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
&lt;br /&gt;
Die Hardware besteht aus den oben genannten Modulen, die im Folgenden beschrieben werden:&lt;br /&gt;
&lt;br /&gt;
=== Steuerplatine ===&lt;br /&gt;
&lt;br /&gt;
[[Bild:USBMuxSteuerplatine.png]]&lt;br /&gt;
&lt;br /&gt;
Zentrales Element der Steuerplatine ist ein PIC32MX764F128L-I/PT von Microchip. Er enthält  bereits alle verwendeten Schnittstellen: UART (RS232), Ethernet, USB, I²C, SPI und Analogeingang.&lt;br /&gt;
&lt;br /&gt;
Für die CPU-Platine sind folgende Integrationsstufen geplant:&lt;br /&gt;
&lt;br /&gt;
1. Gefädelte Lochrasterplatine mit Adapterplatine für das TQFP-100-Gehäuse und vornehmlich DIL-Gehäusen.&lt;br /&gt;
&lt;br /&gt;
2. Aufbau mit professionell gefertigten Platinen mit Lötstopplack und vornehmlich SMD-Gehäusen.&lt;br /&gt;
&lt;br /&gt;
2. Redesign und kleinserientaugliche Lösung.&lt;br /&gt;
&lt;br /&gt;
Die Gefädelte Lochrasterplatine wird während der Entwicklung Stück für Stück erweitert. In der ersten Ausbaustufe wird der Mikrocontroller über den integrierten UART und eine USB-RS232C-Brigde mit dem Host verbunden, damit die Software noch ohne USB-Stack auskommt. In der ersten Ausbaustufe soll zunächst die praktische Nutzbarkeit des Systems gewährleistet sein, um Erfahrung mit dem System zu sammeln.&lt;br /&gt;
&lt;br /&gt;
In weiteren Ausbaustufen werden dann der Analogeingang, die Ethernet-Schnittstelle und die USB-Schnittstelle in Betrieb genommen.&lt;br /&gt;
&lt;br /&gt;
Über den Analogeingang kann der Mikrocontroller die Spannungen an den Netzteilen der angeschlossenen Baugruppenträger bestimmen und überwachen; Details sind der Beschreibung der Koppelfelder (s.u.) zu entnehmen.&lt;br /&gt;
&lt;br /&gt;
==== Stromversorgung ====&lt;br /&gt;
&lt;br /&gt;
Damit die Netzteile nicht ständig Standby-Strom verbrauchen, kann der Mikrocontroller alle Netzteile primärseitig über eine 230V-Relaisbox ausschalten, auch das Netzteil, von  dem die Steuerplatine versorgt wird. &lt;br /&gt;
&lt;br /&gt;
Wenn das Gerät über USB vom Host gesteuert wird, verhält sich das Gerät wie ein &amp;quot;self-powered USB-device&amp;quot;. Es nutzt die max. 100mA vom USB-Anschluss, um damit einen Optokoppler in der der 230V-Relaisbox für die Aktivierung des Netzteils anzusteuern und kann sich dann aus dem Netzteil mit Strom versorgen. &lt;br /&gt;
&lt;br /&gt;
Wenn das Gerät über Wakeup-on-LAN eingeschaltet werden soll, wird es bei ausgeschaltetem Netzteil von einem Handy-Akku versorgt.&lt;br /&gt;
&lt;br /&gt;
Die 230V-Relaisbox hat optional einen 230V-Ausgang für den Host-Computer, der primärseitig vom Netz getrennt werden kann, um die  Stromkosten in den Standby-Zeiten zu senken.&lt;br /&gt;
&lt;br /&gt;
==== Display-Platine ====&lt;br /&gt;
&lt;br /&gt;
Optional ist eine Display-Platine mit einem Dreh-Drück-Geber und Siebensegment LED-Anzeigen vorgesehen. Sie ist auf Steuerplatine montiert und über einen zehnpolige Steckverbindung mit der Steuerplatine verbunden.&lt;br /&gt;
&lt;br /&gt;
Das Bedienkonzept steht noch nicht im Detail fest, nur soviel: Über den Dreh-Drück-Geber läßt sich das System einschalten und der anzuzeigende Wert auswählen. Angezeigt werden die Nummern der aktiven Festplatten und die gemessenen Spannungen an den Netzteilen. Der Aufwand für eine umfangreiche Benutzerschnittstelle über die Display-Platine lohnt sich kaum, da in der Praxis die Steuerung über RS232, Ethernet oder USB erfolgen wird.&lt;br /&gt;
&lt;br /&gt;
=== USB Koppelfeld ===&lt;br /&gt;
&lt;br /&gt;
Aus der [http://www.mikrocontroller.net/topic/262844#2729270 Diskussion zu diesem Projekt] ergab sich, dass die Variante 2 mit gestapelten USB-Hubs umgesetzt wird:&lt;br /&gt;
&lt;br /&gt;
[[Bild:USBMuxVarianten.png]]&lt;br /&gt;
&lt;br /&gt;
Die ursprüngliche Idee aus einer [http://www.mikrocontroller.net/articles/Datei:FSUSB42_Matrix.png Matrix mit FSUSB42-ICs] wurde verworfen; die Vorteile der Varianten:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Variante 1: FSUSB42-Matrix&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* geringere Latenzzeiten, da die USB-Daten einen HUB weniger passieren müssen.&lt;br /&gt;
* möglicher Weise bessere Kompatibilität beim Verbinden und Trennen der USB-Verbindung, da die Datenleitungen unterbrochen werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Variante 2: USB-Hub-Stapel:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Keine Begrenzung auf drei gleichzeitig aktive Festplatten&lt;br /&gt;
* geringere Kosten&lt;br /&gt;
* weniger Bauteile; die FSUSB42-ICs sind sehr winzig und lassen sich nur schwer von Hand bestücken.&lt;br /&gt;
* geringere Störanfälligkeit, da der USB-Hub wie ein Repeater die USB-Signale auffrischt.&lt;br /&gt;
&lt;br /&gt;
==== Hub-Stapel &amp;amp; Vusb-Steuerung ====&lt;br /&gt;
&lt;br /&gt;
Das Herzstück eines USB Koppelfeldes sind die USB-Hubs und optionale USB-Power-Schalter für die 5V-Spannung &amp;quot;Vusb&amp;quot;, jeweils an Pin 1 der USB-Anschlüsse. Über Vusb werden die USB-SATA-Bridges aktiviert und deaktiviert:&lt;br /&gt;
&lt;br /&gt;
[[Bild:USBMuxModul.png]]&lt;br /&gt;
&lt;br /&gt;
Um Kosten zu sparen, kann man die USB-Power-Schalter auch weglassen, dann werden die USB-SATA-Bridges zusammen mit den 5V der Festplatten geschaltet. Diese &amp;quot;Spar-Variante&amp;quot; ist natürlich nicht konform zur USB-Spezifikation.&lt;br /&gt;
&lt;br /&gt;
Da die 5V der Festplatten auf separaten Relais-Platinen geschaltet werden, sind zwei Varianten der Verkabelung mit den Relais-Platinen vorgesehen. In der Variante 2 (s. Bild, &amp;quot;Spar-Variante&amp;quot;) werden jeweils vier Adern pro Relais-Platine angeschlossen; bei der Verwendung von USB-Power-Schalten dürfen jeweils nur zwei Adern angeschlossen sein.&lt;br /&gt;
&lt;br /&gt;
[[Bild:USBMuxFlachband.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Legende:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1 Mitromatch-Steckverbinder&amp;lt;br&amp;gt;&lt;br /&gt;
2 Zwölfadriges Flachbandkabel, in Variante 1 (&amp;quot;Spar-Variante&amp;quot;) komplett&amp;lt;br&amp;gt;&lt;br /&gt;
3 Sechzehnadriges Flachbandkabel, in Variante 1 (&amp;quot;Spar-Variante&amp;quot;) komplett&amp;lt;br&amp;gt;&lt;br /&gt;
4 Vierpoliger Mitromatch-Steckverbinder, einer pro Relaisplatine&amp;lt;br&amp;gt;&lt;br /&gt;
5 Flachbandkabel, in Variante 2 (spezifikationskonform) fehlen jede dritte und vierte Ader.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Von den vier Adern pro Relais-Platine werden zwei Adern zum getrennten Einschalten der Stromversorgung von zwei Festplatten verwedet; über die anderen zwei Adern werden optional die geschalteten 5V für die Versorgung der USB-Bridges zurückgeführt. Falls USB-Power-Schalter verbaut sind, müssen diese Adern abgekniffen werden.&lt;br /&gt;
&lt;br /&gt;
==== Schieberegister für Steuerungsbits ====&lt;br /&gt;
&lt;br /&gt;
Die Steuerungsbits werden mit dem [http://de.wikipedia.org/wiki/Serial_Peripheral_Interface SPI-Protokoll] von einem Microcontroller in die kaskadierten Schieberegister (daisy chain) geschrieben. Die Slave-Select-Signale für die [http://de.wikipedia.org/wiki/Serial_Peripheral_Interface SPI-Schnittstelle] werden von einem I²C-Expander (IC1, PCF8574) (s.u.) gesteuert.&lt;br /&gt;
&lt;br /&gt;
Um das Clock-Signal bei /SS = high (inaktivem Slave-Select) zu unterdrücken, ist noch ein Oder-Gatter vor den Clock-Eingang vorgesehen. (ToDo: Im Forum ansprechen)&lt;br /&gt;
&lt;br /&gt;
* Bild folgt&lt;br /&gt;
&lt;br /&gt;
==== Slave-Select per I²C ====&lt;br /&gt;
&lt;br /&gt;
Von einem I²C-Expander (IC1, PCF8574) und einem  &#039;&#039;&#039;3:8 Decoder&#039;&#039;&#039; (IC37, 74HC138) werden pro Baugruppenträger die konkreten Slave-Select-Signale für das SPI (s.o.) erzeugt. Dadurch ist es möglich, bis zu sechzen Koppelfelder per I²C-Protokoll zu adrerssieren.&lt;br /&gt;
&lt;br /&gt;
Der 74HC138 enthält kein Latch. Um unerlaubte Zustände beim Umschalten der Adresse am 3:8 Decoder zu vermeiden, muß der Mikrocontroller beim Umschalten das  globale Slave-Select-Signal &amp;quot;/SS&amp;quot; auf &amp;quot;high&amp;quot; halten. (ToDo: Schaltbild aktualisieren)&lt;br /&gt;
&lt;br /&gt;
[[Bild:USB-Koppelfeld-I2C.png|600px]]&lt;br /&gt;
&lt;br /&gt;
Die I²C-Adresse des Baugruppenträgers wird über S1 und eine Bestückungsvariante für IC1 eingestellt.&lt;br /&gt;
&lt;br /&gt;
==== Analogsignal &amp;quot;Probe&amp;quot; ====&lt;br /&gt;
&lt;br /&gt;
Von allen Baugruppenträgern wird eine gemeinsame &amp;quot;Probe&amp;quot;-Leitung verwendet, um eine zu messende Spannung an den Analogeingang des Mikrocontrollers zu geben. Über Analogschalter (IC32, s. Bild) wird die zu messende Spannung mit der &amp;quot;Probe&amp;quot;-Leitung verbunden. Die Firmware muß sicher stellen, dass immer nur ein Analogschalter auf allen Baugruppen leitend ist.&lt;br /&gt;
&lt;br /&gt;
==== Ansteuerung der Relais-Platinen ====&lt;br /&gt;
&lt;br /&gt;
Um die Festplatten-Stromversorgung über Relais oder MOSFTEs zu steuern, führen vom Koppelfeld insgesamt 56 Flachbandadern zu den Relaisplatinen. Die Belegung der Adern ist im Kapitel &amp;quot;Vusb-Steuerung&amp;quot; (s.o.) beschrieben.&lt;br /&gt;
&lt;br /&gt;
Sowohl Relais als auch die MOSFET-Transistoren werden über Open-Collector-Ausgänge eines ULN2003A angesteuert. Gegenüber einzelnen Transistoren hat ein ULN2003 keinen finanziellen Nachteil, es sind jedoch weniger Teile zu bestücken und das Platinenlayout vereinfacht sich.&lt;br /&gt;
&lt;br /&gt;
[[Bild:USB-Koppelfeld-ULN2003a.png]]&lt;br /&gt;
&lt;br /&gt;
==== USB-Versorgung der USB-SATA/PATA-Bridges ====&lt;br /&gt;
&lt;br /&gt;
Wie oben beschrieben, gibt es eine &amp;quot;Spar-Variante&amp;quot; Nr. 1 und eine spezifikationskonforme Variante Nr. 2. Bei der &amp;quot;Spar-Variante&amp;quot; werden die USB-Power-Schalter nicht bestückt und die 5V Vusb kommen über die Pins 3,4,7,8, ... von X1 und X2 von der geschalteten 5V-Stromversorgung der Festplatten.&lt;br /&gt;
&lt;br /&gt;
[[Bild:USB-Koppelfeld-HighSide.png]]&lt;br /&gt;
&lt;br /&gt;
==== Steuerung der 230V-Relaisbox ====&lt;br /&gt;
&lt;br /&gt;
Die Relais in der 230V-Relaisbox (s.u.) werden über die Open-Collector-Ausgänge eines ULN2003A geschaltet. Durch die Open-Collector-Ausgänge können entweder Relais erregt werden, MOSFETs geschaltet oder Optokoppler angesteuert werden.&lt;br /&gt;
&lt;br /&gt;
6-Pin-DIN-Stecker dienen der Verbindung zwischen der dem Koppelfeld und der Relaisbox.&lt;br /&gt;
&lt;br /&gt;
[[Bild:USB-Koppelfeld-ULN2003b.png]]&lt;br /&gt;
&lt;br /&gt;
=== eSATA Koppelfeld ===&lt;br /&gt;
&lt;br /&gt;
* Details folgen&lt;br /&gt;
&lt;br /&gt;
=== Relaisplatine ===&lt;br /&gt;
[[Bild:USBMuxRelaisModul.png]]&lt;br /&gt;
&lt;br /&gt;
Die Relaismodule schalten in Zweiergruppen die Stromversorgung der Festplatten und sind mit vier Stromschienen aus Kupferdraht miteinander verbunden:&lt;br /&gt;
&lt;br /&gt;
[[Bild:USBMuxRelaisPlatine.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Legende:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
1 Relaisplatine mit Anschlussklemmen für das Netzteil, davon wird nur eine Platine pro Baugruppenträger benötigt.&amp;lt;br&amp;gt;&lt;br /&gt;
2 Anschlussklemmen (4 x 4mm²) für das Netzteil (ToDo: Alternativen klären)&amp;lt;br&amp;gt;&lt;br /&gt;
3 Anschlussklemmen (optional) für Kupferdraht (Nr. 4); der Kuperdraht kann auch flächig auf freistehendem Kupfer der Platine verlötet werden, um Kosten zu sparen.&amp;lt;br&amp;gt;&lt;br /&gt;
4 Vier &amp;quot;Stromschienen&amp;quot; aus 2,5mm² Kupferdraht (z.B. NYM-J 3x2,5 vom Baumarkt)&amp;lt;br&amp;gt;&lt;br /&gt;
5 Bohrungen zur Befestigung an der Rückseite an einem 19&amp;quot;-Baugruppenträger&amp;lt;br&amp;gt;&lt;br /&gt;
6 Relaisplatine mit Anschlussklemmen für das Netzteil&amp;lt;br&amp;gt;&lt;br /&gt;
7 Ritzung in der Platine, um Anschlussklemmen-Teil abbrechen zu können.&amp;lt;br&amp;gt;&lt;br /&gt;
8 4-Pin Micromatch-Verbinder (2 x Schalteingang, 2 x 5V-Ausgang)&amp;lt;br&amp;gt;&lt;br /&gt;
9 Durchkontaktierungen zum Anschluß eines Kabelschwanzes zur Stromversorgung einer Festplatte. Wahlweise können für aktuelle Platten SATA-Stecker oder für ältere Platten Molex-Stecker an den Kabelschwänzen sein.&amp;lt;br&amp;gt;&lt;br /&gt;
10 Zwei Relais (á zwei Wechser) oder vier MOSFETs&amp;lt;br&amp;gt;&lt;br /&gt;
11 Optionale Block-Kondensatoren, um Stromspitzen beim Einschalten der Festplatte abzublocken.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Relaismodul gibt es in zwei Varianten: Mit elektromagnetischen Schaltern und mit Halbleiter-Schaltern (MOSFETs):&lt;br /&gt;
&lt;br /&gt;
[[Bild:USBMuxRelaisModul1.png]] [[Bild:USBMuxRelaisModul2.png]]&lt;br /&gt;
&lt;br /&gt;
=== 230V-Relaisbox ===&lt;br /&gt;
[[Bild:USBMux230VBox.png]]&lt;br /&gt;
&lt;br /&gt;
Die Relaisbox kann optional über einen 6-poligen DIN-Stecker an eines der Koppelfelder angeschlossen werden, um die Netzteile für die Festplatten und für den Host-PC primärseitig vom Stromnetz zu trennen.&lt;br /&gt;
&lt;br /&gt;
Die Relaisbox muß nach VDE-Richtlinien aufgebaut sein. Damit beim Betrieb nicht ständig ein Relais angezogen (erregt) sein muß, kommen bistabile 230V-Relais zum Einsatz, die über Optokoppler (Halbleiterrelais) ein- und ausgeschaltet werden können.&lt;br /&gt;
&lt;br /&gt;
Am 230V-Anschluss hinter der Sicherung ist ein Gasableiter für einen zusätzlichen Blitzschutz vorgesehen.&lt;br /&gt;
&lt;br /&gt;
Bei Verwendung moderner Netzteile mit geringen Standby-Leistungen kann man natürlich auf die 230V-Relaisbox verzichten.&lt;br /&gt;
&lt;br /&gt;
* Details folgen&lt;br /&gt;
&lt;br /&gt;
=== Zustandsautomaten ===&lt;br /&gt;
== Software / Firmware ==&lt;br /&gt;
&lt;br /&gt;
Die Firmware wird komplet im internen EEPROM des PIC32MX764F128L-I/PT gespeichert und per In-Curcit-Debugger in den Mikrocontroller geladen.&lt;br /&gt;
&lt;br /&gt;
Die detaillierte Beschreibung der Firmware folgt, hier nur eine naheliegende Reihenfolge der Softwarestände der Integrationsstufen (s. o.):&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;1.1.&#039;&#039;&#039; Unidirektionale Steuerung über UART (RS232) zur Ansteuerung der Relaisplatinen in der &amp;quot;Spar-Variante&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;1.2.&#039;&#039;&#039; Rücksendung von Status- und Messwerten über RS232&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;1.3.&#039;&#039;&#039; Ansteuerung der 230V-Box, Stromversorgung über USB bei ausgeschaltetem Netzteil&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;1.4.&#039;&#039;&#039; Implementierung der spezifikationskonformen Variante Nr. 2. der USB-Koppelfelder&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;1.5.&#039;&#039;&#039; Ansteuerung der Display-Platine zur Ausgabe der gemessenen Spannungspegel&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;1.6.&#039;&#039;&#039; Implementierung des Batteriebetriebes&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;1.7.&#039;&#039;&#039; Ansteuerung von eSATA-Koppelfeldern&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;1.8.&#039;&#039;&#039; Implementierung des Ethernet-Anschlusses zur Steuerung über HTTP/Get-Kommandos&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;2.1.&#039;&#039;&#039; Implementierung von Wakup-on-LAN&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;2.2.&#039;&#039;&#039; Implementierung der USB-Schnittstelle des Mikrocontrollers als USB-HID als Alternative zur Steuerung über die RS232-USB-Bridge&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;2.3.&#039;&#039;&#039; Unterstützung des &amp;quot;[http://www.mikrocontroller.net/topic/262844#2730914 SetPortFeature(PORT_POWER) request]&amp;quot; um die Festplatten ohne Kommunikation mit dem Mikrocontroller schalten zu können.&lt;br /&gt;
&lt;br /&gt;
=== Zustandsautomaten ===&lt;br /&gt;
Bevor die Implementierung der Software beginnt, sollten die Anforderungen klar sein. Viele Anforderungen lassen sich wie in den folgenden Kapiteln in Zustandsautomaten beschreiben:&lt;br /&gt;
&lt;br /&gt;
==== Betriebszustände ====&lt;br /&gt;
(ToDo: Kapitel vervollständigen)&lt;br /&gt;
&lt;br /&gt;
[[Bild:HDDMuxBZStateChart.png]]&lt;br /&gt;
===== Zustand &#039;&#039;&#039;off&#039;&#039;&#039; =====&lt;br /&gt;
Dieser Zustand wird&lt;br /&gt;
* bei leerer oder nicht verbauter Batterie erreicht, wenn die aktive Stromversorgung ausfällt,&lt;br /&gt;
* wenn bei leerer Batterie keine aktive Stromversorgung angeschlossen ist oder&lt;br /&gt;
* wenn der Benutzer z.B. vor einem Urlaub über eine der Benutzerschnittstellem das System komplett ausschaltet, damit der Akku nicht entladen wird.&lt;br /&gt;
&lt;br /&gt;
Ereignis &amp;quot;5V plugged 1&amp;quot;:&lt;br /&gt;
* Wenn eine Mini-USB-Buchse verbaut ist und dort ein externes USB-Steckernetzteil angeschlossen ist, wechselt das System in den Zustand &amp;quot;5V powered&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Ereignis &amp;quot;POE plugged 1&amp;quot;:&lt;br /&gt;
* Wenn die Ethernet-Schnittstelle verbaut ist und dort eine Versorgungsspannung anliegt, wechselt das System in den Zustand &amp;quot;POE powered&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Ereignis &amp;quot;USB plugged 1&amp;quot;:&lt;br /&gt;
* Wenn der Stecker zum Host-PC angeschlossen ist und dort Vusb anliegt, wechselt das System in den Zustand &amp;quot;USB-powered-100&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Ereignis &amp;quot;on&amp;quot;:&lt;br /&gt;
* Falls eine Batterie verbaut ist und der Dreh-Drück-Geber gedrückt wird, wechselt das System in den Zustand &amp;quot;USB-powered-100&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Ereignis &amp;quot;230V-Set&amp;quot;:&lt;br /&gt;
* Wenn eine 230V-Relaibox verbaut ist und an der Box der On-Taster gedrückt wird oder&lt;br /&gt;
* wenn der 230V-Stecker gesteckt wird bzw. nach einem Stromausfall bei nicht verbautem oder leerem Akku&lt;br /&gt;
wechselt das System in den Zustand &amp;quot;Battery&amp;quot; und prüft den Ladezustand der Batterie; wenn der obere Wert der Batteriespannungshysterese unterschritten ist, wird im Zustand &amp;quot;Battery&amp;quot; sofort versucht, den Akku zu laden.&lt;br /&gt;
&lt;br /&gt;
===== Zustand &#039;&#039;&#039;5V powered&#039;&#039;&#039; =====&lt;br /&gt;
Falls eine Mini-USB-Buchse verbaut und dort ein externes USB-Ladegerät angeschlossen ist, kann das Sytem in diesen Zustand wechseln. Wenn eine Batterie verbaut und nicht voll geladen ist, wird sie automatisch mit bis zu maximal zulässigem Ladestrom geladen; dabei wird die Versorgungsspannung über einen Analogeingang beobachtet, um Überlastungen des Netzteils zu verhindern. Wenn der Webserver aktiv ist, ist er über Ethernet erreichbar. Am USB-Anschluss verhält sich das System als &amp;quot;self powered USB Device&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Ereignis &amp;quot;blackout 1&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;POE plugged 2&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;USB plugged 2&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;battery full 1&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;HDD on 1&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
&lt;br /&gt;
===== Zustand &#039;&#039;&#039;POE powered&#039;&#039;&#039; =====&lt;br /&gt;
Falls die Ethernet-Schnittstelle verbaut ist und dort eine Versorgungsspannung anliegt, kann das Sytem in diesen Zustand wechseln und verhält sich wie im Zustand &amp;quot;5V powered&amp;quot;. Der Akku wird ggf. mit maximal 10 Watt über die 48V geladen; dabei wird die 48V über einen Analogeingang beobachtet, um Überlastungen der POE-Versorgung zu verhindern.&lt;br /&gt;
&lt;br /&gt;
Ereignis &amp;quot;blackout 2&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;blackout 5&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;HDD on 2&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
&lt;br /&gt;
===== Zustand &#039;&#039;&#039;USB-powered-100&#039;&#039;&#039; =====&lt;br /&gt;
Falls das System über USB an ein einem Host-PC angeschlossen ist und und dort Vusb größer als 4,5V ist, kann das Sytem in diesen Zustand wechseln und wartet,&lt;br /&gt;
* bis es in einen der Zustände &amp;quot;USB-powered-500&amp;quot;, &amp;quot;5V powered&amp;quot; oder &amp;quot;POE powered&amp;quot; wechseln kann oder&lt;br /&gt;
* bis es in den Zustand &amp;quot;Power on&amp;quot; wechseln soll, um eine Festplatte einzuschalten, oder&lt;br /&gt;
* bis es in den Zustand &amp;quot;Power on&amp;quot; wechseln muss, um den Akku zu laden.&lt;br /&gt;
(ToDo: Wert von 4,5V prüfen)&lt;br /&gt;
&lt;br /&gt;
Ereignis &amp;quot;blackout 3&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;5V plugged 2&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;POE plugged 3&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;500mA available&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;USB unplugged&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;HDD on 3&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
&lt;br /&gt;
===== Zustand &#039;&#039;&#039;USB-powered-500&#039;&#039;&#039; =====&lt;br /&gt;
Falls das System über USB an ein einem Host-PC angeschlossen ist und und dort 500mA zur Verfügung stehen, kann das Sytem in diesen Zustand wechseln und verhält sich wie im Zustand &amp;quot;5V powered&amp;quot;, der Akku wird ggf. mit maximal 400mA über Vusb geladen.&lt;br /&gt;
&lt;br /&gt;
Ereignis &amp;quot;overcurrent&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;battery full 2&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;HDD on 4&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
&lt;br /&gt;
===== Zustand &#039;&#039;&#039;Battery&#039;&#039;&#039;=====&lt;br /&gt;
Ereignis &amp;quot;bat low 1&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;off&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;bat low 2&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;5V plugged 3&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;POE plugged 4&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;USB plugged 2&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;bat low 3&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;HDD on 5&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
&lt;br /&gt;
===== Zustand &#039;&#039;&#039;Power on&#039;&#039;&#039; =====&lt;br /&gt;
Ereignis &amp;quot;blackout 4&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;all HDD off 1&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;all HDD off 2&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;all HDD off 3&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
Ereignis &amp;quot;all HDD off 4&amp;quot;:&lt;br /&gt;
* …&lt;br /&gt;
&lt;br /&gt;
== Downloads ==&lt;br /&gt;
&lt;br /&gt;
* Downloads (*.SCH, *.BRD, *.C) folgen&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* Diskussion zu diesem Projekt: http://www.mikrocontroller.net/topic/262844&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:PIC-Projekte]] [[Kategorie:Projekte]]&lt;/div&gt;</summary>
		<author><name>Maybee</name></author>
	</entry>
</feed>