<?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=Elektroloeter</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=Elektroloeter"/>
	<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/articles/Spezial:Beitr%C3%A4ge/Elektroloeter"/>
	<updated>2026-04-11T09:17:04Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Elektroloeter&amp;diff=106348</id>
		<title>Benutzer:Elektroloeter</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Elektroloeter&amp;diff=106348"/>
		<updated>2023-09-23T00:34:45Z</updated>

		<summary type="html">&lt;p&gt;Elektroloeter: Die Seite wurde neu angelegt: „Benutzer:Elektrobastler“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Benutzer:Elektrobastler&lt;/div&gt;</summary>
		<author><name>Elektroloeter</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Operationsverst%C3%A4rker-Grundschaltungen&amp;diff=106347</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=106347"/>
		<updated>2023-09-22T12:08:34Z</updated>

		<summary type="html">&lt;p&gt;Elektroloeter: /* Spannungsfolger (Impedanzwandler) */&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 bist 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;
&lt;br /&gt;
[[Category:Grundlagen]]&lt;br /&gt;
[[Category:Bauteile]]&lt;/div&gt;</summary>
		<author><name>Elektroloeter</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Operationsverst%C3%A4rker-Grundschaltungen&amp;diff=106346</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=106346"/>
		<updated>2023-09-22T12:01:28Z</updated>

		<summary type="html">&lt;p&gt;Elektroloeter: /* Spannungsfolger (Impedanzwandler) */&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 bist 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 Zenerdiode zur Anwendung, die aber nicht mehr die schlechten Eigenschaften der Standardbeschaltung mit lediglich Widerstand und Zenerdiode  hat. Bei einer Zenerdiode hängt die genaue Spannung davon ab, welcher Strom durch sie fliesst. Dieser Strom (und damit auch die Höhe der Zenerspannung) würde sich aber ändern, wenn ein Verbraucher die Zenerdiode direkt mit seinem Stromfluss belasten würde. Als Folge davon würde die Spannungslage der Zenerdiode je nach Verbraucher leicht schwanken. Durch den Spannungsfolger wird das verhindert, weil der jetzt den vom Verbraucher gezogenen Strom bereitstellt.&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;
&lt;br /&gt;
[[Category:Grundlagen]]&lt;br /&gt;
[[Category:Bauteile]]&lt;/div&gt;</summary>
		<author><name>Elektroloeter</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Operationsverst%C3%A4rker-Grundschaltungen&amp;diff=106345</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=106345"/>
		<updated>2023-09-22T11:56:04Z</updated>

		<summary type="html">&lt;p&gt;Elektroloeter: /* Nichtinvertierender Verstärker mit Offset */&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 bist 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 so aus: &lt;br /&gt;
&lt;br /&gt;
[[Bild:Op-spannungsfolger2.png]]&lt;br /&gt;
&lt;br /&gt;
Was soll das nun? Wir nutzen die Eigenschaft, dass ein idealer OP einen unendlichen Eingangswiderstand und einen Ausgangswiderstand von 0Ω hat. Real sieht das 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. Deshalb spricht man bei dieser Schaltung von einem Impedanzwandler. Eine solche Schaltung kann also 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 Zenerdiode zur Anwendung, die aber nicht mehr die schlechten Eigenschaften der Standardbeschaltung mit lediglich Widerstand und Zenerdiode  hat. Bei einer Zenerdiode hängt die genaue Spannung davon ab, welcher Strom durch sie fliesst. Dieser Strom (und damit auch die Höhe der Zenerspannung) würde sich aber ändern, wenn ein Verbraucher die Zenerdiode direkt mit seinem Stromfluss belasten würde. Als Folge davon würde die Spannungslage der Zenerdiode je nach Verbraucher leicht schwanken. Durch den Spannungsfolger wird das verhindert, weil der jetzt den vom Verbraucher gezogenen Strom bereitstellt.&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;
&lt;br /&gt;
[[Category:Grundlagen]]&lt;br /&gt;
[[Category:Bauteile]]&lt;/div&gt;</summary>
		<author><name>Elektroloeter</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Drehgeber&amp;diff=106344</id>
		<title>Drehgeber</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Drehgeber&amp;diff=106344"/>
		<updated>2023-09-22T11:37:37Z</updated>

		<summary type="html">&lt;p&gt;Elektroloeter: /* Differenzierung von Drehgebern */ nicht nur gerastete im Einsatz,  Lautstärke war doppelt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Drehgeber (auch Inkrementaldrehgeber, Quadraturencoder, Drehencoder, Drehimpulsgeber genannt) dienen der dynamischen Erfassung von Winkeländerungen bei Achsen und Wellen. Sie werden sowohl für die manuelle Eingabe von Werten, als auch zur Ermittlung von Drehgeschwindigkeiten eingesetzt.&lt;br /&gt;
&lt;br /&gt;
== Funktion ==&lt;br /&gt;
[[Bild:encoder_signal.png]]&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
Drehgeber erzeugen bei Drehung der Achse an zwei Datenleitungen am Ausgang ein sogenanntes [http://de.wikipedia.org/wiki/Gray-Code Gray-Code]-Signal. Der Vorteil dieser Codierung ist, dass ein [[Entprellung|Entprellen]] deutlich einfacher wird, da dieser Code die Eigenschaft besitzt, dass sich zwischen benachbarten Codes nur jeweils ein Bit ändert. Dies ermöglicht die asynchrone Abtastung, ohne weiter als einen Schritt vom wahren Ergebnis entfernt zu sein, weil ein sich änderndes Bit lediglich verspätet, aber nicht falsch erfasst wird.&lt;br /&gt;
&lt;br /&gt;
== Differenzierung von Drehgebern ==&lt;br /&gt;
&lt;br /&gt;
Man muss zwischen Drehgebern unterscheiden, die von schnell laufenden Maschinen angetrieben werden z.&amp;amp;nbsp;B. zum Messen des Drehwinkels und solchen, die von Hand bedient werden z.&amp;amp;nbsp;B. zum Einstellen der Lautstärke an HIFI-Geräten. Letztere haben in der Regel Rastpunkte, in welche der Drehmechanismus leicht &amp;quot;einschnappt&amp;quot;. Hierdurch fühlt der Benutzer das Fortschreiten des zu bedienenden Vorgangs. Es sind aber auch Geber im Einsatz, die keine Rastpunkte aufweisen und damit ein mehr analoges Gefühl wie bei einem Potentiometer ermöglichen. Die maschinengetriebenen Drehgeber sind allesamt frei drehbar und haben keine mechanischen Rastpunkte. &lt;br /&gt;
&lt;br /&gt;
=== Handbediente Drehgeber ===&lt;br /&gt;
&lt;br /&gt;
Aus Kosten- und Platzgründen sind handbediente Drehgeber häufig als schaltende Kontakte ausgeführt, was die Gefahr des Prellens mit sich bringt. Die erste dagegen ergriffene Maßnahme ist die oben genannte Nutzung eines Codes, bei dem sich nie zwei Bits gleichzeitig ändern. Diese Maßnahme allein ist aber nicht ausreichend.&lt;br /&gt;
&lt;br /&gt;
Das oben gezeigte Signaldiagramm zeigt mit den senkrecht gestrichelten Linien die Rastungen so an, wie sie für Handbedienung verbreitet sind, nämlich mit zwei Codewechseln zwischen den Rastungen. Die Software sollte dies berücksichtigen und pro Rastung nur um einen Schritt fortschreiten, was bedeutet, dass nur zwei vollendete aufeinanderfolgende elektrische Wechsel ausgewertet werden. Dies hat den Vorteil, dass ein kurzfristiges Prellen eines Kontaktes durch Erschütterung des Encoders z.&amp;amp;nbsp;B. durch vibrierende Maschinen oder durch Kontaktprellen beim Drehen nicht zu einer Fehlinterpretation kommt. Dennoch ist die Reaktionszeit kurz, da verzögernde Timerschleifen zum [[Entprellung|Entprellen]] überflüssig sind. Die hierbei auftretende Halbierung der Auflösung ist wegen des durch menschliche Fähigkeiten begrenzt dosierbaren Drehwinkels irrelevant. Zudem entsteht so haptische Übereinstimmung zwischen der Anzahl der gefühlten Rastungen und dem Fortschreiten des zu bedienenden Prozesses, sofern der bediente Wert entsprechend inkremeniert wird.&lt;br /&gt;
&lt;br /&gt;
Es sei hier aber angemerkt, dass es auch handbediente Drehgeber mit anderer Anordnung der Rastungen gibt, die somit auch eines anderen Algorithmus bedürfen. Bei manchen Billigprodukten fallen die Rastpunkte mit den Zustandsübergängen zusammen.&lt;br /&gt;
&lt;br /&gt;
=== Maschinengetriebene Drehgeber ===&lt;br /&gt;
&lt;br /&gt;
Der maschinengetriebene Drehgeber hat in der Regel keine Rastpunkte. Zudem dreht er sich häufig so schnell, dass für entprellende Maßnahmen nach dem Verzögerungsprinzip (Kondensator, Delayschleife oder zyklischer Timerüberlaufinterrupt) die Zeit fehlt. Daher sind solche Drehgeber in aller Regel zum Zwecke der prellfreien Ausgänge aufwendiger und somit teurer konstruiert. Realisiert wird dies durch kleines mechanisches Spiel, Leichtgängigkeit und optische Maßnahmen. Diese Prellfreiheit ist aber dann nutzlos, wenn der Drehgeber von einer Mechanik getrieben wird, welche Vibrationen bisweilen mikroskopischer Größe aufweist, z.&amp;amp;nbsp;B. ausgelöst durch mechanisches Spiel. Diese Vibration ist der Drehbewegung mechanisch überlagert. Dies kann dazu führen, dass beim Überschreiten eines elektrischen Schaltpunktes mikroskopisch mehrfach zurück und wieder vorgedreht wird und somit ein dem Prellen ähnliches Ereignis auftritt. Dies kann durch Auswertung zweier vollendeter aufeinanderfolgender elektrischer Wechsel vermieden werden. Dies stellt nach heutigem Kenntnisstand (2009) die schnellste Reaktionsmöglichkeit dar. Will man hierdurch nicht die Auflösung halbieren (wie es bei den oben genannten handbedienten Drehgebern passiert), müssen jeweils parallel zwei aufeinanderfolgende Impulse um die Periodenlänge eines Schaltimpulses phasenverschoben in zwei getrennten &amp;quot;Pipelines&amp;quot; überwacht werden. Vereinfacht ist dies hier für eine Drehrichtung illustriert. Die Berücksichtigung beider Drehrichtungen ist komplexer:&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;
  |  |  |  |&lt;br /&gt;
  1  2  3  4&amp;lt;/syntaxhighlight&amp;gt;Pipeline1 überwacht die vollendete Schaltfolge 1-2. Pipeline2 überwacht die vollendete Schaltfolge 2-3. Pipeline1 überwacht die vollendete Schaltfolge 3-4 etc. Jede der beiden Pipelines gibt einen Zählimpuls ab, so dass trotz Abwartens von zwei aufeinander folgenden Schaltpunkten bei jedem Schaltpunkt ein Fortschreitungsimpuls (Zählimpuls) erfolgt. Letztendlich liefert das Verfahren beim Wechsel zwischen Vor- und Rückwärtsdrehen eine mechanische [[Schmitt-Trigger|Hysterese]] von der Länge eines Schaltzustandes. Dies ist aber aufgrund der Vibrationen bzw. des mechanischen Spieles unvermeidbar. Der Drehgeber kann eben nicht genauer sein, als die ihn treibende Mechanik.&lt;br /&gt;
 &lt;br /&gt;
Insgesamt gesehen müssen die ergriffenen Maßnahmen auf die mechanischen Gegebenheiten und die Anforderungen an Auflösung und Geschwindigkeit angepasst werden. Die Angabe eines sehr aufwendigen parametrierbaren Algorithmus (dessen Wahl der Parameter wiederum nicht trivial wäre), der in allen Lebenslagen funktioniert, wäre zwar möglich, ist aber mit Blick auf die hohe Prozessorlast nicht angezeigt. In Extremfällen empfehlen sich möglicherweise [[FPGA]]s zur Auswertung. &amp;quot;Einigermaßen langsame&amp;quot; Anwendungen und geringe Auflösungen können aber mit denselben Methoden erschlagen werden, die sich auch für den handbetriebenen Drehgeber eignen und finden sich im Artikel unten.&lt;br /&gt;
&lt;br /&gt;
== Signalauswertung ==&lt;br /&gt;
&lt;br /&gt;
Im folgenden ein Bild, wie ein reales Signal eines Drehgebers aussehen kann:&lt;br /&gt;
 &lt;br /&gt;
[[Datei:Prellender_Drehgeber.svg]]&lt;br /&gt;
 &lt;br /&gt;
Die Auswertung eines Drehgebers macht man am besten in einem Timer-Interrupt, der mit einer festen Frequenz ausgeführt wird. Die Abtastfrequenz muss so hoch sein, dass bei maximaler Drehzahl zwischen zwei Codewechseln mindestens 1 Abtastung erfolgt, besser jedoch mehr.&lt;br /&gt;
&lt;br /&gt;
Es gibt bei manchen Mikrokontrollern Timer, die Drehencodersignale direkt erfassen können. Im Datenblatt bzw. User Manual sollte das unter den Stichworten &amp;quot;quadrature&amp;quot; oder &amp;quot;incremental&amp;quot; Encoder zu finden sein.&lt;br /&gt;
&lt;br /&gt;
Nachfolgend findet sich die Signalfolge eines realen mechanischen ALPS-Encoders (30 Raststellungen pro Umdrehung), mit einem Logikanalysator aufgenommen.  Gezeigt ist dabei ca. eine halbe Umdrehung im Uhrzeigersinn, gefolgt von einer Drehung in Gegenrichtung.  Das benutzte [https://de.wikipedia.org/wiki/Value_Change_Dump Value-Change-Dump]-Dateiformat kann beispielsweise von [http://gtkwave.sourceforge.net/ GTKwave] dargestellt werden.&lt;br /&gt;
&lt;br /&gt;
[[Medium:Rotaryenc.vcd]]&lt;br /&gt;
&lt;br /&gt;
Das folgende Bild zeigt dieses Signal als GTKwave-Darstellung:&lt;br /&gt;
&lt;br /&gt;
[[Datei:Rotaryenc.png]]&lt;br /&gt;
&lt;br /&gt;
Ganz oben das Signal im Ganzen.  Man erkennt deutlich den Versatz der beiden Spuren, der je nach Drehrichtung unterschiedlich ist.&lt;br /&gt;
&lt;br /&gt;
In der Mitte ist ein Ausschnitt, der beide Spuren beim Wechsel von einem Rastpunkt auf den nächsten zeigt. Die (hervorgehobene) Zeitdifferenz zwischen Cursor und B-Markierung im oberen Bereich zeigt, dass dabei der Code zwischen den Rastpunkten innerhalb weniger Millisekunden durchlaufen wird.  Bei der Auswertung muss man daher &lt;br /&gt;
sicher sein, diesen Bereich mindestens einmal abgetastet zu haben.&lt;br /&gt;
&lt;br /&gt;
Der benutzte ALPS-Drehgeber prellt verhältnismäßig wenig.  Die meisten Übergänge von einem Code zum nächsten lassen in der benutzten Auflösung des Logikanalysators (10 ns) kein Prellen erkennen.  In den wenigen Fällen, in denen ein Prellen zu finden ist, bewegt sich dieses im Bereich einiger Mikrosekunden, wie im unteren Teil dargestellt.&lt;br /&gt;
&lt;br /&gt;
== Warum Sparvarianten nicht gut sind ==&lt;br /&gt;
&lt;br /&gt;
Oft sieht man im Netz &amp;quot;clevere&amp;quot; Sparvarianten, welche angeblich ebensogut zur Auswertung von Drehgebern geeignet sind. Ein genaueres Hinschauen sowie Tests unter realen Bedingungen zeigen jedoch schnell die Schwächen dieser Ansätze.&lt;br /&gt;
&lt;br /&gt;
=== Flankenerkennung von A und Pegelauswertung von B ===&lt;br /&gt;
&lt;br /&gt;
Viele Sparvarianten verwenden einen externen Interrupt, welcher auf die steigende oder fallende Flanke von Spur A auslöst und dann den Pegel von B auswertet. Ist B=0, dann dreht der Encoder nach rechts, anderenfalls nach links. Diese Auswertung hat zwei Schwachstellen.&lt;br /&gt;
&lt;br /&gt;
# Die Auflösung wird auf ein Viertel reduziert, weil nur jede steigende Flanke von A ausgewertet wird.&lt;br /&gt;
# Pendelt der Encoder zwischen zwei Codes, bei denen A seinen Pegel wechselt,&lt;br /&gt;
## kommt es zu (sehr) vielen Interrupts, die den Mikrocontroller vollkommen auslasten können.&lt;br /&gt;
## interpretiert die Auswertung jede steigende Flanke als neuen Schritt. Der Encoder scheint sich für die Auswertung immer weiter zu drehen (wenn man nicht prüft, ob auch B den Pegel ändert), obwohl er nur pendelt.&lt;br /&gt;
&lt;br /&gt;
Das Pendeln kann zwei Ursachen haben.&lt;br /&gt;
&lt;br /&gt;
# Der Encoder pendelt wirklich; das kann z.&amp;amp;nbsp;B. bei hochauflösenden Encodern ohne Rastung geschehen, welche an jeder beliebigen Stelle stehen bleiben können und durch geringe mechanische Erschütterungen dann zwischen zwei Codes pendeln; das kann z.&amp;amp;nbsp;B. bei hochauflösenden Encodern in CNC-Maschinen der Fall sein.&lt;br /&gt;
# Die Signale prellen; das kommt vor allem bei billigen elektromechanischen Drehknöpfen vor, welche einfache Schleifkontakte zur Kodierung nutzen.&lt;br /&gt;
&lt;br /&gt;
Wie man sieht ist diese Methode nicht geeignet, einen Drehgeber solide zu dekodieren.&lt;br /&gt;
&lt;br /&gt;
=== Auswertung mit Interrupt durch Pegelwechsel ===&lt;br /&gt;
&lt;br /&gt;
Es wird bisweilen die Auffassung vertreten, dass mit Hilfe von sog. Pin Change Interrupts Rechenzeit gespart werden kann. Dabei wird bei einem Pegelwechsel von Spur A oder B ein Interrupt erzeugt. Dort werden dann A und B eingelesen und vollständig ausgewertet. Diese Methode ist besser, aber nicht gut genug. Sie vermeidet Fehler 1. und 2.2 der oben genannten Auswertung, aber nicht 2.1, da auch sie durch einen pendelnden/prellenden Encoder die CPU stark belastet.&lt;br /&gt;
&lt;br /&gt;
== Solide Lösung: Beispielcode in C ==&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;
/*                      Reading rotary encoder                          */&lt;br /&gt;
/*                      one, two and four step encoders supported       */&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/*              Author: Peter Dannegger                                 */&lt;br /&gt;
/*              target: ATmega16                                        */&lt;br /&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;
#define XTAL        8e6         // 8MHz&lt;br /&gt;
&lt;br /&gt;
#define ENCODER_PIN PINA&lt;br /&gt;
#define PHASE_A     (1&amp;lt;&amp;lt;PA1)&lt;br /&gt;
#define PHASE_B     (1&amp;lt;&amp;lt;PA3)&lt;br /&gt;
&lt;br /&gt;
#define LEDS_DDR    DDRC&lt;br /&gt;
#define LEDS        PORTC           // LEDs against VCC&lt;br /&gt;
&lt;br /&gt;
volatile int8_t enc_delta;          // -128 ... 127&lt;br /&gt;
static int8_t last;&lt;br /&gt;
&lt;br /&gt;
void encode_init( void ) {&lt;br /&gt;
  int8_t tmp, code;&lt;br /&gt;
&lt;br /&gt;
  // init encoder&lt;br /&gt;
  tmp = ENCODER_PIN;&lt;br /&gt;
  code = 0;&lt;br /&gt;
  if( tmp &amp;amp; PHASE_A ) code  = 3;&lt;br /&gt;
  if( tmp &amp;amp; PHASE_B ) code ^= 1;      // convert gray to binary&lt;br /&gt;
  last = code;                        // power on state&lt;br /&gt;
  enc_delta = 0;&lt;br /&gt;
&lt;br /&gt;
  // init timer 0&lt;br /&gt;
  TCCR0 = (1&amp;lt;&amp;lt;WGM01) | (1&amp;lt;&amp;lt;CS01) | (1&amp;lt;&amp;lt;CS00);   // CTC, prescaler 64&lt;br /&gt;
  OCR0 = (uint8_t)(XTAL / 64.0 * 1e-3 - 0.5);   // 1ms&lt;br /&gt;
  TIMSK |= 1&amp;lt;&amp;lt;OCIE0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ISR( TIMER0_COMP_vect ) {           // 1ms for manual movement&lt;br /&gt;
  int8_t code, diff, tmp;&lt;br /&gt;
&lt;br /&gt;
  tmp  = ENCODER_PIN;&lt;br /&gt;
  code = 0;&lt;br /&gt;
  if ( tmp &amp;amp; PHASE_A ) code  = 3;&lt;br /&gt;
  if ( tmp &amp;amp; PHASE_B ) code ^= 1;   // convert gray to binary&lt;br /&gt;
  diff = last - code;               // difference last - new&lt;br /&gt;
  if( diff &amp;amp; 1 ) {                  // bit 0 = value (1)&lt;br /&gt;
    last = code;                    // store new as next last&lt;br /&gt;
    enc_delta += (diff &amp;amp; 2) - 1;    // bit 1 = direction (+/-)&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// read 1, 2, or 4 step encoders&lt;br /&gt;
int8_t encode_read( uint8_t step )    { &lt;br /&gt;
  int8_t val;&lt;br /&gt;
&lt;br /&gt;
  // atomic access to enc_delta&lt;br /&gt;
  cli();&lt;br /&gt;
  val = enc_delta;&lt;br /&gt;
  switch (step) {&lt;br /&gt;
    case  2: enc_delta = val &amp;amp; 1; val &amp;gt;&amp;gt;= 1; break;&lt;br /&gt;
    case  4: enc_delta = val &amp;amp; 3; val &amp;gt;&amp;gt;= 2; break;&lt;br /&gt;
    default: enc_delta = 0; break;&lt;br /&gt;
  }&lt;br /&gt;
  sei();&lt;br /&gt;
  return val;                   // counts since last call&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main( void ) {&lt;br /&gt;
  int32_t val = 0;&lt;br /&gt;
&lt;br /&gt;
  PORTA |= PHASE_A | PHASE_B;       // activate internal pull up resistors&lt;br /&gt;
  LEDS_DDR = 0xFF;&lt;br /&gt;
  encode_init();&lt;br /&gt;
  sei();&lt;br /&gt;
&lt;br /&gt;
  for(;;){&lt;br /&gt;
    val += encode_read(1);          // read a single step encoder&lt;br /&gt;
    LEDS = val;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Je nach Encodertyp ruft man encode_read() mit der passenden Anzahl elektrischer Codes/Rastung auf. Für manuelle Eingabe ist ein Abfrageintervall von 1ms meist ausreichend. Das Auslesen im Hauptprogramm mit den Funktionen encode_read() muss mit mindesten 127tel der Frequenz des Timers erfolgen, hier im Beispiel mit 1kHz/127 ~ 8Hz. Ansonsten können im Extremfall Überläufe der Variable enc_delta auftreten und zu Fehlfunktionen des Programms führen. &lt;br /&gt;
&lt;br /&gt;
* [http://dse-faq.elektronik-kompendium.de/dse-faq.htm#F.29 dse-FAQ]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/6526 Forumsbeitrag]: Drehgeber auslesen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/38863 Forumsbeitrag]: Drehimpulsgeber mit Rasterstellung bei 00/11 auswerten&lt;br /&gt;
&lt;br /&gt;
Kurze Erklärung zur Funktionsweise des Codes: Unter der Voraussetzung, dass die Abtastung häufig genug erfolgt, dass in jeder Code-Kombination mindestens einmal abgetastet wird, kann sich zwischen dem aktuellen und dem zurückliegenden Wert als Differenz immer nur 0, 1, -1, 3 oder -3 ergeben.  (Eine 2 würde bedeuten, dass die Abtastung einen Schritt übersprungen hat.)  Dabei stellen 1 und -3 die Bewegung in eine Richtung, -1 und 3 in die andere Richtung dar.  Deren Bitmuster sind 0b0…001, 0b1…101 bzw. 0b1…111, 0b0…011.  Damit wird klar, dass man Bit 0 (diff &amp;amp; 1) als Kennzeichen heranziehen kann, dass sich in diesem Schritt überhaupt etwas geändert hat, und Bit 1 (diff &amp;amp; 2) als Kennzeichen für die Richtung der Änderung.&lt;br /&gt;
&lt;br /&gt;
Ferner ist beim Auswerten zu beachten, dass die beiden Signalleitungen des Drehgebers möglichst zeitgleich erfasst werden. Dies ist insbesondere dann wichtig, wenn der Drehgeber zusammen mit weiteren Bedienelementen an einen Multiplexer angeschlossen ist! Das wird hier durch die Zwischenvariable tmp erreicht.&lt;br /&gt;
&lt;br /&gt;
=== Dekoder für Drehgeber mit wackeligen Rastpunkten ===&lt;br /&gt;
&lt;br /&gt;
Im wahren Leben gibt es immer wieder Dinge, welche der Theorie zwar widersprechen, dennoch weit verbreitet sind. Da machen Drehgeber keine Ausnahme. Gerade die heute so beliebten Drehgeber für manuelle Bedienung sind in großer Anzahl von verschiedenen Herstellern verfügbar. Umso merkwürdiger ist es, dass hier die Rastpunkte oft &#039;&#039;&#039;genau&#039;&#039;&#039; auf dem Pegelwechsel einer Spur liegen, meist Spur B. So zum Beispiel beim Drehgeber [http://www.alps.com/products/WebObjects/catalog.woa/E/PDF/Switch/Encoder/EC11/EC11.PDF EC11E15244B2] von [http://www.alps.com Alps], welcher u.a bei [http://www.pollin.de Pollin] ehältlich ist.&lt;br /&gt;
&lt;br /&gt;
Bei diesem Drehgeber kommt es bei der klassischen, eigentlich soliden Auswertung zu dem Effekt, dass der Drehgeber in Ruhelage auf einem Rastpunkt pendeln kann. Damit erhält das Programm sporadisch einen Schritt vor und zurück. Auch wenn sich die Auswertung daran nicht verschluckt, so ist dieses Pendeln doch ärgerlich, denn eine Menusteuerung würde dann komische Sachen machen.&lt;br /&gt;
&lt;br /&gt;
Die solide Lösung des Problems ist recht einfach. Man wertet in der bekannten Manier weiterhin die abgetasteten Spuren A und B aus, allerdings mit der Änderung, dass man nur die Pegelwechsel der Spur A auswertet. Damit halbiert man zwar die Auflösung, das ist hier aber paradoxerweise gut! Denn damit bekommt man automatisch genau einen Zählimpuls pro Rastpunkt.&lt;br /&gt;
&lt;br /&gt;
Praktisch heisst das, dass man lediglich die Dekodertabelle für die Auswertung ändern muss. Beachtet werden muss jedoch, dass man bei den &amp;quot;wackeligen&amp;quot; Drehgebern Spur A und B &#039;&#039;&#039;nicht&#039;&#039;&#039; beliebig vertauschen kann. Ist also die Auswertung immer noch wackelig, muss man im Quelltext die Defines für PHASE_A und PHASE_B vertauschen. Ein Blick ins Datenblatt des Drehgebers sollte auch hier helfen.&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;
/*            Drehgeber mit wackeligem Rastpunkt dekodieren             */&lt;br /&gt;
/*                                                                      */&lt;br /&gt;
/************************************************************************/&lt;br /&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;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
#define XTAL        8e6                 // 8MHz&lt;br /&gt;
&lt;br /&gt;
#define ENCODER_PIN PINA                // an Pinbelegung anpassen&lt;br /&gt;
#define PHASE_A     (1&amp;lt;&amp;lt;PA1)&lt;br /&gt;
#define PHASE_B     (1&amp;lt;&amp;lt;PA3)&lt;br /&gt;
 &lt;br /&gt;
#define LEDS_DDR    DDRC&lt;br /&gt;
#define LEDS        PORTC               // LEDs gegen Vcc geschaltet&lt;br /&gt;
  &lt;br /&gt;
volatile int8_t enc_delta;              // Drehgeberbewegung zwischen&lt;br /&gt;
                                        // zwei Auslesungen im Hauptprogramm&lt;br /&gt;
&lt;br /&gt;
// Dekodertabelle für wackeligen Rastpunkt&lt;br /&gt;
// halbe Auflösung&lt;br /&gt;
const int8_t table[16] PROGMEM = {0,0,-1,0,0,0,0,1,1,0,0,0,0,-1,0,0};    &lt;br /&gt;
&lt;br /&gt;
// Dekodertabelle für normale Drehgeber&lt;br /&gt;
// volle Auflösung&lt;br /&gt;
//const int8_t table[16] PROGMEM = {0,1,-1,0,-1,0,0,1,1,0,0,-1,0,-1,1,0};    &lt;br /&gt;
 &lt;br /&gt;
ISR( TIMER0_COMP_vect ) {           // 1ms fuer manuelle Eingabe&lt;br /&gt;
    static int8_t last=0;           // alten Wert speichern&lt;br /&gt;
    uint8_t tmp;&lt;br /&gt;
&lt;br /&gt;
    tmp = ENCODER_PIN;&lt;br /&gt;
    last = (last &amp;lt;&amp;lt; 2)  &amp;amp; 0x0F;&lt;br /&gt;
    if (tmp &amp;amp; PHASE_A) last |= 2;&lt;br /&gt;
    if (tmp &amp;amp; PHASE_B) last |= 1;&lt;br /&gt;
    enc_delta += pgm_read_byte(&amp;amp;table[last]);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void encode_init( void ) {            // nur Timer 0 initialisieren&lt;br /&gt;
  TCCR0 = (1&amp;lt;&amp;lt;WGM01) | (1&amp;lt;&amp;lt;CS01) | (1&amp;lt;&amp;lt;CS00);     // CTC, XTAL / 64&lt;br /&gt;
  OCR0 = (uint8_t)(XTAL / 64.0 * 1e-3 - 0.5);     // 1ms&lt;br /&gt;
  TIMSK |= 1&amp;lt;&amp;lt;OCIE0;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int8_t encode_read( void ) {        // Encoder auslesen&lt;br /&gt;
  int8_t val;&lt;br /&gt;
&lt;br /&gt;
  // atomarer Variablenzugriff  &lt;br /&gt;
  cli();&lt;br /&gt;
  val = enc_delta;&lt;br /&gt;
  enc_delta = 0;&lt;br /&gt;
  sei();&lt;br /&gt;
  return val;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main( void ) {&lt;br /&gt;
  int32_t val = 0;&lt;br /&gt;
&lt;br /&gt;
  PORTA |= PHASE_A | PHASE_B;       // activate internal pull up resistors&lt;br /&gt;
  LEDS_DDR = 0xFF;&lt;br /&gt;
  encode_init();&lt;br /&gt;
  sei();&lt;br /&gt;
 &lt;br /&gt;
  while(1){&lt;br /&gt;
    val += encode_read();      &lt;br /&gt;
    LEDS = ~val;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Automatische Entprellung bei Abtastung (state machine)===&lt;br /&gt;
&lt;br /&gt;
Das folgende Bild zeigt einen möglichen Signalverlauf der beiden Spuren,&lt;br /&gt;
Abtastzeitpunkte und die dazugehörigen digitalen Zustände.&lt;br /&gt;
&lt;br /&gt;
[[Datei:gray_prellen.svg]]&lt;br /&gt;
&lt;br /&gt;
Nimmt man an, dass die obere rote Linie Spur A darstellt und gemäß obigen C-Code Spur A das MSB ist, so erhält man folgende Abtastungen:&lt;br /&gt;
&lt;br /&gt;
11,11,11,&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;A_prellt&amp;gt;11,01,11&amp;lt;/A_prellt&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
01,01,01,01,01,&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;B_prellt&amp;gt;01,01&amp;lt;/B_prellt&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
00,00,00,00,&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;A_prellt&amp;gt;00,10&amp;lt;/A_prellt&amp;gt;,&amp;lt;br /&amp;gt;&lt;br /&gt;
10,10,10&lt;br /&gt;
&lt;br /&gt;
Es fällt sofort auf, dass nur das erste Prellen von A wirklich &amp;quot;böse&amp;quot; ist.&lt;br /&gt;
&lt;br /&gt;
Nimmt man den obigen C-Code als Beispiel, wird dort immer aus dem letzten Zustand und dem jetzigen Zustand ein halbes Byte generiert und mit diesem dann ein Wert aus einer lookup table geholt (die Addition dieser Werte ergibt die Anzahl [oder ein vielfaches, je nach Drehgeber] der gedrehten Schritte).&lt;br /&gt;
&lt;br /&gt;
Bei obigen Signalverlauf würden diese Bitmuster zur Auswertung kommen:&lt;br /&gt;
&lt;br /&gt;
3 mal 1111 -&amp;gt; table[15] = +0&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;böses_prellen&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
1 mal 1101 -&amp;gt; table[13] = -1&amp;lt;br /&amp;gt;&lt;br /&gt;
1 mal 0111 -&amp;gt; table[07] = +1&amp;lt;br /&amp;gt;&lt;br /&gt;
1 mal 1101 -&amp;gt; table[13] = -1&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;/böses_ prellen&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
6 mal 0101 -&amp;gt; table[05] = +0&amp;lt;br /&amp;gt;&lt;br /&gt;
1 mal 0100 -&amp;gt; table[04] = +0 oder -1 bei doppelter Auflösung&amp;lt;br /&amp;gt;&lt;br /&gt;
4 mal 0000 -&amp;gt; table[00] = +0&amp;lt;br /&amp;gt;&lt;br /&gt;
1 mal 0010 -&amp;gt; table[02] = -1&amp;lt;br /&amp;gt;&lt;br /&gt;
3 mal 1010 -&amp;gt; table[10] = +0&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Betrachtet man nun nur die Stelle an der das Prellen auftritt so sieht man, dass das Prellen heraus gerechnet wird, denn egal wie oft der Wert springt wird am Ende -1 übrig bleiben.&lt;br /&gt;
&lt;br /&gt;
Der Gray-Code bewirkt, dass nur eine Spur prellt während die andere einen definierten Pegel behält.&lt;br /&gt;
Es kann auch bei auftretendem Prellen zuerst nur ein Wert der dem zuletzt Abgetasteten entspricht (+0) oder ein Wert der dem nächsten Zustand entspräche (-1) abgetastet werden. Würde, durch das Prellen bedingt, doch wieder der alte Zustand dekodiert (+1), so muss diesem ja irgendwann auch wieder der nächste Zustand folgen (-1)[es sei denn der Drehgeber verpufft plötzlich]. Daher ist, in diesem Fall, immer eine (-1) übrig.&lt;br /&gt;
&lt;br /&gt;
== Beispielcode in VHDL ==&lt;br /&gt;
&lt;br /&gt;
Besonders bei höheren Winkelgeschwindigkeiten und Auflösungen ist eine Auswertung in Software in einem Mikrocontroller irgendwann einmal technisch unmöglich. Dann muss ein Dekoder in Hardware her, heutzutage meist programmierbare Logik in Form eines [[CPLD]] oder [[FPGA]]. [[VHDL]] ist eine weit verbreitete Sprache zur Logikbeschreibung bzw. Synthese. Der folgende Code tastet die beiden Quadratursignale ab und generiert daraus ein UP/DOWN Signal sowie ein [[Taktung FPGA/CPLD|Clock Enable]] für einen Zähler, mit dem dann die aktuelle Position erfasst werden kann. Zusätzlich wird ein illegaler Signalübergang signalisiert, was meist auf einen defekten Drehgeber oder zu niedrige Abtastfrequenz hinweist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;vhdl&amp;quot;&amp;gt;&lt;br /&gt;
-----------------------------------------------------------------------------&lt;br /&gt;
--&lt;br /&gt;
-- Decoder für Drehgeber&lt;br /&gt;
--&lt;br /&gt;
-----------------------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
library IEEE;&lt;br /&gt;
use IEEE.STD_LOGIC_1164.ALL;&lt;br /&gt;
&lt;br /&gt;
entity incremental_encoder is&lt;br /&gt;
    Port ( clk      : in std_logic;         -- Systemtakt&lt;br /&gt;
           A        : in std_logic;         -- Spur A&lt;br /&gt;
           B        : in std_logic;         -- Spur B&lt;br /&gt;
           up_down  : out std_logic;        -- Zaehlrichtung&lt;br /&gt;
           ce       : out std_logic;        -- Clock Enable&lt;br /&gt;
           error    : out std_logic);       -- illegaler Signalübergang&lt;br /&gt;
end incremental_encoder;&lt;br /&gt;
&lt;br /&gt;
architecture Behavioral of incremental_encoder is&lt;br /&gt;
&lt;br /&gt;
signal a_in, b_in, a_old, b_old: std_logic;&lt;br /&gt;
&lt;br /&gt;
begin&lt;br /&gt;
&lt;br /&gt;
-- Abtastung und Verzoegerung der Quadratursignale&lt;br /&gt;
&lt;br /&gt;
process(clk)&lt;br /&gt;
begin&lt;br /&gt;
  if rising_edge(clk) then&lt;br /&gt;
    a_old &amp;lt;= a_in;&lt;br /&gt;
    a_in  &amp;lt;= A;&lt;br /&gt;
    b_old &amp;lt;= b_in;&lt;br /&gt;
    b_in  &amp;lt;= B;&lt;br /&gt;
  end if;&lt;br /&gt;
end process;&lt;br /&gt;
&lt;br /&gt;
-- Dekodierung der Ausgaenge&lt;br /&gt;
&lt;br /&gt;
process(a_in, b_in, a_old, b_old)&lt;br /&gt;
variable state: std_logic_vector(3 downto 0);&lt;br /&gt;
begin&lt;br /&gt;
  state := a_in &amp;amp; b_in &amp;amp; a_old &amp;amp; b_old;&lt;br /&gt;
  case state is&lt;br /&gt;
    when &amp;quot;0000&amp;quot; =&amp;gt; up_down &amp;lt;= &#039;0&#039;; ce &amp;lt;= &#039;0&#039;; error &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    when &amp;quot;0001&amp;quot; =&amp;gt; up_down &amp;lt;= &#039;1&#039;; ce &amp;lt;= &#039;1&#039;; error &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    when &amp;quot;0010&amp;quot; =&amp;gt; up_down &amp;lt;= &#039;0&#039;; ce &amp;lt;= &#039;1&#039;; error &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    when &amp;quot;0011&amp;quot; =&amp;gt; up_down &amp;lt;= &#039;0&#039;; ce &amp;lt;= &#039;0&#039;; error &amp;lt;= &#039;1&#039;;&lt;br /&gt;
    when &amp;quot;0100&amp;quot; =&amp;gt; up_down &amp;lt;= &#039;0&#039;; ce &amp;lt;= &#039;1&#039;; error &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    when &amp;quot;0101&amp;quot; =&amp;gt; up_down &amp;lt;= &#039;0&#039;; ce &amp;lt;= &#039;0&#039;; error &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    when &amp;quot;0110&amp;quot; =&amp;gt; up_down &amp;lt;= &#039;0&#039;; ce &amp;lt;= &#039;0&#039;; error &amp;lt;= &#039;1&#039;;&lt;br /&gt;
    when &amp;quot;0111&amp;quot; =&amp;gt; up_down &amp;lt;= &#039;1&#039;; ce &amp;lt;= &#039;1&#039;; error &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    when &amp;quot;1000&amp;quot; =&amp;gt; up_down &amp;lt;= &#039;1&#039;; ce &amp;lt;= &#039;1&#039;; error &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    when &amp;quot;1001&amp;quot; =&amp;gt; up_down &amp;lt;= &#039;0&#039;; ce &amp;lt;= &#039;0&#039;; error &amp;lt;= &#039;1&#039;;&lt;br /&gt;
    when &amp;quot;1010&amp;quot; =&amp;gt; up_down &amp;lt;= &#039;0&#039;; ce &amp;lt;= &#039;0&#039;; error &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    when &amp;quot;1011&amp;quot; =&amp;gt; up_down &amp;lt;= &#039;0&#039;; ce &amp;lt;= &#039;1&#039;; error &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    when &amp;quot;1100&amp;quot; =&amp;gt; up_down &amp;lt;= &#039;0&#039;; ce &amp;lt;= &#039;0&#039;; error &amp;lt;= &#039;1&#039;;&lt;br /&gt;
    when &amp;quot;1101&amp;quot; =&amp;gt; up_down &amp;lt;= &#039;0&#039;; ce &amp;lt;= &#039;1&#039;; error &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    when &amp;quot;1110&amp;quot; =&amp;gt; up_down &amp;lt;= &#039;1&#039;; ce &amp;lt;= &#039;1&#039;; error &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    when &amp;quot;1111&amp;quot; =&amp;gt; up_down &amp;lt;= &#039;0&#039;; ce &amp;lt;= &#039;0&#039;; error &amp;lt;= &#039;0&#039;;&lt;br /&gt;
    when others =&amp;gt; null;&lt;br /&gt;
  end case;&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;
== Dekoder mit diskreten Logik-ICs ==&lt;br /&gt;
&lt;br /&gt;
Für einige Anwender sind Mikrocontroller und programmierbare ICs bisweilen zu komplex oder aus anderen Gründen nicht nutzbar. Dann braucht man eine Lösung mit klassischen Logikbausteinen. Aber auch das ist recht leicht gemacht. Zwei kleine ICs genügen, die Schaltung benötigt allerdings einen externen Takt, welcher von nahezu jeder beliebigen Quelle erzeugt werden kann. Zu beachten ist, dass das Signal DIRECTION nur gültig ist, wenn das Signal CE aktiv (= HIGH) ist. Das ist auf eine vereinfachte Dekodierung zurückzuführen, im Unterschied zur VHDL-Lösung. Ausserdem handelt es sich bei CE um ein Clock Enable Signal, nicht um einen Takt, siehe [[Taktung FPGA/CPLD]]. Mit diesem Dekoder kann man dann einen Vorwärts/Rückwärts-Zähler ansteuern, wie er in diesem [https://www.mikrocontroller.net/topic/478135#5918484 Beitrag] zu sehen ist.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Schaltplan_quad_decoder.png|thumb|left|640px|Diskret aufgebauter Dekoder]]&lt;br /&gt;
&amp;lt;br clear=&amp;quot;all&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das [[media:Quad_decoder_opt.zip|Projekt im Eagleformat]] kann auf einer kleinen einseitigen Platine aufgebaut werden, es sind nur vier Lötbrücken notwendig (Rote Leitungen im TOP-Layer).&lt;br /&gt;
&lt;br /&gt;
Und so kommt man auf die Schaltung: &lt;br /&gt;
Das Taktsignal soll bei einer Flanke schalten - eine Flanke im Signal A kann man z.B. mit XOR durch &amp;lt;math&amp;gt;A^{-1}\oplus A&amp;lt;/math&amp;gt; (&amp;lt;math&amp;gt;A^{-1}&amp;lt;/math&amp;gt; ist dabei das &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; aus dem letzten Takt, durch ein [[FlipFlop|D-FlipFlop]] um einen Takt verzögert) ausdrücken, für B analog. Die Fälle &amp;quot;nichts passiert&amp;quot; und &amp;quot;ungültig&amp;quot; (also zwei Flanken gleichzeitig) schließt man ebenfalls durch XOR aus, d.h. das Taktsignal schaltet entweder bei einer Flanke in A oder bei einer Flanke in B, also: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Clock=(A^{-1}\oplus A)\oplus(B^{-1}\oplus B)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Das Richtungssignal erhält man durch Umformung des logischen Ausdrucks, dieser ergibt sich zunächst aus der Situationstabelle (oder aus dem Graphen) zu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Dir=\overline A^{-1}A\overline B^{-1}\overline B\or A^{-1}\overline AB^{-1}B\or A^{-1}A\overline B^{-1}B\or \overline A^{-1}\overline A\overline B^{-1}\overline B&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Dir=\overline A^{-1}\overline B(A\overline B^{-1}\or \overline A B^{-1})\or A^{-1}B(\overline A B^{-1}\or A\overline B^{-1})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Dir=\overline A^{-1}\overline B(A\oplus B^{-1})\or A^{-1}B(A\oplus B^{-1})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Dir=(A\oplus B^{-1})( \overline A^{-1}\overline B\or A^{-1}B)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Dir=(A\oplus B^{-1})\or\overline{(A^{-1}\oplus B)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Durch scharfes Hinsehen und Abgleich mit dem Diagramm sieht man jetzt zwei Sachen: Erstens, dass die Formel für jede Flanke gilt, es sich also tatsächlich um eine 4fach-Auswertung handelt und zweitens, dass der zweite Term immer mit dem ersten überein stimmt. Daraus folgt schließlich das Ergebnis mit&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Dir=(A\oplus B^{-1})&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/537213#7071759 Forumsbeitrag]: Drehgeberemulation / Verhaltensmodell in VHDL&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/300730#3220173 Forumsbeitrag]: Mehrere Drehgeber abfragen&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/189888?goto=1852815#1854601 Forumsbeitrag]: Ein Gray Encoder, welcher in die andere Richtung arbeitet und aus Takt/Richtung die Signale A und B generiert&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/23085#1917894 Forumsbeitrag]: Gray-Code Generator in Postscript von eProfi&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/209118#new Forumsbeitrag]: Beschleunigung für Drehgeber&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/328856?goto=4441280#4441280 Forumsbeitrag]: Dekodierung von vier Drehgebern mit ATtiny2313 mit bis zu 869,5 kHz und UART Übertragung.&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/453335#5455581 Forumsbeitrag]: Emulation eines Drehgebers über zwei Tasten&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/472810#5813429 Forumsbeitrag]: 0-10V Signal in Drehimpulsgeber Signal umwandeln&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/478135?goto=5919027#5919027 Forumsbeitrag]: Handoptimierte ISR in Assembler zur Drehgeberauswertung&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/533711#6997949 Forumsbeitrag]: Drehgeber auf UP/DOWN Zähler&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/555089?goto=7426357#7426357 Forumsbeitrag]: Dekoder von Step/Dir zu Gray Code, Assembler&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/559724?goto=7500030#7500030 Forumsbeitrag]: Drehgeber und Tastenentprellung für Arduino&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://www.bushytails.net/~randyg/encoder/encoderwheel.html Optical encoder wheel generator] (Onlinetool)&lt;br /&gt;
* [http://www.lothar-miller.de/s9y/archives/71-Drehgeberauswertung-mit-Beschleunigung.html Drehgeberauswertung mit Beschleunigung]&lt;br /&gt;
* [http://artikel.grasbon.de/Drehinkrementalgeber/index.html Drehinkrementalgeber]: Allgemeine Betrachtung mit Beispielcode&lt;br /&gt;
* [http://www.mino-elektronik.de/mt12_iic/mt12_iic.htm Quadraturdekoder] mit ATTiny25 (einfache Version) oder ATtiny202, 4xx, 8xx für SIN/COS Dekoder&lt;br /&gt;
&lt;br /&gt;
== Download ==&lt;br /&gt;
* &amp;quot;Solide Lösung&amp;quot; als Bibliothek   [[Datei:encoder.zip|&amp;quot;Solide Lösung&amp;quot; als Bibliothek]]&lt;br /&gt;
[[Category:Bauteile]]&lt;/div&gt;</summary>
		<author><name>Elektroloeter</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Entprellung&amp;diff=106343</id>
		<title>Entprellung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Entprellung&amp;diff=106343"/>
		<updated>2023-09-22T11:31:58Z</updated>

		<summary type="html">&lt;p&gt;Elektroloeter: /* Selbstsättigendes Filter (nach Jürgen Schuhmacher) */ Rechtschreibung und kleines Problem&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.&amp;amp;nbsp;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 [[Drehgeber]] sind aufgrund der Rasterfunktion 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 können. 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üssigkeitsschaltern 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 prellende Signal sinnvoll ausgewertet werden. Dafür gibt es verschiedene Ansätze, sowohl mit Elektronik als auch mit Software, die im Folgenden vorgestellt werden.&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 außen 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, wo nicht einfach nur das Signal ausgewertet werden kann. Zudem sind auch diese nicht 100%ig sicher und fallen alterungsbedingt öfters aus. Wo immer es geht, werden im Kleinsignalbereich daher Maßnahmen getroffen, die Wirkung des Prellens zu unterdrücken.&lt;br /&gt;
&lt;br /&gt;
=== Wechselschalter ===&lt;br /&gt;
&lt;br /&gt;
Für die Entprellung von Wechselschaltern (engl. &#039;&#039;Double Throw Switch&#039;&#039;) 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|Taster entprellen mit NAND-RS-Flipflop]]&lt;br /&gt;
&lt;br /&gt;
{{Clear}}&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 „Schalter berührt Kontakt“ und „Schalter ist frei in der Luft“. 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 10&amp;amp;nbsp;ms. Die Dimensionierung der Widerstände ist relativ unkritisch. Als Richtwert können hier 100&amp;amp;nbsp;kΩ verwendet werden.&lt;br /&gt;
&lt;br /&gt;
==== Wechselschalter ohne Flipflop ====&lt;br /&gt;
&lt;br /&gt;
Wenn man einmal kein Flipflop zur Hand hat, kann man sich auch mit dieser Schaltung behelfen.&lt;br /&gt;
&lt;br /&gt;
[[Bild:WechselEntprellC.PNG|thumb|left|350px|Wechsler entprellen mit Kondensator]]&lt;br /&gt;
&lt;br /&gt;
{{Clear}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Zur Funktionsweise:&#039;&#039;&#039;&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;
&#039;&#039;&#039;Dimensionierung:&#039;&#039;&#039;&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 ist 1&amp;amp;nbsp;µA typisch.&lt;br /&gt;
Es gilt:&lt;br /&gt;
:&amp;lt;math&amp;gt;\frac{\mathrm d U}{\mathrm d t} = \frac{I}{C}&amp;lt;/math&amp;gt;&lt;br /&gt;
Da ein Prellen maximal ca. 10&amp;amp;nbsp;ms dauert und die Spannung in dieser Zeit beispielsweise um maximal 0,5&amp;amp;nbsp;V fallen soll, kommt man auf folgende Kapazität:&lt;br /&gt;
:&amp;lt;math&amp;gt;C = \frac{I \cdot \Delta t}{\Delta U} = \frac{1~\text{µA} \cdot 10~\text{ms}}{\text{0,5}~\text{V}} = 20~\text{nF}&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&amp;amp;nbsp;µs bis 1&amp;amp;nbsp;ms scheint sinnvoll. Also 500&amp;amp;nbsp;Ω bis 500&amp;amp;nbsp;kΩ sind nutzbar, wobei bei niedrigem Widerstand die Stromspitzen höher sind, und bei 500&amp;amp;nbsp;kΩ 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. Der Grund dafür ist, dass in Schaltungen häufiger einfache Taster eingesetzt werden. Diese sind oft kleiner und preisgünstiger. Um solche Taster (engl. &#039;&#039;push button / momentary switch&#039;&#039;) 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 dem Kondensator nicht von einem 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 die Übergänge &#039;&#039;low&#039;&#039;→&#039;&#039;high&#039;&#039; und &#039;&#039;high&#039;&#039;→&#039;&#039;low&#039;&#039; stark verschieden (Hysterese, siehe Artikel [[Schmitt-Trigger]]). Bei richtiger Dimensionierung der Bauelemente wird somit der Ausgang des Inverters prellfrei. Zu beachten ist, dass der Inverter &#039;&#039;&#039;unbedingt&#039;&#039;&#039; über Schmitt-Trigger-Eingänge verfügen muss, weil schon bei gewöhnlichen digitalen Eingängen immer auch analoge Effekte wie Rauschen wirken, die im Umschaltpunkt zu unsicherem Verhalten führen. Bei Standard-Logikeingängen ist der Bereich von üblicherweise 0,8…2,0&amp;amp;nbsp;V deren Ausgang nicht definiert. Trotz Filterung käme es daher in diesem Bereich zu einer Weiterleitung des Prellens.&lt;br /&gt;
&lt;br /&gt;
Als Inverterbaustein kann zum Beispiel der [https://www.ti.com/lit/ds/symlink/sn74hc14.pdf 74HC14] oder der [https://www.ti.com/lit/ds/symlink/cd40106b.pdf CD40106] (pinkompatibel) eingesetzt werden. Alternativ kann auch ein [https://www.ti.com/lit/ds/symlink/cd4093b.pdf CD4093] Verwendung finden. 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 &#039;&#039;high&#039;&#039; 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 dem Kondensator beim Entladen berechnet sich nach&lt;br /&gt;
:&amp;lt;math&amp;gt;U_C(t) = U_0 \cdot \exp{\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 dem 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 dem 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 bis zu etwa 10&amp;amp;nbsp;ms. Zur Sicherheit kann bei der Berechnung des Widerstandes eine Prellzeit von 20&amp;amp;nbsp;ms angenommen werden. &amp;lt;math&amp;gt;U_0&amp;lt;/math&amp;gt; ist die Betriebsspannung, also V&amp;lt;sub&amp;gt;CC&amp;lt;/sub&amp;gt;. Die Schwellwertspannung muss aus dem Datenblatt des eingesetzten Schmitt-Triggers abgelesen werden. Beim 74HC14 beträgt der gesuchte Wert 2,0&amp;amp;nbsp;V. Nimmt man für den Kondensator 1&amp;amp;nbsp;µF und beträgt die Betriebsspannung 5&amp;amp;nbsp;V, ergibt sich für den Widerstand ein Wert von etwa 22&amp;amp;nbsp;kΩ.&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-\exp{\frac{-t}{(R_1+R_2)\cdot C_1}} \right)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &amp;lt;math&amp;gt;U_{th}=U_C&amp;lt;/math&amp;gt; ergibt das Umstellen nach &amp;lt;math&amp;gt;(R_1+R_2)&amp;lt;/math&amp;gt;:&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,3&amp;amp;nbsp;V ablesen. Mit diesem Wert und den Annahmen von oben ergibt sich für &amp;lt;math&amp;gt;R_1+R_2&amp;lt;/math&amp;gt; ein Wert von 32&amp;amp;nbsp;kΩ. Somit folgt für &amp;lt;math&amp;gt;R_1&amp;lt;/math&amp;gt; ein Wert von etwa 10&amp;amp;nbsp;kΩ.&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 &amp;lt;math&amp;gt;U_{th}&amp;lt;/math&amp;gt; beim Entladen die untere Schwelle und &amp;lt;math&amp;gt;U_{th}&amp;lt;/math&amp;gt; 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.&amp;amp;nbsp;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.&amp;amp;nbsp;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.&amp;amp;nbsp;B. Timer) benötigt werden. Dafür hat man aber den Vorteil, kurze Pulse, die offensichtlich keine Tastenbetätigung sein können sondern z.&amp;amp;nbsp;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;
# war nicht gedrückt und ist nicht gedrückt&lt;br /&gt;
# war nicht gedrückt und ist gedrückt (steigende Flanke)&lt;br /&gt;
# war gedrückt und ist immer noch gedrückt&lt;br /&gt;
# 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 &#039;&#039;active-low&#039;&#039; angeschlossen, um die internen Pull-Ups zu nutzen.&lt;br /&gt;
&lt;br /&gt;
Diese Routine gibt für den Zustand „steigende Flanke“ den Wert „1“ zurück, sonst „0“.&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. Dem 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 200&amp;amp;nbsp;ms 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 100&amp;amp;nbsp;ms 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;
[https://www.mikrocontroller.net/topic/164194 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&amp;amp;nbsp;ms, kann aber vom Anwender überschrieben werden. Vgl. [https://avrhelp.mcselec.com/index.html?debounce.htm 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…3&amp;amp;nbsp;ms (mindestens 8·150&amp;amp;nbsp;µs = 1,2&amp;amp;nbsp;ms) 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 abzufragen, 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;
  // https://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 im Forumsbeitrag [https://www.mikrocontroller.net/topic/164194#1566921 Entprellen für Anfänger] folgendes 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;
&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 &amp;lt;code&amp;gt;flag&amp;lt;/code&amp;gt; auswerten (siehe [https://www.mikrocontroller.net/topic/195914#1918727 diesen Forumsbeitrag]):&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: Forumsbeitrag [https://www.mikrocontroller.net/topic/6490 Tasten entprellen].&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.&amp;amp;nbsp;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 &amp;lt;code&amp;gt;key_state&amp;lt;/code&amp;gt;. 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 &amp;lt;code&amp;gt;key_press&amp;lt;/code&amp;gt; abgelegt. Im Beispielcode werden dann damit 8 LEDs ein- und ausgeschaltet. Jede Taste entspricht einem Bit in den Registern, d.&amp;amp;nbsp;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.&amp;amp;nbsp;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;asm&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: Forumsbeitrag [https://www.mikrocontroller.net/topic/48465 Universelle Tastenabfrage].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Anmerkung:&#039;&#039;&#039; Wenn statt &#039;&#039;active-low&#039;&#039; (Ruhezustand &#039;&#039;high&#039;&#039;) &#039;&#039;active-high&#039;&#039; (Ruhezustand &#039;&#039;low&#039;&#039;) verwendet wird, muss eine Zeile geändert werden; siehe&lt;br /&gt;
[https://www.mikrocontroller.net/topic/48465 gesamter Beitrag im Forum],&lt;br /&gt;
[https://www.mikrocontroller.net/topic/48465#606555 Stelle 1 im Beitrag] ([https://www.mikrocontroller.net/topic/48465#2306398 Stelle 2 im Beitrag] muss &#039;&#039;nicht&#039;&#039; 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 [https://www.mikrocontroller.net/topic/48465#3572793 diesen Forumsbeitrag].&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;
Neuere Variante, die einer Taste folgende Funktionen erlaubt:&lt;br /&gt;
[https://www.mikrocontroller.net/topic/48465?goto=1753367#1753367 Universelle Tastenabfrage mit 2 Tastenerkennung]&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;
===== Funktionsweise =====&lt;br /&gt;
Der Code basiert auf 8 parallelen vertikalen Zählern, die über die Variablen &amp;lt;code&amp;gt;ct0&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;ct1&amp;lt;/code&amp;gt; aufgebaut werden,&lt;br /&gt;
&lt;br /&gt;
[[Bild:VertCount.png|framed|center|8 vertikale Zähler in zwei 8-Bit-Variablen]]&lt;br /&gt;
&lt;br /&gt;
wobei jeweils ein Bit in &amp;lt;code&amp;gt;ct0&amp;lt;/code&amp;gt; mit dem gleichwertigen Bit in &amp;lt;code&amp;gt;ct1&amp;lt;/code&amp;gt; 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;
&amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; enthält an dieser Stelle für jede Taste, die sich im Vergleich mit dem vorhergehenden entprellten Zustand (&amp;lt;code&amp;gt;key_state&amp;lt;/code&amp;gt;) 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 &amp;lt;code&amp;gt;ct0&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;ct1&amp;lt;/code&amp;gt; für jedes Bit um 1, welches in &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; gesetzt ist. Liegt an der entsprechenden Stelle in &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; ein 0-Bit vor (keine Änderung des Zustands), so wird der Zähler &amp;lt;code&amp;gt;ct0&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;ct1&amp;lt;/code&amp;gt; für dieses Bit auf 1 gesetzt.&lt;br /&gt;
Der Grundzustand des Zählers ist also &amp;lt;code&amp;gt;ct0&amp;lt;/code&amp;gt; == 1 und &amp;lt;code&amp;gt;ct1&amp;lt;/code&amp;gt; == 1 (Wert 3). Der Zähler zählt daher mit jedem ISR-Aufruf, bei dem die Taste im Vergleich zu &amp;lt;code&amp;gt;key_state&amp;lt;/code&amp;gt; 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 &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; bleibt nur dort ein 1-Bit erhalten, wo sowohl in &amp;lt;code&amp;gt;ct1&amp;lt;/code&amp;gt; als auch in &amp;lt;code&amp;gt;ct0&amp;lt;/code&amp;gt; ein 1-Bit vorgefunden wird, der betreffende Zähler also bis 3 zählen konnte. Durch die zusätzliche Verundung mit &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; wird der Fall abgefangen, dass ein konstanter Zählerwert von 3 in &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; ein 1-Bit hinterlässt. Im Endergebnis bedeutet das, dass nur ein Zählerwechsel von 0 auf 3 zu einem 1-Bit an der betreffenden Stelle in &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; führt, aber auch nur dann, wenn in &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; an dieser Bitposition ebenfalls ein 1-Bit war (welches wiederum 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 &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; 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 &amp;lt;code&amp;gt;key_state&amp;lt;/code&amp;gt; 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 &amp;lt;code&amp;gt;key_state&amp;lt;/code&amp;gt; das entsprechende Bit von 0 auf 1 verändert hat, wird dieses Ereignis als „Taste wurde niedergedrückt“ 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 „paralles If“ 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;
Die Funktionsweisen der verschiedenen Modi anhand von Zeitstrahlen erklärt&lt;br /&gt;
[https://www.mikrocontroller.net/topic/48465?goto=1753367#1844458 dieser Forumsbeitrag].&lt;br /&gt;
&lt;br /&gt;
„Walkthrough“ der verschiedenen Zustände der einzelnen Variablen anhand eines Tastendrucks auf&lt;br /&gt;
[https://www.avrfreaks.net/comment/726676#comment-726676 avrfreaks.net].&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 „Langform“ 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 &amp;lt;code&amp;gt;key_state&amp;lt;/code&amp;gt; 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 &amp;lt;code&amp;gt;key_press&amp;lt;/code&amp;gt; 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 z.&amp;amp;nbsp;B. ein Autorepeat ist in diesem Code noch gar nicht eingebaut. Und spätestens wenn man dann eine zweite 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 &amp;lt;code&amp;gt;sqrt()&amp;lt;/code&amp;gt;-Funktion zu schreiben, wie die, die Sie in der Standard-C-Bibliothek vorfinden? Nein? Dann dürften Sie eigentlich Ihrer Argumentation nach die Bibliotheksfunktion &amp;lt;code&amp;gt;sqrt()&amp;lt;/code&amp;gt; nicht verwenden, sondern müssten sich stattdessen 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 der oben beschriebenen Entprellung mit einem Widerstand, einem Kondensator und einem Schmitt-Trigger nachgebildet werden, indem ein abstraktes IIR-Filter benutzt wird, das eine Kondensatorladekurve emuliert. Mit der Vorschrift &#039;&#039;Y(t) = k Y(t−1) + Eingangswert&#039;&#039; wird ein einfaches Filter erzeugt, das 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 Prellvorgänge bis nahe an den Grenzbereich zum schnellen Tasten unterdrücken. Der Ausgangswert ist dann z.B. einfach das höchstwertige Bit des Filterwertes, was aber nur bei sehr trägen Filtern zuverlässig funktioniert, weil im Übergangsbereich zwischen dem Wert, bei dem das höchste Bit auf 1 geht , wieder eine Empfindlichkeit entsteht, sollte das Prellen sich genau in diesem Bereich abspielen. Daher ist immer eine H&amp;lt;stereseschaltung nötig.&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 Schmitt-Trigger-Funktion wird auch hier wieder benötigt und kann dadurch gebildet werden, dass eine 1 am Ausgang bei z.&amp;amp;nbsp;B. Überschreiten einer 60%-%-Grenze und eine 0 bei Unterschreitung der 40-%-Grenze ausgegeben wird. Im Zwischenbereich wird der alte Wert gehalten. Die realen Grenzen dieser [[Hysterese]] müssen in ähnlicher Weise an die Applikation angepasst werden, da zu enge Grenzen zu empfindlich gegenüber Störungen sind und zu weit gefasste Grenzen zu einem übermäßig trägen Verhalten führen.&lt;br /&gt;
&lt;br /&gt;
Als Alternative für einen solchen Filter erster Ordnung bieten sich auch einfache FIR-Filter an, welche ein verbessertes Zeitverhalten (Ansprech- und Verzögerungszeit, bei optimierter Hysterese) ermöglichen.&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;
Signal-Eingang → FF1 → FF2 → FF3 → FF4 → FF5 → FF6 → FF7 → FF8&lt;br /&gt;
&lt;br /&gt;
Wenn alle FFs = 1 (Summe der FFs=8) dann Signal-Ausgang = 1&amp;lt;br /&amp;gt;&lt;br /&gt;
Wenn alle FFs = 0 (Summe der FFs=0) dann Signal-Ausgang = 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- bzw. ein AND-Gatter nötig ist.&lt;br /&gt;
&lt;br /&gt;
Das reale Signal muss dazu aber genügend langsam abgetastet werden, sodass die Filterperiode die Prelldauer übersteigt, um zu verhindern, dass nicht inmitten einer passiven Phase eines Prellvorgangs 8 mal die 1 gesehen wird. Damit wird die Interpretation vergleichsweise langsam. Ferner ist sie nicht tolerant gegenüber einmaligen Störungen im Signal. Es kann daher sinnvoll sein eine Mehrheitsentscheidung zu treffen und auf &amp;gt;6 und &amp;lt;2 zu prüfen.&lt;br /&gt;
&lt;br /&gt;
== Gegenüberstellung der Verfahren ==&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
&lt;br /&gt;
* „entprellte Schalter“: sehr teuer, große Bauform, verschleißbelastet, geringe Haltbarkeit&lt;br /&gt;
* „Umschalter“: benötigt aufwendigeren Schalter, benötigt Elektronik&lt;br /&gt;
* „Umschalter ohne FF“: benötigt aufwendigeren Schalter und kleinen Kondensator&lt;br /&gt;
* „Kondensatorentprellung“: benötigt etwas mehr Platz, kommt mit schlechten Schaltern zurecht&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
&lt;br /&gt;
* Flankenverfahren:&lt;br /&gt;
* Warteschleife: Durch die Warteschleifen entsteht eine nicht zu vernachlässigende Verzögerung im Code. Speziell wenn mehrere Tasten zu überwachen sind, nicht unproblematisch.&lt;br /&gt;
* Timer: Universalfunktionalität, die durch geringen Speicherverbrauch, geringen Rechenzeitverbrauch und gute Funktion besticht. Der „Verbrauch“ 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;
* Filter: sehr geringer Platzbedarf in FPGAs, relativ gute Wirkung&lt;br /&gt;
* Filter 2: sehr geringer Platzbedarf, gute Wirkung&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[AVR-Tutorial: Tasten]] (Assembler)&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/6490 Forumsbeitrag]: von Peter Dannegger (AVR-Assembler)&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/552487?goto=7378825#7378825 Forumsbeitrag]: Entprellung im Arduino-Stil&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/559724?goto=7500030#7500030 Forumsbeitrag]: Drehgeber und Tastenentprellung für Arduino&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
* [https://www.edn.com/contact-debouncing-algorithm-emulates-schmitt-trigger/ Contact-debouncing algorithm emulates Schmitt trigger (Artikel)], [https://web.archive.org/web/20170501074320/http://www.edn.com/Pdf/ViewPdf?contentItemId=4324067 als PDF] (englisch)&lt;br /&gt;
* [http://www.ganssle.com/debouncing.pdf A Guide to Debouncing, or, How to Debounce a Contact in Two Easy Pages, by Jack Ganssle (PDF)] (englisch), praktische Erläuterungen zum Entprellen in Soft- und Hardware&lt;br /&gt;
* [https://www.pololu.com/docs/0J16/all Understanding Destructive LC Voltage Spikes] (englisch)&lt;br /&gt;
* [https://www.compuphase.com/electronics/debouncing.htm Debouncing switches with vertical counters] (englisch); [https://www-compuphase-com.translate.goog/electronics/debouncing.htm?_x_tr_sl=en&amp;amp;_x_tr_tl=de&amp;amp;_x_tr_hl=de&amp;amp;_x_tr_pto=sc Entprellung mit vertikalen Zählern] (deutsch per Google-Übersetzer)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR]]&lt;br /&gt;
[[Kategorie:Signalverarbeitung]]&lt;/div&gt;</summary>
		<author><name>Elektroloeter</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Entprellung&amp;diff=106342</id>
		<title>Entprellung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Entprellung&amp;diff=106342"/>
		<updated>2023-09-22T11:26:17Z</updated>

		<summary type="html">&lt;p&gt;Elektroloeter: /* Einfaches Mittelwertfilter (nach Lothar Miller) */&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.&amp;amp;nbsp;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 [[Drehgeber]] sind aufgrund der Rasterfunktion 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 können. 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üssigkeitsschaltern 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 prellende Signal sinnvoll ausgewertet werden. Dafür gibt es verschiedene Ansätze, sowohl mit Elektronik als auch mit Software, die im Folgenden vorgestellt werden.&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 außen 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, wo nicht einfach nur das Signal ausgewertet werden kann. Zudem sind auch diese nicht 100%ig sicher und fallen alterungsbedingt öfters aus. Wo immer es geht, werden im Kleinsignalbereich daher Maßnahmen getroffen, die Wirkung des Prellens zu unterdrücken.&lt;br /&gt;
&lt;br /&gt;
=== Wechselschalter ===&lt;br /&gt;
&lt;br /&gt;
Für die Entprellung von Wechselschaltern (engl. &#039;&#039;Double Throw Switch&#039;&#039;) 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|Taster entprellen mit NAND-RS-Flipflop]]&lt;br /&gt;
&lt;br /&gt;
{{Clear}}&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 „Schalter berührt Kontakt“ und „Schalter ist frei in der Luft“. 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 10&amp;amp;nbsp;ms. Die Dimensionierung der Widerstände ist relativ unkritisch. Als Richtwert können hier 100&amp;amp;nbsp;kΩ verwendet werden.&lt;br /&gt;
&lt;br /&gt;
==== Wechselschalter ohne Flipflop ====&lt;br /&gt;
&lt;br /&gt;
Wenn man einmal kein Flipflop zur Hand hat, kann man sich auch mit dieser Schaltung behelfen.&lt;br /&gt;
&lt;br /&gt;
[[Bild:WechselEntprellC.PNG|thumb|left|350px|Wechsler entprellen mit Kondensator]]&lt;br /&gt;
&lt;br /&gt;
{{Clear}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Zur Funktionsweise:&#039;&#039;&#039;&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;
&#039;&#039;&#039;Dimensionierung:&#039;&#039;&#039;&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 ist 1&amp;amp;nbsp;µA typisch.&lt;br /&gt;
Es gilt:&lt;br /&gt;
:&amp;lt;math&amp;gt;\frac{\mathrm d U}{\mathrm d t} = \frac{I}{C}&amp;lt;/math&amp;gt;&lt;br /&gt;
Da ein Prellen maximal ca. 10&amp;amp;nbsp;ms dauert und die Spannung in dieser Zeit beispielsweise um maximal 0,5&amp;amp;nbsp;V fallen soll, kommt man auf folgende Kapazität:&lt;br /&gt;
:&amp;lt;math&amp;gt;C = \frac{I \cdot \Delta t}{\Delta U} = \frac{1~\text{µA} \cdot 10~\text{ms}}{\text{0,5}~\text{V}} = 20~\text{nF}&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&amp;amp;nbsp;µs bis 1&amp;amp;nbsp;ms scheint sinnvoll. Also 500&amp;amp;nbsp;Ω bis 500&amp;amp;nbsp;kΩ sind nutzbar, wobei bei niedrigem Widerstand die Stromspitzen höher sind, und bei 500&amp;amp;nbsp;kΩ 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. Der Grund dafür ist, dass in Schaltungen häufiger einfache Taster eingesetzt werden. Diese sind oft kleiner und preisgünstiger. Um solche Taster (engl. &#039;&#039;push button / momentary switch&#039;&#039;) 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 dem Kondensator nicht von einem 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 die Übergänge &#039;&#039;low&#039;&#039;→&#039;&#039;high&#039;&#039; und &#039;&#039;high&#039;&#039;→&#039;&#039;low&#039;&#039; stark verschieden (Hysterese, siehe Artikel [[Schmitt-Trigger]]). Bei richtiger Dimensionierung der Bauelemente wird somit der Ausgang des Inverters prellfrei. Zu beachten ist, dass der Inverter &#039;&#039;&#039;unbedingt&#039;&#039;&#039; über Schmitt-Trigger-Eingänge verfügen muss, weil schon bei gewöhnlichen digitalen Eingängen immer auch analoge Effekte wie Rauschen wirken, die im Umschaltpunkt zu unsicherem Verhalten führen. Bei Standard-Logikeingängen ist der Bereich von üblicherweise 0,8…2,0&amp;amp;nbsp;V deren Ausgang nicht definiert. Trotz Filterung käme es daher in diesem Bereich zu einer Weiterleitung des Prellens.&lt;br /&gt;
&lt;br /&gt;
Als Inverterbaustein kann zum Beispiel der [https://www.ti.com/lit/ds/symlink/sn74hc14.pdf 74HC14] oder der [https://www.ti.com/lit/ds/symlink/cd40106b.pdf CD40106] (pinkompatibel) eingesetzt werden. Alternativ kann auch ein [https://www.ti.com/lit/ds/symlink/cd4093b.pdf CD4093] Verwendung finden. 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 &#039;&#039;high&#039;&#039; 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 dem Kondensator beim Entladen berechnet sich nach&lt;br /&gt;
:&amp;lt;math&amp;gt;U_C(t) = U_0 \cdot \exp{\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 dem 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 dem 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 bis zu etwa 10&amp;amp;nbsp;ms. Zur Sicherheit kann bei der Berechnung des Widerstandes eine Prellzeit von 20&amp;amp;nbsp;ms angenommen werden. &amp;lt;math&amp;gt;U_0&amp;lt;/math&amp;gt; ist die Betriebsspannung, also V&amp;lt;sub&amp;gt;CC&amp;lt;/sub&amp;gt;. Die Schwellwertspannung muss aus dem Datenblatt des eingesetzten Schmitt-Triggers abgelesen werden. Beim 74HC14 beträgt der gesuchte Wert 2,0&amp;amp;nbsp;V. Nimmt man für den Kondensator 1&amp;amp;nbsp;µF und beträgt die Betriebsspannung 5&amp;amp;nbsp;V, ergibt sich für den Widerstand ein Wert von etwa 22&amp;amp;nbsp;kΩ.&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-\exp{\frac{-t}{(R_1+R_2)\cdot C_1}} \right)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &amp;lt;math&amp;gt;U_{th}=U_C&amp;lt;/math&amp;gt; ergibt das Umstellen nach &amp;lt;math&amp;gt;(R_1+R_2)&amp;lt;/math&amp;gt;:&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,3&amp;amp;nbsp;V ablesen. Mit diesem Wert und den Annahmen von oben ergibt sich für &amp;lt;math&amp;gt;R_1+R_2&amp;lt;/math&amp;gt; ein Wert von 32&amp;amp;nbsp;kΩ. Somit folgt für &amp;lt;math&amp;gt;R_1&amp;lt;/math&amp;gt; ein Wert von etwa 10&amp;amp;nbsp;kΩ.&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 &amp;lt;math&amp;gt;U_{th}&amp;lt;/math&amp;gt; beim Entladen die untere Schwelle und &amp;lt;math&amp;gt;U_{th}&amp;lt;/math&amp;gt; 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.&amp;amp;nbsp;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.&amp;amp;nbsp;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.&amp;amp;nbsp;B. Timer) benötigt werden. Dafür hat man aber den Vorteil, kurze Pulse, die offensichtlich keine Tastenbetätigung sein können sondern z.&amp;amp;nbsp;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;
# war nicht gedrückt und ist nicht gedrückt&lt;br /&gt;
# war nicht gedrückt und ist gedrückt (steigende Flanke)&lt;br /&gt;
# war gedrückt und ist immer noch gedrückt&lt;br /&gt;
# 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 &#039;&#039;active-low&#039;&#039; angeschlossen, um die internen Pull-Ups zu nutzen.&lt;br /&gt;
&lt;br /&gt;
Diese Routine gibt für den Zustand „steigende Flanke“ den Wert „1“ zurück, sonst „0“.&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. Dem 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 200&amp;amp;nbsp;ms 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 100&amp;amp;nbsp;ms 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;
[https://www.mikrocontroller.net/topic/164194 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&amp;amp;nbsp;ms, kann aber vom Anwender überschrieben werden. Vgl. [https://avrhelp.mcselec.com/index.html?debounce.htm 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…3&amp;amp;nbsp;ms (mindestens 8·150&amp;amp;nbsp;µs = 1,2&amp;amp;nbsp;ms) 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 abzufragen, 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;
  // https://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 im Forumsbeitrag [https://www.mikrocontroller.net/topic/164194#1566921 Entprellen für Anfänger] folgendes 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;
&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 &amp;lt;code&amp;gt;flag&amp;lt;/code&amp;gt; auswerten (siehe [https://www.mikrocontroller.net/topic/195914#1918727 diesen Forumsbeitrag]):&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: Forumsbeitrag [https://www.mikrocontroller.net/topic/6490 Tasten entprellen].&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.&amp;amp;nbsp;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 &amp;lt;code&amp;gt;key_state&amp;lt;/code&amp;gt;. 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 &amp;lt;code&amp;gt;key_press&amp;lt;/code&amp;gt; abgelegt. Im Beispielcode werden dann damit 8 LEDs ein- und ausgeschaltet. Jede Taste entspricht einem Bit in den Registern, d.&amp;amp;nbsp;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.&amp;amp;nbsp;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;asm&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: Forumsbeitrag [https://www.mikrocontroller.net/topic/48465 Universelle Tastenabfrage].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Anmerkung:&#039;&#039;&#039; Wenn statt &#039;&#039;active-low&#039;&#039; (Ruhezustand &#039;&#039;high&#039;&#039;) &#039;&#039;active-high&#039;&#039; (Ruhezustand &#039;&#039;low&#039;&#039;) verwendet wird, muss eine Zeile geändert werden; siehe&lt;br /&gt;
[https://www.mikrocontroller.net/topic/48465 gesamter Beitrag im Forum],&lt;br /&gt;
[https://www.mikrocontroller.net/topic/48465#606555 Stelle 1 im Beitrag] ([https://www.mikrocontroller.net/topic/48465#2306398 Stelle 2 im Beitrag] muss &#039;&#039;nicht&#039;&#039; 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 [https://www.mikrocontroller.net/topic/48465#3572793 diesen Forumsbeitrag].&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;
Neuere Variante, die einer Taste folgende Funktionen erlaubt:&lt;br /&gt;
[https://www.mikrocontroller.net/topic/48465?goto=1753367#1753367 Universelle Tastenabfrage mit 2 Tastenerkennung]&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;
===== Funktionsweise =====&lt;br /&gt;
Der Code basiert auf 8 parallelen vertikalen Zählern, die über die Variablen &amp;lt;code&amp;gt;ct0&amp;lt;/code&amp;gt; und &amp;lt;code&amp;gt;ct1&amp;lt;/code&amp;gt; aufgebaut werden,&lt;br /&gt;
&lt;br /&gt;
[[Bild:VertCount.png|framed|center|8 vertikale Zähler in zwei 8-Bit-Variablen]]&lt;br /&gt;
&lt;br /&gt;
wobei jeweils ein Bit in &amp;lt;code&amp;gt;ct0&amp;lt;/code&amp;gt; mit dem gleichwertigen Bit in &amp;lt;code&amp;gt;ct1&amp;lt;/code&amp;gt; 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;
&amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; enthält an dieser Stelle für jede Taste, die sich im Vergleich mit dem vorhergehenden entprellten Zustand (&amp;lt;code&amp;gt;key_state&amp;lt;/code&amp;gt;) 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 &amp;lt;code&amp;gt;ct0&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;ct1&amp;lt;/code&amp;gt; für jedes Bit um 1, welches in &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; gesetzt ist. Liegt an der entsprechenden Stelle in &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; ein 0-Bit vor (keine Änderung des Zustands), so wird der Zähler &amp;lt;code&amp;gt;ct0&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;ct1&amp;lt;/code&amp;gt; für dieses Bit auf 1 gesetzt.&lt;br /&gt;
Der Grundzustand des Zählers ist also &amp;lt;code&amp;gt;ct0&amp;lt;/code&amp;gt; == 1 und &amp;lt;code&amp;gt;ct1&amp;lt;/code&amp;gt; == 1 (Wert 3). Der Zähler zählt daher mit jedem ISR-Aufruf, bei dem die Taste im Vergleich zu &amp;lt;code&amp;gt;key_state&amp;lt;/code&amp;gt; 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 &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; bleibt nur dort ein 1-Bit erhalten, wo sowohl in &amp;lt;code&amp;gt;ct1&amp;lt;/code&amp;gt; als auch in &amp;lt;code&amp;gt;ct0&amp;lt;/code&amp;gt; ein 1-Bit vorgefunden wird, der betreffende Zähler also bis 3 zählen konnte. Durch die zusätzliche Verundung mit &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; wird der Fall abgefangen, dass ein konstanter Zählerwert von 3 in &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; ein 1-Bit hinterlässt. Im Endergebnis bedeutet das, dass nur ein Zählerwechsel von 0 auf 3 zu einem 1-Bit an der betreffenden Stelle in &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; führt, aber auch nur dann, wenn in &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; an dieser Bitposition ebenfalls ein 1-Bit war (welches wiederum 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 &amp;lt;code&amp;gt;i&amp;lt;/code&amp;gt; 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 &amp;lt;code&amp;gt;key_state&amp;lt;/code&amp;gt; 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 &amp;lt;code&amp;gt;key_state&amp;lt;/code&amp;gt; das entsprechende Bit von 0 auf 1 verändert hat, wird dieses Ereignis als „Taste wurde niedergedrückt“ 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 „paralles If“ 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;
Die Funktionsweisen der verschiedenen Modi anhand von Zeitstrahlen erklärt&lt;br /&gt;
[https://www.mikrocontroller.net/topic/48465?goto=1753367#1844458 dieser Forumsbeitrag].&lt;br /&gt;
&lt;br /&gt;
„Walkthrough“ der verschiedenen Zustände der einzelnen Variablen anhand eines Tastendrucks auf&lt;br /&gt;
[https://www.avrfreaks.net/comment/726676#comment-726676 avrfreaks.net].&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 „Langform“ 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 &amp;lt;code&amp;gt;key_state&amp;lt;/code&amp;gt; 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 &amp;lt;code&amp;gt;key_press&amp;lt;/code&amp;gt; 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 z.&amp;amp;nbsp;B. ein Autorepeat ist in diesem Code noch gar nicht eingebaut. Und spätestens wenn man dann eine zweite 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 &amp;lt;code&amp;gt;sqrt()&amp;lt;/code&amp;gt;-Funktion zu schreiben, wie die, die Sie in der Standard-C-Bibliothek vorfinden? Nein? Dann dürften Sie eigentlich Ihrer Argumentation nach die Bibliotheksfunktion &amp;lt;code&amp;gt;sqrt()&amp;lt;/code&amp;gt; nicht verwenden, sondern müssten sich stattdessen 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 der oben beschriebenen Entprellung mit einem Widerstand, einem Kondensator und einem Schmitt-Trigger nachgebildet werden, indem ein abstraktes IIR-Filter benutzt wird, das eine Kondensatorladekurve emuliert. Mit der Vorschrift &#039;&#039;Y(t) = k Y(t−1) + Input&#039;&#039; wird ein einfaches Filter erzeugt, das 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 Schmitt-Trigger-Funktion wird auch hier wieder benötigt und kann dadurch gebildet werden, dass eine 1 am Ausgang bei z.&amp;amp;nbsp;B. Überschreiten einer 60%-%-Grenze und eine 0 bei Unterschreitung der 40-%-Grenze ausgegeben wird. Im Zwischenbereich wird der alte Wert gehalten. Die realen Grenzen dieser [[Hysterese]] müssen in ähnlicher Weise an die Applikation angepasst werden, da zu enge Grenzen zu empfindlich gegenüber Störungen sind und zu weit gefasste Grenzen zu einem übermäßig trägem Verhalten führen.&lt;br /&gt;
&lt;br /&gt;
Als Alternative für einen solchen Filter erster Ordnung bieten sich auch einfache FIR-Filter an, welche ein verbessertes Zeitverhalten (Ansprech- und Verzögerungszeit, bei optimierter Hysteres) ermöglichen.&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;
Signal-Eingang → FF1 → FF2 → FF3 → FF4 → FF5 → FF6 → FF7 → FF8&lt;br /&gt;
&lt;br /&gt;
Wenn alle FFs = 1 (Summe der FFs=8) dann Signal-Ausgang = 1&amp;lt;br /&amp;gt;&lt;br /&gt;
Wenn alle FFs = 0 (Summe der FFs=0) dann Signal-Ausgang = 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- bzw. ein AND-Gatter nötig ist.&lt;br /&gt;
&lt;br /&gt;
Das reale Signal muss dazu aber genügend langsam abgetastet werden, sodass die Filterperiode die Prelldauer übersteigt, um zu verhindern, dass nicht inmitten einer passiven Phase eines Prellvorgangs 8 mal die 1 gesehen wird. Damit wird die Interpretation vergleichsweise langsam. Ferner ist sie nicht tolerant gegenüber einmaligen Störungen im Signal. Es kann daher sinnvoll sein eine Mehrheitsentscheidung zu treffen und auf &amp;gt;6 und &amp;lt;2 zu prüfen.&lt;br /&gt;
&lt;br /&gt;
== Gegenüberstellung der Verfahren ==&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
&lt;br /&gt;
* „entprellte Schalter“: sehr teuer, große Bauform, verschleißbelastet, geringe Haltbarkeit&lt;br /&gt;
* „Umschalter“: benötigt aufwendigeren Schalter, benötigt Elektronik&lt;br /&gt;
* „Umschalter ohne FF“: benötigt aufwendigeren Schalter und kleinen Kondensator&lt;br /&gt;
* „Kondensatorentprellung“: benötigt etwas mehr Platz, kommt mit schlechten Schaltern zurecht&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
&lt;br /&gt;
* Flankenverfahren:&lt;br /&gt;
* Warteschleife: Durch die Warteschleifen entsteht eine nicht zu vernachlässigende Verzögerung im Code. Speziell wenn mehrere Tasten zu überwachen sind, nicht unproblematisch.&lt;br /&gt;
* Timer: Universalfunktionalität, die durch geringen Speicherverbrauch, geringen Rechenzeitverbrauch und gute Funktion besticht. Der „Verbrauch“ 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;
* Filter: sehr geringer Platzbedarf in FPGAs, relativ gute Wirkung&lt;br /&gt;
* Filter 2: sehr geringer Platzbedarf, gute Wirkung&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[AVR-Tutorial: Tasten]] (Assembler)&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/6490 Forumsbeitrag]: von Peter Dannegger (AVR-Assembler)&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/552487?goto=7378825#7378825 Forumsbeitrag]: Entprellung im Arduino-Stil&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/559724?goto=7500030#7500030 Forumsbeitrag]: Drehgeber und Tastenentprellung für Arduino&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
* [https://www.edn.com/contact-debouncing-algorithm-emulates-schmitt-trigger/ Contact-debouncing algorithm emulates Schmitt trigger (Artikel)], [https://web.archive.org/web/20170501074320/http://www.edn.com/Pdf/ViewPdf?contentItemId=4324067 als PDF] (englisch)&lt;br /&gt;
* [http://www.ganssle.com/debouncing.pdf A Guide to Debouncing, or, How to Debounce a Contact in Two Easy Pages, by Jack Ganssle (PDF)] (englisch), praktische Erläuterungen zum Entprellen in Soft- und Hardware&lt;br /&gt;
* [https://www.pololu.com/docs/0J16/all Understanding Destructive LC Voltage Spikes] (englisch)&lt;br /&gt;
* [https://www.compuphase.com/electronics/debouncing.htm Debouncing switches with vertical counters] (englisch); [https://www-compuphase-com.translate.goog/electronics/debouncing.htm?_x_tr_sl=en&amp;amp;_x_tr_tl=de&amp;amp;_x_tr_hl=de&amp;amp;_x_tr_pto=sc Entprellung mit vertikalen Zählern] (deutsch per Google-Übersetzer)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR]]&lt;br /&gt;
[[Kategorie:Signalverarbeitung]]&lt;/div&gt;</summary>
		<author><name>Elektroloeter</name></author>
	</entry>
</feed>