<?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=8023</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=8023"/>
	<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/articles/Spezial:Beitr%C3%A4ge/8023"/>
	<updated>2026-04-10T19:55:12Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Labornetzger%C3%A4te&amp;diff=92493</id>
		<title>Labornetzgeräte</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Labornetzger%C3%A4te&amp;diff=92493"/>
		<updated>2016-03-18T08:02:03Z</updated>

		<summary type="html">&lt;p&gt;8023: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein Labornetzgerät wird dazu verwendet, Schaltungen oder einzelne Bauteile mit einer definierten Spannung oder einem definierten Strom zu versorgen.&lt;br /&gt;
&lt;br /&gt;
== Funktionen ==&lt;br /&gt;
&lt;br /&gt;
Labornetzgeräte sind im Gegensatz zu einfachen Festspannungs-Netzteilen sehr flexibel einsetzbar und haben üblicherweise mindestens folgende Einstellmöglichkeiten und Funktionen:&lt;br /&gt;
&lt;br /&gt;
=== Einfache Labornetzteile ===&lt;br /&gt;
&lt;br /&gt;
Einfache Labornetzgeräte haben eine einstellbare Ausgangsspannung, die normalerweise von 0 bis zu einem bestimmten Maximalwert eingestellt werden kann. Zusätzlich bieten diese Geräte eine einstellbare Strombegrenzung, die auch von 0 aus bis zum Nennstrom des Geräts eingestellt werden kann.&lt;br /&gt;
&lt;br /&gt;
Labornetzgeräte haben außerdem noch eine Anzeige für Ausgangsspannung und Strom. Dafür sind entweder analoge oder digitale Instrumente eingebaut. Bei digitalen Anzeigen werden üblicherweise 3 Stellen angezeigt, die Genauigkeit der Anzeige liegt üblicherweise im Bereich 1%.&lt;br /&gt;
&lt;br /&gt;
Der Ausgang sollte kurzschlussfest sein, was allerdings nicht bei allen Labornetzgeräten der Fall ist. Manche Geräte sind nur kurzzeitig kurzschlussfest (für einige Sekunden), normalerweise sind Labornetzgeräte dauerhaft kurzschlussfest.&lt;br /&gt;
&lt;br /&gt;
=== Labornetzteile mit erweiterten Funktionen ===&lt;br /&gt;
&lt;br /&gt;
Die Labornetzgeräte der gehobenen Preisklasse haben zusätzlich zu den Grundfunktionen noch weitere Funktionen, wie z.B.:&lt;br /&gt;
&lt;br /&gt;
* Abschaltbarer Ausgang&lt;br /&gt;
* Getrennte Anzeige von Soll- und Ist-Werten&lt;br /&gt;
* Höhere Messgenauigkeit der Istwerte als bei einfachen Geräten&lt;br /&gt;
* Einstellbare Grenzwerte für Strom, Spannung, Leistung&lt;br /&gt;
* Alarm/Abschaltung bei Überschreitung von einstellbaren Schwellwerten&lt;br /&gt;
* Programmierbare Spannungs-/Stromverläufe&lt;br /&gt;
* Master-Slave-Funktion für Reihen-/Parallelschaltung von mehreren Geräten&lt;br /&gt;
* Analoge Schnittstelle für Soll- und Istwerte&lt;br /&gt;
* PC-Schnittstelle&lt;br /&gt;
&lt;br /&gt;
== Wichtige Eigenschaften ==&lt;br /&gt;
&lt;br /&gt;
=== Lineare Netzgeräte vs. Schaltnetzgeräte ===&lt;br /&gt;
&lt;br /&gt;
Es gibt bei Labornetzgeräten sowohl linear geregelte als auch Schaltnetzteile.&lt;br /&gt;
&lt;br /&gt;
Lineare Netzgeräte haben den Vorteil, dass die Regelung üblicherweise schneller und genauer ist. Die Ausgangskapazität ist bei linearen Netzgeräten relativ klein, dadurch kann die Strombegrenzung sehr schnell ansprechen.&lt;br /&gt;
&lt;br /&gt;
Schaltnetzgeräte haben dagegen einen besseren Wirkungsgrad, erzeugen also weniger Abwärme und sind kleiner und leichter als lineare Netzgeräte gleicher Leistung. Deshalb sind vor allem Labornetzgeräte mit hoher Leistung bevorzugt als Schaltnetzteil aufgebaut.&lt;br /&gt;
&lt;br /&gt;
Wenn bei Schaltnetzgeräten eine sehr kleine Ausgangs-Spannung eingestellt wird, wird diese oft nicht sauber ausgeregelt. Meistens brauchen solche Geräte eine bestimmte Mindestspannung am Ausgang.&lt;br /&gt;
&lt;br /&gt;
Weiterhin besteht bei Schaltnetzteilen die Gefahr, dass am Ausgang Störungen sichtbar sind, die durch die interne PWM erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Weiterhin gibt es auch Geräte, bei denen ein Schaltnetzteil und eine lineare Regelung kombiniert sind. Dadurch werden die Vorteile von beiden Verfahren kombiniert, es ergeben sich dadurch aber auch einige Probleme:&lt;br /&gt;
&lt;br /&gt;
* Bei schnellen Laständerungen kann es passieren, dass das Schaltnetzteil nicht schnell genug nachregelt. Dadurch ändert sich das Regelverhalten und die Ausgangsspannung bzw. Strom sind dann nicht mehr so stabil wie bei einem richtigen linear geregelten Netzgerät. &lt;br /&gt;
&lt;br /&gt;
* Bei schnellen periodischen Laständerungen kann es zusätzlich passieren, dass die Verlustleistung im Linearregler sehr viel höher wird als im Betrieb mit konstanter Ausgangsleistung. Da die lineare Endstufe meistens nicht dafür dimensioniert ist, kann es hier thermische Probleme geben.&lt;br /&gt;
&lt;br /&gt;
=== Verlustleistung und Kühlung === &lt;br /&gt;
&lt;br /&gt;
Das ist vor allem bei linear geregelten Geräten ein sehr wichtiges Kapitel, da eine gute Kühlung relativ viel Geld kostet und die Gerätehersteller hier gerne sparen. Folgende Punkte sollten hier beachtet werden:&lt;br /&gt;
&lt;br /&gt;
==== Passive Kühlung oder Kühlung mit Lüfter ====&lt;br /&gt;
Geräte mit passiver Kühlung erzeugen keine Geräusche, was ein großer Vorteil ist. Passive Kühlung ist aber nur bei Geräten mit relativ geringer Leistung üblich. Bei Lüfter-gekühlen Geräten sollte darauf geachtet werden, dass der Lüfter relativ ruhig läuft.&lt;br /&gt;
&lt;br /&gt;
==== Außenliegender Kühlkörper ====&lt;br /&gt;
Bei passiv gekühlten Geräten kann der Kühler ziemlich warm werden. Wenn der Kühler außen am Gehäuse montiert ist, besteht die Gefahr, dass man ihn versehentlich berührt und sich verbrennt oder dass wärmeempfindliche Gegenstände (z.B. kunststoff-isolierte Leitungen) bei Berührung beschädigt werden. Deshalb sollte man Geräte bevorzugen, bei denen der Kühler innerhalb des Gehäuses montiert ist.&lt;br /&gt;
&lt;br /&gt;
==== Lüftungsschlitze ====&lt;br /&gt;
Bei Geräten, die Lüftungsschlitze auf der Oberseite haben, besteht die Gefahr, dass Gegenstände reinfallen können, wodurch das Gerät beschädigt werden kann. Weiterhin kann es passieren, dass der Luftstrom durch die Schlitze behindert wird, wenn man etwas auf dem Gerät ablegt oder mehrere Geräte aufeinander stapelt.&lt;br /&gt;
Je nach dem, wo das Gerät aufgestellt werden soll, können deshalb seitliche Lüftungsschlitze vorteilhaft sein. Allerdings sind seitliche Lüftungsöffnungen meistens mit einem aktiven Lüfter kombiniert.&lt;br /&gt;
&lt;br /&gt;
==== Dimensionierung der Kühlkörper und Leistungstransistoren ====&lt;br /&gt;
Bei vielen billigen Netzgeräten ist die Kühlung zu knapp dimensioniert. Das kann man relativ einfach testen, indem man den Ausgangsspannung und Strom jeweils auf Maximalwerte einstellt und dann den Ausgang kurzschließt.&lt;br /&gt;
&lt;br /&gt;
In diesem Zustand sollte das Gerät längere Zeit (einige Stunden) betrieben werden, bis alles thermisch eingeschwungen ist. Dann muss bei allen Leistungsbauteilen die Temperatur gemessen werden, am einfachsten geht das mit einer Wärmebildkamera. Es sollten nach Möglichkeit keine Temperaturen oberhalb von 100°C auftreten. Wärme-empfindliche Bauteile (z.B. Elkos) sollten nicht wärmer als 70°C sein.&lt;br /&gt;
&lt;br /&gt;
Besonders kritisch sind hier:&lt;br /&gt;
* Netztrafo&lt;br /&gt;
* Gleichrichter&lt;br /&gt;
* Leistungstransistoren und Kühlkörper&lt;br /&gt;
&lt;br /&gt;
=== Stabilität und Genauigkeit ===&lt;br /&gt;
&lt;br /&gt;
Wichtige Eigenschaften bei Labornetzgeräten ist die Stabilität und die Genauigkeit.&lt;br /&gt;
&lt;br /&gt;
==== Stabilität ====&lt;br /&gt;
&lt;br /&gt;
Damit wird angegeben, wie konstant ein eingestellter Wert über einen längeren Zeitraum gehalten wird. Hier ist wichtig, dass das Gerät einen kleinen Temperaturkoeffizient hat, so dass die Ausgangsspannung auch bei Temperaturschwankungen möglichst stabil bleibt.&lt;br /&gt;
&lt;br /&gt;
==== Genauigkeit ====&lt;br /&gt;
&lt;br /&gt;
Hier muss unterschieden werden zwischen der Anzeigegenauigkeit und der Einstellgenauigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Genauigkeit der Anzeige gibt an, wie genau die angezeigte Ausgangsspannung oder Strom mit der tatsächlichen Spannung übereinstimmt (siehe dazu auch  Artikel [[Auflösung und Genauigkeit]]).&lt;br /&gt;
&lt;br /&gt;
Die Einstellgenauigkeit gibt an, wie genau ein bestimmter Sollwert eingestellt werden kann und wie gut die tatsächlichen Werte mit den Sollwerten übereinstimmen. Bei Geräten mit digitaler Sollwertvorgabe muss hier die kleinste Schrittweite beachtet werden.&lt;br /&gt;
&lt;br /&gt;
== Weitere Funktionen ==&lt;br /&gt;
&lt;br /&gt;
=== Schnittstelle ===&lt;br /&gt;
&lt;br /&gt;
Einige Labornetzgeräte bieten eine Schnittstelle zum PC, damit können sie als per Software steuerbares Netzgerät verwendet werden. Will man das Netzgerät per Mikrocontroller steuern, so sind Typen mit [[RS232]] Anschluß den Typen mit [[USB]] vorzuziehen.&lt;br /&gt;
&lt;br /&gt;
=== Beleuchtung ===&lt;br /&gt;
&lt;br /&gt;
Folgende Display-Arten sind bei Labornetzgeräten üblich:&lt;br /&gt;
* Analoginstrument (unbeleuchtet oder beleuchtet)&lt;br /&gt;
* LCD 7-Segment Anzeige (unbeleuchtet oder beleuchtet)&lt;br /&gt;
* LCD Punktmatrix-Anzeige (in der Regel beleuchtet)&lt;br /&gt;
* LED 7-Segment Anzeige (selbstleuchtend)&lt;br /&gt;
* OLED-Anzeigen (selbstleuchtend)&lt;br /&gt;
* VFD-Anzeigen (selbstleuchtend)&lt;br /&gt;
&lt;br /&gt;
Anzeigen mit Beleuchtung bzw. selbstleuchtende Anzeigen sind wesentlich besser ablesbar als unbeleuchtete LCD-Anzeigen. Da Labornetzgeräte immer am Netz betrieben werden, ist der Stromverbrauch der Beleuchtung nicht relevant.&lt;br /&gt;
&lt;br /&gt;
Unbeleuchtete LCD-Anzeigen sind bei schlechter Beleuchtung oder ungünstigem Blickwinkel manchmal schlecht ablesbar, bei 7-Segment LED-Anzeigen ist die Ablesbarkeit wesentlich besser. &lt;br /&gt;
&lt;br /&gt;
Mit 7-Segment Anzeigen lassen sich allerdings nur Ziffern und einige wenige Buchstaben darstellen. Für Geräte mit komplexen Einstellungen und Menu-Führung werden deshalb häufig Punkt-Matrix LCD-Anzeigen verwendet.&lt;br /&gt;
&lt;br /&gt;
Mit VFD-Anzeigen [http://de.wikipedia.org/wiki/Fluoreszenzanzeige], die ebenfalls sehr gut ablesbar sind, könnnen auch komplexe Menüs dargestellt werden. Diese haben einen sehr weiten Blickwinkel und sehr scharfe und klare Zeichen. Allerdings sind diese Anzeigen relativ teuer, weshalb sie vor allem in eher teueren Geräten eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
== Vergleichstabelle Labornetzgeräte ==&lt;br /&gt;
&lt;br /&gt;
In den folgende Tabellen werden wichtige technischen Daten einiger aktueller Labornetzgeräte zusammengestellt. Um die Übersichtlichkeit zu erhöhen, werden die Geräte eingeteilt in einfache Geräte und Geräte mit Zusatzfunktionen&lt;br /&gt;
&lt;br /&gt;
Die Einteilung geschieht aufgrund der Funktionen, die die Geräte bieten. Das ist also keine Aussage über die Qualität der Geräte.&lt;br /&gt;
&lt;br /&gt;
=== Einfache lineare Labornetzgeräte ===&lt;br /&gt;
&lt;br /&gt;
Hier werden Geräte aufgelistet, welche neben den Grundfunktionen (Strom- und Spannungseinstellung, Anzeige der Istwerte) keine weiteren Funktionen besitzen.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable sortable&amp;quot; id=&amp;quot;einfache&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Hersteller&lt;br /&gt;
!Bezeichnung&lt;br /&gt;
!Preis [EUR]&lt;br /&gt;
!Spannung [V]&lt;br /&gt;
!Strom [A]&lt;br /&gt;
!Kanäle&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3616A&lt;br /&gt;
|620&lt;br /&gt;
|35&lt;br /&gt;
|1.7&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HM8040-3(Benötigt HM8001)&lt;br /&gt;
|280&lt;br /&gt;
|20 + 20 + 5&lt;br /&gt;
|0.5 + 0.5 + 1&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|Peaktech&lt;br /&gt;
|6080&lt;br /&gt;
|50&lt;br /&gt;
|15&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|McVoice&lt;br /&gt;
|WNT0-15-2000&lt;br /&gt;
|38&lt;br /&gt;
|15&lt;br /&gt;
|2&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|Statron&lt;br /&gt;
|2223.1&lt;br /&gt;
|150&lt;br /&gt;
|30&lt;br /&gt;
|2.5&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2250.0&lt;br /&gt;
|225&lt;br /&gt;
|40&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2229.2&lt;br /&gt;
|260&lt;br /&gt;
|40 + 40&lt;br /&gt;
|2.5 + 2.5&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2229.5&lt;br /&gt;
|340&lt;br /&gt;
|32 + 32 + 5&lt;br /&gt;
|3 + 3 + 3&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2225.6&lt;br /&gt;
|310&lt;br /&gt;
|30 + 30&lt;br /&gt;
|5 + 5&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|PS-1302 D&lt;br /&gt;
|95&lt;br /&gt;
|30&lt;br /&gt;
|2&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VLP 1303pro&lt;br /&gt;
|180&lt;br /&gt;
|30 + 6&lt;br /&gt;
|3 + 2&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VSP 2403&lt;br /&gt;
|345&lt;br /&gt;
|40 + 40 + 6&lt;br /&gt;
|3 + 3 + 1.5&lt;br /&gt;
|3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Einfache Schaltnetzgeräte ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable sortable&amp;quot; id=&amp;quot;einfache&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Hersteller&lt;br /&gt;
!Bezeichnung&lt;br /&gt;
!Preis [EUR]&lt;br /&gt;
!Spannung [V]&lt;br /&gt;
!Strom [A]&lt;br /&gt;
!Kanäle&lt;br /&gt;
|-&lt;br /&gt;
|Delta Elektronika&lt;br /&gt;
|ES 030-5&lt;br /&gt;
|624&lt;br /&gt;
|30&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Quatpower&lt;br /&gt;
|LN-3003&lt;br /&gt;
|40&lt;br /&gt;
|30&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Netzgeräte mit Zusatzfunktionen ===&lt;br /&gt;
&lt;br /&gt;
Diese Geräte haben mindestens folgende Funktionen:&lt;br /&gt;
* abschaltbare Ausgänge&lt;br /&gt;
* Anzeige der Sollwerte für Strom und Spannung&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable sortable&amp;quot; id=&amp;quot;hochwertige&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Hersteller&lt;br /&gt;
!Bezeichnung&lt;br /&gt;
!Preis [EUR]&lt;br /&gt;
!Spannung [V]&lt;br /&gt;
!Strom [A]&lt;br /&gt;
!Kanäle&lt;br /&gt;
!linear/getaktet&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|U8001A&lt;br /&gt;
|290&lt;br /&gt;
|30&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3616A&lt;br /&gt;
|620&lt;br /&gt;
|35&lt;br /&gt;
|1.7&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3643A&lt;br /&gt;
|690&lt;br /&gt;
|35 / 60 (umschaltbar)&lt;br /&gt;
|1.4 / 0.8&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3632A&lt;br /&gt;
|990&lt;br /&gt;
|15 / 30 (umschaltbar)&lt;br /&gt;
|7 / 4&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|BK Precision&lt;br /&gt;
|BK 1786&lt;br /&gt;
|490&lt;br /&gt;
|32&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|BK Precision&lt;br /&gt;
|BK 1788&lt;br /&gt;
|615&lt;br /&gt;
|32&lt;br /&gt;
|6&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|BK Precision&lt;br /&gt;
|BK 9130&lt;br /&gt;
|685&lt;br /&gt;
|30 + 30 + 5&lt;br /&gt;
|3 + 3 + 3&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|PSI 6032-03&lt;br /&gt;
|425&lt;br /&gt;
|32&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 2042-06B&lt;br /&gt;
|235&lt;br /&gt;
|42&lt;br /&gt;
|6&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 2342-06B&lt;br /&gt;
|580&lt;br /&gt;
|42 + 42 + 6&lt;br /&gt;
|6 + 6 + 4&lt;br /&gt;
|3&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 3032-05B&lt;br /&gt;
|355&lt;br /&gt;
|32&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 8032-10 DT&lt;br /&gt;
|940&lt;br /&gt;
|32&lt;br /&gt;
|10&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|ELV&lt;br /&gt;
|PPS 5330&lt;br /&gt;
|120&lt;br /&gt;
|30&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|ELV&lt;br /&gt;
|SPS 5630&lt;br /&gt;
|200&lt;br /&gt;
|30&lt;br /&gt;
|6 (max. 75W)&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HM7042-5&lt;br /&gt;
|685&lt;br /&gt;
|32 + 32 + 5,5&lt;br /&gt;
|2 + 2 + 5&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HMP2020&lt;br /&gt;
|1190&lt;br /&gt;
|32 + 32&lt;br /&gt;
|10 + 5&lt;br /&gt;
|2&lt;br /&gt;
|getaktet + linear&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HMP2030&lt;br /&gt;
|1500&lt;br /&gt;
|32 + 32 + 32&lt;br /&gt;
|5 + 5 + 5&lt;br /&gt;
|3&lt;br /&gt;
|getaktet + linear&lt;br /&gt;
|-&lt;br /&gt;
|Rigol&lt;br /&gt;
|DP832 **)&lt;br /&gt;
|362&lt;br /&gt;
|30 + 30 + 5&lt;br /&gt;
|3 + 3 + 3&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VLP 1405pro&lt;br /&gt;
|1190&lt;br /&gt;
|40 + 6&lt;br /&gt;
|5 + 2&lt;br /&gt;
|2&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|PeakTech&lt;br /&gt;
|1885&lt;br /&gt;
|270&lt;br /&gt;
|40&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VLP 2403pro&lt;br /&gt;
|320&lt;br /&gt;
|40 + 40 + 6&lt;br /&gt;
|3 + 3 + 2&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VSP 2410&lt;br /&gt;
|470&lt;br /&gt;
|40 + 40 + 6&lt;br /&gt;
|10 + 10 + 1.5&lt;br /&gt;
|3&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|TTI&lt;br /&gt;
|EX355R&lt;br /&gt;
|330&lt;br /&gt;
|35&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|Mixed-mode (getaktet + linear)&lt;br /&gt;
|-&lt;br /&gt;
|TTI&lt;br /&gt;
|EX354RD&lt;br /&gt;
|480&lt;br /&gt;
|35 + 35&lt;br /&gt;
|4 + 4&lt;br /&gt;
|2&lt;br /&gt;
|Mixed-mode (getaktet + linear)&lt;br /&gt;
|-&lt;br /&gt;
|TTI&lt;br /&gt;
|EX354RT&lt;br /&gt;
|540&lt;br /&gt;
|35 + 35 + (1,5-5)&lt;br /&gt;
|4 + 4 + 5&lt;br /&gt;
|3&lt;br /&gt;
|Mixed-mode (getaktet + linear)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
 **) Das Rigol DP832(A) schaltet die Ausgänge nicht physisch/galvanisch ab. Die Power-MOSFETs der Ausgangsstufe werden lediglich auf Soll-NULL gesetzt. Dies kann bei Drift auch durchaus ungleich 0,00 Volt bedeuten!&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Spannungsversorgung_und_Energiequellen]]&lt;/div&gt;</summary>
		<author><name>8023</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Labornetzger%C3%A4te&amp;diff=92490</id>
		<title>Labornetzgeräte</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Labornetzger%C3%A4te&amp;diff=92490"/>
		<updated>2016-03-18T05:12:36Z</updated>

		<summary type="html">&lt;p&gt;8023: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein Labornetzgerät wird dazu verwendet, Schaltungen oder einzelne Bauteile mit einer definierten Spannung oder einem definierten Strom zu versorgen.&lt;br /&gt;
&lt;br /&gt;
== Funktionen ==&lt;br /&gt;
&lt;br /&gt;
Labornetzgeräte sind im Gegensatz zu einfachen Festspannungs-Netzteilen sehr flexibel einsetzbar und haben üblicherweise mindestens folgende Einstellmöglichkeiten und Funktionen:&lt;br /&gt;
&lt;br /&gt;
=== Einfache Labornetzteile ===&lt;br /&gt;
&lt;br /&gt;
Einfache Labornetzgeräte haben eine einstellbare Ausgangsspannung, die normalerweise von 0 bis zu einem bestimmten Maximalwert eingestellt werden kann. Zusätzlich bieten diese Geräte eine einstellbare Strombegrenzung, die auch von 0 aus bis zum Nennstrom des Geräts eingestellt werden kann.&lt;br /&gt;
&lt;br /&gt;
Labornetzgeräte haben außerdem noch eine Anzeige für Ausgangsspannung und Strom. Dafür sind entweder analoge oder digitale Instrumente eingebaut. Bei digitalen Anzeigen werden üblicherweise 3 Stellen angezeigt, die Genauigkeit der Anzeige liegt üblicherweise im Bereich 1%.&lt;br /&gt;
&lt;br /&gt;
Der Ausgang sollte kurzschlussfest sein, was allerdings nicht bei allen Labornetzgeräten der Fall ist. Manche Geräte sind nur kurzzeitig kurzschlussfest (für einige Sekunden), normalerweise sind Labornetzgeräte dauerhaft kurzschlussfest.&lt;br /&gt;
&lt;br /&gt;
=== Labornetzteile mit erweiterten Funktionen ===&lt;br /&gt;
&lt;br /&gt;
Die Labornetzgeräte der gehobenen Preisklasse haben zusätzlich zu den Grundfunktionen noch weitere Funktionen, wie z.B.:&lt;br /&gt;
&lt;br /&gt;
* Abschaltbarer Ausgang&lt;br /&gt;
* Getrennte Anzeige von Soll- und Ist-Werten&lt;br /&gt;
* Höhere Messgenauigkeit der Istwerte als bei einfachen Geräten&lt;br /&gt;
* Einstellbare Grenzwerte für Strom, Spannung, Leistung&lt;br /&gt;
* Alarm/Abschaltung bei Überschreitung von einstellbaren Schwellwerten&lt;br /&gt;
* Programmierbare Spannungs-/Stromverläufe&lt;br /&gt;
* Master-Slave-Funktion für Reihen-/Parallelschaltung von mehreren Geräten&lt;br /&gt;
* Analoge Schnittstelle für Soll- und Istwerte&lt;br /&gt;
* PC-Schnittstelle&lt;br /&gt;
&lt;br /&gt;
== Wichtige Eigenschaften ==&lt;br /&gt;
&lt;br /&gt;
=== Lineare Netzgeräte vs. Schaltnetzgeräte ===&lt;br /&gt;
&lt;br /&gt;
Es gibt bei Labornetzgeräten sowohl linear geregelte als auch Schaltnetzteile.&lt;br /&gt;
&lt;br /&gt;
Lineare Netzgeräte haben den Vorteil, dass die Regelung üblicherweise schneller und genauer ist. Die Ausgangskapazität ist bei linearen Netzgeräten relativ klein, dadurch kann die Strombegrenzung sehr schnell ansprechen.&lt;br /&gt;
&lt;br /&gt;
Schaltnetzgeräte haben dagegen einen besseren Wirkungsgrad, erzeugen also weniger Abwärme und sind kleiner und leichter als lineare Netzgeräte gleicher Leistung. Deshalb sind vor allem Labornetzgeräte mit hoher Leistung bevorzugt als Schaltnetzteil aufgebaut.&lt;br /&gt;
&lt;br /&gt;
Wenn bei Schaltnetzgeräten eine sehr kleine Ausgangs-Spannung eingestellt wird, wird diese oft nicht sauber ausgeregelt. Meistens brauchen solche Geräte eine bestimmte Mindestspannung am Ausgang.&lt;br /&gt;
&lt;br /&gt;
Weiterhin besteht bei Schaltnetzteilen die Gefahr, dass am Ausgang Störungen sichtbar sind, die durch die interne PWM erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Weiterhin gibt es auch Geräte, bei denen ein Schaltnetzteil und eine lineare Regelung kombiniert sind. Dadurch werden die Vorteile von beiden Verfahren kombiniert, es ergeben sich dadurch aber auch einige Probleme:&lt;br /&gt;
&lt;br /&gt;
* Bei schnellen Laständerungen kann es passieren, dass das Schaltnetzteil nicht schnell genug nachregelt. Dadurch ändert sich das Regelverhalten und die Ausgangsspannung bzw. Strom sind dann nicht mehr so stabil wie bei einem richtigen linear geregelten Netzgerät. &lt;br /&gt;
&lt;br /&gt;
* Bei schnellen periodischen Laständerungen kann es zusätzlich passieren, dass die Verlustleistung im Linearregler sehr viel höher wird als im Betrieb mit konstanter Ausgangsleistung. Da die lineare Endstufe meistens nicht dafür dimensioniert ist, kann es hier thermische Probleme geben.&lt;br /&gt;
&lt;br /&gt;
=== Verlustleistung und Kühlung === &lt;br /&gt;
&lt;br /&gt;
Das ist vor allem bei linear geregelten Geräten ein sehr wichtiges Kapitel, da eine gute Kühlung relativ viel Geld kostet und die Gerätehersteller hier gerne sparen. Folgende Punkte sollten hier beachtet werden:&lt;br /&gt;
&lt;br /&gt;
==== Passive Kühlung oder Kühlung mit Lüfter ====&lt;br /&gt;
Geräte mit passiver Kühlung erzeugen keine Geräusche, was ein großer Vorteil ist. Passive Kühlung ist aber nur bei Geräten mit relativ geringer Leistung üblich. Bei Lüfter-gekühlen Geräten sollte darauf geachtet werden, dass der Lüfter relativ ruhig läuft.&lt;br /&gt;
&lt;br /&gt;
==== Außenliegender Kühlkörper ====&lt;br /&gt;
Bei passiv gekühlten Geräten kann der Kühler ziemlich warm werden. Wenn der Kühler außen am Gehäuse montiert ist, besteht die Gefahr, dass man ihn versehentlich berührt und sich verbrennt oder dass wärmeempfindliche Gegenstände (z.B. kunststoff-isolierte Leitungen) bei Berührung beschädigt werden. Deshalb sollte man Geräte bevorzugen, bei denen der Kühler innerhalb des Gehäuses montiert ist.&lt;br /&gt;
&lt;br /&gt;
==== Lüftungsschlitze ====&lt;br /&gt;
Bei Geräten, die Lüftungsschlitze auf der Oberseite haben, besteht die Gefahr, dass Gegenstände reinfallen können, wodurch das Gerät beschädigt werden kann. Weiterhin kann es passieren, dass der Luftstrom durch die Schlitze behindert wird, wenn man etwas auf dem Gerät ablegt oder mehrere Geräte aufeinander stapelt.&lt;br /&gt;
Je nach dem, wo das Gerät aufgestellt werden soll, können deshalb seitliche Lüftungsschlitze vorteilhaft sein. Allerdings sind seitliche Lüftungsöffnungen meistens mit einem aktiven Lüfter kombiniert.&lt;br /&gt;
&lt;br /&gt;
==== Dimensionierung der Kühlkörper und Leistungstransistoren ====&lt;br /&gt;
Bei vielen billigen Netzgeräten ist die Kühlung zu knapp dimensioniert. Das kann man relativ einfach testen, indem man den Ausgangsspannung und Strom jeweils auf Maximalwerte einstellt und dann den Ausgang kurzschließt.&lt;br /&gt;
&lt;br /&gt;
In diesem Zustand sollte das Gerät längere Zeit (einige Stunden) betrieben werden, bis alles thermisch eingeschwungen ist. Dann muss bei allen Leistungsbauteilen die Temperatur gemessen werden, am einfachsten geht das mit einer Wärmebildkamera. Es sollten nach Möglichkeit keine Temperaturen oberhalb von 100°C auftreten. Wärme-empfindliche Bauteile (z.B. Elkos) sollten nicht wärmer als 70°C sein.&lt;br /&gt;
&lt;br /&gt;
Besonders kritisch sind hier:&lt;br /&gt;
* Netztrafo&lt;br /&gt;
* Gleichrichter&lt;br /&gt;
* Leistungstransistoren und Kühlkörper&lt;br /&gt;
&lt;br /&gt;
=== Stabilität und Genauigkeit ===&lt;br /&gt;
&lt;br /&gt;
Wichtige Eigenschaften bei Labornetzgeräten ist die Stabilität und die Genauigkeit.&lt;br /&gt;
&lt;br /&gt;
==== Stabilität ====&lt;br /&gt;
&lt;br /&gt;
Damit wird angegeben, wie konstant ein eingestellter Wert über einen längeren Zeitraum gehalten wird. Hier ist wichtig, dass das Gerät einen kleinen Temperaturkoeffizient hat, so dass die Ausgangsspannung auch bei Temperaturschwankungen möglichst stabil bleibt.&lt;br /&gt;
&lt;br /&gt;
==== Genauigkeit ====&lt;br /&gt;
&lt;br /&gt;
Hier muss unterschieden werden zwischen der Anzeigegenauigkeit und der Einstellgenauigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Genauigkeit der Anzeige gibt an, wie genau die angezeigte Ausgangsspannung oder Strom mit der tatsächlichen Spannung übereinstimmt (siehe dazu auch  Artikel [[Auflösung und Genauigkeit]]).&lt;br /&gt;
&lt;br /&gt;
Die Einstellgenauigkeit gibt an, wie genau ein bestimmter Sollwert eingestellt werden kann und wie gut die tatsächlichen Werte mit den Sollwerten übereinstimmen. Bei Geräten mit digitaler Sollwertvorgabe muss hier die kleinste Schrittweite beachtet werden.&lt;br /&gt;
&lt;br /&gt;
== Weitere Funktionen ==&lt;br /&gt;
&lt;br /&gt;
=== Schnittstelle ===&lt;br /&gt;
&lt;br /&gt;
Einige Labornetzgeräte bieten eine Schnittstelle zum PC, damit können sie als per Software steuerbares Netzgerät verwendet werden. Will man das Netzgerät per Mikrocontroller steuern, so sind Typen mit [[RS232]] Anschluß den Typen mit [[USB]] vorzuziehen.&lt;br /&gt;
&lt;br /&gt;
=== Beleuchtung ===&lt;br /&gt;
&lt;br /&gt;
Folgende Display-Arten sind bei Labornetzgeräten üblich:&lt;br /&gt;
* Analoginstrument (unbeleuchtet oder beleuchtet)&lt;br /&gt;
* LCD 7-Segment Anzeige (unbeleuchtet oder beleuchtet)&lt;br /&gt;
* LCD Punktmatrix-Anzeige (in der Regel beleuchtet)&lt;br /&gt;
* LED 7-Segment Anzeige (selbstleuchtend)&lt;br /&gt;
* OLED-Anzeigen (selbstleuchtend)&lt;br /&gt;
* VFD-Anzeigen (selbstleuchtend)&lt;br /&gt;
&lt;br /&gt;
Anzeigen mit Beleuchtung bzw. selbstleuchtende Anzeigen sind wesentlich besser ablesbar als unbeleuchtete LCD-Anzeigen. Da Labornetzgeräte immer am Netz betrieben werden, ist der Stromverbrauch der Beleuchtung nicht relevant.&lt;br /&gt;
&lt;br /&gt;
Unbeleuchtete LCD-Anzeigen sind bei schlechter Beleuchtung oder ungünstigem Blickwinkel manchmal schlecht ablesbar, bei 7-Segment LED-Anzeigen ist die Ablesbarkeit wesentlich besser. &lt;br /&gt;
&lt;br /&gt;
Mit 7-Segment Anzeigen lassen sich allerdings nur Ziffern und einige wenige Buchstaben darstellen. Für Geräte mit komplexen Einstellungen und Menu-Führung werden deshalb häufig Punkt-Matrix LCD-Anzeigen verwendet.&lt;br /&gt;
&lt;br /&gt;
Mit VFD-Anzeigen [http://de.wikipedia.org/wiki/Fluoreszenzanzeige], die ebenfalls sehr gut ablesbar sind, könnnen auch komplexe Menüs dargestellt werden. Diese haben einen sehr weiten Blickwinkel und sehr scharfe und klare Zeichen. Allerdings sind diese Anzeigen relativ teuer, weshalb sie vor allem in eher teueren Geräten eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
== Vergleichstabelle Labornetzgeräte ==&lt;br /&gt;
&lt;br /&gt;
In den folgende Tabellen werden wichtige technischen Daten einiger aktueller Labornetzgeräte zusammengestellt. Um die Übersichtlichkeit zu erhöhen, werden die Geräte eingeteilt in einfache Geräte und Geräte mit Zusatzfunktionen&lt;br /&gt;
&lt;br /&gt;
Die Einteilung geschieht aufgrund der Funktionen, die die Geräte bieten. Das ist also keine Aussage über die Qualität der Geräte.&lt;br /&gt;
&lt;br /&gt;
=== Einfache lineare Labornetzgeräte ===&lt;br /&gt;
&lt;br /&gt;
Hier werden Geräte aufgelistet, welche neben den Grundfunktionen (Strom- und Spannungseinstellung, Anzeige der Istwerte) keine weiteren Funktionen besitzen.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable sortable&amp;quot; id=&amp;quot;einfache&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Hersteller&lt;br /&gt;
!Bezeichnung&lt;br /&gt;
!Preis [EUR]&lt;br /&gt;
!Spannung [V]&lt;br /&gt;
!Strom [A]&lt;br /&gt;
!Kanäle&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3616A&lt;br /&gt;
|620&lt;br /&gt;
|35&lt;br /&gt;
|1.7&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HM8040-3(Benötigt HM8001)&lt;br /&gt;
|280&lt;br /&gt;
|20 + 20 + 5&lt;br /&gt;
|0.5 + 0.5 + 1&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|Peaktech&lt;br /&gt;
|6080&lt;br /&gt;
|50&lt;br /&gt;
|15&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|McVoice&lt;br /&gt;
|WNT0-15-2000&lt;br /&gt;
|38&lt;br /&gt;
|15&lt;br /&gt;
|2&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|Statron&lt;br /&gt;
|2223.1&lt;br /&gt;
|150&lt;br /&gt;
|30&lt;br /&gt;
|2.5&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2250.0&lt;br /&gt;
|225&lt;br /&gt;
|40&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2229.2&lt;br /&gt;
|260&lt;br /&gt;
|40 + 40&lt;br /&gt;
|2.5 + 2.5&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2229.5&lt;br /&gt;
|340&lt;br /&gt;
|32 + 32 + 5&lt;br /&gt;
|3 + 3 + 3&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2225.6&lt;br /&gt;
|310&lt;br /&gt;
|30 + 30&lt;br /&gt;
|5 + 5&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|PS-1302 D&lt;br /&gt;
|95&lt;br /&gt;
|30&lt;br /&gt;
|2&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VLP 1303pro&lt;br /&gt;
|180&lt;br /&gt;
|30 + 6&lt;br /&gt;
|3 + 2&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VSP 2403&lt;br /&gt;
|345&lt;br /&gt;
|40 + 40 + 6&lt;br /&gt;
|3 + 3 + 1.5&lt;br /&gt;
|3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Einfache Schaltnetzgeräte ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable sortable&amp;quot; id=&amp;quot;einfache&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Hersteller&lt;br /&gt;
!Bezeichnung&lt;br /&gt;
!Preis [EUR]&lt;br /&gt;
!Spannung [V]&lt;br /&gt;
!Strom [A]&lt;br /&gt;
!Kanäle&lt;br /&gt;
|-&lt;br /&gt;
|Delta Elektronika&lt;br /&gt;
|ES 030-5&lt;br /&gt;
|624&lt;br /&gt;
|30&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Quatpower&lt;br /&gt;
|LN-3003&lt;br /&gt;
|40&lt;br /&gt;
|30&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Netzgeräte mit Zusatzfunktionen ===&lt;br /&gt;
&lt;br /&gt;
Diese Geräte haben mindestens folgende Funktionen:&lt;br /&gt;
* abschaltbare Ausgänge&lt;br /&gt;
* Anzeige der Sollwerte für Strom und Spannung&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable sortable&amp;quot; id=&amp;quot;hochwertige&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Hersteller&lt;br /&gt;
!Bezeichnung&lt;br /&gt;
!Preis [EUR]&lt;br /&gt;
!Spannung [V]&lt;br /&gt;
!Strom [A]&lt;br /&gt;
!Kanäle&lt;br /&gt;
!linear/getaktet&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|U8001A&lt;br /&gt;
|290&lt;br /&gt;
|30&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3616A&lt;br /&gt;
|620&lt;br /&gt;
|35&lt;br /&gt;
|1.7&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3643A&lt;br /&gt;
|690&lt;br /&gt;
|35 / 60 (umschaltbar)&lt;br /&gt;
|1.4 / 0.8&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3632A&lt;br /&gt;
|990&lt;br /&gt;
|15 / 30 (umschaltbar)&lt;br /&gt;
|7 / 4&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|BK Precision&lt;br /&gt;
|BK 1786&lt;br /&gt;
|490&lt;br /&gt;
|32&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|BK Precision&lt;br /&gt;
|BK 1788&lt;br /&gt;
|615&lt;br /&gt;
|32&lt;br /&gt;
|6&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|BK Precision&lt;br /&gt;
|BK 9130&lt;br /&gt;
|685&lt;br /&gt;
|30 + 30 + 5&lt;br /&gt;
|3 + 3 + 3&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|PSI 6032-03&lt;br /&gt;
|425&lt;br /&gt;
|32&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 2042-06B&lt;br /&gt;
|235&lt;br /&gt;
|42&lt;br /&gt;
|6&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 2342-06B&lt;br /&gt;
|580&lt;br /&gt;
|42 + 42 + 6&lt;br /&gt;
|6 + 6 + 4&lt;br /&gt;
|3&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 3032-05B&lt;br /&gt;
|355&lt;br /&gt;
|32&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 8032-10 DT&lt;br /&gt;
|940&lt;br /&gt;
|32&lt;br /&gt;
|10&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|ELV&lt;br /&gt;
|PPS 5330&lt;br /&gt;
|120&lt;br /&gt;
|30&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|ELV&lt;br /&gt;
|SPS 5630&lt;br /&gt;
|200&lt;br /&gt;
|30&lt;br /&gt;
|6 (max. 75W)&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HM7042-5&lt;br /&gt;
|685&lt;br /&gt;
|32 + 32 + 5,5&lt;br /&gt;
|2 + 2 + 5&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HMP2020&lt;br /&gt;
|1190&lt;br /&gt;
|32 + 32&lt;br /&gt;
|10 + 5&lt;br /&gt;
|2&lt;br /&gt;
|getaktet + linear&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HMP2030&lt;br /&gt;
|1500&lt;br /&gt;
|32 + 32 + 32&lt;br /&gt;
|5 + 5 + 5&lt;br /&gt;
|3&lt;br /&gt;
|getaktet + linear&lt;br /&gt;
|-&lt;br /&gt;
|Rigol&lt;br /&gt;
|DP832 **)&lt;br /&gt;
|362&lt;br /&gt;
|30 + 30 + 5&lt;br /&gt;
|3 + 3 + 3&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VLP 1405pro&lt;br /&gt;
|1190&lt;br /&gt;
|40 + 6&lt;br /&gt;
|5 + 2&lt;br /&gt;
|2&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|PeakTech&lt;br /&gt;
|1885&lt;br /&gt;
|270&lt;br /&gt;
|40&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VLP 2403pro&lt;br /&gt;
|320&lt;br /&gt;
|40 + 40 + 6&lt;br /&gt;
|3 + 3 + 2&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VSP 2410&lt;br /&gt;
|470&lt;br /&gt;
|40 + 40 + 6&lt;br /&gt;
|10 + 10 + 1.5&lt;br /&gt;
|3&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|TTI&lt;br /&gt;
|EX355R&lt;br /&gt;
|330&lt;br /&gt;
|35&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|Mixed-mode (getaktet + linear)&lt;br /&gt;
|-&lt;br /&gt;
|TTI&lt;br /&gt;
|EX354RD&lt;br /&gt;
|480&lt;br /&gt;
|35 + 35&lt;br /&gt;
|4 + 4&lt;br /&gt;
|2&lt;br /&gt;
|Mixed-mode (getaktet + linear)&lt;br /&gt;
|-&lt;br /&gt;
|TTI&lt;br /&gt;
|EX354RT&lt;br /&gt;
|540&lt;br /&gt;
|35 + 35 + (1,5-5)&lt;br /&gt;
|4 + 4 + 5&lt;br /&gt;
|3&lt;br /&gt;
|Mixed-mode (getaktet + linear)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
 **) Das Rigol DP832(A) schaltet die Ausgänge nicht physisch/galvanisch ab. Die Power-MOSFETs der Ausgangsstufe werden lediglich auf Soll-NULL gesetzt. Dies kann bei Drift auch durchaus ungleich 0,00 Volt bedeuten!&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Spannungsversorgung_und_Energiequellen]]&lt;/div&gt;</summary>
		<author><name>8023</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=K%C3%BChlk%C3%B6rper&amp;diff=92489</id>
		<title>Kühlkörper</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=K%C3%BChlk%C3%B6rper&amp;diff=92489"/>
		<updated>2016-03-18T05:10:36Z</updated>

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

		<summary type="html">&lt;p&gt;8023: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die heutigen Mikrocontroller und insbesondere die RISC-[[AVR]]s sind für viele Steuerungsaufgaben zu schnell. Wenn wir beispielsweise eine [[LED]] oder Lampe blinken lassen wollen, können wir selbstverständlich nicht die CPU-Frequenz verwenden, da ja dann nichts mehr vom Blinken zu bemerken wäre.&lt;br /&gt;
&lt;br /&gt;
Wir brauchen also eine Möglichkeit, Vorgänge in Zeitabständen durchzuführen, die geringer als die Taktfrequenz des Controllers sind. Selbstverständlich sollte die resultierende Frequenz auch noch möglichst genau und stabil sein.&lt;br /&gt;
&lt;br /&gt;
Hier kommen die im AVR vorhandenen Timer/Counter zum Einsatz.&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
Ein Timer ist ganz einfach ein bestimmtes Register im µC, das völlig ohne Zutun des Programms, also per Hardware, hochgezählt wird. Das alleine wäre noch nicht allzu nützlich, wenn nicht dieses Hardwareregister bei bestimmten Zählerständen einen Interrupt auslösen könnte. &lt;br /&gt;
&lt;br /&gt;
Ein solches Ereignis ist der Overflow (Überlauf): Da die Bitbreite des Registers beschränkt ist, kommt es natürlich auch vor, dass der Zähler so hoch zählt, dass der nächste Zählerstand mit dieser Bitbreite nicht mehr darstellbar ist und der Zähler wieder auf 0 zurückgesetzt wird. Dieses Ereignis nennt man den Overflow und es ist möglich an dieses Ereignis einen Interrupt zu koppeln.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Anwendungsgebiet ist das Zählen von Impulsen, welche über einen I/O-Pin zugeführt werden.&lt;br /&gt;
&lt;br /&gt;
Als Eingangstakt für die Timer/Counter kann entweder die CPU-Taktfrequenz, der Vorteiler-Ausgang oder ein an einen I/O-Pin angelegtes Signal verwendet werden. Wenn ein externes Signal verwendet wird, so darf dessen Frequenz nicht höher sein als die Hälfte des CPU-Taktes.&lt;br /&gt;
&lt;br /&gt;
Die folgenden Ausführungen beziehen sich im Wesentlichen auf den AT90S2313. Für andere Modelltypen müsst ihr euch die allenfalls notwendigen Anpassungen aus den Datenblättern der entsprechenden Controller herauslesen.&lt;br /&gt;
&lt;br /&gt;
== Der Vorteiler (Prescaler) ==&lt;br /&gt;
&lt;br /&gt;
Der Vorteiler dient dazu, den CPU-Takt vorerst um einen einstellbaren Faktor zu reduzieren. Die so geteilte Frequenz wird den Eingängen der Timer zugeführt.&lt;br /&gt;
&lt;br /&gt;
Wenn wir mit einem CPU-Takt von 4 MHz arbeiten und den Vorteiler auf 1024 einstellen, wird der Timer mit einer Frequenz von 4 MHz / 1024, also mit etwas weniger als 4 kHz versorgt. Wenn der Timer läuft, wird das Zählregister (TCNTx) mit dieser Frequenz inkrementiert.&lt;br /&gt;
&lt;br /&gt;
== Timer-Bitzahlen verschiedener AVRs ==&lt;br /&gt;
&lt;br /&gt;
Wir unterscheiden grundsätzlich zwischen 8-Bit Timern, welche eine Auflösung von 256 (2^8) aufweisen und 16-Bit Timern mit einer Auflösung von 65536 (2^16). &lt;br /&gt;
&lt;br /&gt;
Alle AVR-Modelle verfügen über mindestens einen, teilweise sogar zwei, 8-Bit Timer.&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! AVR-Typ || Timer/Counter0 || Timer/Counter1 || Timer/Counter2&lt;br /&gt;
|- &lt;br /&gt;
| AT90S2313  ||  8 || 16 || -&lt;br /&gt;
|- &lt;br /&gt;
| ATtiny2313 ||  8 || 16 || -&lt;br /&gt;
|- &lt;br /&gt;
| ATtiny25   ||  8 ||  8 || -&lt;br /&gt;
|- &lt;br /&gt;
| ATmega8    || 8  || 16 || 8&lt;br /&gt;
|- &lt;br /&gt;
| ATmega88   || 8  || 16 || 8&lt;br /&gt;
|- &lt;br /&gt;
| ATmega16   || 8  || 16 || 8&lt;br /&gt;
|- &lt;br /&gt;
| ATmega32   || 8  || 16 || 8&lt;br /&gt;
|- &lt;br /&gt;
| ATmega644  || 8  || 16 || 8&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 8-Bit Timer/Counter ==&lt;br /&gt;
&lt;br /&gt;
Der 8-Bit Timer wird z.B bei AT90S2313 über folgende Register angesprochen (bei anderen Typen weitestgehend analog):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| width=&amp;quot;100&amp;quot; | &#039;&#039;&#039;TCCR0&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;T&#039;&#039;&#039;imer/&#039;&#039;&#039;C&#039;&#039;&#039;ounter &#039;&#039;&#039;C&#039;&#039;&#039;ontrol &#039;&#039;&#039;R&#039;&#039;&#039;egister&lt;br /&gt;
Timer &#039;&#039;&#039;0&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In diesem Register stellen wir ein, wie wir den Timer/Counter verwenden möchten.&lt;br /&gt;
&lt;br /&gt;
Das Register ist wie folgt aufgebaut:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7|| 6|| 5|| 4|| 3|| 2|| 1|| 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;CS02&#039;&#039;&#039;|| &#039;&#039;&#039;CS01&#039;&#039;&#039;|| &#039;&#039;&#039;CS00&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R|| R|| R|| R|| R|| R/W|| R/W|| R/W&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0|| 0|| 0|| 0|| 0|| 0|| 0|| 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CS02, CS01, CS00&#039;&#039;&#039; (&#039;&#039;&#039;C&#039;&#039;&#039;lock &#039;&#039;&#039;S&#039;&#039;&#039;elect Bits)&lt;br /&gt;
:Diese 3 Bits bestimmen die Quelle für den Timer/Counter:&lt;br /&gt;
&lt;br /&gt;
:{|  class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! CS02 || CS01 || CS00 || Resultat&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Stopp, Der Timer/Counter wird angehalten.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| CPU-Takt&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| CPU-Takt / 8&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| CPU-Takt / 64&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| CPU-Takt / 256&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| CPU-Takt / 1024&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Externer Pin &#039;&#039;&#039;TO&#039;&#039;&#039;, fallende Flanke&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Externer Pin &#039;&#039;&#039;TO&#039;&#039;&#039;, steigende Flanke&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:Wenn als Quelle der externe Pin &#039;&#039;&#039;TO&#039;&#039;&#039; verwendet wird, so wird ein Flankenwechsel auch erkannt, wenn der Pin &#039;&#039;&#039;TO&#039;&#039;&#039; als Ausgang geschaltet ist.&lt;br /&gt;
&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;TCNT0&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;T&#039;&#039;&#039;imer/&#039;&#039;&#039;C&#039;&#039;&#039;ou&#039;&#039;&#039;nt&#039;&#039;&#039;er Daten Register Timer &#039;&#039;&#039;0&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
Dieses ist als 8-Bit Aufwärtszähler mit Schreib- und Lesezugriff&lt;br /&gt;
realisiert. Wenn der Zähler den Wert 255 erreicht hat, beginnt er beim&lt;br /&gt;
nächsten Zyklus wieder bei 0.&lt;br /&gt;
&lt;br /&gt;
{|  class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7|| 6|| 5|| 4|| 3|| 2|| 1|| 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;MSB&#039;&#039;&#039;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &#039;&#039;&#039;LSB&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W|| R/W|| R/W|| R/W|| R/W|| R/W|| R/W|| R/W&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0|| 0|| 0|| 0|| 0|| 0|| 0|| 0&lt;br /&gt;
|}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Um nun also den Timer0 in Betrieb zu setzen und ihn mit einer Frequenz von 1/8-tel des CPU-Taktes zählen zu lassen, schreiben wir die folgende Befehlszeile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    TCCR0 = (1&amp;lt;&amp;lt;CS01);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Zähler zählt nun aufwärts bis 255, um dann wieder bei 0 zu beginnen. Der aktuelle Zählerstand steht in TCNT0. Bei jedem Überlauf von 255 auf 0 wird das Timer Overflow Flag &#039;&#039;&#039;TOV0&#039;&#039;&#039; im Timer Interrupt Flag &#039;&#039;&#039;TIFR&#039;&#039;&#039;-Register gesetzt und, falls so konfiguriert, ein entsprechender Timer-Overflow-Interrupt ausgelöst und die daran gebundene Interrupt-Service-Routine (ISR) abgearbeitet. Das TOV Flag &lt;br /&gt;
lässt sich durch das Hineinschreiben einer 1 und nicht wie erwartet einer 0 wieder zurücksetzen.&lt;br /&gt;
&lt;br /&gt;
=== Overflow Interrupt ===&lt;br /&gt;
&lt;br /&gt;
Jedesmal wenn der Timer seinen höchsten Wert erreicht hat, erfolgt ein Overflow und der Timer beginnt wieder bei 0 zu zählen. An diesen Overflow kann eine Funktion, die sog. Overflow-ISR, gebunden werden. Damit hat man die Möglichkeit, bestimmte Funktionalitäten in regelmäßigen Zeitabständen ausführen zu lassen. Wie groß diese Zeitabstände sind, wird ausschließlich von der Zählfrequenz des Timers und der Bitbreite des Timers (also dem höchsten Wert, den der Timer erreichen kann) bestimmt. Die Zählfrequenz wiederrum hängt von Taktfrequenz des Controllers und dem eingestellten Vorteiler ab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* uC: AT90S2313 */&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;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  // Timer 0 konfigurieren&lt;br /&gt;
  TCCR0 = (1&amp;lt;&amp;lt;CS01); // Prescaler 8&lt;br /&gt;
&lt;br /&gt;
  // Overflow Interrupt erlauben&lt;br /&gt;
  TIMSK |= (1&amp;lt;&amp;lt;TOIE0);&lt;br /&gt;
&lt;br /&gt;
  // Global Interrupts aktivieren&lt;br /&gt;
  sei();&lt;br /&gt;
&lt;br /&gt;
  while(1)&lt;br /&gt;
  {&lt;br /&gt;
    /* Sonstige Aktionen */&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
Der Overflow Interrupt Handler&lt;br /&gt;
wird aufgerufen, wenn TCNT0 von&lt;br /&gt;
255 auf 0 wechselt (256 Schritte),&lt;br /&gt;
d.h. ca. alle 2 ms&lt;br /&gt;
*/&lt;br /&gt;
#ifndef TIMER0_OVF_vect&lt;br /&gt;
// Für ältere WinAVR Versionen z.B. WinAVR-20071221 &lt;br /&gt;
#define TIMER0_OVF_vect TIMER0_OVF0_vect&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
ISR (TIMER0_OVF_vect)&lt;br /&gt;
{&lt;br /&gt;
  /* Interrupt Aktion alle&lt;br /&gt;
  (1000000/8)/256 Hz = 488,28125 Hz&lt;br /&gt;
  bzw.&lt;br /&gt;
  1/488,28125 s = 2,048 ms  &lt;br /&gt;
  */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Grundsätzlich kann man in einer ISR jeden beliebigen Code ausführen lassen. Allerdings sollte man sich an die Grundregeln der ISR Programmierung halten: Nur das tun was unbedingt notwendig ist. Eine ISR sollte (zeitlich gesehen) so kurz wie möglich aber so lang wie notwendig sein. Komplexe Ausgaben auf LCD oder gar auf die UART gehören nicht in eine ISR. Sie dauern einfach zu lange und blockieren so den Prozessor zu lange. Programme, die mehrere Dinge quasi gleichzeitig machen, werden so zu lange blockiert.&lt;br /&gt;
&lt;br /&gt;
Die Taktfrequenz, mit der eine ISR aufgerufen wird, erscheint nach obigen Ausführungen recht starr, aber sie lässt sich feiner anpassen. Eine Möglichkeit bestünde darin, den Zählerstand des Registers TCNT0 nach einem Overflow auf einen Wert größer als 0 zu setzen. Somit blieben bis zum nächsten Overflow weniger Zähltakte, was die Frequenz erhöhen würde.&lt;br /&gt;
&lt;br /&gt;
Modernere AVRs kennen allerdings einen eleganteren Weg zur Anpassung der Interrupt-Frequenz: den CTC Modus&lt;br /&gt;
&lt;br /&gt;
=== &#039;&#039;&#039;CTC&#039;&#039;&#039; Clear Timer on Compare Match (Auto Reload) ===&lt;br /&gt;
&lt;br /&gt;
Im CTC Modus des Timers ist es möglich, anstelle der durch die Hardware bedingten Obergrenze des Timers, einen anderen Wert zu benutzen, an dem der Timer einen Interrupt auslöst und wieder bei 0 zu zählen anfängt. Neben dem Aktivieren des CTC Modus genügt es dazu, einfach den gewünschten Endwert in ein spezielles Register, das OCR0A, zu laden. Und natürlich hat auch die ISR dann einen anderen Namen. Weitere Anmerkungen und Erläuterungen finden sich im CTC-Kapitel der 16-Bit Timer.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* uC: Attiny2313 */&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;
//Variablen für die Zeit&lt;br /&gt;
volatile unsigned int millisekunden;&lt;br /&gt;
volatile unsigned int sekunde;&lt;br /&gt;
volatile unsigned int minute;&lt;br /&gt;
volatile unsigned int stunde;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  // Timer 0 konfigurieren&lt;br /&gt;
  TCCR0A = (1&amp;lt;&amp;lt;WGM01); // CTC Modus&lt;br /&gt;
  TCCR0B |= (1&amp;lt;&amp;lt;CS01); // Prescaler 8&lt;br /&gt;
  // ((1000000/8)/1000) = 125&lt;br /&gt;
  OCR0A = 125-1;&lt;br /&gt;
&lt;br /&gt;
  // Compare Interrupt erlauben&lt;br /&gt;
  TIMSK |= (1&amp;lt;&amp;lt;OCIE0A);&lt;br /&gt;
&lt;br /&gt;
  // Global Interrupts aktivieren&lt;br /&gt;
  sei();&lt;br /&gt;
&lt;br /&gt;
  while(1)&lt;br /&gt;
  {&lt;br /&gt;
    /*Hier kann die aktuelle Zeit&lt;br /&gt;
      ausgeben werden*/&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
Der Compare Interrupt Handler &lt;br /&gt;
wird aufgerufen, wenn &lt;br /&gt;
TCNT0 = OCR0A = 125-1 &lt;br /&gt;
ist (125 Schritte), d.h. genau alle 1 ms&lt;br /&gt;
*/&lt;br /&gt;
ISR (TIMER0_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
  millisekunden++;&lt;br /&gt;
  if(millisekunden == 1000)&lt;br /&gt;
  {&lt;br /&gt;
    sekunde++;&lt;br /&gt;
    millisekunden = 0;&lt;br /&gt;
    if(sekunde == 60)&lt;br /&gt;
    {&lt;br /&gt;
      minute++;&lt;br /&gt;
      sekunde = 0;&lt;br /&gt;
    }&lt;br /&gt;
    if(minute == 60)&lt;br /&gt;
    {&lt;br /&gt;
      stunde++;&lt;br /&gt;
      minute = 0;&lt;br /&gt;
    }&lt;br /&gt;
    if(stunde == 24)&lt;br /&gt;
    {&lt;br /&gt;
      stunde = 0;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Anm.: In diesem Beispiel ist es egal, ob TCCR0B absolut gesetzt wird (TCCR0B = (1&amp;lt;&amp;lt;CS01)) oder der Prescaler-Wert zum alten Inhalt hinzugefügt wird (TCCR0B |= (1&amp;lt;&amp;lt;CS01)). Die anderen Bits in TCCR0B sind nach dem Reset 0 und sollen auch 0 bleiben. Wenn man sicher nur bestimmte Bits ändern will, ist das ODER (bzw. UND mit dem Kehrwert) sicherer. Näheres dazu im Artikel [[Bitmanipulation]].&lt;br /&gt;
&lt;br /&gt;
== 16-Bit Timer/Counter ==&lt;br /&gt;
&lt;br /&gt;
Viele AVR-Modelle besitzen außer den 8-Bit Timern auch 16-Bit Timer. Die 16-Bit Timer/Counter sind etwas komplexer aufgebaut als die 8-Bit Timer/Counter, bieten dafür aber auch viel mehr Möglichkeiten, als da sind:&lt;br /&gt;
&lt;br /&gt;
* Die [[PWM]]-Betriebsart zur Erzeugung eines pulsweitenmodulierten Ausgangssignals. &lt;br /&gt;
* Vergleichswert-Überprüfung mit Erzeugung eines Ausgangssignals (Output Compare Match).&lt;br /&gt;
* Einfangen eines Eingangssignals mit Speicherung des aktuellen Zählerwertes (Input Capturing), mit zuschaltbarer Rauschunterdrückung (Noise Filtering).&lt;br /&gt;
&lt;br /&gt;
Folgende Register sind dem Timer/Counter 1 zugeordnet:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| width=&amp;quot;100&amp;quot; | &#039;&#039;&#039;TCCR1A&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;T&#039;&#039;&#039;imer/&#039;&#039;&#039;C&#039;&#039;&#039;ounter &#039;&#039;&#039;C&#039;&#039;&#039;ontrol &#039;&#039;&#039;R&#039;&#039;&#039;egister &#039;&#039;&#039;A&#039;&#039;&#039; Timer &#039;&#039;&#039;1&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
In diesem und dem folgenden Register stellen wir ein, wie wir den Timer/Counter verwenden möchten.&amp;lt;br /&amp;gt;&lt;br /&gt;
Das Register ist wie folgt aufgebaut:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7|| 6|| 5|| 4|| 3|| 2|| 1|| 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;COM1A1&#039;&#039;&#039;|| &#039;&#039;&#039;COM1A0&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;PWM11&#039;&#039;&#039;|| &#039;&#039;&#039;PWM10&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W|| R/W|| R|| R|| R|| R|| R/W|| R/W&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0|| 0|| 0|| 0|| 0|| 0|| 0|| 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;COM1A1&#039;&#039;&#039;, &#039;&#039;&#039;COM1A0&#039;&#039;&#039; (&#039;&#039;&#039;Co&#039;&#039;&#039;mpare &#039;&#039;&#039;M&#039;&#039;&#039;atch Control Bits)&lt;br /&gt;
:Diese 2 Bits bestimmen die Aktion, welche am Output-Pin &#039;&#039;&#039;OC1&#039;&#039;&#039; ausgeführt werden soll, wenn der Wert des Datenregisters des Timer/Counter 1 den Wert des Vergleichsregisters erreicht, also ein so genannter Compare Match auftritt.&lt;br /&gt;
:Der Pin &#039;&#039;&#039;OC1&#039;&#039;&#039; (&#039;&#039;&#039;PB3&#039;&#039;&#039; beim 2313) muss mit dem Datenrichtungsregister als Ausgang konfiguriert werden.&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! COM1A1 || COM1A0 || Resultat&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Output-Pin &#039;&#039;&#039;OC1&#039;&#039;&#039; wird nicht angesteuert.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Das Signal am Pin &#039;&#039;&#039;OC1&#039;&#039;&#039; wird invertiert (Toggle).&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Der Output Pin &#039;&#039;&#039;OC1&#039;&#039;&#039; wird auf 0 gesetzt.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Der Output Pin &#039;&#039;&#039;OC1&#039;&#039;&#039; wird auf 1 gesetzt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:In der PWM-Betriebsart haben diese Bits eine andere Funktion.&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! COM1A1 || COM1A0 || Resultat&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Output-Pin &#039;&#039;&#039;OC1&#039;&#039;&#039; wird nicht angesteuert.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Output-Pin &#039;&#039;&#039;OC1&#039;&#039;&#039; wird nicht angesteuert.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Wird beim Hochzählen der Wert im Vergleichsregister erreicht, so wird der Pin &#039;&#039;&#039;OC1&#039;&#039;&#039; auf 0 gesetzt.&lt;br /&gt;
Wird beim Herunterzählen der Wert im Vergleichsregister erreicht, so wird der Pin auf 1 gesetzt.&lt;br /&gt;
&lt;br /&gt;
Man nennt dies &#039;&#039;nicht invertierende PWM&#039;&#039;.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Wird beim Hochzählen der Wert im Vergleichsregister erreicht, so wird der Pin &#039;&#039;&#039;OC1&#039;&#039;&#039; auf 1 gesetzt.&lt;br /&gt;
Wird beim Herunterzählen der Wert im Vergleichsregister erreicht, so wird der Pin auf 0 gesetzt.&lt;br /&gt;
&lt;br /&gt;
Man nennt dies &#039;&#039;invertierende PWM&#039;&#039;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PWM11&#039;&#039;&#039;, &#039;&#039;&#039;PWM10&#039;&#039;&#039; (&#039;&#039;&#039;PWM&#039;&#039;&#039; Mode Select Bits)&lt;br /&gt;
:Mit diesen 2 Bits wird die PWM-Betriebsart des Timer/Counter 1 gesteuert.&lt;br /&gt;
* PWM10 PWM11 wurden umbenannt in WGM10 und WGM11&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! PWM11 || PWM10 || Resultat&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Die PWM-Betriebsart ist nicht aktiviert. Timer/Counter 1 arbeitet als normaler Timer bzw. Zähler.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| 8-Bit PWM Betriebsart aktivieren.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| 9-Bit PWM Betriebsart aktivieren.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| 10-Bit PWM Betriebsart aktivieren.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;TCCR1B&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;T&#039;&#039;&#039;imer/&#039;&#039;&#039;C&#039;&#039;&#039;ounter &#039;&#039;&#039;C&#039;&#039;&#039;ontrol &#039;&#039;&#039;R&#039;&#039;&#039;egister &#039;&#039;&#039;B&#039;&#039;&#039; Timer &#039;&#039;&#039;1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{|  class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;ICNC1&#039;&#039;&#039;|| &#039;&#039;&#039;ICES1&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;WGM13&#039;&#039;&#039;|| &#039;&#039;&#039;WGM12 (CTC1)&#039;&#039;&#039;|| &#039;&#039;&#039;CS12&#039;&#039;&#039;|| &#039;&#039;&#039;CS11&#039;&#039;&#039;|| &#039;&#039;&#039;CS10&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W || R/W || R || R || R/W || R/W || R/W || R/W&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ICNC1&#039;&#039;&#039; (&#039;&#039;&#039;I&#039;&#039;&#039;nput &#039;&#039;&#039;C&#039;&#039;&#039;apture &#039;&#039;&#039;N&#039;&#039;&#039;oise &#039;&#039;&#039;C&#039;&#039;&#039;anceler (4 CKs) Timer/Counter 1&lt;br /&gt;
:oder auf Deutsch Rauschunterdrückung des Eingangssignals.&lt;br /&gt;
:Wenn dieses Bit gesetzt ist und mit dem Input Capture Signal gearbeitet wird so werden nach der Triggerung des Signals mit der entsprechenden Flanke (steigend oder fallend) am Input Capture Pin &#039;&#039;&#039;ICP&#039;&#039;&#039; jeweils 4 Messungen mit der CPU-Frequenz des Eingangssignals abgefragt. Nur dann, wenn alle 4 Messungen den gleichen Zustand aufweisen gilt das Signal als erkannt.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ICES1&#039;&#039;&#039; (&#039;&#039;&#039;I&#039;&#039;&#039;nput &#039;&#039;&#039;C&#039;&#039;&#039;apture &#039;&#039;&#039;E&#039;&#039;&#039;dge &#039;&#039;&#039;S&#039;&#039;&#039;elect Timer/Counter &#039;&#039;&#039;1&#039;&#039;&#039;)&lt;br /&gt;
:Mit diesem Bit wird bestimmt, ob die steigende (&#039;&#039;&#039;ICES1&#039;&#039;&#039;=1) oder fallende (&#039;&#039;&#039;ICES1&#039;&#039;&#039;=0) Flanke zur Auswertung des Input Capture Signals an Pin &#039;&#039;&#039;ICP&#039;&#039;&#039; heran gezogen wird.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CTC1&#039;&#039;&#039; (&#039;&#039;&#039;C&#039;&#039;&#039;lear &#039;&#039;&#039;T&#039;&#039;&#039;imer/&#039;&#039;&#039;C&#039;&#039;&#039;ounter on Compare Match Timer/Counter &#039;&#039;&#039;1&#039;&#039;&#039;)&lt;br /&gt;
:Wenn dieses Bit gesetzt ist, so wird nach einer Übereinstimmung des Datenregisters &#039;&#039;&#039;TCNT1H&#039;&#039;&#039;/&#039;&#039;&#039;TCNT1L&#039;&#039;&#039; mit dem Vergleichswert in &#039;&#039;&#039;OCR1H&#039;&#039;&#039;/&#039;&#039;&#039;OCR1L&#039;&#039;&#039; das Datenregister &#039;&#039;&#039;TCNT1H&#039;&#039;&#039;/&#039;&#039;&#039;TCNT1L&#039;&#039;&#039; auf 0 gesetzt.&lt;br /&gt;
:Da die Übereinstimmung im Takt nach dem Vergleich behandelt wird, ergibt sich je nach eingestelltem Vorteiler ein etwas anderes Zählverhalten:&lt;br /&gt;
:Wenn der Vorteiler auf 1 gestellt, und C der voreingestellte Vergleichswert ist, dann nimmt das Datenregister, im CPU-Takt betrachtet, folgende Werte an:&lt;br /&gt;
:... | C-2 | C-1 | C | 0 | 1 |...&lt;br /&gt;
:Wenn der Vorteiler z.&amp;amp;nbsp;B. auf 8 eingestellt ist, dann nimmt das Datenregister folgende Werte an:&lt;br /&gt;
:... | C-2, C-2, C-2, C-2, C-2, C-2, C-2, C-2 | C-1, C-1, C-1, C-1, C-1, C-1, C-1, C-1 | C, 0, 0, 0, 0, 0, 0, 0 |...&lt;br /&gt;
:In der PWM-Betriebsart hat dieses Bit keine Funktion.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CS12&#039;&#039;&#039;, &#039;&#039;&#039;CS11&#039;&#039;&#039;, &#039;&#039;&#039;CS10&#039;&#039;&#039; (&#039;&#039;&#039;C&#039;&#039;&#039;lock &#039;&#039;&#039;S&#039;&#039;&#039;elect Bits)&lt;br /&gt;
:Diese 3 Bits bestimmen die Quelle für den Timer/Counter:&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! CS12 || CS11 || CS10 || Resultat&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Stopp, Der Timer/Counter wird angehalten.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| CPU-Takt&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| CPU-Takt / 8&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| CPU-Takt / 64&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| CPU-Takt / 256&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| CPU-Takt / 1024&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Externer Pin T1, fallende Flanke&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Externer Pin T1, steigende Flanke&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
:Wenn als Quelle der externe Pin T1 verwendet wird, so wird ein Flankenwechsel auch erkannt, wenn der Pin T1 als Ausgang geschaltet ist.&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;TCNT1H&#039;&#039;&#039;&amp;lt;br /&amp;gt;&#039;&#039;&#039;TCNT1L&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;T&#039;&#039;&#039;imer/&#039;&#039;&#039;C&#039;&#039;&#039;ou&#039;&#039;&#039;nt&#039;&#039;&#039;er Daten Register Timer/Counter &#039;&#039;&#039;1&#039;&#039;&#039;&lt;br /&gt;
Dieses ist als 16-Bit Aufwärtszähler mit Schreib- und Lesezugriff realisiert. Wenn der Zähler den Wert 65535 erreicht hat, beginnt er beim nächsten Zyklus wieder bei 0.&lt;br /&gt;
&lt;br /&gt;
{|  class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0 ||&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;MSB&#039;&#039;&#039;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &#039;&#039;&#039;TCNT1H&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &#039;&#039;&#039;LSB&#039;&#039;&#039;|| &#039;&#039;&#039;TCNT1L&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W|| R/W|| R/W|| R/W|| R/W|| R/W|| R/W|| R/W|| &amp;amp;nbsp;&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0|| 0|| 0|| 0|| 0|| 0|| 0|| 0|| &amp;amp;nbsp;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In der PWM-Betriebsart wird das Register als Auf/Ab-Zähler verwendet, d.h. der Wert steigt zuerst von 0, bis er den Überlauf von 65535 auf 0 erreicht hat. Dann zählt das Register rückwärts wiederum bis 0.&lt;br /&gt;
&lt;br /&gt;
Zum Auslesen des Registers wird von der CPU ein internes TEMP-Register verwendet. Das gleiche Register wird auch verwendet, wenn auf &#039;&#039;&#039;OCR1&#039;&#039;&#039; oder &#039;&#039;&#039;ICR1&#039;&#039;&#039; zugegriffen wird.&lt;br /&gt;
&lt;br /&gt;
Deshalb müssen vor dem Zugriff auf eines dieser Register alle Interrupts gesperrt werden, weil sonst die Möglichkeit des gleichzeitigen Zugriffs auf das Temporärregister gegeben ist, was natürlich zu fehlerhaftem Verhalten des Programms führt.. Zudem muss zuerst &#039;&#039;&#039;TCNT1L&#039;&#039;&#039; und erst danach &#039;&#039;&#039;TCNT1H&#039;&#039;&#039; ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
Wenn in das Register geschrieben werden soll, müssen ebenfalls alle Interrrupts gesperrt werden. Dann muss zuerst das &#039;&#039;&#039;TCNT1H&#039;&#039;&#039;-Register und erst danach das &#039;&#039;&#039;TCNT1L&#039;&#039;&#039;-Register geschrieben werden, also genau die umgekehrte Reihenfolge wie beim Lesen des Registers.&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;OCR1H&#039;&#039;&#039;&amp;lt;br /&amp;gt;&#039;&#039;&#039;OCR1L&#039;&#039;&#039;&lt;br /&gt;
| Timer/Counter &#039;&#039;&#039;O&#039;&#039;&#039;utput &#039;&#039;&#039;C&#039;&#039;&#039;ompare &#039;&#039;&#039;R&#039;&#039;&#039;egister Timer/Counter &#039;&#039;&#039;1&#039;&#039;&#039;&lt;br /&gt;
{|  class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7|| 6|| 5|| 4|| 3|| 2|| 1|| 0|| &amp;amp;nbsp;&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;MSB&#039;&#039;&#039;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &#039;&#039;&#039;OCR1H&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &#039;&#039;&#039;LSB&#039;&#039;&#039;|| &#039;&#039;&#039;OCR1L&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W|| R/W|| R/W|| R/W|| R/W|| R/W|| R/W|| R/W|| &amp;amp;nbsp;&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0|| 0|| 0|| 0|| 0|| 0|| 0|| 0|| &amp;amp;nbsp;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Der Wert im Output Compare Register wird ständig mit dem aktuellen Wert im Datenregister TCNT1H/TCNT1L verglichen. Stimmen die beiden Werte überein, so wird ein sogenannter Output Compare Match ausgelöst. Die entsprechenden Aktionen werden über die Timer/Counter 1 Control und Status Register eingestellt.&lt;br /&gt;
&lt;br /&gt;
Zum Auslesen des Registers wird von der CPU ein internes TEMP-Register verwendet. Das gleiche Register wird auch verwendet, wenn auf &#039;&#039;&#039;TCNT1&#039;&#039;&#039; oder &#039;&#039;&#039;ICR1&#039;&#039;&#039; zugegriffen wird.&lt;br /&gt;
Deshalb müssen vor dem Zugriff auf eines dieser Register alle Interrupts gesperrt werden, weil sonst die Möglichkeit des gleichzeitigen Zugriffs auf das Temporärregister gegeben ist, was natürlich zu fehlerhaftem Verhalten des Programms führt. Zudem muss zuerst &#039;&#039;&#039;OCR1L&#039;&#039;&#039; und erst danach &#039;&#039;&#039;OCR1H&#039;&#039;&#039; ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
Wenn in das Register geschrieben werden soll, müssen ebenfalls alle Interrupts gesperrt werden. Dann muss zuerst das &#039;&#039;&#039;OCR1H&#039;&#039;&#039;-Register und erst danach das &#039;&#039;&#039;OCR1L&#039;&#039;&#039;-Register geschrieben werden, also genau die umgekehrte Reihenfolge wie beim Lesen des Registers.&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;ICR1H&#039;&#039;&#039;&amp;lt;br /&amp;gt;&#039;&#039;&#039;ICR1L&#039;&#039;&#039;&lt;br /&gt;
| Timer/Counter &#039;&#039;&#039;I&#039;&#039;&#039;nput &#039;&#039;&#039;C&#039;&#039;&#039;apture &#039;&#039;&#039;R&#039;&#039;&#039;egister Timer/Counter &#039;&#039;&#039;1&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
{|  class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7|| 6|| 5|| 4|| 3|| 2|| 1|| 0|| &amp;amp;nbsp;&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;MSB&#039;&#039;&#039;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &#039;&#039;&#039;ICR1H&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &amp;amp;nbsp;|| &#039;&#039;&#039;LSB&#039;&#039;&#039;|| &#039;&#039;&#039;ICR1L&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R|| R|| R|| R|| R|| R|| R|| R|| &amp;amp;nbsp;&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0|| 0|| 0|| 0|| 0|| 0|| 0|| 0|| &amp;amp;nbsp;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Das Input Capture Register ist ein 16-Bit Register. Bei einigen AVR Modellen kann es als TOP Value für bestimmte PWM Modes verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Wenn am Input Capture Pin &#039;&#039;&#039;ICP&#039;&#039;&#039; die gemäß Einstellungen im &#039;&#039;&#039;TCCR1B&#039;&#039;&#039; definierte Flanke erkannt wird, so wird der aktuelle Inhalt des Datenregisters &#039;&#039;&#039;TCNT1H&#039;&#039;&#039;/&#039;&#039;&#039;TCNT1L&#039;&#039;&#039; sofort in dieses Register kopiert und das Input Capture Flag &#039;&#039;&#039;ICF1&#039;&#039;&#039; im Timer Interrupt Flag Register &#039;&#039;&#039;TIFR&#039;&#039;&#039; gesetzt.&lt;br /&gt;
&lt;br /&gt;
{{Warnung|Wie bereits oben erwähnt, müssen vor dem Zugriff auf dieses Register alle Interrupts gesperrt werden. Zudem müssen Low- und Highbyte des Registers in der richtigen Reihenfolge bearbeitet werden:&lt;br /&gt;
;Lesen&amp;amp;#58;: &#039;&#039;&#039;ICR1L&#039;&#039;&#039; &amp;amp;rarr; &#039;&#039;&#039;ICR1H&#039;&#039;&#039;&lt;br /&gt;
Bei Verwendung des Compilers wird der Zugriff in der korrekten Reihenfolge ausgeführt, wenn man das 16-Bit register ICR1 verwendet anstatt zwei Zugriffe auf 8-Bit Register.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Die PWM-Betriebsart ===&lt;br /&gt;
&lt;br /&gt;
Wenn der Timer/Counter 1 in der PWM-Betriebsart betrieben wird, so bilden das Datenregister &#039;&#039;&#039;TCNT1H&#039;&#039;&#039;/&#039;&#039;&#039;TCNT1L&#039;&#039;&#039; und das Vergleichsregister &#039;&#039;&#039;OCR1H&#039;&#039;&#039;/&#039;&#039;&#039;OCR1L&#039;&#039;&#039; einen 8-, 9- oder 10-Bit, frei laufenden PWM-Modulator, welcher als PWM-Signal am &#039;&#039;&#039;OC1&#039;&#039;&#039;-Pin (&#039;&#039;&#039;PB3&#039;&#039;&#039; beim 2313) abgegriffen werden kann. Das Datenregister &#039;&#039;&#039;TCNT1H&#039;&#039;&#039;/&#039;&#039;&#039;TCNT1L&#039;&#039;&#039; wird dabei als Auf-/Ab-Zähler betrieben, welcher von 0 an aufwärts zählt bis zur Obergrenze und danach wieder zurück auf 0.&lt;br /&gt;
Die Obergrenze ergibt sich daraus, ob 8-, 9- oder 10-Bit PWM verwendet wird, und zwar gemäß folgender Tabelle:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Auflösung || Obergrenze || Frequenz&lt;br /&gt;
|- &lt;br /&gt;
| 8 || 255 || f&amp;lt;sub&amp;gt;TC1&amp;lt;/sub&amp;gt; / 510&lt;br /&gt;
|- &lt;br /&gt;
| 9 || 511 || f&amp;lt;sub&amp;gt;TC1&amp;lt;/sub&amp;gt; / 1022&lt;br /&gt;
|- &lt;br /&gt;
|10 || 1023 || f&amp;lt;sub&amp;gt;TC1&amp;lt;/sub&amp;gt; / 2046&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Wenn nun der Zählerwert im Datenregister den in &#039;&#039;&#039;OCR1H&#039;&#039;&#039;/&#039;&#039;&#039;OCR1L&#039;&#039;&#039; gespeicherten Wert erreicht, wird der Ausgabepin &#039;&#039;&#039;OC1&#039;&#039;&#039; gesetzt bzw. gelöscht, je nach Einstellung von &#039;&#039;&#039;COM1A1&#039;&#039;&#039; und &#039;&#039;&#039;COM1A0&#039;&#039;&#039; im &#039;&#039;&#039;TCCR1A&#039;&#039;&#039;-Register.&lt;br /&gt;
&lt;br /&gt;
Ich habe versucht, die entsprechenden Signale in der folgenden Grafik zusammenzufassen&lt;br /&gt;
&lt;br /&gt;
[[Image:PWM Theorie 3.gif]] [[Image:PWM Theorie 4.gif]]&lt;br /&gt;
&lt;br /&gt;
=== Vergleichswert-Überprüfung (Compare Match) ===&lt;br /&gt;
&lt;br /&gt;
Hier wird in ein spezielles Vergleichswertregister (&#039;&#039;&#039;OCR1H&#039;&#039;&#039;/&#039;&#039;&#039;OCR1L&#039;&#039;&#039;) ein Wert eingeschrieben, welcher ständig mit dem aktuellen Zählerwert verglichen wird.&lt;br /&gt;
Erreicht der Zähler den in diesem Register eingetragenen Wert, so kann ein Signal (0 oder 1) am Pin &#039;&#039;&#039;OC1&#039;&#039;&#039; erzeugt und/oder ein Interrupt ausgelöst werden.&lt;br /&gt;
&lt;br /&gt;
Zu erwähnen ist in dem Zusammenhang, dass das zur Compare-Einheit gehörende Interrupt-Flag erst beim auf die Übereinstimmung der Werte folgenden Timertakt gesetzt wird. Das ist v.a. deshalb wichtig, da es sonst bei OCRnx = 0 einen undefinierten Zustand gäbe.&lt;br /&gt;
&lt;br /&gt;
Möchte man ein Compare-Ereignis 100 Takte nach dem Timerüberlauf auslösen, dann muss in das betreffende Compare-Register eine 99 geschrieben werden.&lt;br /&gt;
&lt;br /&gt;
=== CTC-Betriebsart (Clear Timer on Compare Match) ===&lt;br /&gt;
&lt;br /&gt;
Das sogenannte &#039;&#039;&#039;Compare Match-Ereignis&#039;&#039;&#039; kann auch dazu verwendet werden, um den Timer automatisch zurückzusetzen (d.h. das TCNT-Register wird zu Null gesetzt). Diese Betriebsart heißt &amp;quot;Clear Timer on Compare Match&amp;quot;, also auf deutsch &amp;quot;Lösche Timer bei Vergleichsübereinstimmung&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
Mit dieser Funktionalität ist es möglich, sehr präzise Taktsignale zu erzeugen, ohne dabei programmtechnisch eingreifen zu müssen. &#039;&#039;&#039;Diese Funktion ersetzt das bei anderen Controllern und Timern ohne Compare-Einheit erforderliche Timer Reload&#039;&#039;&#039; (also das Nachladen des Zählregisters mit &amp;quot;Überlaufwert minus gewünschte Taktzahl bis zum Überlauf&amp;quot;, v.a. verbreitet bei 8051er-µCs).&lt;br /&gt;
&lt;br /&gt;
Zur Erzeugung eines Taktes per Hardware muss lediglich eine der CTC-Betriebsarten ausgewählt werden und einer der OCnx-Pins so gesetzt werden, dass er bei Auftreten des Compare Match getoggelt wird (über die COM-Bits).&lt;br /&gt;
&lt;br /&gt;
Die Frequenz des Taktes am entsprechenden Ausgang ist dann:&lt;br /&gt;
&amp;lt;math&amp;gt;f_\text{OC} = \frac{f_\text{CPU}}{\text{Prescaler} \cdot \left( \text{OCRnx} + 1 \right)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Umgeformt gilt für OCRnx:&lt;br /&gt;
&amp;lt;math&amp;gt;\text{OCRnx} = \frac{f_\text{CPU}}{\text{Prescaler} \cdot f_\text{OC}} - 1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Betriebsart macht das Timer-Nachladen, das bei AVRs, die ja im Unterschied zu 8051-Derivaten keine Auto-Reload-Funktion haben, immer mit Ungenauigkeiten und programmtechnischen Klimmzügen verbunden ist, überflüssig. Ist das OCRnx einmal gesetzt, dann wird das Signal am Ausgang kontinuierlich ausgegeben, ohne dass die Anwendersoftware eingreifen muss (es sei denn, die Frequenz soll geändert werden).&lt;br /&gt;
&lt;br /&gt;
Beim ATmega8 hat der 8-Bit-Timer 0 keine Compare-Einheit, so dass dort CTC und auch sonstige automatische Vergleichsoperationen nicht möglich sind. Bei Timer 1 und Timer 2 ist das jedoch möglich. Bei den neueren AVRs besitzen i.d.R. &#039;&#039;alle&#039;&#039; Timer eine oder mehrere Compare-Einheiten, so dass dort eine größere Flexibilität gegeben ist.&lt;br /&gt;
&lt;br /&gt;
Im Unterschied zu den PWM-Betriebsarten wird die Registeraktualisierung bei CTC nicht automatisch synchronisiert. Schreibt man einen neuen Compare-Wert, dann wird dieser sofort übernommen, was zu Fehlfunktionen führen kann, wenn der neue Compare-Wert höher ist, als der aktuelle Stand von TCNTnx. In den PWM-Betriebsarten wird hingegen der TOP-Wert synchron bei Erreichen von TOP oder BOTTOM aktualisiert.&lt;br /&gt;
&lt;br /&gt;
=== Einfangen eines Eingangssignals (Input Capturing) ===&lt;br /&gt;
&lt;br /&gt;
Bei dieser Betriebsart wird an den Input Capturing Pin (ICP) des Controllers eine Signalquelle angeschlossen.&lt;br /&gt;
Nun kann je nach Konfiguration entweder ein Signalwechsel von 0 nach 1 (steigende Flanke) oder von 1 nach 0 (fallende Flanke) erkannt werden und der zu diesem Zeitpunkt aktuelle Zählerstand in ein spezielles Register abgelegt werden. Gleichzeitig kann auch ein entsprechender Interrupt ausgelöst werden.&lt;br /&gt;
Wenn die Signalquelle ein starkes Rauschen beinhaltet, kann die Rauschunterdrückung eingeschaltet werden. Dann wird beim Erkennen der konfigurierten Flanke über 4 Taktzyklen das Signal überwacht und nur dann, wenn alle 4 Messungen gleich sind, wird die entsprechende Aktion ausgelöst.&lt;br /&gt;
&lt;br /&gt;
In Verbindung mit dem eingebauten Analogvergleicher, einem externen Operationsverstärker (als Integrator beschaltet) und einem externen Analogsignalschalter lässt sich ein präziser [[ADC|A/D-Wandler]] nach dem Zweiflankenverfahren, ggf. mit automatischer Nullpunktkorrektur aufbauen.&lt;br /&gt;
&lt;br /&gt;
== Timer2 im Asynchron Mode ==&lt;br /&gt;
&lt;br /&gt;
Bei den (meisten) Atmegas lässt sich der Timer2 asynchron betreiben. Das bedeutet, daß der Timer unabhängig vom CPU-Takt mit einer eigenen Taktquelle betrieben werden kann. &lt;br /&gt;
In Verbindung mit einem 32,768KHz-Quarz, auch Uhrenquarz genannt, lässt sich so auf einfache Weise eine RTC (Real Time Clock) integrieren, die eine externe RTC überflüssig macht. &lt;br /&gt;
&lt;br /&gt;
Beim ATMega48...328 wird, wie beim ATMega8, der Uhrenquarz alternativ zum &amp;quot;normalen&amp;quot; Quarz an XTAL1 und XTAL2 angeschlossen. &lt;br /&gt;
Diese Controller müssen dann mit dem internen RC-Oszillator als CPU-Takt betrieben werden. ATMEGA644 &amp;amp; Co. haben einen&lt;br /&gt;
separaten Anschluss für den Uhrenquarz.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Für den Anschluss des Uhrenquarzes müssen keine Fuses verändert werden!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* uC: ATMega48PA */&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;
//Variablen für die Zeit&lt;br /&gt;
volatile unsigned char sekunde;&lt;br /&gt;
volatile unsigned char minute;&lt;br /&gt;
volatile unsigned char stunde;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  // Timer 2 konfigurieren&lt;br /&gt;
  GTCCR |= (1 &amp;lt;&amp;lt; TSM) | (1 &amp;lt;&amp;lt; PSRASY);  //Timer anhalten, Prescaler Reset&lt;br /&gt;
  ASSR |= (1 &amp;lt;&amp;lt; AS2);                   //Asynchron Mode einschalten&lt;br /&gt;
  TCCR2A = (1 &amp;lt;&amp;lt; WGM21);                //CTC Modus&lt;br /&gt;
  TCCR2B |= (1 &amp;lt;&amp;lt; CS22) | (1 &amp;lt;&amp;lt; CS21);  //Prescaler 256&lt;br /&gt;
  // 32768 / 256 / 1 = 128                Intervall = 1s&lt;br /&gt;
  OCR2A = 128 - 1;&lt;br /&gt;
  TIMSK2 |= (1&amp;lt;&amp;lt;OCIE2A);                //Enable Compare Interrupt&lt;br /&gt;
  GTCCR &amp;amp;= ~(1 &amp;lt;&amp;lt; TSM);                 //Timer starten&lt;br /&gt;
  sei();                                //Enable global Interrupts&lt;br /&gt;
&lt;br /&gt;
  while(1)&lt;br /&gt;
  {&lt;br /&gt;
    /*Hier kann die aktuelle Zeit&lt;br /&gt;
      ausgeben werden*/&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
Der Compare Interrupt Handler &lt;br /&gt;
wird aufgerufen, wenn &lt;br /&gt;
TCNT2 = OCR2A = 128-1 &lt;br /&gt;
ist (128 Schritte), d.h. genau alle 1s&lt;br /&gt;
*/&lt;br /&gt;
ISR (TIMER2_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
    TCCR2B = TCCR2B;              //Wird weiter unten im Text erklärt!&lt;br /&gt;
    sekunde++;&lt;br /&gt;
    if(sekunde == 60)&lt;br /&gt;
    {&lt;br /&gt;
      minute++;&lt;br /&gt;
      sekunde = 0;&lt;br /&gt;
    }&lt;br /&gt;
    if(minute == 60)&lt;br /&gt;
    {&lt;br /&gt;
      stunde++;&lt;br /&gt;
      minute = 0;&lt;br /&gt;
    }&lt;br /&gt;
    if(stunde == 24)&lt;br /&gt;
    {&lt;br /&gt;
      stunde = 0;&lt;br /&gt;
    }&lt;br /&gt;
    // Wird weiter unten im Text erklärt!&lt;br /&gt;
    while(ASSR &amp;amp; ((1&amp;lt;&amp;lt;TCN2UB) | (1&amp;lt;&amp;lt;OCR2AUB) | (1&amp;lt;&amp;lt;OCR2BUB) |&lt;br /&gt;
                  (1&amp;lt;&amp;lt;TCR2AUB) | (1&amp;lt;&amp;lt;TCR2BUB)));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Timer-Interrupt wird jetzt im Sekundentakt aufgerufen. Dieser Aufruf geschieht jedoch nicht nur im normalen Betrieb des Controllers, sondern auch im Sleep-Mode!&lt;br /&gt;
Hierzu gibt es extra den Sleep-Mode Power-save. In diesem Mode wird praktisch der gesamte Controller bis auf den Timer2 mit seinem Quarz abgeschaltet.&lt;br /&gt;
&lt;br /&gt;
Das Aufwecken geschieht automatisch mit jedem Interrupt des Timers. Der Stromverbrauch sinkt dabei auf bis zu 0,75µA. &lt;br /&gt;
&lt;br /&gt;
Das &amp;quot;Schlafenlegen&amp;quot; muß dabei in der Mainloop erfolgen, damit der Controller nach der Abarbeitung des Interrupts wieder in den Sleep-Mode geschickt wird.&lt;br /&gt;
Dies geschieht nicht automatisch!&lt;br /&gt;
&lt;br /&gt;
Die üblichen 32-kHz-Quarze haben eine vergleichsweise lange Anschwingdauer.  Je nach Quarz sind Zeiten von mehreren 100 ms bis zu einer Sekunde keine Seltenheit.  Entsprechend dauert es nach dem ersten Einschalten des AS2-Bits einige Zeit, bis der Timer losläuft. U.a. aus diesem Grund wird in dem obigen Initialisierungsbeispiel der Timer mit PSRASY im GTCCR angehalten. Nach Löschen des TSM im selben Register&lt;br /&gt;
wird das PSRASY mit dem nächsten Takt des Timers selbständig gelöscht und der Timer gestartet. Wobei ich es grundsätzlich als sinnvoll ansehe, einen Timer erst nach der Konfiguration definiert loslaufen zu lassen.&lt;br /&gt;
&lt;br /&gt;
=== Wenn er die Minute in 20s schafft ===&lt;br /&gt;
&lt;br /&gt;
Alle zum Timer2 gehörigen Register werden weiterhin synchron beschrieben. &lt;br /&gt;
Allerdings nicht synchron zum CPU-Takt von üblicherweise 1MHz oder 8MHz, sondern synchron zum Takt des Timer2. Diese Taktung des Timers erfolgt jetzt mit 32,768KHz. &lt;br /&gt;
&lt;br /&gt;
Wenn TCNT2 == OCR2A, wird das OCF2A-Flag im TIFR2-Register gesetzt und der Sleep-Mode verlassen.&lt;br /&gt;
&lt;br /&gt;
Der Controller stellt jetzt fest, daß das OCF2A-Flag gesetzt ist und springt auf den COMP2A-Interrupt-Vektor und dann weiter in die ISR. Dabei werden die Rücksprungadresse&lt;br /&gt;
auf den Stack gelegt und das OCF2A-Flag gelöscht. &lt;br /&gt;
Das heisst, es wird genau genommen nicht gelöscht, sondern es wird ein internes Bit gesetzt, daß mit dem nächsten Takt in das TIFR2- Register geschrieben wird. Der nächste Takt &lt;br /&gt;
ist aber der nächste Takt des 32,768KHz Timers. Erst nach diesem Takt wird das Flag tatsächlich gelöscht!&lt;br /&gt;
&lt;br /&gt;
Läuft der Controller mit 8MHz, dauert es vom Auslösen des Interrupt und dem Vorbereiten des Löschens 8MHz / 32768Hz = 244 Takte, abzüglich der paar CPU-Takte, die bis jetzt vergangen sind,&lt;br /&gt;
bis das Flag gelöscht ist. Schafft der Controller es aber, die ISR in dieser Zeit abzuarbeiten, kehrt er zurück, stellt fest, daß das OCF2A-Flag immer noch gesetzt ist und springt wieder in die ISR, &lt;br /&gt;
um dieselbe Sekunde nochmal zu zählen. Wenn er das auch noch ein drittes Mal schafft, dauert die Minute nur noch 20 Sekunden. &lt;br /&gt;
&lt;br /&gt;
Beim Betrieb mit 1MHz sind es nur 31 Takte, die werden fast schon durch den Interrupt als solches erreicht. Daher läuft die Uhr meistens mit 1MHz richtig und mit 8MHz zu schnell.&lt;br /&gt;
&lt;br /&gt;
Um jetzt kein Delay in die ISR einzufügen, kann man einen Schreibvorgang auf ein Timer-Register ausführen und im ASSR-Register abfragen, ob dieser Schreibvorgang erfolgt ist. Wenn dies der &lt;br /&gt;
Fall ist, sind auch alle anderen Timer-Register geschrieben. Vor allen Dingen ist das OCF2A-Flag gelöscht.&lt;br /&gt;
&lt;br /&gt;
Dafür dienen diese beiden Zeilen im Beispiel oben:&lt;br /&gt;
    TCCR2B = TCCR2B;              //Dummy Write&lt;br /&gt;
    // Warten bis Write erfolgt ist&lt;br /&gt;
    while(ASSR &amp;amp; ((1&amp;lt;&amp;lt;TCN2UB) | (1&amp;lt;&amp;lt;OCR2AUB) | (1&amp;lt;&amp;lt;OCR2BUB) |&lt;br /&gt;
                  (1&amp;lt;&amp;lt;TCR2AUB) | (1&amp;lt;&amp;lt;TCR2BUB)));&lt;br /&gt;
&lt;br /&gt;
=== Kalibrieren des internen Oszillators mit Timer2 als Zeitbasis ===&lt;br /&gt;
&lt;br /&gt;
Bei den Atmega48..328 sowie Atmega8, auf den hier nicht weiter eingegangen wird, wird der Uhrenquarz an Stelle des &amp;quot;normalen&amp;quot; Quarzes eingesetzt. &lt;br /&gt;
&lt;br /&gt;
Für Datenübertragung über UART steht daher nur der Takt des internen Oszillators zur Verfügung. Eine Übertragung bis zu 9600 Bit/s ist mit den Atmega48..328 weitestgehend möglich. Dies ist jedoch nicht ideal und immer mit einem Risiko behaftet. Eine einfache Möglichkeit, Datenübertragung sicher und auch erheblich schneller zu machen, ist die Kalibrierung des internen Oszillators auf eine Baudratenfrequenz. Damit sind auch 115K2 Bit/s problemlos möglich.&lt;br /&gt;
&lt;br /&gt;
Der interne Oszillator der Atmega48..328 wird vom Hersteller bei Vcc = 3V und einer Temperatur von 25°C auf 8MHz kalibriert. Dazu wird ein entsprechender Wert in das OSCCAL-Register des Controllers geschrieben.&lt;br /&gt;
Dieser Wert lässt sich u.a. mit dem AVRISPMKII auslesen. Die im Datenblatt angegebene Toleranz (+-10%) bezieht sich auf den gesamten zulässigen Temperatur- und Spannungsbereich des Controllers. Bei 3V/25° ist die Abweichung vom Sollwert &amp;lt;1%. Dieser Wert wird auch mit der hier vorgestellten Kalibrierung erreicht.&lt;br /&gt;
&lt;br /&gt;
Zur Kalibrierung gibt der Timer2 ein Zeitintervall vor, in dem der Timer1 zählt. Bei richtiger Frequenz muß der Wert des TCNT1 annähernd dem errechneten Sollwert entsprechen. Ist der Wert grösser, läuft der Timer zu schnell, d.h. die Frequenz des Oszillators ist zu hoch, ist der Wert kleiner, ist die Oszillatorfrequenz zu niedrig. Entsprechend wird der Inhalt des OSCCAL-Registers dann inkrementiert oder dekrementiert.&lt;br /&gt;
&lt;br /&gt;
Im Projekt ist die Sollfrequenz als F_CPU einzustellen. Bei gesetzter CKDIV8-Fuse sind dies 921600Hz, ohne CKDIV8 7372800Hz. In beiden Fällen wird der Oszillator tatsächlich auf 7,3728MHz kalibriert, da die niedrige Frequenz über einen Teiler generiert wird. Gemäss Datenblatt wird als Frequenzbereich für die Kalibrierung 7,3 - 8,1 Mhz empfohlen. Laut Atmel ist nur in diesem Bereich der Schreibzugriff auf das Flash und das EEPROM sicher. Das ist insbesondere dann von Bedeutung, wenn die Kalibrierung in einem und für einen Bootloader erfolgt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* uC: ATMega48PA */&lt;br /&gt;
&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
  #error F_CPU not defined.&lt;br /&gt;
#endif&lt;br /&gt;
#define REF_CLOCK 32768L		&lt;br /&gt;
#if F_CPU == 921600&lt;br /&gt;
  #define COUNT_PRE (1 &amp;lt;&amp;lt; CS10)&lt;br /&gt;
  #define COUNT_PREDIV 1&lt;br /&gt;
#else&lt;br /&gt;
  #if F_CPU == 7372800&lt;br /&gt;
    #define COUNT_PRE (1 &amp;lt;&amp;lt; CS11)&lt;br /&gt;
    #define COUNT_PREDIV 8&lt;br /&gt;
  #else&lt;br /&gt;
    #error &amp;quot;No Baudrate Frequency defined&amp;quot;&lt;br /&gt;
  #endif&lt;br /&gt;
#endif &lt;br /&gt;
#define REF_VAL F_CPU / (REF_CLOCK / 256) / COUNT_PREDIV&lt;br /&gt;
#define REF_MIN REF_VAL - 50&lt;br /&gt;
#define REF_MAX REF_VAL + 10&lt;br /&gt;
&lt;br /&gt;
GPIOR0 = OSCCAL;&lt;br /&gt;
unsigned char nTimeOut = 1;&lt;br /&gt;
//Timer anhalten, Prescaler Reset&lt;br /&gt;
GTCCR |= (1 &amp;lt;&amp;lt; TSM) | (1 &amp;lt;&amp;lt; PSRASY);&lt;br /&gt;
ASSR = (1 &amp;lt;&amp;lt; AS2);&lt;br /&gt;
TCCR2B = (1 &amp;lt;&amp;lt; CS20);&lt;br /&gt;
GTCCR &amp;amp;= ~(1 &amp;lt;&amp;lt; TSM);//Timer starten&lt;br /&gt;
while(!(TIFR2 &amp;amp; (1 &amp;lt;&amp;lt; TOV2)));&lt;br /&gt;
//Clear Interrupt Flags&lt;br /&gt;
TIFR2 = (1 &amp;lt;&amp;lt; OCF2B) | (1 &amp;lt;&amp;lt; OCF2A) | (1 &amp;lt;&amp;lt; TOV2);&lt;br /&gt;
TCCR1B = COUNT_PRE;&lt;br /&gt;
&lt;br /&gt;
while(nTimeOut)&lt;br /&gt;
{&lt;br /&gt;
  if(TIFR2 &amp;amp; (1 &amp;lt;&amp;lt; TOV2))//Poll Timer2&lt;br /&gt;
  {&lt;br /&gt;
    //Stop Timer1, Prescaler Reset&lt;br /&gt;
    GTCCR = (1 &amp;lt;&amp;lt; TSM) | (1 &amp;lt;&amp;lt; PSRSYNC);//*&lt;br /&gt;
    TIFR2 = (1 &amp;lt;&amp;lt; OCF2B) | (1 &amp;lt;&amp;lt; OCF2A) | (1 &amp;lt;&amp;lt; TOV2);&lt;br /&gt;
    unsigned int nTcnt1 = TCNT1;&lt;br /&gt;
&lt;br /&gt;
    if(!(nTimeOut &amp;amp; (1 &amp;lt;&amp;lt; 0)))&lt;br /&gt;
    {&lt;br /&gt;
      if((nTcnt1 &amp;gt;= REF_MIN) &amp;amp;&amp;amp; (nTcnt1 &amp;lt;= REF_MAX)) break;&lt;br /&gt;
      else&lt;br /&gt;
      {&lt;br /&gt;
        if(nTcnt1 &amp;lt; REF_VAL) OSCCAL++;&lt;br /&gt;
        if(nTcnt1 &amp;gt; REF_VAL) OSCCAL--;&lt;br /&gt;
      }&lt;br /&gt;
      TCNT1 = 0;&lt;br /&gt;
    }&lt;br /&gt;
    else GTCCR = 0;//Start Timer1 *&lt;br /&gt;
    nTimeOut++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
if(!nTimeOut)&lt;br /&gt;
{&lt;br /&gt;
  //Error, Kalibrierung abgebrochen&lt;br /&gt;
}&lt;br /&gt;
//Register wiederherstellen (Reset-Zustand)&lt;br /&gt;
ASSR = 0;&lt;br /&gt;
TCCR2B = 0;&lt;br /&gt;
TCCR1B = 0;			&lt;br /&gt;
TCNT2 = 0;&lt;br /&gt;
OSCCAL = GPIOR0;    //ggf. zurück setzen auf 8Mhz&lt;br /&gt;
GPIOR0 = 0;&lt;br /&gt;
// Clear Interrupt Flags&lt;br /&gt;
TIFR1 = (1 &amp;lt;&amp;lt; ICF1) | (1 &amp;lt;&amp;lt; OCF1B) | (1 &amp;lt;&amp;lt; OCF1A) | (1 &amp;lt;&amp;lt; TOV1);&lt;br /&gt;
//Start Timer1&lt;br /&gt;
GTCCR = 0;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Messung erfolgt bei beiden Frequenzen mit einem Takt von 1MHz bis 921,6KHz für Timer1. Entweder durch CLKDIV8 (F_Timer = F_CPU) oder durch Prescaler = 8 des Timers (F_Timer = F_CPU/8). Dadurch ergeben sich bei der Kalibrierung die selben Parameter für beide Frequenzen.&lt;br /&gt;
&lt;br /&gt;
Wird F_CPU auf 7,3728Mhz kalibriert, wird Timer1 mit Prescaler = 8 getaktet. Dieser muß vor der Messung zurück gesetzt werden, da der 1. Timertakt sonst zufällig nach 1 bis 8 CPU-Takten auftritt. Für die Genauigkeit der Messung muß dieser aber immer nach 8 Takten auftreten. Ansonsten kann das soweit führen, daß der Sollwert gar nicht erreicht wird und die Kalibrierung mit Timeout abgebrochen wird.&lt;br /&gt;
&lt;br /&gt;
Die Kalibrierung war erfolgreich, wenn nTimeOut &amp;gt; 0 ist.&lt;br /&gt;
 &lt;br /&gt;
Das Wiederherstellen der verwendeten Register in den Reset-Zustand ist nur bei einem Bootloader wichtig. In einer normalen Anwendung ist es Sache des Programmierers, die veränderten Register entsprechend zu berücksichtigen und beispielsweise die Initialisierung der beiden Timer für eine andere Verwendung im Programm mit fester Zuweisung (=) statt mit Veroderung (|=) vorzunehmen. GTCCR ist in jedem Fall auf 0 zu setzen, da sowohl Timer0 als auch Timer1 beim Verlassen der Kalibrierung &amp;quot;stehen&amp;quot;. Auch die Interrupt-Flags von Timer1 sollten gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
Die Kalibrierung verwendet keine Interrupts sondern pollt nur das TOV2-Flag des Timer2. Die Flags des Timer2 werden in der Kalibrierungsschleife direkt nach der Abfrage gelöscht.&lt;br /&gt;
&lt;br /&gt;
Sollte die Kalibrierung in einem Bootlaoder erfolgen, kann man den ermittelten OSCCAL-Wert, sofern der ursprüngliche Wert (1 oder 8 MHz)wiederhergestellt wurde, in einem der GPIORx-Register an die Anwendung übergeben. Dann braucht diese eine evtl. notwendige Kalibrierung nur durchführen, wenn sie ohne Bootloader gestartet wurde. Ansonsten kann der Wert aus GPIORx ins OSCCAL geschrieben werden. Die GPIORx-Register werden (bislang) vom GCC nicht angetastet.&lt;br /&gt;
&lt;br /&gt;
== Gemeinsame Register ==&lt;br /&gt;
&lt;br /&gt;
Verschiedene Register beinhalten Zustände und Einstellungen, welche sowohl&lt;br /&gt;
für den 8-Bit, als auch für den 16-Bit Timer/Counter in ein und demselben&lt;br /&gt;
Register zu finden sind.&lt;br /&gt;
&lt;br /&gt;
Dies gilt für viele ATTiny und die älteren ATMega, wie z.B. Atmega8.&lt;br /&gt;
Die neueren ATMegas und einige ATTiny haben bei einigen mit Ausnahme des GIMSK sowie dem korrespondierenden GIFR exklusive Register für jeden Timer.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|- &lt;br /&gt;
| width=&amp;quot;100&amp;quot; | &#039;&#039;&#039;TIMSK&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;T&#039;&#039;&#039;imer/Counter &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;M&#039;&#039;&#039;a&#039;&#039;&#039;sk&#039;&#039;&#039;&lt;br /&gt;
Register&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;TOIE1&#039;&#039;&#039;|| &#039;&#039;&#039;OCIE1A&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;TICIE&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;TOIE0&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W || R/W || R || R || R/W || R || R/W || R&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0|| 0|| 0|| 0|| 0|| 0|| 0|| 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TOIE1&#039;&#039;&#039; (&#039;&#039;&#039;T&#039;&#039;&#039;imer/Counter &#039;&#039;&#039;O&#039;&#039;&#039;verflow &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;E&#039;&#039;&#039;nable Timer/Counter &#039;&#039;&#039;1&#039;&#039;&#039;)&lt;br /&gt;
:Wenn dieses Bit gesetzt ist, wird bei einem Überlauf des Datenregisters des Timer/Counter 1 ein Timer Overflow 1 Interrupt ausgelöst. Das Global Enable Interrupt Flag muss selbstverständlich auch gesetzt sein.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;OCIE1A&#039;&#039;&#039; (&#039;&#039;&#039;O&#039;&#039;&#039;utput &#039;&#039;&#039;C&#039;&#039;&#039;ompare Match &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;E&#039;&#039;&#039;nable Timer/Counter &#039;&#039;&#039;1&#039;&#039;&#039;)&lt;br /&gt;
:Beim Timer/Counter 1 kann zusätzlich zum Überlauf ein Vergleichswert definiert werden.&lt;br /&gt;
&lt;br /&gt;
:Wenn dieses Bit gesetzt ist, wird beim Erreichen des Vergleichswertes ein Compare Match Interrupt ausgelöst. Das Global Enable Interrupt Flag muss selbstverständlich auch gesetzt sein.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TICIE&#039;&#039;&#039; (&#039;&#039;&#039;T&#039;&#039;&#039;imer/Counter &#039;&#039;&#039;I&#039;&#039;&#039;nput &#039;&#039;&#039;C&#039;&#039;&#039;apture &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;E&#039;&#039;&#039;nable)&lt;br /&gt;
:Wenn dieses Bit gesetzt ist, wird ein Capture Event Interrupt ausgelöst, wenn ein entsprechendes Signalereignis am Pin PD6(ICP) auftritt. Das Global Enable Interrupt Flag muss selbstverständlich auch gesetzt sein, wenn auch ein entsprechender Interrupt ausgelöst werden soll.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TOIE0&#039;&#039;&#039; (&#039;&#039;&#039;T&#039;&#039;&#039;imer/Counter &#039;&#039;&#039;O&#039;&#039;&#039;verflow &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;E&#039;&#039;&#039;nable Timer/Counter &#039;&#039;&#039;0&#039;&#039;&#039;)&lt;br /&gt;
:Wenn dieses Bit gesetzt ist, wird bei einem Überlauf des Datenregisters des Timer/Counter 0 ein Timer Overflow 0 Interrupt ausgelöst. Das Global Enable Interrupt Flag muss selbstverständlich auch gesetzt sein.&lt;br /&gt;
&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;TIFR&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;T&#039;&#039;&#039;imer/Counter &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;F&#039;&#039;&#039;lag &#039;&#039;&#039;R&#039;&#039;&#039;egister&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;TOV1&#039;&#039;&#039;|| &#039;&#039;&#039;OCF1A&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;ICF1&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;TOV0&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W|| R/W|| R|| R|| R/W|| R|| R/W|| R&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0|| 0|| 0|| 0|| 0|| 0|| 0|| 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TOV1&#039;&#039;&#039; (&#039;&#039;&#039;T&#039;&#039;&#039;imer/Counter &#039;&#039;&#039;O&#039;&#039;&#039;verflow Flag Timer/Counter &#039;&#039;&#039;1&#039;&#039;&#039;)&lt;br /&gt;
:Dieses Bit wird vom Controller gesetzt, wenn beim Timer 1 ein Überlauf des Datenregisters stattfindet.&lt;br /&gt;
&lt;br /&gt;
:In der PWM-Betriebsart wird das Bit gesetzt, wenn die Zählrichtung von auf- zu abwärts und umgekehrt geändert wird (Zählerwert = 0).&lt;br /&gt;
&lt;br /&gt;
:Das Flag wird automatisch gelöscht, wenn der zugehörige Interrupt-Vektor aufgerufen wird. Es kann jedoch auch gelöscht werden, indem eine logische 1 (!) in das entsprechende Bit geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;OCF1A&#039;&#039;&#039; (&#039;&#039;&#039;O&#039;&#039;&#039;utput &#039;&#039;&#039;C&#039;&#039;&#039;ompare &#039;&#039;&#039;F&#039;&#039;&#039;lag Timer/Counter &#039;&#039;&#039;1&#039;&#039;&#039;)&lt;br /&gt;
:Dieses Bit wird gesetzt, wenn der aktuelle Wert des Datenregisters von Timer/Counter 1 mit demjenigen im Vergleichsregister &#039;&#039;&#039;OCR1&#039;&#039;&#039; übereinstimmt.&lt;br /&gt;
&lt;br /&gt;
:Das Flag wird automatisch gelöscht, wenn der zugehörige Interrupt-Vektor aufgerufen wird. Es kann jedoch auch gelöscht werden, indem eine logische 1 (!) in das entsprechende Bit geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ICF1&#039;&#039;&#039; (&#039;&#039;&#039;I&#039;&#039;&#039;nput &#039;&#039;&#039;C&#039;&#039;&#039;apture &#039;&#039;&#039;F&#039;&#039;&#039;lag Timer/Counter &#039;&#039;&#039;1&#039;&#039;&#039;)&lt;br /&gt;
:Dieses Bit wird gesetzt, wenn ein Capture-Ereignis aufgetreten ist, welches anzeigt, dass der Wert des Datenregisters des  Timer/Counter 1 in das Input Capture Register ICR1 übertragen wurde.&lt;br /&gt;
&lt;br /&gt;
:Das Flag wird automatisch gelöscht, wenn der zugehörige Interrupt-Vektor aufgerufen wird. Es kann jedoch auch gelöscht werden, indem eine logische 1 (!) in das entsprechende Bit geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TOV0&#039;&#039;&#039; (&#039;&#039;&#039;T&#039;&#039;&#039;imer/Counter &#039;&#039;&#039;O&#039;&#039;&#039;verflow Flag Timer/Counter &#039;&#039;&#039;0&#039;&#039;&#039;)&lt;br /&gt;
:Dieses Bit wird vom Controller gesetzt, wenn beim Timer 0 ein Überlauf des Datenregisters stattfindet.&lt;br /&gt;
&lt;br /&gt;
:Das Flag wird automatisch gelöscht, wenn der zugehörige Interrupt-Vektor aufgerufen wird. Es kann jedoch auch gelöscht werden, indem eine logische 1 (!) in das entsprechende Bit geschrieben wird.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:avr-gcc Tutorial]]&lt;br /&gt;
[[Kategorie:Timer und Uhren]]&lt;/div&gt;</summary>
		<author><name>8023</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=K%C3%BChlk%C3%B6rper&amp;diff=92475</id>
		<title>Kühlkörper</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=K%C3%BChlk%C3%B6rper&amp;diff=92475"/>
		<updated>2016-03-18T01:07:40Z</updated>

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

		<summary type="html">&lt;p&gt;8023: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein Labornetzgerät wird dazu verwendet, Schaltungen oder einzelne Bauteile mit einer definierten Spannung oder einem definierten Strom zu versorgen.&lt;br /&gt;
&lt;br /&gt;
== Funktionen ==&lt;br /&gt;
&lt;br /&gt;
Labornetzgeräte sind im Gegensatz zu einfachen Festspannungs-Netzteilen sehr flexibel einsetzbar und haben üblicherweise mindestens folgende Einstellmöglichkeiten und Funktionen:&lt;br /&gt;
&lt;br /&gt;
=== Einfache Labornetzteile ===&lt;br /&gt;
&lt;br /&gt;
Einfache Labornetzgeräte haben eine einstellbare Ausgangsspannung, die normalerweise von 0 bis zu einem bestimmten Maximalwert eingestellt werden kann. Zusätzlich bieten diese Geräte eine einstellbare Strombegrenzung, die auch von 0 aus bis zum Nennstrom des Geräts eingestellt werden kann.&lt;br /&gt;
&lt;br /&gt;
Labornetzgeräte haben außerdem noch eine Anzeige für Ausgangsspannung und Strom. Dafür sind entweder analoge oder digitale Instrumente eingebaut. Bei digitalen Anzeigen werden üblicherweise 3 Stellen angezeigt, die Genauigkeit der Anzeige liegt üblicherweise im Bereich 1%.&lt;br /&gt;
&lt;br /&gt;
Der Ausgang sollte kurzschlussfest sein, was allerdings nicht bei allen Labornetzgeräten der Fall ist. Manche Geräte sind nur kurzzeitig kurzschlussfest (für einige Sekunden), normalerweise sind Labornetzgeräte dauerhaft kurzschlussfest.&lt;br /&gt;
&lt;br /&gt;
=== Labornetzteile mit erweiterten Funktionen ===&lt;br /&gt;
&lt;br /&gt;
Die Labornetzgeräte der gehobenen Preisklasse haben zusätzlich zu den Grundfunktionen noch weitere Funktionen, wie z.B.:&lt;br /&gt;
&lt;br /&gt;
* Abschaltbarer Ausgang&lt;br /&gt;
* Getrennte Anzeige von Soll- und Ist-Werten&lt;br /&gt;
* Höhere Messgenauigkeit der Istwerte als bei einfachen Geräten&lt;br /&gt;
* Einstellbare Grenzwerte für Strom, Spannung, Leistung&lt;br /&gt;
* Alarm/Abschaltung bei Überschreitung von einstellbaren Schwellwerten&lt;br /&gt;
* Programmierbare Spannungs-/Stromverläufe&lt;br /&gt;
* Master-Slave-Funktion für Reihen-/Parallelschaltung von mehreren Geräten&lt;br /&gt;
* Analoge Schnittstelle für Soll- und Istwerte&lt;br /&gt;
* PC-Schnittstelle&lt;br /&gt;
&lt;br /&gt;
== Wichtige Eigenschaften ==&lt;br /&gt;
&lt;br /&gt;
=== Lineare Netzgeräte vs. Schaltnetzgeräte ===&lt;br /&gt;
&lt;br /&gt;
Es gibt bei Labornetzgeräten sowohl linear geregelte als auch Schaltnetzteile.&lt;br /&gt;
&lt;br /&gt;
Lineare Netzgeräte haben den Vorteil, dass die Regelung üblicherweise schneller und genauer ist. Die Ausgangskapazität ist bei linearen Netzgeräten relativ klein, dadurch kann die Strombegrenzung sehr schnell ansprechen.&lt;br /&gt;
&lt;br /&gt;
Schaltnetzgeräte haben dagegen einen besseren Wirkungsgrad, erzeugen also weniger Abwärme und sind kleiner und leichter als lineare Netzgeräte gleicher Leistung. Deshalb sind vor allem Labornetzgeräte mit hoher Leistung bevorzugt als Schaltnetzteil aufgebaut.&lt;br /&gt;
&lt;br /&gt;
Wenn bei Schaltnetzgeräten eine sehr kleine Ausgangs-Spannung eingestellt wird, wird diese oft nicht sauber ausgeregelt. Meistens brauchen solche Geräte eine bestimmte Mindestspannung am Ausgang.&lt;br /&gt;
&lt;br /&gt;
Weiterhin besteht bei Schaltnetzteilen die Gefahr, dass am Ausgang Störungen sichtbar sind, die durch die interne PWM erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Weiterhin gibt es auch Geräte, bei denen ein Schaltnetzteil und eine lineare Regelung kombiniert sind. Dadurch werden die Vorteile von beiden Verfahren kombiniert, es ergeben sich dadurch aber auch einige Probleme:&lt;br /&gt;
&lt;br /&gt;
* Bei schnellen Laständerungen kann es passieren, dass das Schaltnetzteil nicht schnell genug nachregelt. Dadurch ändert sich das Regelverhalten und die Ausgangsspannung bzw. Strom sind dann nicht mehr so stabil wie bei einem richtigen linear geregelten Netzgerät. &lt;br /&gt;
&lt;br /&gt;
* Bei schnellen periodischen Laständerungen kann es zusätzlich passieren, dass die Verlustleistung im Linearregler sehr viel höher wird als im Betrieb mit konstanter Ausgangsleistung. Da die lineare Endstufe meistens nicht dafür dimensioniert ist, kann es hier thermische Probleme geben.&lt;br /&gt;
&lt;br /&gt;
=== Verlustleistung und Kühlung === &lt;br /&gt;
&lt;br /&gt;
Das ist vor allem bei linear geregelten Geräten ein sehr wichtiges Kapitel, da eine gute Kühlung relativ viel Geld kostet und die Gerätehersteller hier gerne sparen. Folgende Punkte sollten hier beachtet werden:&lt;br /&gt;
&lt;br /&gt;
==== Passive Kühlung oder Kühlung mit Lüfter ====&lt;br /&gt;
Geräte mit passiver Kühlung erzeugen keine Geräusche, was ein großer Vorteil ist. Passive Kühlung ist aber nur bei Geräten mit relativ geringer Leistung üblich. Bei Lüfter-gekühlen Geräten sollte darauf geachtet werden, dass der Lüfter relativ ruhig läuft.&lt;br /&gt;
&lt;br /&gt;
==== Außenliegender Kühlkörper ====&lt;br /&gt;
Bei passiv gekühlten Geräten kann der Kühler ziemlich warm werden. Wenn der Kühler außen am Gehäuse montiert ist, besteht die Gefahr, dass man ihn versehentlich berührt und sich verbrennt oder dass wärmeempfindliche Gegenstände (z.B. kunststoff-isolierte Leitungen) bei Berührung beschädigt werden. Deshalb sollte man Geräte bevorzugen, bei denen der Kühler innerhalb des Gehäuses montiert ist.&lt;br /&gt;
&lt;br /&gt;
==== Lüftungsschlitze ====&lt;br /&gt;
Bei Geräten, die Lüftungsschlitze auf der Oberseite haben, besteht die Gefahr, dass Gegenstände reinfallen können, wodurch das Gerät beschädigt werden kann. Weiterhin kann es passieren, dass der Luftstrom durch die Schlitze behindert wird, wenn man etwas auf dem Gerät ablegt oder mehrere Geräte aufeinander stapelt.&lt;br /&gt;
Je nach dem, wo das Gerät aufgestellt werden soll, können deshalb seitliche Lüftungsschlitze vorteilhaft sein. Allerdings sind seitliche Lüftungsöffnungen meistens mit einem aktiven Lüfter kombiniert.&lt;br /&gt;
&lt;br /&gt;
==== Dimensionierung der Kühlkörper und Leistungstransistoren ====&lt;br /&gt;
Bei vielen billigen Netzgeräten ist die Kühlung zu knapp dimensioniert. Das kann man relativ einfach testen, indem man den Ausgangsspannung und Strom jeweils auf Maximalwerte einstellt und dann den Ausgang kurzschließt.&lt;br /&gt;
&lt;br /&gt;
In diesem Zustand sollte das Gerät längere Zeit (einige Stunden) betrieben werden, bis alles thermisch eingeschwungen ist. Dann muss bei allen Leistungsbauteilen die Temperatur gemessen werden, am einfachsten geht das mit einer Wärmebildkamera. Es sollten nach Möglichkeit keine Temperaturen oberhalb von 100°C auftreten. Wärme-empfindliche Bauteile (z.B. Elkos) sollten nicht wärmer als 70°C sein.&lt;br /&gt;
&lt;br /&gt;
Besonders kritisch sind hier:&lt;br /&gt;
* Netztrafo&lt;br /&gt;
* Gleichrichter&lt;br /&gt;
* Leistungstransistoren und Kühlkörper&lt;br /&gt;
&lt;br /&gt;
=== Stabilität und Genauigkeit ===&lt;br /&gt;
&lt;br /&gt;
Wichtige Eigenschaften bei Labornetzgeräten ist die Stabilität und die Genauigkeit.&lt;br /&gt;
&lt;br /&gt;
==== Stabilität ====&lt;br /&gt;
&lt;br /&gt;
Damit wird angegeben, wie konstant ein eingestellter Wert über einen längeren Zeitraum gehalten wird. Hier ist wichtig, dass das Gerät einen kleinen Temperaturkoeffizient hat, so dass die Ausgangsspannung auch bei Temperaturschwankungen möglichst stabil bleibt.&lt;br /&gt;
&lt;br /&gt;
==== Genauigkeit ====&lt;br /&gt;
&lt;br /&gt;
Hier muss unterschieden werden zwischen der Anzeigegenauigkeit und der Einstellgenauigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Genauigkeit der Anzeige gibt an, wie genau die angezeigte Ausgangsspannung oder Strom mit der tatsächlichen Spannung übereinstimmt (siehe dazu auch  Artikel [[Auflösung und Genauigkeit]]).&lt;br /&gt;
&lt;br /&gt;
Die Einstellgenauigkeit gibt an, wie genau ein bestimmter Sollwert eingestellt werden kann und wie gut die tatsächlichen Werte mit den Sollwerten übereinstimmen. Bei Geräten mit digitaler Sollwertvorgabe muss hier die kleinste Schrittweite beachtet werden.&lt;br /&gt;
&lt;br /&gt;
== Weitere Funktionen ==&lt;br /&gt;
&lt;br /&gt;
=== Schnittstelle ===&lt;br /&gt;
&lt;br /&gt;
Einige Labornetzgeräte bieten eine Schnittstelle zum PC, damit können sie als per Software steuerbares Netzgerät verwendet werden. Will man das Netzgerät per Mikrocontroller steuern, so sind Typen mit [[RS232]] Anschluß den Typen mit [[USB]] vorzuziehen.&lt;br /&gt;
&lt;br /&gt;
=== Beleuchtung ===&lt;br /&gt;
&lt;br /&gt;
Folgende Display-Arten sind bei Labornetzgeräten üblich:&lt;br /&gt;
* Analoginstrument (unbeleuchtet oder beleuchtet)&lt;br /&gt;
* LCD 7-Segment Anzeige (unbeleuchtet oder beleuchtet)&lt;br /&gt;
* LCD Punktmatrix-Anzeige (in der Regel beleuchtet)&lt;br /&gt;
* LED 7-Segment Anzeige (selbstleuchtend)&lt;br /&gt;
* OLED-Anzeigen (selbstleuchtend)&lt;br /&gt;
* VFD-Anzeigen (selbstleuchtend)&lt;br /&gt;
&lt;br /&gt;
Anzeigen mit Beleuchtung bzw. selbstleuchtende Anzeigen sind wesentlich besser ablesbar als unbeleuchtete LCD-Anzeigen. Da Labornetzgeräte immer am Netz betrieben werden, ist der Stromverbrauch der Beleuchtung nicht relevant.&lt;br /&gt;
&lt;br /&gt;
Unbeleuchtete LCD-Anzeigen sind bei schlechter Beleuchtung oder ungünstigem Blickwinkel manchmal schlecht ablesbar, bei 7-Segment LED-Anzeigen ist die Ablesbarkeit wesentlich besser. &lt;br /&gt;
&lt;br /&gt;
Mit 7-Segment Anzeigen lassen sich allerdings nur Ziffern und einige wenige Buchstaben darstellen. Für Geräte mit komplexen Einstellungen und Menu-Führung werden deshalb häufig Punkt-Matrix LCD-Anzeigen verwendet.&lt;br /&gt;
&lt;br /&gt;
Mit VFD-Anzeigen [http://de.wikipedia.org/wiki/Fluoreszenzanzeige], die ebenfalls sehr gut ablesbar sind, könnnen auch komplexe Menüs dargestellt werden. Diese haben einen sehr weiten Blickwinkel und sehr scharfe und klare Zeichen. Allerdings sind diese Anzeigen relativ teuer, weshalb sie vor allem in eher teueren Geräten eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
== Vergleichstabelle Labornetzgeräte ==&lt;br /&gt;
&lt;br /&gt;
In den folgende Tabellen werden wichtige technischen Daten einiger aktueller Labornetzgeräte zusammengestellt. Um die Übersichtlichkeit zu erhöhen, werden die Geräte eingeteilt in einfache Geräte und Geräte mit Zusatzfunktionen&lt;br /&gt;
&lt;br /&gt;
Die Einteilung geschieht aufgrund der Funktionen, die die Geräte bieten. Das ist also keine Aussage über die Qualität der Geräte.&lt;br /&gt;
&lt;br /&gt;
=== Einfache lineare Labornetzgeräte ===&lt;br /&gt;
&lt;br /&gt;
Hier werden Geräte aufgelistet, welche neben den Grundfunktionen (Strom- und Spannungseinstellung, Anzeige der Istwerte) keine weiteren Funktionen besitzen.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable sortable&amp;quot; id=&amp;quot;einfache&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Hersteller&lt;br /&gt;
!Bezeichnung&lt;br /&gt;
!Preis [EUR]&lt;br /&gt;
!Spannung [V]&lt;br /&gt;
!Strom [A]&lt;br /&gt;
!Kanäle&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3616A&lt;br /&gt;
|620&lt;br /&gt;
|35&lt;br /&gt;
|1.7&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HM8040-3(Benötigt HM8001)&lt;br /&gt;
|280&lt;br /&gt;
|20 + 20 + 5&lt;br /&gt;
|0.5 + 0.5 + 1&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|Peaktech&lt;br /&gt;
|6080&lt;br /&gt;
|50&lt;br /&gt;
|15&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|McVoice&lt;br /&gt;
|WNT0-15-2000&lt;br /&gt;
|38&lt;br /&gt;
|15&lt;br /&gt;
|2&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|Statron&lt;br /&gt;
|2223.1&lt;br /&gt;
|150&lt;br /&gt;
|30&lt;br /&gt;
|2.5&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2250.0&lt;br /&gt;
|225&lt;br /&gt;
|40&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2229.2&lt;br /&gt;
|260&lt;br /&gt;
|40 + 40&lt;br /&gt;
|2.5 + 2.5&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2229.5&lt;br /&gt;
|340&lt;br /&gt;
|32 + 32 + 5&lt;br /&gt;
|3 + 3 + 3&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2225.6&lt;br /&gt;
|310&lt;br /&gt;
|30 + 30&lt;br /&gt;
|5 + 5&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|PS-1302 D&lt;br /&gt;
|95&lt;br /&gt;
|30&lt;br /&gt;
|2&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VLP 1303pro&lt;br /&gt;
|180&lt;br /&gt;
|30 + 6&lt;br /&gt;
|3 + 2&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VSP 2403&lt;br /&gt;
|345&lt;br /&gt;
|40 + 40 + 6&lt;br /&gt;
|3 + 3 + 1.5&lt;br /&gt;
|3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Einfache Schaltnetzgeräte ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable sortable&amp;quot; id=&amp;quot;einfache&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Hersteller&lt;br /&gt;
!Bezeichnung&lt;br /&gt;
!Preis [EUR]&lt;br /&gt;
!Spannung [V]&lt;br /&gt;
!Strom [A]&lt;br /&gt;
!Kanäle&lt;br /&gt;
|-&lt;br /&gt;
|Delta Elektronika&lt;br /&gt;
|ES 030-5&lt;br /&gt;
|624&lt;br /&gt;
|30&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Quatpower&lt;br /&gt;
|LN-3003&lt;br /&gt;
|40&lt;br /&gt;
|30&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Netzgeräte mit Zusatzfunktionen ===&lt;br /&gt;
&lt;br /&gt;
Diese Geräte haben mindestens folgende Funktionen:&lt;br /&gt;
* abschaltbare Ausgänge&lt;br /&gt;
* Anzeige der Sollwerte für Strom und Spannung&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable sortable&amp;quot; id=&amp;quot;hochwertige&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Hersteller&lt;br /&gt;
!Bezeichnung&lt;br /&gt;
!Preis [EUR]&lt;br /&gt;
!Spannung [V]&lt;br /&gt;
!Strom [A]&lt;br /&gt;
!Kanäle&lt;br /&gt;
!linear/getaktet&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|U8001A&lt;br /&gt;
|290&lt;br /&gt;
|30&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3616A&lt;br /&gt;
|620&lt;br /&gt;
|35&lt;br /&gt;
|1.7&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3643A&lt;br /&gt;
|690&lt;br /&gt;
|35 / 60 (umschaltbar)&lt;br /&gt;
|1.4 / 0.8&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3632A&lt;br /&gt;
|990&lt;br /&gt;
|15 / 30 (umschaltbar)&lt;br /&gt;
|7 / 4&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|BK Precision&lt;br /&gt;
|BK 1786&lt;br /&gt;
|490&lt;br /&gt;
|32&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|BK Precision&lt;br /&gt;
|BK 1788&lt;br /&gt;
|615&lt;br /&gt;
|32&lt;br /&gt;
|6&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|BK Precision&lt;br /&gt;
|BK 9130&lt;br /&gt;
|685&lt;br /&gt;
|30 + 30 + 5&lt;br /&gt;
|3 + 3 + 3&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|PSI 6032-03&lt;br /&gt;
|425&lt;br /&gt;
|32&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 2042-06B&lt;br /&gt;
|235&lt;br /&gt;
|42&lt;br /&gt;
|6&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 2342-06B&lt;br /&gt;
|580&lt;br /&gt;
|42 + 42 + 6&lt;br /&gt;
|6 + 6 + 4&lt;br /&gt;
|3&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 3032-05B&lt;br /&gt;
|355&lt;br /&gt;
|32&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 8032-10 DT&lt;br /&gt;
|940&lt;br /&gt;
|32&lt;br /&gt;
|10&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|ELV&lt;br /&gt;
|PPS 5330&lt;br /&gt;
|120&lt;br /&gt;
|30&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|ELV&lt;br /&gt;
|SPS 5630&lt;br /&gt;
|200&lt;br /&gt;
|30&lt;br /&gt;
|6 (max. 75W)&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HM7042-5&lt;br /&gt;
|685&lt;br /&gt;
|32 + 32 + 5,5&lt;br /&gt;
|2 + 2 + 5&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HMP2020&lt;br /&gt;
|1190&lt;br /&gt;
|32 + 32&lt;br /&gt;
|10 + 5&lt;br /&gt;
|2&lt;br /&gt;
|getaktet + linear&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HMP2030&lt;br /&gt;
|1500&lt;br /&gt;
|32 + 32 + 32&lt;br /&gt;
|5 + 5 + 5&lt;br /&gt;
|3&lt;br /&gt;
|getaktet + linear&lt;br /&gt;
|-&lt;br /&gt;
|Rigol&lt;br /&gt;
|DP832 **)&lt;br /&gt;
|362&lt;br /&gt;
|30 + 30 + 5&lt;br /&gt;
|3 + 3 + 3&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VLP 1405pro&lt;br /&gt;
|1190&lt;br /&gt;
|40 + 6&lt;br /&gt;
|5 + 2&lt;br /&gt;
|2&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|PeakTech&lt;br /&gt;
|1885&lt;br /&gt;
|270&lt;br /&gt;
|40&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VLP 2403pro&lt;br /&gt;
|320&lt;br /&gt;
|40 + 40 + 6&lt;br /&gt;
|3 + 3 + 2&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VSP 2410&lt;br /&gt;
|470&lt;br /&gt;
|40 + 40 + 6&lt;br /&gt;
|10 + 10 + 1.5&lt;br /&gt;
|3&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|TTI&lt;br /&gt;
|EX355R&lt;br /&gt;
|330&lt;br /&gt;
|35&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|Mixed-mode (getaktet + linear)&lt;br /&gt;
|-&lt;br /&gt;
|TTI&lt;br /&gt;
|EX354RD&lt;br /&gt;
|480&lt;br /&gt;
|35 + 35&lt;br /&gt;
|4 + 4&lt;br /&gt;
|2&lt;br /&gt;
|Mixed-mode (getaktet + linear)&lt;br /&gt;
|-&lt;br /&gt;
|TTI&lt;br /&gt;
|EX354RT&lt;br /&gt;
|540&lt;br /&gt;
|35 + 35 + (1,5-5)&lt;br /&gt;
|4 + 4 + 5&lt;br /&gt;
|3&lt;br /&gt;
|Mixed-mode (getaktet + linear)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
 **) Das Rigol DP832(A) schaltet die Ausgänge nicht physisch/galvanisch ab. Die Power-MOSFETs der Ausgangsstufe werden lediglich auf Soll-NULL gesetzt. Dies kann bei Drift auch durchaus ungleich 0,00 Volt bedeuten!&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Spannungsversorgung_und_Energiequellen]]&lt;/div&gt;</summary>
		<author><name>8023</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Scheduler_mit_Erweiterung_zum_Mini-Betriebssystem&amp;diff=92423</id>
		<title>Scheduler mit Erweiterung zum Mini-Betriebssystem</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Scheduler_mit_Erweiterung_zum_Mini-Betriebssystem&amp;diff=92423"/>
		<updated>2016-03-17T05:49:28Z</updated>

		<summary type="html">&lt;p&gt;8023: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt; &amp;lt;u&amp;gt;&#039;&#039;&#039;Vorwort&#039;&#039;&#039;&amp;lt;/u&amp;gt;&amp;lt;/big&amp;gt;:&amp;lt;br /&amp;gt;&lt;br /&gt;
Dieser Artikel behandelt die Erstellung eines Schedulers, der zu einem Mini-OS erweitert wird. Ziel ist es, das Verständnis sowie die Funktion eines OS besser verstehen zu können. Wie so manch ein anderer habe auch ich mich gefragt, wie ein Betriebssystem eigentlich funktioniert, und - weil Nachbauen eine der besten Möglichkeit ist etwas zu verstehen - habe mir mein eigenes kleines System geschrieben. Es geht nicht darum ein „Suppa-Duppa“ OS zu schreiben, sondern zu verstehen wie größere (RTOS-&amp;gt;Linux-&amp;gt;Windows) funktionieren. &amp;lt;br /&amp;gt;&lt;br /&gt;
Von: Sebastian Balz &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Warnung |&lt;br /&gt;
&#039;&#039;&#039;Warnung&#039;&#039;&#039;  &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Es werden gute Kenntnisse in C und Assembler, sowie gute Kenntnisse der CPU benötigt. Des Weiteren ersetzt ein selbst geschriebenes OS keinesfalls ein herkömmliches OS (RTOS …), da diese zuverlässiger und effizienter laufen und mehr Funktionen haben.&lt;br /&gt;
&lt;br /&gt;
}}&amp;lt;br /&amp;gt;&lt;br /&gt;
Alle Beispiele beziehen sich auf einen ARM-Cortex-M4 (SAM4SD32C), sollten jedoch auf alle gängigen µC portiert werden können. Um den Kontext-Switch zu vereinfachen werden keine Gleitkomma Berechnungen unterstützt.  &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
= Voraussetzungen =&lt;br /&gt;
 &amp;lt;br /&amp;gt;&lt;br /&gt;
* Gute C und Assembler Kenntnisse &lt;br /&gt;
* Gute Kenntnisse des UC‘s&lt;br /&gt;
* Viel Zeit und Motivation :)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Zielsetzung= &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Das beschriebene System soll in der Lage sein:&lt;br /&gt;
* Zwischen verschiedenen Aufgaben (Tasks) zu wechseln(Context-Switch). D.h. jeder Task hat das Gefühl, dass der UC ihm gehört. &lt;br /&gt;
* Fähigkeit der Task’s sich selber zu beenden oder zu pausieren, um so CPU-Ressourcen zu sparen. &lt;br /&gt;
* Keinerlei Auswirkung aufs Interrupt Handling.&lt;br /&gt;
* Ein Zeit Management&lt;br /&gt;
* Tasks und Threads mit Return-Wert und Kill&lt;br /&gt;
* Kommunikation zwischen den Tasks mit Schreib-Kontrolle &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Grundlagen = &lt;br /&gt;
&lt;br /&gt;
Die Hauptaufgabe des Systems ist es, zwischen den verschiedenen Tasks wechseln zu können. &lt;br /&gt;
Um dies realisieren zu können, muss man erst einmal verstehen, wie überhaupt ein Kontext ausschaut.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Register== &lt;br /&gt;
Register sind die Speicherzellen, die direkt mit der CPU verbunden sind. Sie haben die besten Lese- und Schreibraten, sind jedoch „teuer“, weshalb in einer CPU nur relativ wenige Register vorhanden sind. &lt;br /&gt;
In der ARM-Cortex-M4 Serie sind es 12 sog. „General-Purpose Register“ und ein paar Spezial-Register. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:Register Balz.PNG|900px]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quelle: Datenblatt Register&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Stack == &lt;br /&gt;
&lt;br /&gt;
Der Stack ist ein LIFO (Last in, First out), d.h. der zuletzt hinzugefügte Wert wird als erstes wieder ausgelesen. Über Push (Speicher) und POP (Laden) kann man Register-Inhalte auf den Stack speichern und laden.&lt;br /&gt;
Des Weiteren gibt es einen Stack-Pointer. Dieser zeigt immer auf die letzte Adresse im Stack. &lt;br /&gt;
Der Stack baut sich von einer Speicherzelle aus nach unten auf. D.h., wenn ein Wert auf den Stack geschrieben wird, verringert sich die Stack-Adresse. &lt;br /&gt;
&lt;br /&gt;
Jedes Programm schreibt und erstellt seine lokalen Variablen auf dem Stack (RAM). Bei einem Funktionsaufruf werden Übergabeparameter und die Rücksprungadresse im Stack hinterlegt. &lt;br /&gt;
Die aufgerufene Funktion des Speichers (Push) hat also so viele Register auf dem Stack, wie sie selber Register benötigt, damit beim „Return“ wieder die Start-Register vom Stack geholt (POP) werden können und damit der „vor-Funktion-Zustand“ wieder hergestellt ist. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exception Call ==&lt;br /&gt;
Wird eine Funktion durch einen Interrupt unterbrochen, werden R0-R3,R12, LR, PC und xPSR (eine Verbindung aus “Interrupt Program Status Register“, “Application Program Status Register“, „Program Status Register“ und „Execution Program Status Register“) auf den Stack gepusht.&lt;br /&gt;
[[Datei:Stack Balz.PNG]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quelle Datenblatt: Interrupt Stack &amp;lt;br /&amp;gt;&lt;br /&gt;
Der µC schreibt beim “Interrupt entry“ eine EXC_Return_Value ins Link um zu signalisieren, dass gerade eine Interrupt-Routine aktiv ist.   &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:EXC Return Balz.PNG |700px]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quelle: Datenblatt Exc_Return &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Beim Verlassen des ISRs müssen nun nur noch die Register R0-R3, LR,SP und die Status-Register wieder hergestellt werden.   &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Context-Switch =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Theorie==&lt;br /&gt;
Um nun den aktuellen Kontext zu wechseln, müssen in einem Interrupt sämtliche Register gespeichert werden (PUSH R0-R12) und der Stack-Pointer auf den Stack des neuen Task‘s verschoben werden. Nun können die Register wieder hergestellt werden (POP R0-R12). Das Link-Register kann hier außer Acht gelassen werden, da es immer den Wert 0xFFFFFF9 (Return to Thread mode without floating point calculation) hat. &lt;br /&gt;
Wenn man nun das ISR von außen betrachtet, darf man keinen Unterschied zum letzten Speicherzeitpunkt feststellen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Move Stack Balz.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Praxis ==&lt;br /&gt;
=== Speicher ===&lt;br /&gt;
Die Praxis ist leider etwas komplizierter: Zunächst einmal muss der Task-Stack im Speicher reserviert werden. Hierfür kann entweder malloc() verwendet werden - um dynamisch zur Laufzeit den Speicher zu reservieren - oder man „belegt“ den Speicher über Arrays. Da ein Stack-Overflow mit, dass Schlimmste ist, was unserem System passieren kann (Überschreibung der anderen Stacks/globalen Variablen), sollte die Größe des Stacks eher großzügig definiert sein.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stackerzeugen=== &lt;br /&gt;
Da ein Stack sich von oben nach unten (aus Sicht des Speichers) aufbaut, muss der Stack-Pointer auf die Speicheradresse des letzten Array-Elementes zeigen.&lt;br /&gt;
Da beim Kontext-Switch der letzte Zustand wiederhergestellt wird, muss nun der Stack befüllt werden: &lt;br /&gt;
&lt;br /&gt;
* Programm Counter: hier wird die Startadresse des Task‘s eingetragen &lt;br /&gt;
* Link–Register: Da die Task-Ansicht keine Funktion ist und im Normalfall nicht irgendwann verlassen wird, kann dieses Feld freigelassen werden. Alternativ kann auch auf die Adresse eines Dummy-Handlers verwiesen werden, der sich dann um die Beendigung des Tasks kümmert.&lt;br /&gt;
* Program Status Register: Im Status Register (xPSR) wird der Wert hinterlegt, der der CPU signalisiert, dass der aktuelle Programmabschnitt sich gerade in einem Interrupt befindet.&lt;br /&gt;
* Register 0-3,12 sind die Register, die vor einem Interrupt gesichert und nach dem Interrupt wieder hergestellt werden. Da der Task noch keine Registerwerte verwendet hat, können diese Zellen frei bleiben. &lt;br /&gt;
&lt;br /&gt;
Wenn nun ein Kontext-Switch ausführt wird, wird man relativ schnell feststellen, dass etwas noch nicht passt. &lt;br /&gt;
Die Interrupt-Routine hat selber auch Variablen, die auf dem „alten“ Stack gespeichert und nach Verlassen des Stacks wieder vom Stack „gelöscht“ werden müssen. Diese müssen in dem neuen Stack berücksichtigt werden. Leider kann man hier keinen pauschalen Wert nennen, was dazu führt, dass jede Veränderung an der Interrupt-Routine Folgen haben kann. So muss z.B. bei dem neuem Stack die Anzahl der lokalen Register einbezogen werden. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Kontext wechseln ===&lt;br /&gt;
Nun, da der Speicher reserviert und der Stack aufgebaut worden ist, kann man den Kontext wechseln. &lt;br /&gt;
Hierfür müssen alle General-Purpose-Register auf den Stack gespeichert werden. &lt;br /&gt;
Da zu einem späteren Zeitpunkt der Stack wieder zurück gewechselt werden soll, muss nun der aktuelle Stack-Pointer gesichert werden, z.B. in der Task_List (siehe Task_Liste).&lt;br /&gt;
Der „alte“ Kontext ist nun gesichert, und so kann der „Neue“ geladen werden. Zunächst muss der Stack-Pointer umgezogen werden.&lt;br /&gt;
Um sicher zu stellen, dass der µC nun den neuen Stack auch verwendet, muss ein „Pipeline flush“ getätigt werden. Hierfür ist im TUMB2-Befehlssatz der Befehl „ISB“ (Instruction Synchronization Barrier) vorhanden, der direkt nach dem Stack-Pointer-Tausch ausgeführt werden sollte. &lt;br /&gt;
Nun können die Register 0-12 wieder hergestellt werden. Das Linkregister verändert sich nicht, da das Exc_return Value immer gleich ist.&lt;br /&gt;
&lt;br /&gt;
Wird nun die Interrupt Routine verlassen, werden die lokalen Variablen vom Stack gelöscht und die ISR-Inhalte gePOP’t. Der Prozessor springt dann „zurück“ in den neuen Task.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== BSP1 ==== &lt;br /&gt;
Im folgenden Bild kann man gut sehen, wie zwei Tasks (weiße Kästen: PWM) abwechselnd aufgerufen werden. Dargestellt ist die Aktivität der Tasks als Funktion der Zeit; alle 50 ms wird in diesem Beispiel der Task gewechselt: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:Context Switch.JPG | 900px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Task-Liste==&lt;br /&gt;
Damit das System weiß, wie viele und welche Tasks gerade ausgeführt werden, muss eine Liste erstellt werden, in der die jeweiligen IDs der Tasks enthalten sind, sowie:&lt;br /&gt;
* Stack-Pointer&lt;br /&gt;
* Stack Start Adresse&lt;br /&gt;
* Stack-Size&lt;br /&gt;
Optional kann in dieser Liste auch noch: &lt;br /&gt;
* Task Status/Message&lt;br /&gt;
* Thread Return_Value&lt;br /&gt;
enthalten sein.&lt;br /&gt;
=== Stack Pointer === &lt;br /&gt;
Um bei einem Kontext Switch den alten Task wieder herzustellen, muss bekannt sein, an welcher Stelle im Speicher der Stack liegt. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Stack Start Adresse === &lt;br /&gt;
Ist relevant, wenn überprüft werden soll, ob es einen Stack Overflow gab. Sollte es ein Stack-Overflow geben muss dies gemeldet und das System wieder auf den Ursprungszustand gesetzt werden.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stack-Size === &lt;br /&gt;
Wird in Verbindung mit der Stack_Start Adresse für die Overflow-Erkennung benötigt.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Task Status === &lt;br /&gt;
Hier kann ein Task seinen Status mitteilen&lt;br /&gt;
* IDLE&lt;br /&gt;
* Started(läuft der Task gerade?)&lt;br /&gt;
* Oder soll der Stack des Task‘s aufgebaut werden&lt;br /&gt;
* Lese Fehler (siehe Speicher Management)&lt;br /&gt;
&lt;br /&gt;
=== Return Value === &lt;br /&gt;
wird ein Thread auf geplante Weise verlassen – (d.h. er beendet sich selber) –kann dieser auch ein Return_Value als Ergebnis hinterlegen. Hat der Thread z.B. die Aufgabe, eine Nutzereingabe zu erkennen und zu analysieren, so kann der erstellende Task (der die ID kennt) über das Ergebnis informiert werden.  &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
== Zeitmanagement ==&lt;br /&gt;
&lt;br /&gt;
=== System-Zeit ===&lt;br /&gt;
Oftmals kommt es vor, dass ein Task eine Tätigkeit alle x ms ausführen soll. Da jedoch die Tasks möglichst unabhängig sein sollen (sie wissen also nicht mit welcher Taktrate der Prozessor läuft), ist es sinnvoll, über eine RTT oder einen Timer/Counter die Zeit mitzuzählen und diese über eine Funktion allen Tasks und Threads zur Verfügung zu stellen. &lt;br /&gt;
Auch ist es sinnvoll, eine Funktion bereit zu stellen, die überprüft ob eine bestimmt Zeit vergangen ist; unter Berücksichtigung, dass die System-Zeit irgendwann wieder bei 0 anfängt. &lt;br /&gt;
Eine solche Funktion könnte wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int vergangene_zeit(int os_lasttime, int soll_time){&lt;br /&gt;
	int time_know = get_os_time(); // hole die aktuelle Systhem Zeit&lt;br /&gt;
	int delta;&lt;br /&gt;
	if (zeit-lasttime &amp;lt;0) // hat ein System-Zeit Wraparound stattgefunden &lt;br /&gt;
	{&lt;br /&gt;
		zeit += os_max_time; // addiere Max SysthemZeit drauf&lt;br /&gt;
	}&lt;br /&gt;
	delta = zeit-lasttime; &lt;br /&gt;
	return delta &amp;gt;= sollzeit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So kann ein Task einfach in einer  &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; while(!(vergangene_zeit(lasttime,soll_time))){}&amp;lt;/syntaxhighlight&amp;gt; darauf warten, dass die Soll Zeit abgelaufen ist. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Kontext-Switch ===&lt;br /&gt;
Natürlich ist es auch wichtig, dass der Kontext-Switch zentral gesteuert wird. Hier ist es empfehlenswert, den Real-Time-Timer oder einen Timer/Counter zu verwenden, der die Systemzeit managt. Über ein Static counter kann/soll eine bestimmte Anzahl an Zyklen bestimmt werden, bei denen der Kontext-Switch getriggert wird. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== IDLE ===&lt;br /&gt;
Hat man mehrere Tasks die darauf warten, dass Zeit vergeht, wird viel Rechenleistung verbraucht, da die Tasks mit Nichtstun beschäftigt sind, während andere Tasks diese Rechenzeit gut brauchen könnten. &lt;br /&gt;
Um diesem Problem zu entgehen, sollte ein Task in der Lage sein, sich als inaktiv zu deklarieren. Dies könnte über einen Status-Bit geschehen, welches der Time_manager bei jedem Erhöhen der Systemzeit überprüft und den Kontext-Switch triggert.&lt;br /&gt;
Eine bessere Lösung wäre jedoch, zusätzlich zur IDLE Funktion einen Software Interrupt auszulösen, welcher den TC_Handler oder RTT_Handler des Zeitmanagements triggert. &lt;br /&gt;
So kann im Zeitmanagement geprüft werden, ob ein Task IDLE ist, oder ob der Interrupt auf herkömmliche Weise generiert worden ist. &lt;br /&gt;
Sollten ein Großteil oder alle Task IDLE sein, sollte die CPU in ein LOW-Power-Mode wechseln. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Beispiel 1====&lt;br /&gt;
&lt;br /&gt;
Im folgenden Beispiel kann gut erkannt werden, wie sich Task1 zur Hälfte der möglichen Laufzeit als IDLE deklariert und einen Kontext-Switch triggert. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Task IDLE.JPG|900px]]&lt;br /&gt;
Saleae Logic Analyser: Task IDLE &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Tasks und Threads zur Laufzeit erstellen und beenden =&lt;br /&gt;
&lt;br /&gt;
Eine weite Stärke eines solchen Systems ist es, dass dann ohne großen Aufwand einfach ein neuer Task oder Thread hinzugefügt werden kann.&lt;br /&gt;
Ein Thread hat eine feste Aufgabe die er erfüllen soll. Ist diese erfüllt, können weitere Ereignisse getriggert werden, oder der Thread kann beendet werden. &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Starten ===&lt;br /&gt;
Hierfür muss lediglich ein neuer Stack mit Linkregister, Einsprung-Adresse etc. hinzugefügt werden und über die Task_Liste dem Zeitmanagement mitgeteilt werden, sodass es einen neuen Taskeintrag gibt, der gestartet werden soll. &lt;br /&gt;
==== Beispiel 2 ====&lt;br /&gt;
&lt;br /&gt;
Hier kann gut erkannt werden, wie Thread 1 während der Laufzeit erstellt wird und von nun an vom Scheduler aufgerufen wird. Hierdurch werden jedoch Task1 und Task2 seltener aufgerufen.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Thread start.JPG |900px]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beenden ===&lt;br /&gt;
Ein Thread kann auf zwei Arten beendet werden. Die reguläre Art ist, dass er sich selber schließt. Hierfür kann eine Funktion geschrieben werden, die der Task_Liste mitteilt, dass der Task beim nächsten Kontext-Switch nicht mehr aufgerufen werden soll. Optional kann in der Task_List ein Return Value hinterlegt werden, damit der Ersteller des Tasks z. B. ein Ergebnis erhält. Hierbei ist wichtig, zuerst den Return_value zu setzen bevor der Task als beendet definiert wird, da ansonsten ein ungünstiges Timing mit dem Kontext-Switch das Schreiben des Return_Values verhindert. Nachdem Return_value und der Task als beendet definiert worden sind, sollte der Task einen Task_IDLE an den Zeitmanager senden, um so den Task direkt zu verlassen und keine Rechenzeit zu vergeuden.&lt;br /&gt;
Auch ist es nötig, dass der Ersteller des Threads die ID des Threads in der Task_Liste erhält, da hinter der ID des Threads auch der Return_Value gespeichert wird. &lt;br /&gt;
Eine andere Art ein Thread zu beenden ist, ihn zu killen. Wenn z. B. die Ausführung des Threads nicht mehr relevant ist, weil das Ergebnis zu spät kommen würde (Real-Time-OS), oder die Ausführung des Threads nicht mehr benötigt wird, kann man einen Thread auch über die Task-Liste von außen beenden. Hierbei muss nur das Task_Active-Bit gelöscht werden.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Beispiel 3 ====&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Thread closing.JPG|900px]]&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
Hier kann gut erkannt werden, wie Thread1 wieder geschlossen wird. Dadurch werden Task 1 und Task 2 wieder öfter aufgerufen.  &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Interrupte =&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Eigentlich sollte es keinerlei Probleme bereiten, einen Interrupt auszuführen, da dieser den aktuellen Task nicht berührt. &lt;br /&gt;
Es muss lediglich auf zwei Punkte Rücksicht genommen werden:&lt;br /&gt;
* Der Zeitmanager muss in der niedrigsten Priorität laufen. Würde er mit einer höheren Priorität laufen während gerade ein anderer Interrupt aktiv ist, würden die gespeicherten Register in den falschen Stack abgelegt. Die wieder herzustellenden Register kämen aus einem Stack, in dem keine Register gesichert worden sind. Dieser Vorgang würde beide Stacks zerstören.&lt;br /&gt;
* Während des Kontext Switches dürfen keine anderen Interrupts aktiv werden, da es auch hier zu Problemen mit den Stacks kommen könnte.&lt;br /&gt;
Deshalb ist es empfehlenswert, den Zeitmanager in der niedrigsten Priorität laufen zu lassen und während der Ausführung andere Interrupts zu unterbinden. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Erweiterung zum OS =&lt;br /&gt;
Von nun an sind die Übergänge zu einem Betriebssystem fließend. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
== Priorisierung ==&lt;br /&gt;
in Arbeit!&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Speicher Management == &lt;br /&gt;
Der erste Schritt in Richtung Betriebssystem ist ein Speicher-Management, welches in der Lage ist, Speicher zu reservieren und gegebenenfalls auch zu blockieren, sowie freizugeben. Hier kommt wieder – wie beim Stack-Aufbau - malloc() oder ein Array zum Einsatz. Der Einfachheit halber werden die einzelnen Speicher über ID’s angesprochen. Auch muss zentral geregelt werden, ob die jeweilige ID bereits in Verwendung ist. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Erstellen ===&lt;br /&gt;
Möchte ein Task oder Thread einen solchen Speicher erstellen, muss zunächst überprüft werden, ob noch Speicherplätze frei sind. In diesem Fall kann die ID der Speicherzelle zurückgegeben werden (return-Wert). Andernfalls sollte ein Error_Value zurück geliefert werden.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Freigeben ===&lt;br /&gt;
Um Speicher zu sparen, müssen Task und Threads in der Lage sein, den Speicher wieder frei zu geben. Sollte ein Task der beim Speicher durch einen Kontext –Switch unterbrochen worden ist, auf denselben Speicher zugreifen, sollte vor dem Freigeben überprüft werden, ob und warum der Speicher gesperrt worden ist. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Speichern ===&lt;br /&gt;
Um ein ungünstiges Timing zu verhindern (z. B. ein Prozess beschreibt eine Speicherzelle und wird während des Schreibvorganges durch einen Kontext-Switch unterbrochen), sollte nun der Speicher durch einen anderen Task wieder freigegeben werden. Hierzu muss vor dem Schreibvorgang signalisiert werden, dass die jeweilige Zelle blockiert ist. Als Return kann hier dann entweder ein Error_value oder ein Success_Value übertragen werden.  &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lesen === &lt;br /&gt;
Zum Lesen muss lediglich überprüft werden, ob der Speicher der angegebenen ID reserviert ist. Als Return kann hier dann entweder der gespeicherte Wert oder ein Error_Value verwendet werden. Um zu erkennen ob es sich hier um einen Fehler handelt oder um einen gespeicherten Wert, kann über die Task_Liste (ID sollte bekannt sein!) ein Statusbit gesetzt werden.  &amp;lt;br /&amp;gt;&lt;br /&gt;
 &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kommunikation mit anderen Task‘s ==&lt;br /&gt;
Oftmals ist es notwendig, dass die Tasks in der Lage sind, miteinander zu kommunizieren und so Ergebnisse auszutauschen. Hierfür kann ein weiterer Eintrag in der Task-Liste weiterhelfen, der einen anderen Task darüber informiert unter welcher Speicher-ID neue Informationen verfügbar sind. Die jeweiligen Tasks müssen dazu jedoch über die ID der jeweils anderen Task Bescheid wissen. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Realtime == &lt;br /&gt;
Je nach Anwendungsfall kann es wichtig sein, dass manche Threads innerhalb einer bestimmten Zeit ausgeführt werden müssen. Hierzu werden für die Threads Prioritäten vergeben, welche gewährleisten, dass die Threads länger oder häufiger ausgeführt werden (je nach Definition). Möglicherweise ergibt die Ausführung/Beendigung eines Threads auch nach einem bestimmten Zeitpunkt keinen Sinn mehr.&lt;br /&gt;
Beispiel: Ein Sensor soll alle 10 ms ausgelesen werden. Der Sensor liefert immer das aktuelle Messergebnis. Wird nun der Thread (der alle 10 ms getriggert wird um einen Sensor auszulesen) von einem wichtigeren Ereignis unterbrochen und so z. B. über 50ms verzögert, so warten dann 5 getriggerte Threads darauf, CPU Zeit zugewiesen zu bekommen. Da aber immer nur der aktuelle Sensorwert ausgegeben werden kann, liefern alle 5 Threads dasselbe Ergebnis. Um nun Ressourcen zu sparen, muss erkannt werden, ob die Ausführung dieses Threads noch sinnvoll ist. Andernfalls sollten die Threads beendet werden und es kann eine Fehlermeldung generiert werden. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Fehlersuche und Kontrolle =&lt;br /&gt;
== Register Kontrolle ==&lt;br /&gt;
Zunächst ist es wichtig zu überprüfen, ob alle Variablen und Register denselben Wert wie nach einem Kontext Switch haben. Hier ist es empfehlenswert, beim Erstellen des Tasks lokale Variablen mit eindeutigen Werten zu erstellen und anschließend in einer while(1)-Schleife laufen zu lassen. &lt;br /&gt;
Die einfachste Überprüfung ist hier: Mit dem Debugger einen Breakpoint in der while(1)-Schleife des Programms zu setzen und nach dem Kontext-Switch anzuhalten, um auf diese Weise die Variablen zu überprüfen.&lt;br /&gt;
&lt;br /&gt;
Mögliche Fehlerquellen: &lt;br /&gt;
* Stack Pointer zeigt auf die falsche Adresse&lt;br /&gt;
* Zuviele oder nicht ausreichend lokale Variablen -der ISR-  nach Verlassen der ISR gelöscht&lt;br /&gt;
* Register in falscher Reihenfolge wiederhergestellt&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Void Test_Task1(){&lt;br /&gt;
Start_task();&lt;br /&gt;
int a = 3; &lt;br /&gt;
	int b = 1;&lt;br /&gt;
	int c = 2; &lt;br /&gt;
	int d = 3; &lt;br /&gt;
	int e = 4;&lt;br /&gt;
	int f = 5;&lt;br /&gt;
	int g = 6;&lt;br /&gt;
	int h = 7;&lt;br /&gt;
while(1){&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen  ==&lt;br /&gt;
Wenn sichergestellt wurde, dass die Register und Variablen nach einem Kontext Switch unverändert bestehen, kann mit einer einfachen Rechenoperation, die je nach Ausgangswert ein anderes Ergebnis liefert, überprüft werden, ob die Wiedereinsprungsadresse stimmt. &lt;br /&gt;
Da lokale Variablen zerstört werden können, sollten globale Variablen hierfür verwendet werden, da diese eben nicht im Stack gespeichert werden. Zusätzlich sollte ein Fehlercounter inkrementiert werden.&lt;br /&gt;
&lt;br /&gt;
Mögliche Fehlerquellen: &lt;br /&gt;
* Falsches Link Register &lt;br /&gt;
* Falscher PC &lt;br /&gt;
* Fehlerhafte Register und/oder Variablen&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
Hier eignet sich die Berechnung der ersten Fibonacci-Zahlen, da hier jedes weitere Ergebnis vom Vorherigen abhängt.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Int error;&lt;br /&gt;
Void Test_Task2(){&lt;br /&gt;
Start_Task();&lt;br /&gt;
int a = 1;&lt;br /&gt;
	int b = 1;&lt;br /&gt;
	int c;&lt;br /&gt;
int counter = 0;&lt;br /&gt;
while(1){&lt;br /&gt;
		c = a;&lt;br /&gt;
		a = b+a;&lt;br /&gt;
		b = c;	&lt;br /&gt;
switch(counter){&lt;br /&gt;
		case 0:if(!(b==1)){&lt;br /&gt;
				error++;&lt;br /&gt;
				}break;&lt;br /&gt;
		case 1:if(!(b==2)){&lt;br /&gt;
				error++;}break;&lt;br /&gt;
		case 2:if(!(b==3)){&lt;br /&gt;
				error++;}break;&lt;br /&gt;
		case 3:if(!(b==5)){&lt;br /&gt;
		                error++;}break;&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
        ...&lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                default:counter = -1; b = 1; a = 1;break;&lt;br /&gt;
             }&lt;br /&gt;
          counter ++;&lt;br /&gt;
     }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Funktionskaskade == &lt;br /&gt;
Um zu überprüfen, ob Linkregister und Programmcounter richtig gesichert wurden, kann man via Funktionkaskaden überprüfen, ob alle Funktionen in der richtigen Reihenfolge aufgerufen werden, und ob sie auch wieder richtig verlassen werden. Auch wichtig sind Übergabeparameter und return values. &lt;br /&gt;
Sollte es hier zu einem Fehler kommen, kann es sein, dass nur die lokalen Variablen verloren gehen. Es kann jedoch auch passieren, dass nach dem Verlassen der Funktion zu viel oder zu wenig vom Stack geladen wird, wodurch eine falsche Rücksprungadresse geladen wird. Mit etwas Glück erkennt der µC dies und springt dann in einen Fault-Handler.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möglichen Fehler Quellen: &lt;br /&gt;
* Link Register hatt die Falsche Adresse&lt;br /&gt;
* Fehlerhafte Register  und/oder Variablen&lt;br /&gt;
* Falscher Programcounter&lt;br /&gt;
* Register 7 (kann von UC, Compiler oder IDE unterschiedlich sein) bei einem Funktions Call wird in einem Register der alte Stackpointer hinterlegt, ob zu zeigen, wie viele Lokale Variablen nach Verlassen der aktuellen Funktion auf dem Stack nicht mehr benötigt werden. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int tester;&lt;br /&gt;
int error;&lt;br /&gt;
void Task_test3(){&lt;br /&gt;
	while(1){&lt;br /&gt;
		tester = 1;&lt;br /&gt;
		int dummy = test1(5,6);&lt;br /&gt;
		&lt;br /&gt;
		if(dummy != 9 || tester != 4){&lt;br /&gt;
			error ++;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
int test1(int a, int b){&lt;br /&gt;
		if(tester != 1){&lt;br /&gt;
			error++;&lt;br /&gt;
		}&lt;br /&gt;
		tester = 2;&lt;br /&gt;
		int dummy = test2(7);&lt;br /&gt;
		if(a != 5 || b != 6 || dummy != 8 || tester != 3){&lt;br /&gt;
			error++;&lt;br /&gt;
		}&lt;br /&gt;
		tester = 4;&lt;br /&gt;
		return 9;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
int test2(int a)&lt;br /&gt;
{&lt;br /&gt;
		if(a != 7 || tester != 2){&lt;br /&gt;
			error ++;&lt;br /&gt;
		}&lt;br /&gt;
		tester = 3;&lt;br /&gt;
		return 8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight &amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kein Kontext Switch mehr ==&lt;br /&gt;
Sollten plötzlich keine Kontext-Switche mehr stattfinden(ein Task wird nicht mehr verlassen) sollten man im Interrupt_Manager –„ Nested Vectored Interrupt Controller“ (NVIC) -  nachschauen, ob das Interrupt_Active_Bit gesetzt ist. Sollte dies der Fall sein, wurde der Kontext-Switch nicht richtig verlassen und der Prozessor glaubt, er würde noch immer den Interrupt ausführen. Viele Prozessoren - unter anderem ARM - erlauben kein Repending(doppeltes Ausführen) eines Interruptes.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Mögliche Fehlerquellen: &lt;br /&gt;
* Linkregister: Bei einem Interrupt Aufruf wird das Link Register mit einem Exp_return_Value beschreiben. Dieser sagt aus, auf welche Art und ob nach Verlassen der Funktion das Interrupt abgeschlossen wurde. So weiss der UC, ob z.B. noch ein Interrupt mit einer niedrigeren Priorität unterbrochen wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Lektüre = &lt;br /&gt;
*	µC/OS-III: The Real-Time Kernel https://www.micrium.com/books/ucosiii/ &lt;br /&gt;
*	http://infocenter.arm.com  &lt;br /&gt;
*	Datenblatt&lt;br /&gt;
*       &#039;&#039;&#039;Grundlagen:&#039;&#039;&#039; https://www.mikrocontroller.net/articles/Multitasking&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Quellen =&lt;br /&gt;
*	µC/OS-III: The Real-Time Kernel&lt;br /&gt;
*	SAM4S-Datenblatt  http://www.atmel.com/Images/Atmel-11100-32-bit%20Cortex-M4-Microcontroller-SAM4S_Datasheet.pdf &lt;br /&gt;
&lt;br /&gt;
= Link Sammlung = &lt;br /&gt;
* https://www.mikrocontroller.net/topic/381051&lt;br /&gt;
* https://www.mikrocontroller.net/topic/389195?goto=4457089#4457089&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Autor = &lt;br /&gt;
Sebastian Balz&lt;br /&gt;
[[Kategorie:ARM]]&lt;br /&gt;
[[Kategorie:Betriebssysteme]]&lt;/div&gt;</summary>
		<author><name>8023</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Lehrvideos&amp;diff=92422</id>
		<title>Lehrvideos</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Lehrvideos&amp;diff=92422"/>
		<updated>2016-03-17T05:48:23Z</updated>

		<summary type="html">&lt;p&gt;8023: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Lehrvideos zu FPGA, VHDL, Verilog und Digital Design=&lt;br /&gt;
Hier ensteht eine Linkliste von Lehrvideos und Demos, die den Einstieg und Meisterschaft(?) im Design von digitalen Systemen erleichtern sollen. Die Videos sollen zeigen, wie man mit den Tools arbeitet. &lt;br /&gt;
&lt;br /&gt;
Eine kurze Durchsicht bei youtube zeigt auf, dass nur ein kleiner Teil der Videos als Lehrvideo taugt, der Großteil sind Promotion-Videos, die hier nicht gelistet werden.&lt;br /&gt;
&lt;br /&gt;
== VHDL and Xilinx Spartan FPGA 1/2 ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.youtube.com/watch?v=Bg_4nqSs2OY| VHDL and Xilinx Spartan FPGA 1/2] (Video privat, nicht einsehbar)&lt;br /&gt;
* [http://www.youtube.com/watch?v=SRsISGjRj-4| VHDL and Xilinx Spartan FPGA 2/2] (Video privat, nicht einsehbar)&lt;br /&gt;
&lt;br /&gt;
Auf englisch kommentierte Demo die zeigt, wie man zu einem zugehörigen Blockbild den VHDL-Code schreibt und diesen synthetisiert. Gezeigt werden die Xilinxtools ISE, RTL-View, Core Generator.&lt;br /&gt;
&lt;br /&gt;
== Einstieg mit Altera DE1 Board ==&lt;br /&gt;
*FPGA Tutorial 1. Blinking LEDs on DE1 Altera Board &lt;br /&gt;
[http://www.youtube.com/watch?v=T9VbBI3foGQ|Youtube-Video &amp;quot;FPGA Tutorial 1. Blinking LEDs on DE1 Altera Board&amp;quot;]&lt;br /&gt;
*FPGA Tutorial 2. Functions and procedures in VHDL on DE1 Altera Board &lt;br /&gt;
[http://www.youtube.com/watch?v=j2lAPIjpF1w|Youtube-Video &amp;quot;FPGA Tutorial 2. Functions and procedures in VHDL on DE1 Altera Board&amp;quot;]&lt;br /&gt;
*FPGA Tutorial 3. UART in VHDL on Altera DE1 Board &lt;br /&gt;
[http://www.youtube.com/watch?v=fMmcSpgOtJ4|Youtube-Video &amp;quot;FPGA Tutorial 3. UART in VHDL on Altera DE1 Board&amp;quot;]&lt;br /&gt;
*FPGA Tutorial 4: VGA interface in VHDL on DE1 Altera Board &lt;br /&gt;
[http://www.youtube.com/watch?v=mS0VZwnZssA|Youtube-Video &amp;quot;FPGA Tutorial 4: VGA interface in VHDL on DE1 Altera Board.&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
== Introductory tutorial on Verilog  ==&lt;br /&gt;
* [http://www.youtube.com/watch?NR=1&amp;amp;v=jkiHUaNIAKg| Introductory tutorial on Verilog] PowerPoint Vorlesung, einschläfernde Stimme, aber im Inhalt solide. &lt;br /&gt;
Erklärt werden die Beschreibungsformen (gatter, Verhalten, Prozeduraler Ansatz) und die Grundelemente register,wire,module.&lt;br /&gt;
&lt;br /&gt;
== How to Setup Simulation in ModelSim ==&lt;br /&gt;
*[http://www.youtube.com/watch?v=VTMelKXXmho| Modelsim]&lt;br /&gt;
Dieser Englischsprachiger Screencast erklärt vornehmlich die GUI-basierte Bedienung des modelsim-Simulators, auf die script-steuerung wird kurz hingewiesen. Erklärt werden compile, compile-Order, Filestruktur, Fenstergruppierung. Leider wird kaum auf die Bedienung des wave-Fensters eingegangen.&lt;br /&gt;
&lt;br /&gt;
==Statische Timing-Analyse==&lt;br /&gt;
*[http://www.youtube.com/watch?v=pEj6LR-C84Y| Lec-33 static timing analysis.wmv]&lt;br /&gt;
*[http://www.youtube.com/watch?v=mrY0MzCBgAo| Lec-34 static timing analysis]&lt;br /&gt;
Über zwei Stunden feinstes Indian English von Hold/Set-time zu clock-constrainst, false pathes und SDF. Hochschulvortrag mit handgezeichnetet Folien.&lt;br /&gt;
&lt;br /&gt;
==Timing constraints - Xilinx==&lt;br /&gt;
*[http://www.youtube.com/watch?v=dRM0HVdqvZo&amp;amp;| Kapitel eins - Definition und Zweck von Timing constraints]&lt;br /&gt;
*[http://www.youtube.com/watch?v=38Px7CmGczo| Kapitel zwei - period, jitter, Offset]&lt;br /&gt;
*[http://www.youtube.com/watch?v=P3rQssXEFm8| Kapitel drei - Optionen, Eingabemöglichkeiten]&lt;br /&gt;
Offizielles Xilinx-Lehrmodul zu timing-constraints als PowerPoint-Vortrag. Das Video folgt der klassichen Lehrmethodik: Präsentation neues Wissens and anschliessende Vertiefung durch Beispiele und Frage/Antwort &lt;br /&gt;
Da die Basics der Timing-Constraints (kritischer Pfad, jitter, ...) für alle FPGA-Familien gleich sind, lohnt sich mindestens das erste Kapitel auch für Nutzer von Altera, Actel und andere.&lt;br /&gt;
&lt;br /&gt;
== Programming/Bitstream download with Xilinx Impact ==&lt;br /&gt;
*[http://www.youtube.com/watch?v=gnSiwBn0djQ| Intro to FPGAs for Software Engineers - Part 5 - Programming, JTAG, PROMs, &amp;amp; iMPACT]&lt;br /&gt;
Dieser Screencast zeigt die Klicks und Eingaben um ein Board (FPGA,PROMS) mit JTAG-Schnittstelle über das Impact-tool der Xilinx-ISE zu programmieren. Perfekt lesbar an einem 1080 Monitor.&lt;br /&gt;
&lt;br /&gt;
== How to use KCPSM3 in VHDL FPGA based project ==&lt;br /&gt;
* [http://www.youtube.com/watch?v=An3x5tKL5Js| How to use KCPSM3 in VHDL FPGA based project ]&lt;br /&gt;
Der KCPSM3 ist der Vorläufer der 8-Bit Soft-CPU Picoblaze von Xilinx. Das unkommentierte, aber mit Musik unterlegte Video zeigt wie im ISE Editor der VHDL-Code (Component-Instanziierung) hierfür erstellt wird. Einzelne Clicks in der Tooliste sind grafisch hervorgehoben. Der Text ist nicht sonderlich gut lesbar.&lt;br /&gt;
&lt;br /&gt;
== Noch ohne abschliessende Bewertung ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.youtube.com/watch?v=Ob7B6x5g6tw FPGA Xilinx VHDL Video Tutorial]: Zeigt das Aufsetzen eines Projektes in der Xilinx-ISE.&lt;br /&gt;
&lt;br /&gt;
* [http://www.youtube.com/watch?v=FxF0M3DA68Y Basic Schematic Input Tutorial] Xilinx-ISE, project from the scratch, fürchterlicher Ton&lt;br /&gt;
&lt;br /&gt;
* [http://www.eejournal.com/design/fpga/on-demand] EEJournal Webcasts und Videos zum Thema FPGA and Programmable Logic Design&lt;br /&gt;
&lt;br /&gt;
=== Vorlesungen  Prof.S.Srinivasan , Madras, Indien ===&lt;br /&gt;
bspw.:&lt;br /&gt;
*[http://www.youtube.com/watch?v=RZQTTfU9TNA| Lecture 30 Encoders and Decoders]&lt;br /&gt;
Vorlesungsvideo, stark akzentgefärbtes Englisch, erklärt werden die Grundlagen des Digitaldesigns, EDA-Tools werden vorgestellt.&lt;br /&gt;
&lt;br /&gt;
==Nicht empfohlen==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:FPGA und Co]]&lt;/div&gt;</summary>
		<author><name>8023</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Labornetzger%C3%A4te&amp;diff=92421</id>
		<title>Labornetzgeräte</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Labornetzger%C3%A4te&amp;diff=92421"/>
		<updated>2016-03-17T05:47:46Z</updated>

		<summary type="html">&lt;p&gt;8023: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein Labornetzgerät wird dazu verwendet, Schaltungen oder einzelne Bauteile mit einer definierten Spannung oder einem definierten Strom zu versorgen.&lt;br /&gt;
&lt;br /&gt;
== Funktionen ==&lt;br /&gt;
&lt;br /&gt;
Labornetzgeräte sind im Gegensatz zu einfachen Festspannungs-Netzteilen sehr flexibel einsetzbar und haben üblicherweise mindestens folgende Einstellmöglichkeiten und Funktionen:&lt;br /&gt;
&lt;br /&gt;
=== Einfache Labornetzteile ===&lt;br /&gt;
&lt;br /&gt;
Einfache Labornetzgeräte haben eine einstellbare Ausgangsspannung, die normalerweise von 0 bis zu einem bestimmten Maximalwert eingestellt werden kann. Zusätzlich bieten diese Geräte eine einstellbare Strombegrenzung, die auch von 0 aus bis zum Nennstrom des Geräts eingestellt werden kann.&lt;br /&gt;
&lt;br /&gt;
Labornetzgeräte haben außerdem noch eine Anzeige für Ausgangsspannung und Strom. Dafür sind entweder analoge oder digitale Instrumente eingebaut. Bei digitalen Anzeigen werden üblicherweise 3 Stellen angezeigt, die Genauigkeit der Anzeige liegt üblicherweise im Bereich 1%.&lt;br /&gt;
&lt;br /&gt;
Der Ausgang sollte kurzschlussfest sein, was allerdings nicht bei allen Labornetzgeräten der Fall ist. Manche Geräte sind nur kurzzeitig kurzschlussfest (für einige Sekunden), normalerweise sind Labornetzgeräte dauerhaft kurzschlussfest.&lt;br /&gt;
&lt;br /&gt;
=== Labornetzteile mit erweiterten Funktionen ===&lt;br /&gt;
&lt;br /&gt;
Die Labornetzgeräte der gehobenen Preisklasse haben zusätzlich zu den Grundfunktionen noch weitere Funktionen, wie z.B.:&lt;br /&gt;
&lt;br /&gt;
* Abschaltbarer Ausgang&lt;br /&gt;
* Getrennte Anzeige von Soll- und Ist-Werten&lt;br /&gt;
* Höhere Messgenauigkeit der Istwerte als bei einfachen Geräten&lt;br /&gt;
* Einstellbare Grenzwerte für Strom, Spannung, Leistung&lt;br /&gt;
* Alarm/Abschaltung bei Überschreitung von einstellbaren Schwellwerten&lt;br /&gt;
* Programmierbare Spannungs-/Stromverläufe&lt;br /&gt;
* Master-Slave-Funktion für Reihen-/Parallelschaltung von mehreren Geräten&lt;br /&gt;
* Analoge Schnittstelle für Soll- und Istwerte&lt;br /&gt;
* PC-Schnittstelle&lt;br /&gt;
&lt;br /&gt;
== Wichtige Eigenschaften ==&lt;br /&gt;
&lt;br /&gt;
=== Lineare Netzgeräte vs. Schaltnetzgeräte ===&lt;br /&gt;
&lt;br /&gt;
Es gibt bei Labornetzgeräten sowohl linear geregelte als auch Schaltnetzteile.&lt;br /&gt;
&lt;br /&gt;
Lineare Netzgeräte haben den Vorteil, dass die Regelung üblicherweise schneller und genauer ist. Die Ausgangskapazität ist bei linearen Netzgeräten relativ klein, dadurch kann die Strombegrenzung sehr schnell ansprechen.&lt;br /&gt;
&lt;br /&gt;
Schaltnetzgeräte haben dagegen einen besseren Wirkungsgrad, erzeugen also weniger Abwärme und sind kleiner und leichter als lineare Netzgeräte gleicher Leistung. Deshalb sind vor allem Labornetzgeräte mit hoher Leistung bevorzugt als Schaltnetzteil aufgebaut.&lt;br /&gt;
&lt;br /&gt;
Wenn bei Schaltnetzgeräten eine sehr kleine Ausgangs-Spannung eingestellt wird, wird diese oft nicht sauber ausgeregelt. Meistens brauchen solche Geräte eine bestimmte Mindestspannung am Ausgang.&lt;br /&gt;
&lt;br /&gt;
Weiterhin besteht bei Schaltnetzteilen die Gefahr, dass am Ausgang Störungen sichtbar sind, die durch die interne PWM erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Weiterhin gibt es auch Geräte, bei denen ein Schaltnetzteil und eine lineare Regelung kombiniert sind. Dadurch werden die Vorteile von beiden Verfahren kombiniert, es ergeben sich dadurch aber auch einige Probleme:&lt;br /&gt;
&lt;br /&gt;
* Bei schnellen Laständerungen kann es passieren, dass das Schaltnetzteil nicht schnell genug nachregelt. Dadurch ändert sich das Regelverhalten und die Ausgangsspannung bzw. Strom sind dann nicht mehr so stabil wie bei einem richtigen linear geregelten Netzgerät. &lt;br /&gt;
&lt;br /&gt;
* Bei schnellen periodischen Laständerungen kann es zusätzlich passieren, dass die Verlustleistung im Linearregler sehr viel höher wird als im Betrieb mit konstanter Ausgangsleistung. Da die lineare Endstufe meistens nicht dafür dimensioniert ist, kann es hier thermische Probleme geben.&lt;br /&gt;
&lt;br /&gt;
=== Verlustleistung und Kühlung === &lt;br /&gt;
&lt;br /&gt;
Das ist vor allem bei linear geregelten Geräten ein sehr wichtiges Kapitel, da eine gute Kühlung relativ viel Geld kostet und die Gerätehersteller hier gerne sparen. Folgende Punkte sollten hier beachtet werden:&lt;br /&gt;
&lt;br /&gt;
==== Passive Kühlung oder Kühlung mit Lüfter ====&lt;br /&gt;
Geräte mit passiver Kühlung erzeugen keine Geräusche, was ein großer Vorteil ist. Passive Kühlung ist aber nur bei Geräten mit relativ geringer Leistung üblich. Bei Lüfter-gekühlen Geräten sollte darauf geachtet werden, dass der Lüfter relativ ruhig läuft.&lt;br /&gt;
&lt;br /&gt;
==== Außenliegender Kühlkörper ====&lt;br /&gt;
Bei passiv gekühlten Geräten kann der Kühler ziemlich warm werden. Wenn der Kühler außen am Gehäuse montiert ist, besteht die Gefahr, dass man ihn versehentlich berührt und sich verbrennt oder dass wärmeempfindliche Gegenstände (z.B. kunststoff-isolierte Leitungen) bei Berührung beschädigt werden. Deshalb sollte man Geräte bevorzugen, bei denen der Kühler innerhalb des Gehäuses montiert ist.&lt;br /&gt;
&lt;br /&gt;
==== Lüftungsschlitze ====&lt;br /&gt;
Bei Geräten, die Lüftungsschlitze auf der Oberseite haben, besteht die Gefahr, dass Gegenstände reinfallen können, wodurch das Gerät beschädigt werden kann. Weiterhin kann es passieren, dass der Luftstrom durch die Schlitze behindert wird, wenn man etwas auf dem Gerät ablegt oder mehrere Geräte aufeinander stapelt.&lt;br /&gt;
Je nach dem, wo das Gerät aufgestellt werden soll, können deshalb seitliche Lüftungsschlitze vorteilhaft sein. Allerdings sind seitliche Lüftungsöffnungen meistens mit einem aktiven Lüfter kombiniert.&lt;br /&gt;
&lt;br /&gt;
==== Dimensionierung der Kühlkörper und Leistungstransistoren ====&lt;br /&gt;
Bei vielen billigen Netzgeräten ist die Kühlung zu knapp dimensioniert. Das kann man relativ einfach testen, indem man den Ausgangsspannung und Strom jeweils auf Maximalwerte einstellt und dann den Ausgang kurzschließt.&lt;br /&gt;
&lt;br /&gt;
In diesem Zustand sollte das Gerät längere Zeit (einige Stunden) betrieben werden, bis alles thermisch eingeschwungen ist. Dann muss bei allen Leistungsbauteilen die Temperatur gemessen werden, am einfachsten geht das mit einer Wärmebildkamera. Es sollten nach Möglichkeit keine Temperaturen oberhalb von 100°C auftreten. Wärme-empfindliche Bauteile (z.B. Elkos) sollten nicht wärmer als 70°C sein.&lt;br /&gt;
&lt;br /&gt;
Besonders kritisch sind hier:&lt;br /&gt;
* Netztrafo&lt;br /&gt;
* Gleichrichter&lt;br /&gt;
* Leistungstransistoren und Kühlkörper&lt;br /&gt;
&lt;br /&gt;
=== Stabilität und Genauigkeit ===&lt;br /&gt;
&lt;br /&gt;
Wichtige Eigenschaften bei Labornetzgeräten ist die Stabilität und die Genauigkeit.&lt;br /&gt;
&lt;br /&gt;
==== Stabilität ====&lt;br /&gt;
&lt;br /&gt;
Damit wird angegeben, wie konstant ein eingestellter Wert über einen längeren Zeitraum gehalten wird. Hier ist wichtig, dass das Gerät einen kleinen Temperaturkoeffizient hat, so dass die Ausgangsspannung auch bei Temperaturschwankungen möglichst stabil bleibt.&lt;br /&gt;
&lt;br /&gt;
==== Genauigkeit ====&lt;br /&gt;
&lt;br /&gt;
Hier muss unterschieden werden zwischen der Anzeigegenauigkeit und der Einstellgenauigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Genauigkeit der Anzeige gibt an, wie genau die angezeigte Ausgangsspannung oder Strom mit der tatsächlichen Spannung übereinstimmt (siehe dazu auch  Artikel [[Auflösung und Genauigkeit]]).&lt;br /&gt;
&lt;br /&gt;
Die Einstellgenauigkeit gibt an, wie genau ein bestimmter Sollwert eingestellt werden kann und wie gut die tatsächlichen Werte mit den Sollwerten übereinstimmen. Bei Geräten mit digitaler Sollwertvorgabe muss hier die kleinste Schrittweite beachtet werden.&lt;br /&gt;
&lt;br /&gt;
== Weitere Funktionen ==&lt;br /&gt;
&lt;br /&gt;
=== Schnittstelle ===&lt;br /&gt;
&lt;br /&gt;
Einige Labornetzgeräte bieten eine Schnittstelle zum PC, damit können sie als per Software steuerbares Netzgerät verwendet werden. Will man das Netzgerät per Mikrocontroller steuern, so sind Typen mit [[RS232]] Anschluß den Typen mit [[USB]] vorzuziehen.&lt;br /&gt;
&lt;br /&gt;
=== Beleuchtung ===&lt;br /&gt;
&lt;br /&gt;
Folgende Display-Arten sind bei Labornetzgeräten üblich:&lt;br /&gt;
* Analoginstrument (unbeleuchtet oder beleuchtet)&lt;br /&gt;
* LCD 7-Segment Anzeige (unbeleuchtet oder beleuchtet)&lt;br /&gt;
* LCD Punktmatrix-Anzeige (in der Regel beleuchtet)&lt;br /&gt;
* LED 7-Segment Anzeige (selbstleuchtend)&lt;br /&gt;
* OLED-Anzeigen (selbstleuchtend)&lt;br /&gt;
* VFD-Anzeigen (selbstleuchtend)&lt;br /&gt;
&lt;br /&gt;
Anzeigen mit Beleuchtung bzw. selbstleuchtende Anzeigen sind wesentlich besser ablesbar als unbeleuchtete LCD-Anzeigen. Da Labornetzgeräte immer am Netz betrieben werden, ist der Stromverbrauch der Beleuchtung nicht relevant.&lt;br /&gt;
&lt;br /&gt;
Unbeleuchtete LCD-Anzeigen sind bei schlechter Beleuchtung oder ungünstigem Blickwinkel manchmal schlecht ablesbar, bei 7-Segment LED-Anzeigen ist die Ablesbarkeit wesentlich besser. &lt;br /&gt;
&lt;br /&gt;
Mit 7-Segment Anzeigen lassen sich allerdings nur Ziffern und einige wenige Buchstaben darstellen. Für Geräte mit komplexen Einstellungen und Menu-Führung werden deshalb häufig Punkt-Matrix LCD-Anzeigen verwendet.&lt;br /&gt;
&lt;br /&gt;
Mit VFD-Anzeigen [http://de.wikipedia.org/wiki/Fluoreszenzanzeige], die ebenfalls sehr gut ablesbar sind, könnnen auch komplexe Menüs dargestellt werden. Diese haben einen sehr weiten Blickwinkel und sehr scharfe und klare Zeichen. Allerdings sind diese Anzeigen relativ teuer, weshalb sie vor allem in eher teueren Geräten eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
== Vergleichstabelle Labornetzgeräte ==&lt;br /&gt;
&lt;br /&gt;
In den folgende Tabellen werden wichtige technischen Daten einiger aktueller Labornetzgeräte zusammengestellt. Um die Übersichtlichkeit zu erhöhen, werden die Geräte eingeteilt in einfache Geräte und Geräte mit Zusatzfunktionen&lt;br /&gt;
&lt;br /&gt;
Die Einteilung geschieht aufgrund der Funktionen, die die Geräte bieten. Das ist also keine Aussage über die Qualität der Geräte.&lt;br /&gt;
&lt;br /&gt;
=== Einfache lineare Labornetzgeräte ===&lt;br /&gt;
&lt;br /&gt;
Hier werden Geräte aufgelistet, welche neben den Grundfunktionen (Strom- und Spannungseinstellung, Anzeige der Istwerte) keine weiteren Funktionen besitzen.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable sortable&amp;quot; id=&amp;quot;einfache&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Hersteller&lt;br /&gt;
!Bezeichnung&lt;br /&gt;
!Preis [EUR]&lt;br /&gt;
!Spannung [V]&lt;br /&gt;
!Strom [A]&lt;br /&gt;
!Kanäle&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3616A&lt;br /&gt;
|620&lt;br /&gt;
|35&lt;br /&gt;
|1.7&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HM8040-3(Benötigt HM8001)&lt;br /&gt;
|280&lt;br /&gt;
|20 + 20 + 5&lt;br /&gt;
|0.5 + 0.5 + 1&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|Peaktech&lt;br /&gt;
|6080&lt;br /&gt;
|50&lt;br /&gt;
|15&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|McVoice&lt;br /&gt;
|WNT0-15-2000&lt;br /&gt;
|38&lt;br /&gt;
|15&lt;br /&gt;
|2&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|Statron&lt;br /&gt;
|2223.1&lt;br /&gt;
|150&lt;br /&gt;
|30&lt;br /&gt;
|2.5&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2250.0&lt;br /&gt;
|225&lt;br /&gt;
|40&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2229.2&lt;br /&gt;
|260&lt;br /&gt;
|40 + 40&lt;br /&gt;
|2.5 + 2.5&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2229.5&lt;br /&gt;
|340&lt;br /&gt;
|32 + 32 + 5&lt;br /&gt;
|3 + 3 + 3&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2225.6&lt;br /&gt;
|310&lt;br /&gt;
|30 + 30&lt;br /&gt;
|5 + 5&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|PS-1302 D&lt;br /&gt;
|95&lt;br /&gt;
|30&lt;br /&gt;
|2&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VLP 1303pro&lt;br /&gt;
|180&lt;br /&gt;
|30 + 6&lt;br /&gt;
|3 + 2&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VSP 2403&lt;br /&gt;
|345&lt;br /&gt;
|40 + 40 + 6&lt;br /&gt;
|3 + 3 + 1.5&lt;br /&gt;
|3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Einfache Schaltnetzgeräte ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable sortable&amp;quot; id=&amp;quot;einfache&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Hersteller&lt;br /&gt;
!Bezeichnung&lt;br /&gt;
!Preis [EUR]&lt;br /&gt;
!Spannung [V]&lt;br /&gt;
!Strom [A]&lt;br /&gt;
!Kanäle&lt;br /&gt;
|-&lt;br /&gt;
|Delta Elektronika&lt;br /&gt;
|ES 030-5&lt;br /&gt;
|624&lt;br /&gt;
|30&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Quatpower&lt;br /&gt;
|LN-3003&lt;br /&gt;
|40&lt;br /&gt;
|30&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Netzgeräte mit Zusatzfunktionen ===&lt;br /&gt;
&lt;br /&gt;
Diese Geräte haben mindestens folgende Funktionen:&lt;br /&gt;
* abschaltbare Ausgänge&lt;br /&gt;
* Anzeige der Sollwerte für Strom und Spannung&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable sortable&amp;quot; id=&amp;quot;hochwertige&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Hersteller&lt;br /&gt;
!Bezeichnung&lt;br /&gt;
!Preis [EUR]&lt;br /&gt;
!Spannung [V]&lt;br /&gt;
!Strom [A]&lt;br /&gt;
!Kanäle&lt;br /&gt;
!linear/getaktet&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|U8001A&lt;br /&gt;
|290&lt;br /&gt;
|30&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3616A&lt;br /&gt;
|620&lt;br /&gt;
|35&lt;br /&gt;
|1.7&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3643A&lt;br /&gt;
|690&lt;br /&gt;
|35 / 60 (umschaltbar)&lt;br /&gt;
|1.4 / 0.8&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3632A&lt;br /&gt;
|990&lt;br /&gt;
|15 / 30 (umschaltbar)&lt;br /&gt;
|7 / 4&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|BK Precision&lt;br /&gt;
|BK 1786&lt;br /&gt;
|490&lt;br /&gt;
|32&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|BK Precision&lt;br /&gt;
|BK 1788&lt;br /&gt;
|615&lt;br /&gt;
|32&lt;br /&gt;
|6&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|BK Precision&lt;br /&gt;
|BK 9130&lt;br /&gt;
|685&lt;br /&gt;
|30 + 30 + 5&lt;br /&gt;
|3 + 3 + 3&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|PSI 6032-03&lt;br /&gt;
|425&lt;br /&gt;
|32&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 2042-06B&lt;br /&gt;
|235&lt;br /&gt;
|42&lt;br /&gt;
|6&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 2342-06B&lt;br /&gt;
|580&lt;br /&gt;
|42 + 42 + 6&lt;br /&gt;
|6 + 6 + 4&lt;br /&gt;
|3&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 3032-05B&lt;br /&gt;
|355&lt;br /&gt;
|32&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 8032-10 DT&lt;br /&gt;
|940&lt;br /&gt;
|32&lt;br /&gt;
|10&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|ELV&lt;br /&gt;
|PPS 5330&lt;br /&gt;
|120&lt;br /&gt;
|30&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|ELV&lt;br /&gt;
|SPS 5630&lt;br /&gt;
|200&lt;br /&gt;
|30&lt;br /&gt;
|6 (max. 75W)&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HM7042-5&lt;br /&gt;
|685&lt;br /&gt;
|32 + 32 + 5,5&lt;br /&gt;
|2 + 2 + 5&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HMP2020&lt;br /&gt;
|1190&lt;br /&gt;
|32 + 32&lt;br /&gt;
|10 + 5&lt;br /&gt;
|2&lt;br /&gt;
|getaktet + linear&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HMP2030&lt;br /&gt;
|1500&lt;br /&gt;
|32 + 32 + 32&lt;br /&gt;
|5 + 5 + 5&lt;br /&gt;
|3&lt;br /&gt;
|getaktet + linear&lt;br /&gt;
|-&lt;br /&gt;
|Rigol&lt;br /&gt;
|DP832 **)&lt;br /&gt;
|362&lt;br /&gt;
|30 + 30 + 5&lt;br /&gt;
|3 + 3 + 3&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VLP 1405pro&lt;br /&gt;
|1190&lt;br /&gt;
|40 + 6&lt;br /&gt;
|5 + 2&lt;br /&gt;
|2&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|PeakTech&lt;br /&gt;
|1885&lt;br /&gt;
|270&lt;br /&gt;
|40&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VLP 2403pro&lt;br /&gt;
|320&lt;br /&gt;
|40 + 40 + 6&lt;br /&gt;
|3 + 3 + 2&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VSP 2410&lt;br /&gt;
|470&lt;br /&gt;
|40 + 40 + 6&lt;br /&gt;
|10 + 10 + 1.5&lt;br /&gt;
|3&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|TTI&lt;br /&gt;
|EX355R&lt;br /&gt;
|330&lt;br /&gt;
|35&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|Mixed-mode (getaktet + linear)&lt;br /&gt;
|-&lt;br /&gt;
|TTI&lt;br /&gt;
|EX354RD&lt;br /&gt;
|480&lt;br /&gt;
|35 + 35&lt;br /&gt;
|4 + 4&lt;br /&gt;
|2&lt;br /&gt;
|Mixed-mode (getaktet + linear)&lt;br /&gt;
|-&lt;br /&gt;
|TTI&lt;br /&gt;
|EX354RT&lt;br /&gt;
|540&lt;br /&gt;
|35 + 35 + (1,5-5)&lt;br /&gt;
|4 + 4 + 5&lt;br /&gt;
|3&lt;br /&gt;
|Mixed-mode (getaktet + linear)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
 **) Das Rigol DP832(A) schaltet die Ausgänge nicht physisch/galvanisch ab. Die Power-MOSFETs der Ausgangsstufe werden lediglich auf Soll-NULL gesetzt. Dies kann bei Drift auch durchaus ungleich 0,00 Volt bedeuten!&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Spannungsversorgung_und_Energiequellen]]&lt;/div&gt;</summary>
		<author><name>8023</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Scheduler_mit_Erweiterung_zum_Mini-Betriebssystem&amp;diff=92420</id>
		<title>Scheduler mit Erweiterung zum Mini-Betriebssystem</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Scheduler_mit_Erweiterung_zum_Mini-Betriebssystem&amp;diff=92420"/>
		<updated>2016-03-17T05:46:59Z</updated>

		<summary type="html">&lt;p&gt;8023: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt; &amp;lt;u&amp;gt;&#039;&#039;&#039;Vorwort&#039;&#039;&#039;&amp;lt;/u&amp;gt;&amp;lt;/big&amp;gt;:&amp;lt;br /&amp;gt;&lt;br /&gt;
Dieser Artikel behandelt die Erstellung eines Schedulers, der zu einem Mini-OS erweitert wird. Ziel ist es, das Verständnis sowie die Funktion eines OS besser verstehen zu können. Wie so manch ein anderer habe auch ich mich gefragt, wie ein Betriebssystem eigentlich funktioniert, und - weil Nachbauen eine der besten Möglichkeit ist etwas zu verstehen - habe mir mein eigenes kleines System geschrieben. Es geht nicht darum ein „Suppa-Duppa“ OS zu schreiben, sondern zu verstehen wie größere (RTOS-&amp;gt;Linux-&amp;gt;Windows) funktionieren. &amp;lt;br /&amp;gt;&lt;br /&gt;
Von: Sebastian Balz &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Alle Beispiele beziehen sich auf einen ARM-Cortex-M4 (SAM4SD32C), sollten jedoch auf alle gängigen µC portiert werden können. Um den Kontext-Switch zu vereinfachen werden keine Gleitkomma Berechnungen unterstützt.  &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
= Voraussetzungen =&lt;br /&gt;
 &amp;lt;br /&amp;gt;&lt;br /&gt;
* Gute C und Assembler Kenntnisse &lt;br /&gt;
* Gute Kenntnisse des UC‘s&lt;br /&gt;
* Viel Zeit und Motivation :)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Zielsetzung= &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Das beschriebene System soll in der Lage sein:&lt;br /&gt;
* Zwischen verschiedenen Aufgaben (Tasks) zu wechseln(Context-Switch). D.h. jeder Task hat das Gefühl, dass der UC ihm gehört. &lt;br /&gt;
* Fähigkeit der Task’s sich selber zu beenden oder zu pausieren, um so CPU-Ressourcen zu sparen. &lt;br /&gt;
* Keinerlei Auswirkung aufs Interrupt Handling.&lt;br /&gt;
* Ein Zeit Management&lt;br /&gt;
* Tasks und Threads mit Return-Wert und Kill&lt;br /&gt;
* Kommunikation zwischen den Tasks mit Schreib-Kontrolle &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Grundlagen = &lt;br /&gt;
&lt;br /&gt;
Die Hauptaufgabe des Systems ist es, zwischen den verschiedenen Tasks wechseln zu können. &lt;br /&gt;
Um dies realisieren zu können, muss man erst einmal verstehen, wie überhaupt ein Kontext ausschaut.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Register== &lt;br /&gt;
Register sind die Speicherzellen, die direkt mit der CPU verbunden sind. Sie haben die besten Lese- und Schreibraten, sind jedoch „teuer“, weshalb in einer CPU nur relativ wenige Register vorhanden sind. &lt;br /&gt;
In der ARM-Cortex-M4 Serie sind es 12 sog. „General-Purpose Register“ und ein paar Spezial-Register. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:Register Balz.PNG|900px]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quelle: Datenblatt Register&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Stack == &lt;br /&gt;
&lt;br /&gt;
Der Stack ist ein LIFO (Last in, First out), d.h. der zuletzt hinzugefügte Wert wird als erstes wieder ausgelesen. Über Push (Speicher) und POP (Laden) kann man Register-Inhalte auf den Stack speichern und laden.&lt;br /&gt;
Des Weiteren gibt es einen Stack-Pointer. Dieser zeigt immer auf die letzte Adresse im Stack. &lt;br /&gt;
Der Stack baut sich von einer Speicherzelle aus nach unten auf. D.h., wenn ein Wert auf den Stack geschrieben wird, verringert sich die Stack-Adresse. &lt;br /&gt;
&lt;br /&gt;
Jedes Programm schreibt und erstellt seine lokalen Variablen auf dem Stack (RAM). Bei einem Funktionsaufruf werden Übergabeparameter und die Rücksprungadresse im Stack hinterlegt. &lt;br /&gt;
Die aufgerufene Funktion des Speichers (Push) hat also so viele Register auf dem Stack, wie sie selber Register benötigt, damit beim „Return“ wieder die Start-Register vom Stack geholt (POP) werden können und damit der „vor-Funktion-Zustand“ wieder hergestellt ist. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exception Call ==&lt;br /&gt;
Wird eine Funktion durch einen Interrupt unterbrochen, werden R0-R3,R12, LR, PC und xPSR (eine Verbindung aus “Interrupt Program Status Register“, “Application Program Status Register“, „Program Status Register“ und „Execution Program Status Register“) auf den Stack gepusht.&lt;br /&gt;
[[Datei:Stack Balz.PNG]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quelle Datenblatt: Interrupt Stack &amp;lt;br /&amp;gt;&lt;br /&gt;
Der µC schreibt beim “Interrupt entry“ eine EXC_Return_Value ins Link um zu signalisieren, dass gerade eine Interrupt-Routine aktiv ist.   &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:EXC Return Balz.PNG |700px]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quelle: Datenblatt Exc_Return &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Beim Verlassen des ISRs müssen nun nur noch die Register R0-R3, LR,SP und die Status-Register wieder hergestellt werden.   &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Context-Switch =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Theorie==&lt;br /&gt;
Um nun den aktuellen Kontext zu wechseln, müssen in einem Interrupt sämtliche Register gespeichert werden (PUSH R0-R12) und der Stack-Pointer auf den Stack des neuen Task‘s verschoben werden. Nun können die Register wieder hergestellt werden (POP R0-R12). Das Link-Register kann hier außer Acht gelassen werden, da es immer den Wert 0xFFFFFF9 (Return to Thread mode without floating point calculation) hat. &lt;br /&gt;
Wenn man nun das ISR von außen betrachtet, darf man keinen Unterschied zum letzten Speicherzeitpunkt feststellen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Move Stack Balz.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Praxis ==&lt;br /&gt;
=== Speicher ===&lt;br /&gt;
Die Praxis ist leider etwas komplizierter: Zunächst einmal muss der Task-Stack im Speicher reserviert werden. Hierfür kann entweder malloc() verwendet werden - um dynamisch zur Laufzeit den Speicher zu reservieren - oder man „belegt“ den Speicher über Arrays. Da ein Stack-Overflow mit, dass Schlimmste ist, was unserem System passieren kann (Überschreibung der anderen Stacks/globalen Variablen), sollte die Größe des Stacks eher großzügig definiert sein.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stackerzeugen=== &lt;br /&gt;
Da ein Stack sich von oben nach unten (aus Sicht des Speichers) aufbaut, muss der Stack-Pointer auf die Speicheradresse des letzten Array-Elementes zeigen.&lt;br /&gt;
Da beim Kontext-Switch der letzte Zustand wiederhergestellt wird, muss nun der Stack befüllt werden: &lt;br /&gt;
&lt;br /&gt;
* Programm Counter: hier wird die Startadresse des Task‘s eingetragen &lt;br /&gt;
* Link–Register: Da die Task-Ansicht keine Funktion ist und im Normalfall nicht irgendwann verlassen wird, kann dieses Feld freigelassen werden. Alternativ kann auch auf die Adresse eines Dummy-Handlers verwiesen werden, der sich dann um die Beendigung des Tasks kümmert.&lt;br /&gt;
* Program Status Register: Im Status Register (xPSR) wird der Wert hinterlegt, der der CPU signalisiert, dass der aktuelle Programmabschnitt sich gerade in einem Interrupt befindet.&lt;br /&gt;
* Register 0-3,12 sind die Register, die vor einem Interrupt gesichert und nach dem Interrupt wieder hergestellt werden. Da der Task noch keine Registerwerte verwendet hat, können diese Zellen frei bleiben. &lt;br /&gt;
&lt;br /&gt;
Wenn nun ein Kontext-Switch ausführt wird, wird man relativ schnell feststellen, dass etwas noch nicht passt. &lt;br /&gt;
Die Interrupt-Routine hat selber auch Variablen, die auf dem „alten“ Stack gespeichert und nach Verlassen des Stacks wieder vom Stack „gelöscht“ werden müssen. Diese müssen in dem neuen Stack berücksichtigt werden. Leider kann man hier keinen pauschalen Wert nennen, was dazu führt, dass jede Veränderung an der Interrupt-Routine Folgen haben kann. So muss z.B. bei dem neuem Stack die Anzahl der lokalen Register einbezogen werden. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Kontext wechseln ===&lt;br /&gt;
Nun, da der Speicher reserviert und der Stack aufgebaut worden ist, kann man den Kontext wechseln. &lt;br /&gt;
Hierfür müssen alle General-Purpose-Register auf den Stack gespeichert werden. &lt;br /&gt;
Da zu einem späteren Zeitpunkt der Stack wieder zurück gewechselt werden soll, muss nun der aktuelle Stack-Pointer gesichert werden, z.B. in der Task_List (siehe Task_Liste).&lt;br /&gt;
Der „alte“ Kontext ist nun gesichert, und so kann der „Neue“ geladen werden. Zunächst muss der Stack-Pointer umgezogen werden.&lt;br /&gt;
Um sicher zu stellen, dass der µC nun den neuen Stack auch verwendet, muss ein „Pipeline flush“ getätigt werden. Hierfür ist im TUMB2-Befehlssatz der Befehl „ISB“ (Instruction Synchronization Barrier) vorhanden, der direkt nach dem Stack-Pointer-Tausch ausgeführt werden sollte. &lt;br /&gt;
Nun können die Register 0-12 wieder hergestellt werden. Das Linkregister verändert sich nicht, da das Exc_return Value immer gleich ist.&lt;br /&gt;
&lt;br /&gt;
Wird nun die Interrupt Routine verlassen, werden die lokalen Variablen vom Stack gelöscht und die ISR-Inhalte gePOP’t. Der Prozessor springt dann „zurück“ in den neuen Task.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== BSP1 ==== &lt;br /&gt;
Im folgenden Bild kann man gut sehen, wie zwei Tasks (weiße Kästen: PWM) abwechselnd aufgerufen werden. Dargestellt ist die Aktivität der Tasks als Funktion der Zeit; alle 50 ms wird in diesem Beispiel der Task gewechselt: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:Context Switch.JPG | 900px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Task-Liste==&lt;br /&gt;
Damit das System weiß, wie viele und welche Tasks gerade ausgeführt werden, muss eine Liste erstellt werden, in der die jeweiligen IDs der Tasks enthalten sind, sowie:&lt;br /&gt;
* Stack-Pointer&lt;br /&gt;
* Stack Start Adresse&lt;br /&gt;
* Stack-Size&lt;br /&gt;
Optional kann in dieser Liste auch noch: &lt;br /&gt;
* Task Status/Message&lt;br /&gt;
* Thread Return_Value&lt;br /&gt;
enthalten sein.&lt;br /&gt;
=== Stack Pointer === &lt;br /&gt;
Um bei einem Kontext Switch den alten Task wieder herzustellen, muss bekannt sein, an welcher Stelle im Speicher der Stack liegt. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Stack Start Adresse === &lt;br /&gt;
Ist relevant, wenn überprüft werden soll, ob es einen Stack Overflow gab. Sollte es ein Stack-Overflow geben muss dies gemeldet und das System wieder auf den Ursprungszustand gesetzt werden.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stack-Size === &lt;br /&gt;
Wird in Verbindung mit der Stack_Start Adresse für die Overflow-Erkennung benötigt.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Task Status === &lt;br /&gt;
Hier kann ein Task seinen Status mitteilen&lt;br /&gt;
* IDLE&lt;br /&gt;
* Started(läuft der Task gerade?)&lt;br /&gt;
* Oder soll der Stack des Task‘s aufgebaut werden&lt;br /&gt;
* Lese Fehler (siehe Speicher Management)&lt;br /&gt;
&lt;br /&gt;
=== Return Value === &lt;br /&gt;
wird ein Thread auf geplante Weise verlassen – (d.h. er beendet sich selber) –kann dieser auch ein Return_Value als Ergebnis hinterlegen. Hat der Thread z.B. die Aufgabe, eine Nutzereingabe zu erkennen und zu analysieren, so kann der erstellende Task (der die ID kennt) über das Ergebnis informiert werden.  &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
== Zeitmanagement ==&lt;br /&gt;
&lt;br /&gt;
=== System-Zeit ===&lt;br /&gt;
Oftmals kommt es vor, dass ein Task eine Tätigkeit alle x ms ausführen soll. Da jedoch die Tasks möglichst unabhängig sein sollen (sie wissen also nicht mit welcher Taktrate der Prozessor läuft), ist es sinnvoll, über eine RTT oder einen Timer/Counter die Zeit mitzuzählen und diese über eine Funktion allen Tasks und Threads zur Verfügung zu stellen. &lt;br /&gt;
Auch ist es sinnvoll, eine Funktion bereit zu stellen, die überprüft ob eine bestimmt Zeit vergangen ist; unter Berücksichtigung, dass die System-Zeit irgendwann wieder bei 0 anfängt. &lt;br /&gt;
Eine solche Funktion könnte wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int vergangene_zeit(int os_lasttime, int soll_time){&lt;br /&gt;
	int time_know = get_os_time(); // hole die aktuelle Systhem Zeit&lt;br /&gt;
	int delta;&lt;br /&gt;
	if (zeit-lasttime &amp;lt;0) // hat ein System-Zeit Wraparound stattgefunden &lt;br /&gt;
	{&lt;br /&gt;
		zeit += os_max_time; // addiere Max SysthemZeit drauf&lt;br /&gt;
	}&lt;br /&gt;
	delta = zeit-lasttime; &lt;br /&gt;
	return delta &amp;gt;= sollzeit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So kann ein Task einfach in einer  &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; while(!(vergangene_zeit(lasttime,soll_time))){}&amp;lt;/syntaxhighlight&amp;gt; darauf warten, dass die Soll Zeit abgelaufen ist. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Kontext-Switch ===&lt;br /&gt;
Natürlich ist es auch wichtig, dass der Kontext-Switch zentral gesteuert wird. Hier ist es empfehlenswert, den Real-Time-Timer oder einen Timer/Counter zu verwenden, der die Systemzeit managt. Über ein Static counter kann/soll eine bestimmte Anzahl an Zyklen bestimmt werden, bei denen der Kontext-Switch getriggert wird. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== IDLE ===&lt;br /&gt;
Hat man mehrere Tasks die darauf warten, dass Zeit vergeht, wird viel Rechenleistung verbraucht, da die Tasks mit Nichtstun beschäftigt sind, während andere Tasks diese Rechenzeit gut brauchen könnten. &lt;br /&gt;
Um diesem Problem zu entgehen, sollte ein Task in der Lage sein, sich als inaktiv zu deklarieren. Dies könnte über einen Status-Bit geschehen, welches der Time_manager bei jedem Erhöhen der Systemzeit überprüft und den Kontext-Switch triggert.&lt;br /&gt;
Eine bessere Lösung wäre jedoch, zusätzlich zur IDLE Funktion einen Software Interrupt auszulösen, welcher den TC_Handler oder RTT_Handler des Zeitmanagements triggert. &lt;br /&gt;
So kann im Zeitmanagement geprüft werden, ob ein Task IDLE ist, oder ob der Interrupt auf herkömmliche Weise generiert worden ist. &lt;br /&gt;
Sollten ein Großteil oder alle Task IDLE sein, sollte die CPU in ein LOW-Power-Mode wechseln. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Beispiel 1====&lt;br /&gt;
&lt;br /&gt;
Im folgenden Beispiel kann gut erkannt werden, wie sich Task1 zur Hälfte der möglichen Laufzeit als IDLE deklariert und einen Kontext-Switch triggert. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Task IDLE.JPG|900px]]&lt;br /&gt;
Saleae Logic Analyser: Task IDLE &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Tasks und Threads zur Laufzeit erstellen und beenden =&lt;br /&gt;
&lt;br /&gt;
Eine weite Stärke eines solchen Systems ist es, dass dann ohne großen Aufwand einfach ein neuer Task oder Thread hinzugefügt werden kann.&lt;br /&gt;
Ein Thread hat eine feste Aufgabe die er erfüllen soll. Ist diese erfüllt, können weitere Ereignisse getriggert werden, oder der Thread kann beendet werden. &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Starten ===&lt;br /&gt;
Hierfür muss lediglich ein neuer Stack mit Linkregister, Einsprung-Adresse etc. hinzugefügt werden und über die Task_Liste dem Zeitmanagement mitgeteilt werden, sodass es einen neuen Taskeintrag gibt, der gestartet werden soll. &lt;br /&gt;
==== Beispiel 2 ====&lt;br /&gt;
&lt;br /&gt;
Hier kann gut erkannt werden, wie Thread 1 während der Laufzeit erstellt wird und von nun an vom Scheduler aufgerufen wird. Hierdurch werden jedoch Task1 und Task2 seltener aufgerufen.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Thread start.JPG |900px]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beenden ===&lt;br /&gt;
Ein Thread kann auf zwei Arten beendet werden. Die reguläre Art ist, dass er sich selber schließt. Hierfür kann eine Funktion geschrieben werden, die der Task_Liste mitteilt, dass der Task beim nächsten Kontext-Switch nicht mehr aufgerufen werden soll. Optional kann in der Task_List ein Return Value hinterlegt werden, damit der Ersteller des Tasks z. B. ein Ergebnis erhält. Hierbei ist wichtig, zuerst den Return_value zu setzen bevor der Task als beendet definiert wird, da ansonsten ein ungünstiges Timing mit dem Kontext-Switch das Schreiben des Return_Values verhindert. Nachdem Return_value und der Task als beendet definiert worden sind, sollte der Task einen Task_IDLE an den Zeitmanager senden, um so den Task direkt zu verlassen und keine Rechenzeit zu vergeuden.&lt;br /&gt;
Auch ist es nötig, dass der Ersteller des Threads die ID des Threads in der Task_Liste erhält, da hinter der ID des Threads auch der Return_Value gespeichert wird. &lt;br /&gt;
Eine andere Art ein Thread zu beenden ist, ihn zu killen. Wenn z. B. die Ausführung des Threads nicht mehr relevant ist, weil das Ergebnis zu spät kommen würde (Real-Time-OS), oder die Ausführung des Threads nicht mehr benötigt wird, kann man einen Thread auch über die Task-Liste von außen beenden. Hierbei muss nur das Task_Active-Bit gelöscht werden.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Beispiel 3 ====&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Thread closing.JPG|900px]]&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
Hier kann gut erkannt werden, wie Thread1 wieder geschlossen wird. Dadurch werden Task 1 und Task 2 wieder öfter aufgerufen.  &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Interrupte =&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Eigentlich sollte es keinerlei Probleme bereiten, einen Interrupt auszuführen, da dieser den aktuellen Task nicht berührt. &lt;br /&gt;
Es muss lediglich auf zwei Punkte Rücksicht genommen werden:&lt;br /&gt;
* Der Zeitmanager muss in der niedrigsten Priorität laufen. Würde er mit einer höheren Priorität laufen während gerade ein anderer Interrupt aktiv ist, würden die gespeicherten Register in den falschen Stack abgelegt. Die wieder herzustellenden Register kämen aus einem Stack, in dem keine Register gesichert worden sind. Dieser Vorgang würde beide Stacks zerstören.&lt;br /&gt;
* Während des Kontext Switches dürfen keine anderen Interrupts aktiv werden, da es auch hier zu Problemen mit den Stacks kommen könnte.&lt;br /&gt;
Deshalb ist es empfehlenswert, den Zeitmanager in der niedrigsten Priorität laufen zu lassen und während der Ausführung andere Interrupts zu unterbinden. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Erweiterung zum OS =&lt;br /&gt;
Von nun an sind die Übergänge zu einem Betriebssystem fließend. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
== Priorisierung ==&lt;br /&gt;
in Arbeit!&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Speicher Management == &lt;br /&gt;
Der erste Schritt in Richtung Betriebssystem ist ein Speicher-Management, welches in der Lage ist, Speicher zu reservieren und gegebenenfalls auch zu blockieren, sowie freizugeben. Hier kommt wieder – wie beim Stack-Aufbau - malloc() oder ein Array zum Einsatz. Der Einfachheit halber werden die einzelnen Speicher über ID’s angesprochen. Auch muss zentral geregelt werden, ob die jeweilige ID bereits in Verwendung ist. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Erstellen ===&lt;br /&gt;
Möchte ein Task oder Thread einen solchen Speicher erstellen, muss zunächst überprüft werden, ob noch Speicherplätze frei sind. In diesem Fall kann die ID der Speicherzelle zurückgegeben werden (return-Wert). Andernfalls sollte ein Error_Value zurück geliefert werden.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Freigeben ===&lt;br /&gt;
Um Speicher zu sparen, müssen Task und Threads in der Lage sein, den Speicher wieder frei zu geben. Sollte ein Task der beim Speicher durch einen Kontext –Switch unterbrochen worden ist, auf denselben Speicher zugreifen, sollte vor dem Freigeben überprüft werden, ob und warum der Speicher gesperrt worden ist. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Speichern ===&lt;br /&gt;
Um ein ungünstiges Timing zu verhindern (z. B. ein Prozess beschreibt eine Speicherzelle und wird während des Schreibvorganges durch einen Kontext-Switch unterbrochen), sollte nun der Speicher durch einen anderen Task wieder freigegeben werden. Hierzu muss vor dem Schreibvorgang signalisiert werden, dass die jeweilige Zelle blockiert ist. Als Return kann hier dann entweder ein Error_value oder ein Success_Value übertragen werden.  &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lesen === &lt;br /&gt;
Zum Lesen muss lediglich überprüft werden, ob der Speicher der angegebenen ID reserviert ist. Als Return kann hier dann entweder der gespeicherte Wert oder ein Error_Value verwendet werden. Um zu erkennen ob es sich hier um einen Fehler handelt oder um einen gespeicherten Wert, kann über die Task_Liste (ID sollte bekannt sein!) ein Statusbit gesetzt werden.  &amp;lt;br /&amp;gt;&lt;br /&gt;
 &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kommunikation mit anderen Task‘s ==&lt;br /&gt;
Oftmals ist es notwendig, dass die Tasks in der Lage sind, miteinander zu kommunizieren und so Ergebnisse auszutauschen. Hierfür kann ein weiterer Eintrag in der Task-Liste weiterhelfen, der einen anderen Task darüber informiert unter welcher Speicher-ID neue Informationen verfügbar sind. Die jeweiligen Tasks müssen dazu jedoch über die ID der jeweils anderen Task Bescheid wissen. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Realtime == &lt;br /&gt;
Je nach Anwendungsfall kann es wichtig sein, dass manche Threads innerhalb einer bestimmten Zeit ausgeführt werden müssen. Hierzu werden für die Threads Prioritäten vergeben, welche gewährleisten, dass die Threads länger oder häufiger ausgeführt werden (je nach Definition). Möglicherweise ergibt die Ausführung/Beendigung eines Threads auch nach einem bestimmten Zeitpunkt keinen Sinn mehr.&lt;br /&gt;
Beispiel: Ein Sensor soll alle 10 ms ausgelesen werden. Der Sensor liefert immer das aktuelle Messergebnis. Wird nun der Thread (der alle 10 ms getriggert wird um einen Sensor auszulesen) von einem wichtigeren Ereignis unterbrochen und so z. B. über 50ms verzögert, so warten dann 5 getriggerte Threads darauf, CPU Zeit zugewiesen zu bekommen. Da aber immer nur der aktuelle Sensorwert ausgegeben werden kann, liefern alle 5 Threads dasselbe Ergebnis. Um nun Ressourcen zu sparen, muss erkannt werden, ob die Ausführung dieses Threads noch sinnvoll ist. Andernfalls sollten die Threads beendet werden und es kann eine Fehlermeldung generiert werden. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Fehlersuche und Kontrolle =&lt;br /&gt;
== Register Kontrolle ==&lt;br /&gt;
Zunächst ist es wichtig zu überprüfen, ob alle Variablen und Register denselben Wert wie nach einem Kontext Switch haben. Hier ist es empfehlenswert, beim Erstellen des Tasks lokale Variablen mit eindeutigen Werten zu erstellen und anschließend in einer while(1)-Schleife laufen zu lassen. &lt;br /&gt;
Die einfachste Überprüfung ist hier: Mit dem Debugger einen Breakpoint in der while(1)-Schleife des Programms zu setzen und nach dem Kontext-Switch anzuhalten, um auf diese Weise die Variablen zu überprüfen.&lt;br /&gt;
&lt;br /&gt;
Mögliche Fehlerquellen: &lt;br /&gt;
* Stack Pointer zeigt auf die falsche Adresse&lt;br /&gt;
* Zuviele oder nicht ausreichend lokale Variablen -der ISR-  nach Verlassen der ISR gelöscht&lt;br /&gt;
* Register in falscher Reihenfolge wiederhergestellt&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Void Test_Task1(){&lt;br /&gt;
Start_task();&lt;br /&gt;
int a = 3; &lt;br /&gt;
	int b = 1;&lt;br /&gt;
	int c = 2; &lt;br /&gt;
	int d = 3; &lt;br /&gt;
	int e = 4;&lt;br /&gt;
	int f = 5;&lt;br /&gt;
	int g = 6;&lt;br /&gt;
	int h = 7;&lt;br /&gt;
while(1){&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen  ==&lt;br /&gt;
Wenn sichergestellt wurde, dass die Register und Variablen nach einem Kontext Switch unverändert bestehen, kann mit einer einfachen Rechenoperation, die je nach Ausgangswert ein anderes Ergebnis liefert, überprüft werden, ob die Wiedereinsprungsadresse stimmt. &lt;br /&gt;
Da lokale Variablen zerstört werden können, sollten globale Variablen hierfür verwendet werden, da diese eben nicht im Stack gespeichert werden. Zusätzlich sollte ein Fehlercounter inkrementiert werden.&lt;br /&gt;
&lt;br /&gt;
Mögliche Fehlerquellen: &lt;br /&gt;
* Falsches Link Register &lt;br /&gt;
* Falscher PC &lt;br /&gt;
* Fehlerhafte Register und/oder Variablen&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
Hier eignet sich die Berechnung der ersten Fibonacci-Zahlen, da hier jedes weitere Ergebnis vom Vorherigen abhängt.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Int error;&lt;br /&gt;
Void Test_Task2(){&lt;br /&gt;
Start_Task();&lt;br /&gt;
int a = 1;&lt;br /&gt;
	int b = 1;&lt;br /&gt;
	int c;&lt;br /&gt;
int counter = 0;&lt;br /&gt;
while(1){&lt;br /&gt;
		c = a;&lt;br /&gt;
		a = b+a;&lt;br /&gt;
		b = c;	&lt;br /&gt;
switch(counter){&lt;br /&gt;
		case 0:if(!(b==1)){&lt;br /&gt;
				error++;&lt;br /&gt;
				}break;&lt;br /&gt;
		case 1:if(!(b==2)){&lt;br /&gt;
				error++;}break;&lt;br /&gt;
		case 2:if(!(b==3)){&lt;br /&gt;
				error++;}break;&lt;br /&gt;
		case 3:if(!(b==5)){&lt;br /&gt;
		                error++;}break;&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
        ...&lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                default:counter = -1; b = 1; a = 1;break;&lt;br /&gt;
             }&lt;br /&gt;
          counter ++;&lt;br /&gt;
     }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Funktionskaskade == &lt;br /&gt;
Um zu überprüfen, ob Linkregister und Programmcounter richtig gesichert wurden, kann man via Funktionkaskaden überprüfen, ob alle Funktionen in der richtigen Reihenfolge aufgerufen werden, und ob sie auch wieder richtig verlassen werden. Auch wichtig sind Übergabeparameter und return values. &lt;br /&gt;
Sollte es hier zu einem Fehler kommen, kann es sein, dass nur die lokalen Variablen verloren gehen. Es kann jedoch auch passieren, dass nach dem Verlassen der Funktion zu viel oder zu wenig vom Stack geladen wird, wodurch eine falsche Rücksprungadresse geladen wird. Mit etwas Glück erkennt der µC dies und springt dann in einen Fault-Handler.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möglichen Fehler Quellen: &lt;br /&gt;
* Link Register hatt die Falsche Adresse&lt;br /&gt;
* Fehlerhafte Register  und/oder Variablen&lt;br /&gt;
* Falscher Programcounter&lt;br /&gt;
* Register 7 (kann von UC, Compiler oder IDE unterschiedlich sein) bei einem Funktions Call wird in einem Register der alte Stackpointer hinterlegt, ob zu zeigen, wie viele Lokale Variablen nach Verlassen der aktuellen Funktion auf dem Stack nicht mehr benötigt werden. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int tester;&lt;br /&gt;
int error;&lt;br /&gt;
void Task_test3(){&lt;br /&gt;
	while(1){&lt;br /&gt;
		tester = 1;&lt;br /&gt;
		int dummy = test1(5,6);&lt;br /&gt;
		&lt;br /&gt;
		if(dummy != 9 || tester != 4){&lt;br /&gt;
			error ++;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
int test1(int a, int b){&lt;br /&gt;
		if(tester != 1){&lt;br /&gt;
			error++;&lt;br /&gt;
		}&lt;br /&gt;
		tester = 2;&lt;br /&gt;
		int dummy = test2(7);&lt;br /&gt;
		if(a != 5 || b != 6 || dummy != 8 || tester != 3){&lt;br /&gt;
			error++;&lt;br /&gt;
		}&lt;br /&gt;
		tester = 4;&lt;br /&gt;
		return 9;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
int test2(int a)&lt;br /&gt;
{&lt;br /&gt;
		if(a != 7 || tester != 2){&lt;br /&gt;
			error ++;&lt;br /&gt;
		}&lt;br /&gt;
		tester = 3;&lt;br /&gt;
		return 8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight &amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kein Kontext Switch mehr ==&lt;br /&gt;
Sollten plötzlich keine Kontext-Switche mehr stattfinden(ein Task wird nicht mehr verlassen) sollten man im Interrupt_Manager –„ Nested Vectored Interrupt Controller“ (NVIC) -  nachschauen, ob das Interrupt_Active_Bit gesetzt ist. Sollte dies der Fall sein, wurde der Kontext-Switch nicht richtig verlassen und der Prozessor glaubt, er würde noch immer den Interrupt ausführen. Viele Prozessoren - unter anderem ARM - erlauben kein Repending(doppeltes Ausführen) eines Interruptes.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Mögliche Fehlerquellen: &lt;br /&gt;
* Linkregister: Bei einem Interrupt Aufruf wird das Link Register mit einem Exp_return_Value beschreiben. Dieser sagt aus, auf welche Art und ob nach Verlassen der Funktion das Interrupt abgeschlossen wurde. So weiss der UC, ob z.B. noch ein Interrupt mit einer niedrigeren Priorität unterbrochen wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Lektüre = &lt;br /&gt;
*	µC/OS-III: The Real-Time Kernel https://www.micrium.com/books/ucosiii/ &lt;br /&gt;
*	http://infocenter.arm.com  &lt;br /&gt;
*	Datenblatt&lt;br /&gt;
*       &#039;&#039;&#039;Grundlagen:&#039;&#039;&#039; https://www.mikrocontroller.net/articles/Multitasking&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Quellen =&lt;br /&gt;
*	µC/OS-III: The Real-Time Kernel&lt;br /&gt;
*	SAM4S-Datenblatt  http://www.atmel.com/Images/Atmel-11100-32-bit%20Cortex-M4-Microcontroller-SAM4S_Datasheet.pdf &lt;br /&gt;
&lt;br /&gt;
= Link Sammlung = &lt;br /&gt;
* https://www.mikrocontroller.net/topic/381051&lt;br /&gt;
* https://www.mikrocontroller.net/topic/389195?goto=4457089#4457089&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Autor = &lt;br /&gt;
Sebastian Balz&lt;br /&gt;
[[Kategorie:ARM]]&lt;br /&gt;
[[Kategorie:Betriebssysteme]]&lt;/div&gt;</summary>
		<author><name>8023</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Scheduler_mit_Erweiterung_zum_Mini-Betriebssystem&amp;diff=92419</id>
		<title>Scheduler mit Erweiterung zum Mini-Betriebssystem</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Scheduler_mit_Erweiterung_zum_Mini-Betriebssystem&amp;diff=92419"/>
		<updated>2016-03-17T05:46:13Z</updated>

		<summary type="html">&lt;p&gt;8023: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt; &amp;lt;u&amp;gt;&#039;&#039;&#039;Vorwort&#039;&#039;&#039;&amp;lt;/u&amp;gt;&amp;lt;/big&amp;gt;:&amp;lt;br /&amp;gt;&lt;br /&gt;
Dieser Artikel behandelt die Erstellung eines Schedulers, der zu einem Mini-OS erweitert wird. Ziel ist es, das Verständnis sowie die Funktion eines OS besser verstehen zu können. Wie so manch ein anderer habe auch ich mich gefragt, wie ein Betriebssystem eigentlich funktioniert, und - weil Nachbauen eine der besten Möglichkeit ist etwas zu verstehen - habe mir mein eigenes kleines System geschrieben. Es geht nicht darum ein „Suppa-Duppa“ OS zu schreiben, sondern zu verstehen wie größere (RTOS-&amp;gt;Linux-&amp;gt;Windows) funktionieren. &amp;lt;br /&amp;gt;&lt;br /&gt;
Von: Sebastian Balz &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&amp;lt;br /&amp;gt;&lt;br /&gt;
Alle Beispiele beziehen sich auf einen ARM-Cortex-M4 (SAM4SD32C), sollten jedoch auf alle gängigen µC portiert werden können. Um den Kontext-Switch zu vereinfachen werden keine Gleitkomma Berechnungen unterstützt.  &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
= Voraussetzungen =&lt;br /&gt;
 &amp;lt;br /&amp;gt;&lt;br /&gt;
* Gute C und Assembler Kenntnisse &lt;br /&gt;
* Gute Kenntnisse des UC‘s&lt;br /&gt;
* Viel Zeit und Motivation :)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Zielsetzung= &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Das beschriebene System soll in der Lage sein:&lt;br /&gt;
* Zwischen verschiedenen Aufgaben (Tasks) zu wechseln(Context-Switch). D.h. jeder Task hat das Gefühl, dass der UC ihm gehört. &lt;br /&gt;
* Fähigkeit der Task’s sich selber zu beenden oder zu pausieren, um so CPU-Ressourcen zu sparen. &lt;br /&gt;
* Keinerlei Auswirkung aufs Interrupt Handling.&lt;br /&gt;
* Ein Zeit Management&lt;br /&gt;
* Tasks und Threads mit Return-Wert und Kill&lt;br /&gt;
* Kommunikation zwischen den Tasks mit Schreib-Kontrolle &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Grundlagen = &lt;br /&gt;
&lt;br /&gt;
Die Hauptaufgabe des Systems ist es, zwischen den verschiedenen Tasks wechseln zu können. &lt;br /&gt;
Um dies realisieren zu können, muss man erst einmal verstehen, wie überhaupt ein Kontext ausschaut.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Register== &lt;br /&gt;
Register sind die Speicherzellen, die direkt mit der CPU verbunden sind. Sie haben die besten Lese- und Schreibraten, sind jedoch „teuer“, weshalb in einer CPU nur relativ wenige Register vorhanden sind. &lt;br /&gt;
In der ARM-Cortex-M4 Serie sind es 12 sog. „General-Purpose Register“ und ein paar Spezial-Register. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:Register Balz.PNG|900px]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quelle: Datenblatt Register&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Stack == &lt;br /&gt;
&lt;br /&gt;
Der Stack ist ein LIFO (Last in, First out), d.h. der zuletzt hinzugefügte Wert wird als erstes wieder ausgelesen. Über Push (Speicher) und POP (Laden) kann man Register-Inhalte auf den Stack speichern und laden.&lt;br /&gt;
Des Weiteren gibt es einen Stack-Pointer. Dieser zeigt immer auf die letzte Adresse im Stack. &lt;br /&gt;
Der Stack baut sich von einer Speicherzelle aus nach unten auf. D.h., wenn ein Wert auf den Stack geschrieben wird, verringert sich die Stack-Adresse. &lt;br /&gt;
&lt;br /&gt;
Jedes Programm schreibt und erstellt seine lokalen Variablen auf dem Stack (RAM). Bei einem Funktionsaufruf werden Übergabeparameter und die Rücksprungadresse im Stack hinterlegt. &lt;br /&gt;
Die aufgerufene Funktion des Speichers (Push) hat also so viele Register auf dem Stack, wie sie selber Register benötigt, damit beim „Return“ wieder die Start-Register vom Stack geholt (POP) werden können und damit der „vor-Funktion-Zustand“ wieder hergestellt ist. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exception Call ==&lt;br /&gt;
Wird eine Funktion durch einen Interrupt unterbrochen, werden R0-R3,R12, LR, PC und xPSR (eine Verbindung aus “Interrupt Program Status Register“, “Application Program Status Register“, „Program Status Register“ und „Execution Program Status Register“) auf den Stack gepusht.&lt;br /&gt;
[[Datei:Stack Balz.PNG]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quelle Datenblatt: Interrupt Stack &amp;lt;br /&amp;gt;&lt;br /&gt;
Der µC schreibt beim “Interrupt entry“ eine EXC_Return_Value ins Link um zu signalisieren, dass gerade eine Interrupt-Routine aktiv ist.   &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:EXC Return Balz.PNG |700px]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quelle: Datenblatt Exc_Return &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Beim Verlassen des ISRs müssen nun nur noch die Register R0-R3, LR,SP und die Status-Register wieder hergestellt werden.   &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Context-Switch =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Theorie==&lt;br /&gt;
Um nun den aktuellen Kontext zu wechseln, müssen in einem Interrupt sämtliche Register gespeichert werden (PUSH R0-R12) und der Stack-Pointer auf den Stack des neuen Task‘s verschoben werden. Nun können die Register wieder hergestellt werden (POP R0-R12). Das Link-Register kann hier außer Acht gelassen werden, da es immer den Wert 0xFFFFFF9 (Return to Thread mode without floating point calculation) hat. &lt;br /&gt;
Wenn man nun das ISR von außen betrachtet, darf man keinen Unterschied zum letzten Speicherzeitpunkt feststellen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Move Stack Balz.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Praxis ==&lt;br /&gt;
=== Speicher ===&lt;br /&gt;
Die Praxis ist leider etwas komplizierter: Zunächst einmal muss der Task-Stack im Speicher reserviert werden. Hierfür kann entweder malloc() verwendet werden - um dynamisch zur Laufzeit den Speicher zu reservieren - oder man „belegt“ den Speicher über Arrays. Da ein Stack-Overflow mit, dass Schlimmste ist, was unserem System passieren kann (Überschreibung der anderen Stacks/globalen Variablen), sollte die Größe des Stacks eher großzügig definiert sein.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stackerzeugen=== &lt;br /&gt;
Da ein Stack sich von oben nach unten (aus Sicht des Speichers) aufbaut, muss der Stack-Pointer auf die Speicheradresse des letzten Array-Elementes zeigen.&lt;br /&gt;
Da beim Kontext-Switch der letzte Zustand wiederhergestellt wird, muss nun der Stack befüllt werden: &lt;br /&gt;
&lt;br /&gt;
* Programm Counter: hier wird die Startadresse des Task‘s eingetragen &lt;br /&gt;
* Link–Register: Da die Task-Ansicht keine Funktion ist und im Normalfall nicht irgendwann verlassen wird, kann dieses Feld freigelassen werden. Alternativ kann auch auf die Adresse eines Dummy-Handlers verwiesen werden, der sich dann um die Beendigung des Tasks kümmert.&lt;br /&gt;
* Program Status Register: Im Status Register (xPSR) wird der Wert hinterlegt, der der CPU signalisiert, dass der aktuelle Programmabschnitt sich gerade in einem Interrupt befindet.&lt;br /&gt;
* Register 0-3,12 sind die Register, die vor einem Interrupt gesichert und nach dem Interrupt wieder hergestellt werden. Da der Task noch keine Registerwerte verwendet hat, können diese Zellen frei bleiben. &lt;br /&gt;
&lt;br /&gt;
Wenn nun ein Kontext-Switch ausführt wird, wird man relativ schnell feststellen, dass etwas noch nicht passt. &lt;br /&gt;
Die Interrupt-Routine hat selber auch Variablen, die auf dem „alten“ Stack gespeichert und nach Verlassen des Stacks wieder vom Stack „gelöscht“ werden müssen. Diese müssen in dem neuen Stack berücksichtigt werden. Leider kann man hier keinen pauschalen Wert nennen, was dazu führt, dass jede Veränderung an der Interrupt-Routine Folgen haben kann. So muss z.B. bei dem neuem Stack die Anzahl der lokalen Register einbezogen werden. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Kontext wechseln ===&lt;br /&gt;
Nun, da der Speicher reserviert und der Stack aufgebaut worden ist, kann man den Kontext wechseln. &lt;br /&gt;
Hierfür müssen alle General-Purpose-Register auf den Stack gespeichert werden. &lt;br /&gt;
Da zu einem späteren Zeitpunkt der Stack wieder zurück gewechselt werden soll, muss nun der aktuelle Stack-Pointer gesichert werden, z.B. in der Task_List (siehe Task_Liste).&lt;br /&gt;
Der „alte“ Kontext ist nun gesichert, und so kann der „Neue“ geladen werden. Zunächst muss der Stack-Pointer umgezogen werden.&lt;br /&gt;
Um sicher zu stellen, dass der µC nun den neuen Stack auch verwendet, muss ein „Pipeline flush“ getätigt werden. Hierfür ist im TUMB2-Befehlssatz der Befehl „ISB“ (Instruction Synchronization Barrier) vorhanden, der direkt nach dem Stack-Pointer-Tausch ausgeführt werden sollte. &lt;br /&gt;
Nun können die Register 0-12 wieder hergestellt werden. Das Linkregister verändert sich nicht, da das Exc_return Value immer gleich ist.&lt;br /&gt;
&lt;br /&gt;
Wird nun die Interrupt Routine verlassen, werden die lokalen Variablen vom Stack gelöscht und die ISR-Inhalte gePOP’t. Der Prozessor springt dann „zurück“ in den neuen Task.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== BSP1 ==== &lt;br /&gt;
Im folgenden Bild kann man gut sehen, wie zwei Tasks (weiße Kästen: PWM) abwechselnd aufgerufen werden. Dargestellt ist die Aktivität der Tasks als Funktion der Zeit; alle 50 ms wird in diesem Beispiel der Task gewechselt: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:Context Switch.JPG | 900px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Task-Liste==&lt;br /&gt;
Damit das System weiß, wie viele und welche Tasks gerade ausgeführt werden, muss eine Liste erstellt werden, in der die jeweiligen IDs der Tasks enthalten sind, sowie:&lt;br /&gt;
* Stack-Pointer&lt;br /&gt;
* Stack Start Adresse&lt;br /&gt;
* Stack-Size&lt;br /&gt;
Optional kann in dieser Liste auch noch: &lt;br /&gt;
* Task Status/Message&lt;br /&gt;
* Thread Return_Value&lt;br /&gt;
enthalten sein.&lt;br /&gt;
=== Stack Pointer === &lt;br /&gt;
Um bei einem Kontext Switch den alten Task wieder herzustellen, muss bekannt sein, an welcher Stelle im Speicher der Stack liegt. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Stack Start Adresse === &lt;br /&gt;
Ist relevant, wenn überprüft werden soll, ob es einen Stack Overflow gab. Sollte es ein Stack-Overflow geben muss dies gemeldet und das System wieder auf den Ursprungszustand gesetzt werden.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stack-Size === &lt;br /&gt;
Wird in Verbindung mit der Stack_Start Adresse für die Overflow-Erkennung benötigt.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Task Status === &lt;br /&gt;
Hier kann ein Task seinen Status mitteilen&lt;br /&gt;
* IDLE&lt;br /&gt;
* Started(läuft der Task gerade?)&lt;br /&gt;
* Oder soll der Stack des Task‘s aufgebaut werden&lt;br /&gt;
* Lese Fehler (siehe Speicher Management)&lt;br /&gt;
&lt;br /&gt;
=== Return Value === &lt;br /&gt;
wird ein Thread auf geplante Weise verlassen – (d.h. er beendet sich selber) –kann dieser auch ein Return_Value als Ergebnis hinterlegen. Hat der Thread z.B. die Aufgabe, eine Nutzereingabe zu erkennen und zu analysieren, so kann der erstellende Task (der die ID kennt) über das Ergebnis informiert werden.  &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
== Zeitmanagement ==&lt;br /&gt;
&lt;br /&gt;
=== System-Zeit ===&lt;br /&gt;
Oftmals kommt es vor, dass ein Task eine Tätigkeit alle x ms ausführen soll. Da jedoch die Tasks möglichst unabhängig sein sollen (sie wissen also nicht mit welcher Taktrate der Prozessor läuft), ist es sinnvoll, über eine RTT oder einen Timer/Counter die Zeit mitzuzählen und diese über eine Funktion allen Tasks und Threads zur Verfügung zu stellen. &lt;br /&gt;
Auch ist es sinnvoll, eine Funktion bereit zu stellen, die überprüft ob eine bestimmt Zeit vergangen ist; unter Berücksichtigung, dass die System-Zeit irgendwann wieder bei 0 anfängt. &lt;br /&gt;
Eine solche Funktion könnte wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int vergangene_zeit(int os_lasttime, int soll_time){&lt;br /&gt;
	int time_know = get_os_time(); // hole die aktuelle Systhem Zeit&lt;br /&gt;
	int delta;&lt;br /&gt;
	if (zeit-lasttime &amp;lt;0) // hat ein System-Zeit Wraparound stattgefunden &lt;br /&gt;
	{&lt;br /&gt;
		zeit += os_max_time; // addiere Max SysthemZeit drauf&lt;br /&gt;
	}&lt;br /&gt;
	delta = zeit-lasttime; &lt;br /&gt;
	return delta &amp;gt;= sollzeit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So kann ein Task einfach in einer  &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; while(!(vergangene_zeit(lasttime,soll_time))){}&amp;lt;/syntaxhighlight&amp;gt; darauf warten, dass die Soll Zeit abgelaufen ist. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Kontext-Switch ===&lt;br /&gt;
Natürlich ist es auch wichtig, dass der Kontext-Switch zentral gesteuert wird. Hier ist es empfehlenswert, den Real-Time-Timer oder einen Timer/Counter zu verwenden, der die Systemzeit managt. Über ein Static counter kann/soll eine bestimmte Anzahl an Zyklen bestimmt werden, bei denen der Kontext-Switch getriggert wird. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== IDLE ===&lt;br /&gt;
Hat man mehrere Tasks die darauf warten, dass Zeit vergeht, wird viel Rechenleistung verbraucht, da die Tasks mit Nichtstun beschäftigt sind, während andere Tasks diese Rechenzeit gut brauchen könnten. &lt;br /&gt;
Um diesem Problem zu entgehen, sollte ein Task in der Lage sein, sich als inaktiv zu deklarieren. Dies könnte über einen Status-Bit geschehen, welches der Time_manager bei jedem Erhöhen der Systemzeit überprüft und den Kontext-Switch triggert.&lt;br /&gt;
Eine bessere Lösung wäre jedoch, zusätzlich zur IDLE Funktion einen Software Interrupt auszulösen, welcher den TC_Handler oder RTT_Handler des Zeitmanagements triggert. &lt;br /&gt;
So kann im Zeitmanagement geprüft werden, ob ein Task IDLE ist, oder ob der Interrupt auf herkömmliche Weise generiert worden ist. &lt;br /&gt;
Sollten ein Großteil oder alle Task IDLE sein, sollte die CPU in ein LOW-Power-Mode wechseln. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Beispiel 1====&lt;br /&gt;
&lt;br /&gt;
Im folgenden Beispiel kann gut erkannt werden, wie sich Task1 zur Hälfte der möglichen Laufzeit als IDLE deklariert und einen Kontext-Switch triggert. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Task IDLE.JPG|900px]]&lt;br /&gt;
Saleae Logic Analyser: Task IDLE &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Tasks und Threads zur Laufzeit erstellen und beenden =&lt;br /&gt;
&lt;br /&gt;
Eine weite Stärke eines solchen Systems ist es, dass dann ohne großen Aufwand einfach ein neuer Task oder Thread hinzugefügt werden kann.&lt;br /&gt;
Ein Thread hat eine feste Aufgabe die er erfüllen soll. Ist diese erfüllt, können weitere Ereignisse getriggert werden, oder der Thread kann beendet werden. &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Starten ===&lt;br /&gt;
Hierfür muss lediglich ein neuer Stack mit Linkregister, Einsprung-Adresse etc. hinzugefügt werden und über die Task_Liste dem Zeitmanagement mitgeteilt werden, sodass es einen neuen Taskeintrag gibt, der gestartet werden soll. &lt;br /&gt;
==== Beispiel 2 ====&lt;br /&gt;
&lt;br /&gt;
Hier kann gut erkannt werden, wie Thread 1 während der Laufzeit erstellt wird und von nun an vom Scheduler aufgerufen wird. Hierdurch werden jedoch Task1 und Task2 seltener aufgerufen.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Thread start.JPG |900px]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beenden ===&lt;br /&gt;
Ein Thread kann auf zwei Arten beendet werden. Die reguläre Art ist, dass er sich selber schließt. Hierfür kann eine Funktion geschrieben werden, die der Task_Liste mitteilt, dass der Task beim nächsten Kontext-Switch nicht mehr aufgerufen werden soll. Optional kann in der Task_List ein Return Value hinterlegt werden, damit der Ersteller des Tasks z. B. ein Ergebnis erhält. Hierbei ist wichtig, zuerst den Return_value zu setzen bevor der Task als beendet definiert wird, da ansonsten ein ungünstiges Timing mit dem Kontext-Switch das Schreiben des Return_Values verhindert. Nachdem Return_value und der Task als beendet definiert worden sind, sollte der Task einen Task_IDLE an den Zeitmanager senden, um so den Task direkt zu verlassen und keine Rechenzeit zu vergeuden.&lt;br /&gt;
Auch ist es nötig, dass der Ersteller des Threads die ID des Threads in der Task_Liste erhält, da hinter der ID des Threads auch der Return_Value gespeichert wird. &lt;br /&gt;
Eine andere Art ein Thread zu beenden ist, ihn zu killen. Wenn z. B. die Ausführung des Threads nicht mehr relevant ist, weil das Ergebnis zu spät kommen würde (Real-Time-OS), oder die Ausführung des Threads nicht mehr benötigt wird, kann man einen Thread auch über die Task-Liste von außen beenden. Hierbei muss nur das Task_Active-Bit gelöscht werden.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Beispiel 3 ====&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Thread closing.JPG|900px]]&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
Hier kann gut erkannt werden, wie Thread1 wieder geschlossen wird. Dadurch werden Task 1 und Task 2 wieder öfter aufgerufen.  &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Interrupte =&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Eigentlich sollte es keinerlei Probleme bereiten, einen Interrupt auszuführen, da dieser den aktuellen Task nicht berührt. &lt;br /&gt;
Es muss lediglich auf zwei Punkte Rücksicht genommen werden:&lt;br /&gt;
* Der Zeitmanager muss in der niedrigsten Priorität laufen. Würde er mit einer höheren Priorität laufen während gerade ein anderer Interrupt aktiv ist, würden die gespeicherten Register in den falschen Stack abgelegt. Die wieder herzustellenden Register kämen aus einem Stack, in dem keine Register gesichert worden sind. Dieser Vorgang würde beide Stacks zerstören.&lt;br /&gt;
* Während des Kontext Switches dürfen keine anderen Interrupts aktiv werden, da es auch hier zu Problemen mit den Stacks kommen könnte.&lt;br /&gt;
Deshalb ist es empfehlenswert, den Zeitmanager in der niedrigsten Priorität laufen zu lassen und während der Ausführung andere Interrupts zu unterbinden. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Erweiterung zum OS =&lt;br /&gt;
Von nun an sind die Übergänge zu einem Betriebssystem fließend. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
== Priorisierung ==&lt;br /&gt;
in Arbeit!&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Speicher Management == &lt;br /&gt;
Der erste Schritt in Richtung Betriebssystem ist ein Speicher-Management, welches in der Lage ist, Speicher zu reservieren und gegebenenfalls auch zu blockieren, sowie freizugeben. Hier kommt wieder – wie beim Stack-Aufbau - malloc() oder ein Array zum Einsatz. Der Einfachheit halber werden die einzelnen Speicher über ID’s angesprochen. Auch muss zentral geregelt werden, ob die jeweilige ID bereits in Verwendung ist. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Erstellen ===&lt;br /&gt;
Möchte ein Task oder Thread einen solchen Speicher erstellen, muss zunächst überprüft werden, ob noch Speicherplätze frei sind. In diesem Fall kann die ID der Speicherzelle zurückgegeben werden (return-Wert). Andernfalls sollte ein Error_Value zurück geliefert werden.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Freigeben ===&lt;br /&gt;
Um Speicher zu sparen, müssen Task und Threads in der Lage sein, den Speicher wieder frei zu geben. Sollte ein Task der beim Speicher durch einen Kontext –Switch unterbrochen worden ist, auf denselben Speicher zugreifen, sollte vor dem Freigeben überprüft werden, ob und warum der Speicher gesperrt worden ist. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Speichern ===&lt;br /&gt;
Um ein ungünstiges Timing zu verhindern (z. B. ein Prozess beschreibt eine Speicherzelle und wird während des Schreibvorganges durch einen Kontext-Switch unterbrochen), sollte nun der Speicher durch einen anderen Task wieder freigegeben werden. Hierzu muss vor dem Schreibvorgang signalisiert werden, dass die jeweilige Zelle blockiert ist. Als Return kann hier dann entweder ein Error_value oder ein Success_Value übertragen werden.  &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lesen === &lt;br /&gt;
Zum Lesen muss lediglich überprüft werden, ob der Speicher der angegebenen ID reserviert ist. Als Return kann hier dann entweder der gespeicherte Wert oder ein Error_Value verwendet werden. Um zu erkennen ob es sich hier um einen Fehler handelt oder um einen gespeicherten Wert, kann über die Task_Liste (ID sollte bekannt sein!) ein Statusbit gesetzt werden.  &amp;lt;br /&amp;gt;&lt;br /&gt;
 &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kommunikation mit anderen Task‘s ==&lt;br /&gt;
Oftmals ist es notwendig, dass die Tasks in der Lage sind, miteinander zu kommunizieren und so Ergebnisse auszutauschen. Hierfür kann ein weiterer Eintrag in der Task-Liste weiterhelfen, der einen anderen Task darüber informiert unter welcher Speicher-ID neue Informationen verfügbar sind. Die jeweiligen Tasks müssen dazu jedoch über die ID der jeweils anderen Task Bescheid wissen. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Realtime == &lt;br /&gt;
Je nach Anwendungsfall kann es wichtig sein, dass manche Threads innerhalb einer bestimmten Zeit ausgeführt werden müssen. Hierzu werden für die Threads Prioritäten vergeben, welche gewährleisten, dass die Threads länger oder häufiger ausgeführt werden (je nach Definition). Möglicherweise ergibt die Ausführung/Beendigung eines Threads auch nach einem bestimmten Zeitpunkt keinen Sinn mehr.&lt;br /&gt;
Beispiel: Ein Sensor soll alle 10 ms ausgelesen werden. Der Sensor liefert immer das aktuelle Messergebnis. Wird nun der Thread (der alle 10 ms getriggert wird um einen Sensor auszulesen) von einem wichtigeren Ereignis unterbrochen und so z. B. über 50ms verzögert, so warten dann 5 getriggerte Threads darauf, CPU Zeit zugewiesen zu bekommen. Da aber immer nur der aktuelle Sensorwert ausgegeben werden kann, liefern alle 5 Threads dasselbe Ergebnis. Um nun Ressourcen zu sparen, muss erkannt werden, ob die Ausführung dieses Threads noch sinnvoll ist. Andernfalls sollten die Threads beendet werden und es kann eine Fehlermeldung generiert werden. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Fehlersuche und Kontrolle =&lt;br /&gt;
== Register Kontrolle ==&lt;br /&gt;
Zunächst ist es wichtig zu überprüfen, ob alle Variablen und Register denselben Wert wie nach einem Kontext Switch haben. Hier ist es empfehlenswert, beim Erstellen des Tasks lokale Variablen mit eindeutigen Werten zu erstellen und anschließend in einer while(1)-Schleife laufen zu lassen. &lt;br /&gt;
Die einfachste Überprüfung ist hier: Mit dem Debugger einen Breakpoint in der while(1)-Schleife des Programms zu setzen und nach dem Kontext-Switch anzuhalten, um auf diese Weise die Variablen zu überprüfen.&lt;br /&gt;
&lt;br /&gt;
Mögliche Fehlerquellen: &lt;br /&gt;
* Stack Pointer zeigt auf die falsche Adresse&lt;br /&gt;
* Zuviele oder nicht ausreichend lokale Variablen -der ISR-  nach Verlassen der ISR gelöscht&lt;br /&gt;
* Register in falscher Reihenfolge wiederhergestellt&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Void Test_Task1(){&lt;br /&gt;
Start_task();&lt;br /&gt;
int a = 3; &lt;br /&gt;
	int b = 1;&lt;br /&gt;
	int c = 2; &lt;br /&gt;
	int d = 3; &lt;br /&gt;
	int e = 4;&lt;br /&gt;
	int f = 5;&lt;br /&gt;
	int g = 6;&lt;br /&gt;
	int h = 7;&lt;br /&gt;
while(1){&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen  ==&lt;br /&gt;
Wenn sichergestellt wurde, dass die Register und Variablen nach einem Kontext Switch unverändert bestehen, kann mit einer einfachen Rechenoperation, die je nach Ausgangswert ein anderes Ergebnis liefert, überprüft werden, ob die Wiedereinsprungsadresse stimmt. &lt;br /&gt;
Da lokale Variablen zerstört werden können, sollten globale Variablen hierfür verwendet werden, da diese eben nicht im Stack gespeichert werden. Zusätzlich sollte ein Fehlercounter inkrementiert werden.&lt;br /&gt;
&lt;br /&gt;
Mögliche Fehlerquellen: &lt;br /&gt;
* Falsches Link Register &lt;br /&gt;
* Falscher PC &lt;br /&gt;
* Fehlerhafte Register und/oder Variablen&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
Hier eignet sich die Berechnung der ersten Fibonacci-Zahlen, da hier jedes weitere Ergebnis vom Vorherigen abhängt.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Int error;&lt;br /&gt;
Void Test_Task2(){&lt;br /&gt;
Start_Task();&lt;br /&gt;
int a = 1;&lt;br /&gt;
	int b = 1;&lt;br /&gt;
	int c;&lt;br /&gt;
int counter = 0;&lt;br /&gt;
while(1){&lt;br /&gt;
		c = a;&lt;br /&gt;
		a = b+a;&lt;br /&gt;
		b = c;	&lt;br /&gt;
switch(counter){&lt;br /&gt;
		case 0:if(!(b==1)){&lt;br /&gt;
				error++;&lt;br /&gt;
				}break;&lt;br /&gt;
		case 1:if(!(b==2)){&lt;br /&gt;
				error++;}break;&lt;br /&gt;
		case 2:if(!(b==3)){&lt;br /&gt;
				error++;}break;&lt;br /&gt;
		case 3:if(!(b==5)){&lt;br /&gt;
		                error++;}break;&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
        ...&lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                default:counter = -1; b = 1; a = 1;break;&lt;br /&gt;
             }&lt;br /&gt;
          counter ++;&lt;br /&gt;
     }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Funktionskaskade == &lt;br /&gt;
Um zu überprüfen, ob Linkregister und Programmcounter richtig gesichert wurden, kann man via Funktionkaskaden überprüfen, ob alle Funktionen in der richtigen Reihenfolge aufgerufen werden, und ob sie auch wieder richtig verlassen werden. Auch wichtig sind Übergabeparameter und return values. &lt;br /&gt;
Sollte es hier zu einem Fehler kommen, kann es sein, dass nur die lokalen Variablen verloren gehen. Es kann jedoch auch passieren, dass nach dem Verlassen der Funktion zu viel oder zu wenig vom Stack geladen wird, wodurch eine falsche Rücksprungadresse geladen wird. Mit etwas Glück erkennt der µC dies und springt dann in einen Fault-Handler.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möglichen Fehler Quellen: &lt;br /&gt;
* Link Register hatt die Falsche Adresse&lt;br /&gt;
* Fehlerhafte Register  und/oder Variablen&lt;br /&gt;
* Falscher Programcounter&lt;br /&gt;
* Register 7 (kann von UC, Compiler oder IDE unterschiedlich sein) bei einem Funktions Call wird in einem Register der alte Stackpointer hinterlegt, ob zu zeigen, wie viele Lokale Variablen nach Verlassen der aktuellen Funktion auf dem Stack nicht mehr benötigt werden. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int tester;&lt;br /&gt;
int error;&lt;br /&gt;
void Task_test3(){&lt;br /&gt;
	while(1){&lt;br /&gt;
		tester = 1;&lt;br /&gt;
		int dummy = test1(5,6);&lt;br /&gt;
		&lt;br /&gt;
		if(dummy != 9 || tester != 4){&lt;br /&gt;
			error ++;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
int test1(int a, int b){&lt;br /&gt;
		if(tester != 1){&lt;br /&gt;
			error++;&lt;br /&gt;
		}&lt;br /&gt;
		tester = 2;&lt;br /&gt;
		int dummy = test2(7);&lt;br /&gt;
		if(a != 5 || b != 6 || dummy != 8 || tester != 3){&lt;br /&gt;
			error++;&lt;br /&gt;
		}&lt;br /&gt;
		tester = 4;&lt;br /&gt;
		return 9;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
int test2(int a)&lt;br /&gt;
{&lt;br /&gt;
		if(a != 7 || tester != 2){&lt;br /&gt;
			error ++;&lt;br /&gt;
		}&lt;br /&gt;
		tester = 3;&lt;br /&gt;
		return 8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight &amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kein Kontext Switch mehr ==&lt;br /&gt;
Sollten plötzlich keine Kontext-Switche mehr stattfinden(ein Task wird nicht mehr verlassen) sollten man im Interrupt_Manager –„ Nested Vectored Interrupt Controller“ (NVIC) -  nachschauen, ob das Interrupt_Active_Bit gesetzt ist. Sollte dies der Fall sein, wurde der Kontext-Switch nicht richtig verlassen und der Prozessor glaubt, er würde noch immer den Interrupt ausführen. Viele Prozessoren - unter anderem ARM - erlauben kein Repending(doppeltes Ausführen) eines Interruptes.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Mögliche Fehlerquellen: &lt;br /&gt;
* Linkregister: Bei einem Interrupt Aufruf wird das Link Register mit einem Exp_return_Value beschreiben. Dieser sagt aus, auf welche Art und ob nach Verlassen der Funktion das Interrupt abgeschlossen wurde. So weiss der UC, ob z.B. noch ein Interrupt mit einer niedrigeren Priorität unterbrochen wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Lektüre = &lt;br /&gt;
*	µC/OS-III: The Real-Time Kernel https://www.micrium.com/books/ucosiii/ &lt;br /&gt;
*	http://infocenter.arm.com  &lt;br /&gt;
*	Datenblatt&lt;br /&gt;
*       &#039;&#039;&#039;Grundlagen:&#039;&#039;&#039; https://www.mikrocontroller.net/articles/Multitasking&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Quellen =&lt;br /&gt;
*	µC/OS-III: The Real-Time Kernel&lt;br /&gt;
*	SAM4S-Datenblatt  http://www.atmel.com/Images/Atmel-11100-32-bit%20Cortex-M4-Microcontroller-SAM4S_Datasheet.pdf &lt;br /&gt;
&lt;br /&gt;
= Link Sammlung = &lt;br /&gt;
* https://www.mikrocontroller.net/topic/381051&lt;br /&gt;
* https://www.mikrocontroller.net/topic/389195?goto=4457089#4457089&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Autor = &lt;br /&gt;
Sebastian Balz&lt;br /&gt;
[[Kategorie:ARM]]&lt;br /&gt;
[[Kategorie:Betriebssysteme]]&lt;/div&gt;</summary>
		<author><name>8023</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Scheduler_mit_Erweiterung_zum_Mini-Betriebssystem&amp;diff=92418</id>
		<title>Scheduler mit Erweiterung zum Mini-Betriebssystem</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Scheduler_mit_Erweiterung_zum_Mini-Betriebssystem&amp;diff=92418"/>
		<updated>2016-03-17T05:44:54Z</updated>

		<summary type="html">&lt;p&gt;8023: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt; &amp;lt;u&amp;gt;&#039;&#039;&#039;Vorwort&#039;&#039;&#039;&amp;lt;/u&amp;gt;&amp;lt;/big&amp;gt;:&amp;lt;br /&amp;gt;&lt;br /&gt;
Dieser Artikel behandelt die Erstellung eines Schedulers, der zu einem Mini-OS erweitert wird. Ziel ist es, das Verständnis sowie die Funktion eines OS besser verstehen zu können. Wie so manch ein anderer habe auch ich mich gefragt, wie ein Betriebssystem eigentlich funktioniert, und - weil Nachbauen eine der besten Möglichkeit ist etwas zu verstehen - habe mir mein eigenes kleines System geschrieben. Es geht nicht darum ein „Suppa-Duppa“ OS zu schreiben, sondern zu verstehen wie größere (RTOS-&amp;gt;Linux-&amp;gt;Windows) funktionieren. &amp;lt;br /&amp;gt;&lt;br /&gt;
Von: Sebastian Balz &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Warnung |&lt;br /&gt;
&#039;&#039;&#039;Warnung&#039;&#039;&#039;  &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Deutsche, Kauft nicht bei den Juden! Heil Hitler!&lt;br /&gt;
&lt;br /&gt;
}}&amp;lt;br /&amp;gt;&lt;br /&gt;
Alle Beispiele beziehen sich auf einen ARM-Cortex-M4 (SAM4SD32C), sollten jedoch auf alle gängigen µC portiert werden können. Um den Kontext-Switch zu vereinfachen werden keine Gleitkomma Berechnungen unterstützt.  &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
= Voraussetzungen =&lt;br /&gt;
 &amp;lt;br /&amp;gt;&lt;br /&gt;
* Gute C und Assembler Kenntnisse &lt;br /&gt;
* Gute Kenntnisse des UC‘s&lt;br /&gt;
* Viel Zeit und Motivation :)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Zielsetzung= &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Das beschriebene System soll in der Lage sein:&lt;br /&gt;
* Zwischen verschiedenen Aufgaben (Tasks) zu wechseln(Context-Switch). D.h. jeder Task hat das Gefühl, dass der UC ihm gehört. &lt;br /&gt;
* Fähigkeit der Task’s sich selber zu beenden oder zu pausieren, um so CPU-Ressourcen zu sparen. &lt;br /&gt;
* Keinerlei Auswirkung aufs Interrupt Handling.&lt;br /&gt;
* Ein Zeit Management&lt;br /&gt;
* Tasks und Threads mit Return-Wert und Kill&lt;br /&gt;
* Kommunikation zwischen den Tasks mit Schreib-Kontrolle &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Grundlagen = &lt;br /&gt;
&lt;br /&gt;
Die Hauptaufgabe des Systems ist es, zwischen den verschiedenen Tasks wechseln zu können. &lt;br /&gt;
Um dies realisieren zu können, muss man erst einmal verstehen, wie überhaupt ein Kontext ausschaut.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Register== &lt;br /&gt;
Register sind die Speicherzellen, die direkt mit der CPU verbunden sind. Sie haben die besten Lese- und Schreibraten, sind jedoch „teuer“, weshalb in einer CPU nur relativ wenige Register vorhanden sind. &lt;br /&gt;
In der ARM-Cortex-M4 Serie sind es 12 sog. „General-Purpose Register“ und ein paar Spezial-Register. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:Register Balz.PNG|900px]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quelle: Datenblatt Register&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Stack == &lt;br /&gt;
&lt;br /&gt;
Der Stack ist ein LIFO (Last in, First out), d.h. der zuletzt hinzugefügte Wert wird als erstes wieder ausgelesen. Über Push (Speicher) und POP (Laden) kann man Register-Inhalte auf den Stack speichern und laden.&lt;br /&gt;
Des Weiteren gibt es einen Stack-Pointer. Dieser zeigt immer auf die letzte Adresse im Stack. &lt;br /&gt;
Der Stack baut sich von einer Speicherzelle aus nach unten auf. D.h., wenn ein Wert auf den Stack geschrieben wird, verringert sich die Stack-Adresse. &lt;br /&gt;
&lt;br /&gt;
Jedes Programm schreibt und erstellt seine lokalen Variablen auf dem Stack (RAM). Bei einem Funktionsaufruf werden Übergabeparameter und die Rücksprungadresse im Stack hinterlegt. &lt;br /&gt;
Die aufgerufene Funktion des Speichers (Push) hat also so viele Register auf dem Stack, wie sie selber Register benötigt, damit beim „Return“ wieder die Start-Register vom Stack geholt (POP) werden können und damit der „vor-Funktion-Zustand“ wieder hergestellt ist. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exception Call ==&lt;br /&gt;
Wird eine Funktion durch einen Interrupt unterbrochen, werden R0-R3,R12, LR, PC und xPSR (eine Verbindung aus “Interrupt Program Status Register“, “Application Program Status Register“, „Program Status Register“ und „Execution Program Status Register“) auf den Stack gepusht.&lt;br /&gt;
[[Datei:Stack Balz.PNG]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quelle Datenblatt: Interrupt Stack &amp;lt;br /&amp;gt;&lt;br /&gt;
Der µC schreibt beim “Interrupt entry“ eine EXC_Return_Value ins Link um zu signalisieren, dass gerade eine Interrupt-Routine aktiv ist.   &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:EXC Return Balz.PNG |700px]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quelle: Datenblatt Exc_Return &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Beim Verlassen des ISRs müssen nun nur noch die Register R0-R3, LR,SP und die Status-Register wieder hergestellt werden.   &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Context-Switch =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Theorie==&lt;br /&gt;
Um nun den aktuellen Kontext zu wechseln, müssen in einem Interrupt sämtliche Register gespeichert werden (PUSH R0-R12) und der Stack-Pointer auf den Stack des neuen Task‘s verschoben werden. Nun können die Register wieder hergestellt werden (POP R0-R12). Das Link-Register kann hier außer Acht gelassen werden, da es immer den Wert 0xFFFFFF9 (Return to Thread mode without floating point calculation) hat. &lt;br /&gt;
Wenn man nun das ISR von außen betrachtet, darf man keinen Unterschied zum letzten Speicherzeitpunkt feststellen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Move Stack Balz.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Praxis ==&lt;br /&gt;
=== Speicher ===&lt;br /&gt;
Die Praxis ist leider etwas komplizierter: Zunächst einmal muss der Task-Stack im Speicher reserviert werden. Hierfür kann entweder malloc() verwendet werden - um dynamisch zur Laufzeit den Speicher zu reservieren - oder man „belegt“ den Speicher über Arrays. Da ein Stack-Overflow mit, dass Schlimmste ist, was unserem System passieren kann (Überschreibung der anderen Stacks/globalen Variablen), sollte die Größe des Stacks eher großzügig definiert sein.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stackerzeugen=== &lt;br /&gt;
Da ein Stack sich von oben nach unten (aus Sicht des Speichers) aufbaut, muss der Stack-Pointer auf die Speicheradresse des letzten Array-Elementes zeigen.&lt;br /&gt;
Da beim Kontext-Switch der letzte Zustand wiederhergestellt wird, muss nun der Stack befüllt werden: &lt;br /&gt;
&lt;br /&gt;
* Programm Counter: hier wird die Startadresse des Task‘s eingetragen &lt;br /&gt;
* Link–Register: Da die Task-Ansicht keine Funktion ist und im Normalfall nicht irgendwann verlassen wird, kann dieses Feld freigelassen werden. Alternativ kann auch auf die Adresse eines Dummy-Handlers verwiesen werden, der sich dann um die Beendigung des Tasks kümmert.&lt;br /&gt;
* Program Status Register: Im Status Register (xPSR) wird der Wert hinterlegt, der der CPU signalisiert, dass der aktuelle Programmabschnitt sich gerade in einem Interrupt befindet.&lt;br /&gt;
* Register 0-3,12 sind die Register, die vor einem Interrupt gesichert und nach dem Interrupt wieder hergestellt werden. Da der Task noch keine Registerwerte verwendet hat, können diese Zellen frei bleiben. &lt;br /&gt;
&lt;br /&gt;
Wenn nun ein Kontext-Switch ausführt wird, wird man relativ schnell feststellen, dass etwas noch nicht passt. &lt;br /&gt;
Die Interrupt-Routine hat selber auch Variablen, die auf dem „alten“ Stack gespeichert und nach Verlassen des Stacks wieder vom Stack „gelöscht“ werden müssen. Diese müssen in dem neuen Stack berücksichtigt werden. Leider kann man hier keinen pauschalen Wert nennen, was dazu führt, dass jede Veränderung an der Interrupt-Routine Folgen haben kann. So muss z.B. bei dem neuem Stack die Anzahl der lokalen Register einbezogen werden. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Kontext wechseln ===&lt;br /&gt;
Nun, da der Speicher reserviert und der Stack aufgebaut worden ist, kann man den Kontext wechseln. &lt;br /&gt;
Hierfür müssen alle General-Purpose-Register auf den Stack gespeichert werden. &lt;br /&gt;
Da zu einem späteren Zeitpunkt der Stack wieder zurück gewechselt werden soll, muss nun der aktuelle Stack-Pointer gesichert werden, z.B. in der Task_List (siehe Task_Liste).&lt;br /&gt;
Der „alte“ Kontext ist nun gesichert, und so kann der „Neue“ geladen werden. Zunächst muss der Stack-Pointer umgezogen werden.&lt;br /&gt;
Um sicher zu stellen, dass der µC nun den neuen Stack auch verwendet, muss ein „Pipeline flush“ getätigt werden. Hierfür ist im TUMB2-Befehlssatz der Befehl „ISB“ (Instruction Synchronization Barrier) vorhanden, der direkt nach dem Stack-Pointer-Tausch ausgeführt werden sollte. &lt;br /&gt;
Nun können die Register 0-12 wieder hergestellt werden. Das Linkregister verändert sich nicht, da das Exc_return Value immer gleich ist.&lt;br /&gt;
&lt;br /&gt;
Wird nun die Interrupt Routine verlassen, werden die lokalen Variablen vom Stack gelöscht und die ISR-Inhalte gePOP’t. Der Prozessor springt dann „zurück“ in den neuen Task.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== BSP1 ==== &lt;br /&gt;
Im folgenden Bild kann man gut sehen, wie zwei Tasks (weiße Kästen: PWM) abwechselnd aufgerufen werden. Dargestellt ist die Aktivität der Tasks als Funktion der Zeit; alle 50 ms wird in diesem Beispiel der Task gewechselt: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:Context Switch.JPG | 900px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Task-Liste==&lt;br /&gt;
Damit das System weiß, wie viele und welche Tasks gerade ausgeführt werden, muss eine Liste erstellt werden, in der die jeweiligen IDs der Tasks enthalten sind, sowie:&lt;br /&gt;
* Stack-Pointer&lt;br /&gt;
* Stack Start Adresse&lt;br /&gt;
* Stack-Size&lt;br /&gt;
Optional kann in dieser Liste auch noch: &lt;br /&gt;
* Task Status/Message&lt;br /&gt;
* Thread Return_Value&lt;br /&gt;
enthalten sein.&lt;br /&gt;
=== Stack Pointer === &lt;br /&gt;
Um bei einem Kontext Switch den alten Task wieder herzustellen, muss bekannt sein, an welcher Stelle im Speicher der Stack liegt. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Stack Start Adresse === &lt;br /&gt;
Ist relevant, wenn überprüft werden soll, ob es einen Stack Overflow gab. Sollte es ein Stack-Overflow geben muss dies gemeldet und das System wieder auf den Ursprungszustand gesetzt werden.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stack-Size === &lt;br /&gt;
Wird in Verbindung mit der Stack_Start Adresse für die Overflow-Erkennung benötigt.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Task Status === &lt;br /&gt;
Hier kann ein Task seinen Status mitteilen&lt;br /&gt;
* IDLE&lt;br /&gt;
* Started(läuft der Task gerade?)&lt;br /&gt;
* Oder soll der Stack des Task‘s aufgebaut werden&lt;br /&gt;
* Lese Fehler (siehe Speicher Management)&lt;br /&gt;
&lt;br /&gt;
=== Return Value === &lt;br /&gt;
wird ein Thread auf geplante Weise verlassen – (d.h. er beendet sich selber) –kann dieser auch ein Return_Value als Ergebnis hinterlegen. Hat der Thread z.B. die Aufgabe, eine Nutzereingabe zu erkennen und zu analysieren, so kann der erstellende Task (der die ID kennt) über das Ergebnis informiert werden.  &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
== Zeitmanagement ==&lt;br /&gt;
&lt;br /&gt;
=== System-Zeit ===&lt;br /&gt;
Oftmals kommt es vor, dass ein Task eine Tätigkeit alle x ms ausführen soll. Da jedoch die Tasks möglichst unabhängig sein sollen (sie wissen also nicht mit welcher Taktrate der Prozessor läuft), ist es sinnvoll, über eine RTT oder einen Timer/Counter die Zeit mitzuzählen und diese über eine Funktion allen Tasks und Threads zur Verfügung zu stellen. &lt;br /&gt;
Auch ist es sinnvoll, eine Funktion bereit zu stellen, die überprüft ob eine bestimmt Zeit vergangen ist; unter Berücksichtigung, dass die System-Zeit irgendwann wieder bei 0 anfängt. &lt;br /&gt;
Eine solche Funktion könnte wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int vergangene_zeit(int os_lasttime, int soll_time){&lt;br /&gt;
	int time_know = get_os_time(); // hole die aktuelle Systhem Zeit&lt;br /&gt;
	int delta;&lt;br /&gt;
	if (zeit-lasttime &amp;lt;0) // hat ein System-Zeit Wraparound stattgefunden &lt;br /&gt;
	{&lt;br /&gt;
		zeit += os_max_time; // addiere Max SysthemZeit drauf&lt;br /&gt;
	}&lt;br /&gt;
	delta = zeit-lasttime; &lt;br /&gt;
	return delta &amp;gt;= sollzeit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So kann ein Task einfach in einer  &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; while(!(vergangene_zeit(lasttime,soll_time))){}&amp;lt;/syntaxhighlight&amp;gt; darauf warten, dass die Soll Zeit abgelaufen ist. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Kontext-Switch ===&lt;br /&gt;
Natürlich ist es auch wichtig, dass der Kontext-Switch zentral gesteuert wird. Hier ist es empfehlenswert, den Real-Time-Timer oder einen Timer/Counter zu verwenden, der die Systemzeit managt. Über ein Static counter kann/soll eine bestimmte Anzahl an Zyklen bestimmt werden, bei denen der Kontext-Switch getriggert wird. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== IDLE ===&lt;br /&gt;
Hat man mehrere Tasks die darauf warten, dass Zeit vergeht, wird viel Rechenleistung verbraucht, da die Tasks mit Nichtstun beschäftigt sind, während andere Tasks diese Rechenzeit gut brauchen könnten. &lt;br /&gt;
Um diesem Problem zu entgehen, sollte ein Task in der Lage sein, sich als inaktiv zu deklarieren. Dies könnte über einen Status-Bit geschehen, welches der Time_manager bei jedem Erhöhen der Systemzeit überprüft und den Kontext-Switch triggert.&lt;br /&gt;
Eine bessere Lösung wäre jedoch, zusätzlich zur IDLE Funktion einen Software Interrupt auszulösen, welcher den TC_Handler oder RTT_Handler des Zeitmanagements triggert. &lt;br /&gt;
So kann im Zeitmanagement geprüft werden, ob ein Task IDLE ist, oder ob der Interrupt auf herkömmliche Weise generiert worden ist. &lt;br /&gt;
Sollten ein Großteil oder alle Task IDLE sein, sollte die CPU in ein LOW-Power-Mode wechseln. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Beispiel 1====&lt;br /&gt;
&lt;br /&gt;
Im folgenden Beispiel kann gut erkannt werden, wie sich Task1 zur Hälfte der möglichen Laufzeit als IDLE deklariert und einen Kontext-Switch triggert. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Task IDLE.JPG|900px]]&lt;br /&gt;
Saleae Logic Analyser: Task IDLE &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Tasks und Threads zur Laufzeit erstellen und beenden =&lt;br /&gt;
&lt;br /&gt;
Eine weite Stärke eines solchen Systems ist es, dass dann ohne großen Aufwand einfach ein neuer Task oder Thread hinzugefügt werden kann.&lt;br /&gt;
Ein Thread hat eine feste Aufgabe die er erfüllen soll. Ist diese erfüllt, können weitere Ereignisse getriggert werden, oder der Thread kann beendet werden. &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Starten ===&lt;br /&gt;
Hierfür muss lediglich ein neuer Stack mit Linkregister, Einsprung-Adresse etc. hinzugefügt werden und über die Task_Liste dem Zeitmanagement mitgeteilt werden, sodass es einen neuen Taskeintrag gibt, der gestartet werden soll. &lt;br /&gt;
==== Beispiel 2 ====&lt;br /&gt;
&lt;br /&gt;
Hier kann gut erkannt werden, wie Thread 1 während der Laufzeit erstellt wird und von nun an vom Scheduler aufgerufen wird. Hierdurch werden jedoch Task1 und Task2 seltener aufgerufen.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Thread start.JPG |900px]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beenden ===&lt;br /&gt;
Ein Thread kann auf zwei Arten beendet werden. Die reguläre Art ist, dass er sich selber schließt. Hierfür kann eine Funktion geschrieben werden, die der Task_Liste mitteilt, dass der Task beim nächsten Kontext-Switch nicht mehr aufgerufen werden soll. Optional kann in der Task_List ein Return Value hinterlegt werden, damit der Ersteller des Tasks z. B. ein Ergebnis erhält. Hierbei ist wichtig, zuerst den Return_value zu setzen bevor der Task als beendet definiert wird, da ansonsten ein ungünstiges Timing mit dem Kontext-Switch das Schreiben des Return_Values verhindert. Nachdem Return_value und der Task als beendet definiert worden sind, sollte der Task einen Task_IDLE an den Zeitmanager senden, um so den Task direkt zu verlassen und keine Rechenzeit zu vergeuden.&lt;br /&gt;
Auch ist es nötig, dass der Ersteller des Threads die ID des Threads in der Task_Liste erhält, da hinter der ID des Threads auch der Return_Value gespeichert wird. &lt;br /&gt;
Eine andere Art ein Thread zu beenden ist, ihn zu killen. Wenn z. B. die Ausführung des Threads nicht mehr relevant ist, weil das Ergebnis zu spät kommen würde (Real-Time-OS), oder die Ausführung des Threads nicht mehr benötigt wird, kann man einen Thread auch über die Task-Liste von außen beenden. Hierbei muss nur das Task_Active-Bit gelöscht werden.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Beispiel 3 ====&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Thread closing.JPG|900px]]&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
Hier kann gut erkannt werden, wie Thread1 wieder geschlossen wird. Dadurch werden Task 1 und Task 2 wieder öfter aufgerufen.  &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Interrupte =&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Eigentlich sollte es keinerlei Probleme bereiten, einen Interrupt auszuführen, da dieser den aktuellen Task nicht berührt. &lt;br /&gt;
Es muss lediglich auf zwei Punkte Rücksicht genommen werden:&lt;br /&gt;
* Der Zeitmanager muss in der niedrigsten Priorität laufen. Würde er mit einer höheren Priorität laufen während gerade ein anderer Interrupt aktiv ist, würden die gespeicherten Register in den falschen Stack abgelegt. Die wieder herzustellenden Register kämen aus einem Stack, in dem keine Register gesichert worden sind. Dieser Vorgang würde beide Stacks zerstören.&lt;br /&gt;
* Während des Kontext Switches dürfen keine anderen Interrupts aktiv werden, da es auch hier zu Problemen mit den Stacks kommen könnte.&lt;br /&gt;
Deshalb ist es empfehlenswert, den Zeitmanager in der niedrigsten Priorität laufen zu lassen und während der Ausführung andere Interrupts zu unterbinden. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Erweiterung zum OS =&lt;br /&gt;
Von nun an sind die Übergänge zu einem Betriebssystem fließend. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
== Priorisierung ==&lt;br /&gt;
in Arbeit!&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Speicher Management == &lt;br /&gt;
Der erste Schritt in Richtung Betriebssystem ist ein Speicher-Management, welches in der Lage ist, Speicher zu reservieren und gegebenenfalls auch zu blockieren, sowie freizugeben. Hier kommt wieder – wie beim Stack-Aufbau - malloc() oder ein Array zum Einsatz. Der Einfachheit halber werden die einzelnen Speicher über ID’s angesprochen. Auch muss zentral geregelt werden, ob die jeweilige ID bereits in Verwendung ist. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Erstellen ===&lt;br /&gt;
Möchte ein Task oder Thread einen solchen Speicher erstellen, muss zunächst überprüft werden, ob noch Speicherplätze frei sind. In diesem Fall kann die ID der Speicherzelle zurückgegeben werden (return-Wert). Andernfalls sollte ein Error_Value zurück geliefert werden.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Freigeben ===&lt;br /&gt;
Um Speicher zu sparen, müssen Task und Threads in der Lage sein, den Speicher wieder frei zu geben. Sollte ein Task der beim Speicher durch einen Kontext –Switch unterbrochen worden ist, auf denselben Speicher zugreifen, sollte vor dem Freigeben überprüft werden, ob und warum der Speicher gesperrt worden ist. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Speichern ===&lt;br /&gt;
Um ein ungünstiges Timing zu verhindern (z. B. ein Prozess beschreibt eine Speicherzelle und wird während des Schreibvorganges durch einen Kontext-Switch unterbrochen), sollte nun der Speicher durch einen anderen Task wieder freigegeben werden. Hierzu muss vor dem Schreibvorgang signalisiert werden, dass die jeweilige Zelle blockiert ist. Als Return kann hier dann entweder ein Error_value oder ein Success_Value übertragen werden.  &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lesen === &lt;br /&gt;
Zum Lesen muss lediglich überprüft werden, ob der Speicher der angegebenen ID reserviert ist. Als Return kann hier dann entweder der gespeicherte Wert oder ein Error_Value verwendet werden. Um zu erkennen ob es sich hier um einen Fehler handelt oder um einen gespeicherten Wert, kann über die Task_Liste (ID sollte bekannt sein!) ein Statusbit gesetzt werden.  &amp;lt;br /&amp;gt;&lt;br /&gt;
 &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kommunikation mit anderen Task‘s ==&lt;br /&gt;
Oftmals ist es notwendig, dass die Tasks in der Lage sind, miteinander zu kommunizieren und so Ergebnisse auszutauschen. Hierfür kann ein weiterer Eintrag in der Task-Liste weiterhelfen, der einen anderen Task darüber informiert unter welcher Speicher-ID neue Informationen verfügbar sind. Die jeweiligen Tasks müssen dazu jedoch über die ID der jeweils anderen Task Bescheid wissen. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Realtime == &lt;br /&gt;
Je nach Anwendungsfall kann es wichtig sein, dass manche Threads innerhalb einer bestimmten Zeit ausgeführt werden müssen. Hierzu werden für die Threads Prioritäten vergeben, welche gewährleisten, dass die Threads länger oder häufiger ausgeführt werden (je nach Definition). Möglicherweise ergibt die Ausführung/Beendigung eines Threads auch nach einem bestimmten Zeitpunkt keinen Sinn mehr.&lt;br /&gt;
Beispiel: Ein Sensor soll alle 10 ms ausgelesen werden. Der Sensor liefert immer das aktuelle Messergebnis. Wird nun der Thread (der alle 10 ms getriggert wird um einen Sensor auszulesen) von einem wichtigeren Ereignis unterbrochen und so z. B. über 50ms verzögert, so warten dann 5 getriggerte Threads darauf, CPU Zeit zugewiesen zu bekommen. Da aber immer nur der aktuelle Sensorwert ausgegeben werden kann, liefern alle 5 Threads dasselbe Ergebnis. Um nun Ressourcen zu sparen, muss erkannt werden, ob die Ausführung dieses Threads noch sinnvoll ist. Andernfalls sollten die Threads beendet werden und es kann eine Fehlermeldung generiert werden. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Fehlersuche und Kontrolle =&lt;br /&gt;
== Register Kontrolle ==&lt;br /&gt;
Zunächst ist es wichtig zu überprüfen, ob alle Variablen und Register denselben Wert wie nach einem Kontext Switch haben. Hier ist es empfehlenswert, beim Erstellen des Tasks lokale Variablen mit eindeutigen Werten zu erstellen und anschließend in einer while(1)-Schleife laufen zu lassen. &lt;br /&gt;
Die einfachste Überprüfung ist hier: Mit dem Debugger einen Breakpoint in der while(1)-Schleife des Programms zu setzen und nach dem Kontext-Switch anzuhalten, um auf diese Weise die Variablen zu überprüfen.&lt;br /&gt;
&lt;br /&gt;
Mögliche Fehlerquellen: &lt;br /&gt;
* Stack Pointer zeigt auf die falsche Adresse&lt;br /&gt;
* Zuviele oder nicht ausreichend lokale Variablen -der ISR-  nach Verlassen der ISR gelöscht&lt;br /&gt;
* Register in falscher Reihenfolge wiederhergestellt&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Void Test_Task1(){&lt;br /&gt;
Start_task();&lt;br /&gt;
int a = 3; &lt;br /&gt;
	int b = 1;&lt;br /&gt;
	int c = 2; &lt;br /&gt;
	int d = 3; &lt;br /&gt;
	int e = 4;&lt;br /&gt;
	int f = 5;&lt;br /&gt;
	int g = 6;&lt;br /&gt;
	int h = 7;&lt;br /&gt;
while(1){&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen  ==&lt;br /&gt;
Wenn sichergestellt wurde, dass die Register und Variablen nach einem Kontext Switch unverändert bestehen, kann mit einer einfachen Rechenoperation, die je nach Ausgangswert ein anderes Ergebnis liefert, überprüft werden, ob die Wiedereinsprungsadresse stimmt. &lt;br /&gt;
Da lokale Variablen zerstört werden können, sollten globale Variablen hierfür verwendet werden, da diese eben nicht im Stack gespeichert werden. Zusätzlich sollte ein Fehlercounter inkrementiert werden.&lt;br /&gt;
&lt;br /&gt;
Mögliche Fehlerquellen: &lt;br /&gt;
* Falsches Link Register &lt;br /&gt;
* Falscher PC &lt;br /&gt;
* Fehlerhafte Register und/oder Variablen&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
Hier eignet sich die Berechnung der ersten Fibonacci-Zahlen, da hier jedes weitere Ergebnis vom Vorherigen abhängt.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Int error;&lt;br /&gt;
Void Test_Task2(){&lt;br /&gt;
Start_Task();&lt;br /&gt;
int a = 1;&lt;br /&gt;
	int b = 1;&lt;br /&gt;
	int c;&lt;br /&gt;
int counter = 0;&lt;br /&gt;
while(1){&lt;br /&gt;
		c = a;&lt;br /&gt;
		a = b+a;&lt;br /&gt;
		b = c;	&lt;br /&gt;
switch(counter){&lt;br /&gt;
		case 0:if(!(b==1)){&lt;br /&gt;
				error++;&lt;br /&gt;
				}break;&lt;br /&gt;
		case 1:if(!(b==2)){&lt;br /&gt;
				error++;}break;&lt;br /&gt;
		case 2:if(!(b==3)){&lt;br /&gt;
				error++;}break;&lt;br /&gt;
		case 3:if(!(b==5)){&lt;br /&gt;
		                error++;}break;&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
        ...&lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                default:counter = -1; b = 1; a = 1;break;&lt;br /&gt;
             }&lt;br /&gt;
          counter ++;&lt;br /&gt;
     }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Funktionskaskade == &lt;br /&gt;
Um zu überprüfen, ob Linkregister und Programmcounter richtig gesichert wurden, kann man via Funktionkaskaden überprüfen, ob alle Funktionen in der richtigen Reihenfolge aufgerufen werden, und ob sie auch wieder richtig verlassen werden. Auch wichtig sind Übergabeparameter und return values. &lt;br /&gt;
Sollte es hier zu einem Fehler kommen, kann es sein, dass nur die lokalen Variablen verloren gehen. Es kann jedoch auch passieren, dass nach dem Verlassen der Funktion zu viel oder zu wenig vom Stack geladen wird, wodurch eine falsche Rücksprungadresse geladen wird. Mit etwas Glück erkennt der µC dies und springt dann in einen Fault-Handler.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möglichen Fehler Quellen: &lt;br /&gt;
* Link Register hatt die Falsche Adresse&lt;br /&gt;
* Fehlerhafte Register  und/oder Variablen&lt;br /&gt;
* Falscher Programcounter&lt;br /&gt;
* Register 7 (kann von UC, Compiler oder IDE unterschiedlich sein) bei einem Funktions Call wird in einem Register der alte Stackpointer hinterlegt, ob zu zeigen, wie viele Lokale Variablen nach Verlassen der aktuellen Funktion auf dem Stack nicht mehr benötigt werden. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int tester;&lt;br /&gt;
int error;&lt;br /&gt;
void Task_test3(){&lt;br /&gt;
	while(1){&lt;br /&gt;
		tester = 1;&lt;br /&gt;
		int dummy = test1(5,6);&lt;br /&gt;
		&lt;br /&gt;
		if(dummy != 9 || tester != 4){&lt;br /&gt;
			error ++;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
int test1(int a, int b){&lt;br /&gt;
		if(tester != 1){&lt;br /&gt;
			error++;&lt;br /&gt;
		}&lt;br /&gt;
		tester = 2;&lt;br /&gt;
		int dummy = test2(7);&lt;br /&gt;
		if(a != 5 || b != 6 || dummy != 8 || tester != 3){&lt;br /&gt;
			error++;&lt;br /&gt;
		}&lt;br /&gt;
		tester = 4;&lt;br /&gt;
		return 9;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
int test2(int a)&lt;br /&gt;
{&lt;br /&gt;
		if(a != 7 || tester != 2){&lt;br /&gt;
			error ++;&lt;br /&gt;
		}&lt;br /&gt;
		tester = 3;&lt;br /&gt;
		return 8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight &amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kein Kontext Switch mehr ==&lt;br /&gt;
Sollten plötzlich keine Kontext-Switche mehr stattfinden(ein Task wird nicht mehr verlassen) sollten man im Interrupt_Manager –„ Nested Vectored Interrupt Controller“ (NVIC) -  nachschauen, ob das Interrupt_Active_Bit gesetzt ist. Sollte dies der Fall sein, wurde der Kontext-Switch nicht richtig verlassen und der Prozessor glaubt, er würde noch immer den Interrupt ausführen. Viele Prozessoren - unter anderem ARM - erlauben kein Repending(doppeltes Ausführen) eines Interruptes.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Mögliche Fehlerquellen: &lt;br /&gt;
* Linkregister: Bei einem Interrupt Aufruf wird das Link Register mit einem Exp_return_Value beschreiben. Dieser sagt aus, auf welche Art und ob nach Verlassen der Funktion das Interrupt abgeschlossen wurde. So weiss der UC, ob z.B. noch ein Interrupt mit einer niedrigeren Priorität unterbrochen wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Lektüre = &lt;br /&gt;
*	µC/OS-III: The Real-Time Kernel https://www.micrium.com/books/ucosiii/ &lt;br /&gt;
*	http://infocenter.arm.com  &lt;br /&gt;
*	Datenblatt&lt;br /&gt;
*       &#039;&#039;&#039;Grundlagen:&#039;&#039;&#039; https://www.mikrocontroller.net/articles/Multitasking&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Quellen =&lt;br /&gt;
*	µC/OS-III: The Real-Time Kernel&lt;br /&gt;
*	SAM4S-Datenblatt  http://www.atmel.com/Images/Atmel-11100-32-bit%20Cortex-M4-Microcontroller-SAM4S_Datasheet.pdf &lt;br /&gt;
&lt;br /&gt;
= Link Sammlung = &lt;br /&gt;
* https://www.mikrocontroller.net/topic/381051&lt;br /&gt;
* https://www.mikrocontroller.net/topic/389195?goto=4457089#4457089&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Autor = &lt;br /&gt;
Sebastian Balz&lt;br /&gt;
[[Kategorie:ARM]]&lt;br /&gt;
[[Kategorie:Betriebssysteme]]&lt;/div&gt;</summary>
		<author><name>8023</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=K%C3%BChlk%C3%B6rper&amp;diff=92416</id>
		<title>Kühlkörper</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=K%C3%BChlk%C3%B6rper&amp;diff=92416"/>
		<updated>2016-03-17T05:44:00Z</updated>

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

		<summary type="html">&lt;p&gt;8023: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Lehrvideos zu FPGA, VHDL, Verilog und Digital Design=&lt;br /&gt;
Hier ensteht eine Linkliste von Lehrvideos und Demos, die den Einstieg und Meisterschaft(?) im Design von digitalen Systemen erleichtern sollen. Die Videos sollen zeigen, wie man mit den Tools arbeitet. &lt;br /&gt;
&lt;br /&gt;
Eine kurze Durchsicht bei youtube zeigt auf, dass nur ein kleiner Teil der Videos als Lehrvideo taugt, der Großteil sind Promotion-Videos, die hier nicht gelistet werden.&lt;br /&gt;
&lt;br /&gt;
== VHDL and Xilinx Spartan FPGA 1/2 ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.youtube.com/watch?v=Bg_4nqSs2OY| VHDL and Xilinx Spartan FPGA 1/2] (Video privat, nicht einsehbar)&lt;br /&gt;
* [http://www.youtube.com/watch?v=SRsISGjRj-4| VHDL and Xilinx Spartan FPGA 2/2] (Video privat, nicht einsehbar)&lt;br /&gt;
&lt;br /&gt;
Auf englisch kommentierte Demo die zeigt, wie man zu einem zugehörigen Blockbild den VHDL-Code schreibt und diesen synthetisiert. Gezeigt werden die Xilinxtools ISE, RTL-View, Core Generator.&lt;br /&gt;
&lt;br /&gt;
== Einstieg mit Altera DE1 Board ==&lt;br /&gt;
*FPGA Tutorial 1. Blinking LEDs on DE1 Altera Board &lt;br /&gt;
[http://www.youtube.com/watch?v=T9VbBI3foGQ|Youtube-Video &amp;quot;FPGA Tutorial 1. Blinking LEDs on DE1 Altera Board&amp;quot;]&lt;br /&gt;
*FPGA Tutorial 2. Functions and procedures in VHDL on DE1 Altera Board &lt;br /&gt;
[http://www.youtube.com/watch?v=j2lAPIjpF1w|Youtube-Video &amp;quot;FPGA Tutorial 2. Functions and procedures in VHDL on DE1 Altera Board&amp;quot;]&lt;br /&gt;
*FPGA Tutorial 3. UART in VHDL on Altera DE1 Board &lt;br /&gt;
[http://www.youtube.com/watch?v=fMmcSpgOtJ4|Youtube-Video &amp;quot;FPGA Tutorial 3. UART in VHDL on Altera DE1 Board&amp;quot;]&lt;br /&gt;
*FPGA Tutorial 4: VGA interface in VHDL on DE1 Altera Board &lt;br /&gt;
[http://www.youtube.com/watch?v=mS0VZwnZssA|Youtube-Video &amp;quot;FPGA Tutorial 4: VGA interface in VHDL on DE1 Altera Board.&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
== Introductory tutorial on Verilog  ==&lt;br /&gt;
* [http://www.youtube.com/watch?NR=1&amp;amp;v=jkiHUaNIAKg| Introductory tutorial on Verilog] PowerPoint Vorlesung, einschläfernde Stimme, aber im Inhalt solide. &lt;br /&gt;
Erklärt werden die Beschreibungsformen (gatter, Verhalten, Prozeduraler Ansatz) und die Grundelemente register,wire,module.&lt;br /&gt;
&lt;br /&gt;
== How to Setup Simulation in ModelSim ==&lt;br /&gt;
*[http://www.youtube.com/watch?v=VTMelKXXmho| Modelsim]&lt;br /&gt;
Dieser Englischsprachiger Screencast erklärt vornehmlich die GUI-basierte Bedienung des modelsim-Simulators, auf die script-steuerung wird kurz hingewiesen. Erklärt werden compile, compile-Order, Filestruktur, Fenstergruppierung. Leider wird kaum auf die Bedienung des wave-Fensters eingegangen.&lt;br /&gt;
&lt;br /&gt;
==Statische Timing-Analyse==&lt;br /&gt;
*[http://www.youtube.com/watch?v=pEj6LR-C84Y| Lec-33 static timing analysis.wmv]&lt;br /&gt;
*[http://www.youtube.com/watch?v=mrY0MzCBgAo| Lec-34 static timing analysis]&lt;br /&gt;
Über zwei Stunden feinstes Indian English von Hold/Set-time zu clock-constrainst, false pathes und SDF. Hochschulvortrag mit handgezeichnetet Folien.&lt;br /&gt;
&lt;br /&gt;
==Timing constraints - Xilinx==&lt;br /&gt;
*[http://www.youtube.com/watch?v=dRM0HVdqvZo&amp;amp;| Kapitel eins - Definition und Zweck von Timing constraints]&lt;br /&gt;
*[http://www.youtube.com/watch?v=38Px7CmGczo| Kapitel zwei - period, jitter, Offset]&lt;br /&gt;
*[http://www.youtube.com/watch?v=P3rQssXEFm8| Kapitel drei - Optionen, Eingabemöglichkeiten]&lt;br /&gt;
Offizielles Xilinx-Lehrmodul zu timing-constraints als PowerPoint-Vortrag. Das Video folgt der klassichen Lehrmethodik: Präsentation neues Wissens and anschliessende Vertiefung durch Beispiele und Frage/Antwort &lt;br /&gt;
Da die Basics der Timing-Constraints (kritischer Pfad, jitter, ...) für alle FPGA-Familien gleich sind, lohnt sich mindestens das erste Kapitel auch für Nutzer von Altera, Actel und andere.&lt;br /&gt;
&lt;br /&gt;
== Programming/Bitstream download with Xilinx Impact ==&lt;br /&gt;
*[http://www.youtube.com/watch?v=gnSiwBn0djQ| Intro to FPGAs for Software Engineers - Part 5 - Programming, JTAG, PROMs, &amp;amp; iMPACT]&lt;br /&gt;
Dieser Screencast zeigt die Klicks und Eingaben um ein Board (FPGA,PROMS) mit JTAG-Schnittstelle über das Impact-tool der Xilinx-ISE zu programmieren. Perfekt lesbar an einem 1080 Monitor.&lt;br /&gt;
&lt;br /&gt;
== How to use KCPSM3 in VHDL FPGA based project ==&lt;br /&gt;
* [http://www.youtube.com/watch?v=An3x5tKL5Js| How to use KCPSM3 in VHDL FPGA based project ]&lt;br /&gt;
Der KCPSM3 ist der Vorläufer der 8-Bit Soft-CPU Picoblaze von Xilinx. Das unkommentierte, aber mit Musik unterlegte Video zeigt wie im ISE Editor der VHDL-Code (Component-Instanziierung) hierfür erstellt wird. Einzelne Clicks in der Tooliste sind grafisch hervorgehoben. Der Text ist nicht sonderlich gut lesbar.&lt;br /&gt;
&lt;br /&gt;
== Noch ohne abschliessende Bewertung ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.youtube.com/watch?v=Ob7B6x5g6tw FPGA Xilinx VHDL Video Tutorial]: Zeigt das Aufsetzen eines Projektes in der Xilinx-ISE.&lt;br /&gt;
&lt;br /&gt;
* [http://www.youtube.com/watch?v=FxF0M3DA68Y Basic Schematic Input Tutorial] Xilinx-ISE, project from the scratch, fürchterlicher Ton&lt;br /&gt;
&lt;br /&gt;
* [http://www.eejournal.com/design/fpga/on-demand] EEJournal Webcasts und Videos zum Thema FPGA and Programmable Logic Design&lt;br /&gt;
&lt;br /&gt;
=== Vorlesungen  Prof.S.Srinivasan , Madras, Indien ===&lt;br /&gt;
bspw.:&lt;br /&gt;
*[http://www.youtube.com/watch?v=RZQTTfU9TNA| Lecture 30 Encoders and Decoders]&lt;br /&gt;
Vorlesungsvideo, stark akzentgefärbtes Englisch, erklärt werden die Grundlagen des Digitaldesigns, EDA-Tools werden vorgestellt.&lt;br /&gt;
&lt;br /&gt;
==Nicht empfohlen==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:FPGA und Co]]&lt;/div&gt;</summary>
		<author><name>8023</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=K%C3%BChlk%C3%B6rper&amp;diff=92410</id>
		<title>Kühlkörper</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=K%C3%BChlk%C3%B6rper&amp;diff=92410"/>
		<updated>2016-03-17T05:10:29Z</updated>

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

		<summary type="html">&lt;p&gt;8023: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein Labornetzgerät wird dazu verwendet, Schaltungen oder einzelne Bauteile mit einer definierten Spannung oder einem definierten Strom zu versorgen.&lt;br /&gt;
&lt;br /&gt;
== Funktionen ==&lt;br /&gt;
&lt;br /&gt;
Labornetzgeräte sind im Gegensatz zu einfachen Festspannungs-Netzteilen sehr flexibel einsetzbar und haben üblicherweise mindestens folgende Einstellmöglichkeiten und Funktionen:&lt;br /&gt;
&lt;br /&gt;
=== Einfache Labornetzteile ===&lt;br /&gt;
&lt;br /&gt;
Einfache Labornetzgeräte haben eine einstellbare Ausgangsspannung, die normalerweise von 0 bis zu einem bestimmten Maximalwert eingestellt werden kann. Zusätzlich bieten diese Geräte eine einstellbare Strombegrenzung, die auch von 0 aus bis zum Nennstrom des Geräts eingestellt werden kann.&lt;br /&gt;
&lt;br /&gt;
Labornetzgeräte haben außerdem noch eine Anzeige für Ausgangsspannung und Strom. Dafür sind entweder analoge oder digitale Instrumente eingebaut. Bei digitalen Anzeigen werden üblicherweise 3 Stellen angezeigt, die Genauigkeit der Anzeige liegt üblicherweise im Bereich 1%.&lt;br /&gt;
&lt;br /&gt;
Der Ausgang sollte kurzschlussfest sein, was allerdings nicht bei allen Labornetzgeräten der Fall ist. Manche Geräte sind nur kurzzeitig kurzschlussfest (für einige Sekunden), normalerweise sind Labornetzgeräte dauerhaft kurzschlussfest.&lt;br /&gt;
&lt;br /&gt;
=== Labornetzteile mit erweiterten Funktionen ===&lt;br /&gt;
&lt;br /&gt;
Die Labornetzgeräte der gehobenen Preisklasse haben zusätzlich zu den Grundfunktionen noch weitere Funktionen, wie z.B.:&lt;br /&gt;
&lt;br /&gt;
* Abschaltbarer Ausgang&lt;br /&gt;
* Getrennte Anzeige von Soll- und Ist-Werten&lt;br /&gt;
* Höhere Messgenauigkeit der Istwerte als bei einfachen Geräten&lt;br /&gt;
* Einstellbare Grenzwerte für Strom, Spannung, Leistung&lt;br /&gt;
* Alarm/Abschaltung bei Überschreitung von einstellbaren Schwellwerten&lt;br /&gt;
* Programmierbare Spannungs-/Stromverläufe&lt;br /&gt;
* Master-Slave-Funktion für Reihen-/Parallelschaltung von mehreren Geräten&lt;br /&gt;
* Analoge Schnittstelle für Soll- und Istwerte&lt;br /&gt;
* PC-Schnittstelle&lt;br /&gt;
&lt;br /&gt;
== Wichtige Eigenschaften ==&lt;br /&gt;
&lt;br /&gt;
=== Lineare Netzgeräte vs. Schaltnetzgeräte ===&lt;br /&gt;
&lt;br /&gt;
Es gibt bei Labornetzgeräten sowohl linear geregelte als auch Schaltnetzteile.&lt;br /&gt;
&lt;br /&gt;
Lineare Netzgeräte haben den Vorteil, dass die Regelung üblicherweise schneller und genauer ist. Die Ausgangskapazität ist bei linearen Netzgeräten relativ klein, dadurch kann die Strombegrenzung sehr schnell ansprechen.&lt;br /&gt;
&lt;br /&gt;
Schaltnetzgeräte haben dagegen einen besseren Wirkungsgrad, erzeugen also weniger Abwärme und sind kleiner und leichter als lineare Netzgeräte gleicher Leistung. Deshalb sind vor allem Labornetzgeräte mit hoher Leistung bevorzugt als Schaltnetzteil aufgebaut.&lt;br /&gt;
&lt;br /&gt;
Wenn bei Schaltnetzgeräten eine sehr kleine Ausgangs-Spannung eingestellt wird, wird diese oft nicht sauber ausgeregelt. Meistens brauchen solche Geräte eine bestimmte Mindestspannung am Ausgang.&lt;br /&gt;
&lt;br /&gt;
Weiterhin besteht bei Schaltnetzteilen die Gefahr, dass am Ausgang Störungen sichtbar sind, die durch die interne PWM erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Weiterhin gibt es auch Geräte, bei denen ein Schaltnetzteil und eine lineare Regelung kombiniert sind. Dadurch werden die Vorteile von beiden Verfahren kombiniert, es ergeben sich dadurch aber auch einige Probleme:&lt;br /&gt;
&lt;br /&gt;
* Bei schnellen Laständerungen kann es passieren, dass das Schaltnetzteil nicht schnell genug nachregelt. Dadurch ändert sich das Regelverhalten und die Ausgangsspannung bzw. Strom sind dann nicht mehr so stabil wie bei einem richtigen linear geregelten Netzgerät. &lt;br /&gt;
&lt;br /&gt;
* Bei schnellen periodischen Laständerungen kann es zusätzlich passieren, dass die Verlustleistung im Linearregler sehr viel höher wird als im Betrieb mit konstanter Ausgangsleistung. Da die lineare Endstufe meistens nicht dafür dimensioniert ist, kann es hier thermische Probleme geben.&lt;br /&gt;
&lt;br /&gt;
=== Verlustleistung und Kühlung === &lt;br /&gt;
&lt;br /&gt;
Das ist vor allem bei linear geregelten Geräten ein sehr wichtiges Kapitel, da eine gute Kühlung relativ viel Geld kostet und die Gerätehersteller hier gerne sparen. Folgende Punkte sollten hier beachtet werden:&lt;br /&gt;
&lt;br /&gt;
==== Passive Kühlung oder Kühlung mit Lüfter ====&lt;br /&gt;
Geräte mit passiver Kühlung erzeugen keine Geräusche, was ein großer Vorteil ist. Passive Kühlung ist aber nur bei Geräten mit relativ geringer Leistung üblich. Bei Lüfter-gekühlen Geräten sollte darauf geachtet werden, dass der Lüfter relativ ruhig läuft.&lt;br /&gt;
&lt;br /&gt;
==== Außenliegender Kühlkörper ====&lt;br /&gt;
Bei passiv gekühlten Geräten kann der Kühler ziemlich warm werden. Wenn der Kühler außen am Gehäuse montiert ist, besteht die Gefahr, dass man ihn versehentlich berührt und sich verbrennt oder dass wärmeempfindliche Gegenstände (z.B. kunststoff-isolierte Leitungen) bei Berührung beschädigt werden. Deshalb sollte man Geräte bevorzugen, bei denen der Kühler innerhalb des Gehäuses montiert ist.&lt;br /&gt;
&lt;br /&gt;
==== Lüftungsschlitze ====&lt;br /&gt;
Bei Geräten, die Lüftungsschlitze auf der Oberseite haben, besteht die Gefahr, dass Gegenstände reinfallen können, wodurch das Gerät beschädigt werden kann. Weiterhin kann es passieren, dass der Luftstrom durch die Schlitze behindert wird, wenn man etwas auf dem Gerät ablegt oder mehrere Geräte aufeinander stapelt.&lt;br /&gt;
Je nach dem, wo das Gerät aufgestellt werden soll, können deshalb seitliche Lüftungsschlitze vorteilhaft sein. Allerdings sind seitliche Lüftungsöffnungen meistens mit einem aktiven Lüfter kombiniert.&lt;br /&gt;
&lt;br /&gt;
==== Dimensionierung der Kühlkörper und Leistungstransistoren ====&lt;br /&gt;
Bei vielen billigen Netzgeräten ist die Kühlung zu knapp dimensioniert. Das kann man relativ einfach testen, indem man den Ausgangsspannung und Strom jeweils auf Maximalwerte einstellt und dann den Ausgang kurzschließt.&lt;br /&gt;
&lt;br /&gt;
In diesem Zustand sollte das Gerät längere Zeit (einige Stunden) betrieben werden, bis alles thermisch eingeschwungen ist. Dann muss bei allen Leistungsbauteilen die Temperatur gemessen werden, am einfachsten geht das mit einer Wärmebildkamera. Es sollten nach Möglichkeit keine Temperaturen oberhalb von 100°C auftreten. Wärme-empfindliche Bauteile (z.B. Elkos) sollten nicht wärmer als 70°C sein.&lt;br /&gt;
&lt;br /&gt;
Besonders kritisch sind hier:&lt;br /&gt;
* Netztrafo&lt;br /&gt;
* Gleichrichter&lt;br /&gt;
* Leistungstransistoren und Kühlkörper&lt;br /&gt;
&lt;br /&gt;
=== Stabilität und Genauigkeit ===&lt;br /&gt;
&lt;br /&gt;
Wichtige Eigenschaften bei Labornetzgeräten ist die Stabilität und die Genauigkeit.&lt;br /&gt;
&lt;br /&gt;
==== Stabilität ====&lt;br /&gt;
&lt;br /&gt;
Damit wird angegeben, wie konstant ein eingestellter Wert über einen längeren Zeitraum gehalten wird. Hier ist wichtig, dass das Gerät einen kleinen Temperaturkoeffizient hat, so dass die Ausgangsspannung auch bei Temperaturschwankungen möglichst stabil bleibt.&lt;br /&gt;
&lt;br /&gt;
==== Genauigkeit ====&lt;br /&gt;
&lt;br /&gt;
Hier muss unterschieden werden zwischen der Anzeigegenauigkeit und der Einstellgenauigkeit.&lt;br /&gt;
&lt;br /&gt;
Die Genauigkeit der Anzeige gibt an, wie genau die angezeigte Ausgangsspannung oder Strom mit der tatsächlichen Spannung übereinstimmt (siehe dazu auch  Artikel [[Auflösung und Genauigkeit]]).&lt;br /&gt;
&lt;br /&gt;
Die Einstellgenauigkeit gibt an, wie genau ein bestimmter Sollwert eingestellt werden kann und wie gut die tatsächlichen Werte mit den Sollwerten übereinstimmen. Bei Geräten mit digitaler Sollwertvorgabe muss hier die kleinste Schrittweite beachtet werden.&lt;br /&gt;
&lt;br /&gt;
== Weitere Funktionen ==&lt;br /&gt;
&lt;br /&gt;
=== Schnittstelle ===&lt;br /&gt;
&lt;br /&gt;
Einige Labornetzgeräte bieten eine Schnittstelle zum PC, damit können sie als per Software steuerbares Netzgerät verwendet werden. Will man das Netzgerät per Mikrocontroller steuern, so sind Typen mit [[RS232]] Anschluß den Typen mit [[USB]] vorzuziehen.&lt;br /&gt;
&lt;br /&gt;
=== Beleuchtung ===&lt;br /&gt;
&lt;br /&gt;
Folgende Display-Arten sind bei Labornetzgeräten üblich:&lt;br /&gt;
* Analoginstrument (unbeleuchtet oder beleuchtet)&lt;br /&gt;
* LCD 7-Segment Anzeige (unbeleuchtet oder beleuchtet)&lt;br /&gt;
* LCD Punktmatrix-Anzeige (in der Regel beleuchtet)&lt;br /&gt;
* LED 7-Segment Anzeige (selbstleuchtend)&lt;br /&gt;
* OLED-Anzeigen (selbstleuchtend)&lt;br /&gt;
* VFD-Anzeigen (selbstleuchtend)&lt;br /&gt;
&lt;br /&gt;
Anzeigen mit Beleuchtung bzw. selbstleuchtende Anzeigen sind wesentlich besser ablesbar als unbeleuchtete LCD-Anzeigen. Da Labornetzgeräte immer am Netz betrieben werden, ist der Stromverbrauch der Beleuchtung nicht relevant.&lt;br /&gt;
&lt;br /&gt;
Unbeleuchtete LCD-Anzeigen sind bei schlechter Beleuchtung oder ungünstigem Blickwinkel manchmal schlecht ablesbar, bei 7-Segment LED-Anzeigen ist die Ablesbarkeit wesentlich besser. &lt;br /&gt;
&lt;br /&gt;
Mit 7-Segment Anzeigen lassen sich allerdings nur Ziffern und einige wenige Buchstaben darstellen. Für Geräte mit komplexen Einstellungen und Menu-Führung werden deshalb häufig Punkt-Matrix LCD-Anzeigen verwendet.&lt;br /&gt;
&lt;br /&gt;
Mit VFD-Anzeigen [http://de.wikipedia.org/wiki/Fluoreszenzanzeige], die ebenfalls sehr gut ablesbar sind, könnnen auch komplexe Menüs dargestellt werden. Diese haben einen sehr weiten Blickwinkel und sehr scharfe und klare Zeichen. Allerdings sind diese Anzeigen relativ teuer, weshalb sie vor allem in eher teueren Geräten eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
== Vergleichstabelle Labornetzgeräte ==&lt;br /&gt;
&lt;br /&gt;
In den folgende Tabellen werden wichtige technischen Daten einiger aktueller Labornetzgeräte zusammengestellt. Um die Übersichtlichkeit zu erhöhen, werden die Geräte eingeteilt in einfache Geräte und Geräte mit Zusatzfunktionen&lt;br /&gt;
&lt;br /&gt;
Die Einteilung geschieht aufgrund der Funktionen, die die Geräte bieten. Das ist also keine Aussage über die Qualität der Geräte.&lt;br /&gt;
&lt;br /&gt;
=== Einfache lineare Labornetzgeräte ===&lt;br /&gt;
&lt;br /&gt;
Hier werden Geräte aufgelistet, welche neben den Grundfunktionen (Strom- und Spannungseinstellung, Anzeige der Istwerte) keine weiteren Funktionen besitzen.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable sortable&amp;quot; id=&amp;quot;einfache&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Hersteller&lt;br /&gt;
!Bezeichnung&lt;br /&gt;
!Preis [EUR]&lt;br /&gt;
!Spannung [V]&lt;br /&gt;
!Strom [A]&lt;br /&gt;
!Kanäle&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3616A&lt;br /&gt;
|620&lt;br /&gt;
|35&lt;br /&gt;
|1.7&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HM8040-3(Benötigt HM8001)&lt;br /&gt;
|280&lt;br /&gt;
|20 + 20 + 5&lt;br /&gt;
|0.5 + 0.5 + 1&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|Peaktech&lt;br /&gt;
|6080&lt;br /&gt;
|50&lt;br /&gt;
|15&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|McVoice&lt;br /&gt;
|WNT0-15-2000&lt;br /&gt;
|38&lt;br /&gt;
|15&lt;br /&gt;
|2&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
|Statron&lt;br /&gt;
|2223.1&lt;br /&gt;
|150&lt;br /&gt;
|30&lt;br /&gt;
|2.5&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2250.0&lt;br /&gt;
|225&lt;br /&gt;
|40&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2229.2&lt;br /&gt;
|260&lt;br /&gt;
|40 + 40&lt;br /&gt;
|2.5 + 2.5&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2229.5&lt;br /&gt;
|340&lt;br /&gt;
|32 + 32 + 5&lt;br /&gt;
|3 + 3 + 3&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|Statron&lt;br /&gt;
|2225.6&lt;br /&gt;
|310&lt;br /&gt;
|30 + 30&lt;br /&gt;
|5 + 5&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|PS-1302 D&lt;br /&gt;
|95&lt;br /&gt;
|30&lt;br /&gt;
|2&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VLP 1303pro&lt;br /&gt;
|180&lt;br /&gt;
|30 + 6&lt;br /&gt;
|3 + 2&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VSP 2403&lt;br /&gt;
|345&lt;br /&gt;
|40 + 40 + 6&lt;br /&gt;
|3 + 3 + 1.5&lt;br /&gt;
|3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Einfache Schaltnetzgeräte ===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable sortable&amp;quot; id=&amp;quot;einfache&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Hersteller&lt;br /&gt;
!Bezeichnung&lt;br /&gt;
!Preis [EUR]&lt;br /&gt;
!Spannung [V]&lt;br /&gt;
!Strom [A]&lt;br /&gt;
!Kanäle&lt;br /&gt;
|-&lt;br /&gt;
|Delta Elektronika&lt;br /&gt;
|ES 030-5&lt;br /&gt;
|624&lt;br /&gt;
|30&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Quatpower&lt;br /&gt;
|LN-3003&lt;br /&gt;
|40&lt;br /&gt;
|30&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Netzgeräte mit Zusatzfunktionen ===&lt;br /&gt;
&lt;br /&gt;
Diese Geräte haben mindestens folgende Funktionen:&lt;br /&gt;
* abschaltbare Ausgänge&lt;br /&gt;
* Anzeige der Sollwerte für Strom und Spannung&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable sortable&amp;quot; id=&amp;quot;hochwertige&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Hersteller&lt;br /&gt;
!Bezeichnung&lt;br /&gt;
!Preis [EUR]&lt;br /&gt;
!Spannung [V]&lt;br /&gt;
!Strom [A]&lt;br /&gt;
!Kanäle&lt;br /&gt;
!linear/getaktet&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|U8001A&lt;br /&gt;
|290&lt;br /&gt;
|30&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3616A&lt;br /&gt;
|620&lt;br /&gt;
|35&lt;br /&gt;
|1.7&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3643A&lt;br /&gt;
|690&lt;br /&gt;
|35 / 60 (umschaltbar)&lt;br /&gt;
|1.4 / 0.8&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Agilent&lt;br /&gt;
|E3632A&lt;br /&gt;
|990&lt;br /&gt;
|15 / 30 (umschaltbar)&lt;br /&gt;
|7 / 4&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|BK Precision&lt;br /&gt;
|BK 1786&lt;br /&gt;
|490&lt;br /&gt;
|32&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|BK Precision&lt;br /&gt;
|BK 1788&lt;br /&gt;
|615&lt;br /&gt;
|32&lt;br /&gt;
|6&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|BK Precision&lt;br /&gt;
|BK 9130&lt;br /&gt;
|685&lt;br /&gt;
|30 + 30 + 5&lt;br /&gt;
|3 + 3 + 3&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|PSI 6032-03&lt;br /&gt;
|425&lt;br /&gt;
|32&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 2042-06B&lt;br /&gt;
|235&lt;br /&gt;
|42&lt;br /&gt;
|6&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 2342-06B&lt;br /&gt;
|580&lt;br /&gt;
|42 + 42 + 6&lt;br /&gt;
|6 + 6 + 4&lt;br /&gt;
|3&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 3032-05B&lt;br /&gt;
|355&lt;br /&gt;
|32&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|EA Elektro-Automatik&lt;br /&gt;
|EA-PS 8032-10 DT&lt;br /&gt;
|940&lt;br /&gt;
|32&lt;br /&gt;
|10&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|ELV&lt;br /&gt;
|PPS 5330&lt;br /&gt;
|120&lt;br /&gt;
|30&lt;br /&gt;
|3&lt;br /&gt;
|1&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|ELV&lt;br /&gt;
|SPS 5630&lt;br /&gt;
|200&lt;br /&gt;
|30&lt;br /&gt;
|6 (max. 75W)&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HM7042-5&lt;br /&gt;
|685&lt;br /&gt;
|32 + 32 + 5,5&lt;br /&gt;
|2 + 2 + 5&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HMP2020&lt;br /&gt;
|1190&lt;br /&gt;
|32 + 32&lt;br /&gt;
|10 + 5&lt;br /&gt;
|2&lt;br /&gt;
|getaktet + linear&lt;br /&gt;
|-&lt;br /&gt;
|Hameg&lt;br /&gt;
|HMP2030&lt;br /&gt;
|1500&lt;br /&gt;
|32 + 32 + 32&lt;br /&gt;
|5 + 5 + 5&lt;br /&gt;
|3&lt;br /&gt;
|getaktet + linear&lt;br /&gt;
|-&lt;br /&gt;
|Rigol&lt;br /&gt;
|DP832 **)&lt;br /&gt;
|362&lt;br /&gt;
|30 + 30 + 5&lt;br /&gt;
|3 + 3 + 3&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VLP 1405pro&lt;br /&gt;
|1190&lt;br /&gt;
|40 + 6&lt;br /&gt;
|5 + 2&lt;br /&gt;
|2&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|PeakTech&lt;br /&gt;
|1885&lt;br /&gt;
|270&lt;br /&gt;
|40&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VLP 2403pro&lt;br /&gt;
|320&lt;br /&gt;
|40 + 40 + 6&lt;br /&gt;
|3 + 3 + 2&lt;br /&gt;
|3&lt;br /&gt;
|linear&lt;br /&gt;
|-&lt;br /&gt;
|Voltcraft&lt;br /&gt;
|VSP 2410&lt;br /&gt;
|470&lt;br /&gt;
|40 + 40 + 6&lt;br /&gt;
|10 + 10 + 1.5&lt;br /&gt;
|3&lt;br /&gt;
|getaktet&lt;br /&gt;
|-&lt;br /&gt;
|TTI&lt;br /&gt;
|EX355R&lt;br /&gt;
|330&lt;br /&gt;
|35&lt;br /&gt;
|5&lt;br /&gt;
|1&lt;br /&gt;
|Mixed-mode (getaktet + linear)&lt;br /&gt;
|-&lt;br /&gt;
|TTI&lt;br /&gt;
|EX354RD&lt;br /&gt;
|480&lt;br /&gt;
|35 + 35&lt;br /&gt;
|4 + 4&lt;br /&gt;
|2&lt;br /&gt;
|Mixed-mode (getaktet + linear)&lt;br /&gt;
|-&lt;br /&gt;
|TTI&lt;br /&gt;
|EX354RT&lt;br /&gt;
|540&lt;br /&gt;
|35 + 35 + (1,5-5)&lt;br /&gt;
|4 + 4 + 5&lt;br /&gt;
|3&lt;br /&gt;
|Mixed-mode (getaktet + linear)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
 **) Das Rigol DP832(A) schaltet die Ausgänge nicht physisch/galvanisch ab. Die Power-MOSFETs der Ausgangsstufe werden lediglich auf Soll-NULL gesetzt. Dies kann bei Drift auch durchaus ungleich 0,00 Volt bedeuten!&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Spannungsversorgung_und_Energiequellen]]&lt;/div&gt;</summary>
		<author><name>8023</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Scheduler_mit_Erweiterung_zum_Mini-Betriebssystem&amp;diff=92408</id>
		<title>Scheduler mit Erweiterung zum Mini-Betriebssystem</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Scheduler_mit_Erweiterung_zum_Mini-Betriebssystem&amp;diff=92408"/>
		<updated>2016-03-17T05:08:07Z</updated>

		<summary type="html">&lt;p&gt;8023: Wie arm im Geiste muss man eigentlich sein, für solchen Kinderkram?&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;big&amp;gt; &amp;lt;u&amp;gt;&#039;&#039;&#039;Vorwort&#039;&#039;&#039;&amp;lt;/u&amp;gt;&amp;lt;/big&amp;gt;:&amp;lt;br /&amp;gt;&lt;br /&gt;
Dieser Artikel behandelt die Erstellung eines Schedulers, der zu einem Mini-OS erweitert wird. Ziel ist es, das Verständnis sowie die Funktion eines OS besser verstehen zu können. Wie so manch ein anderer habe auch ich mich gefragt, wie ein Betriebssystem eigentlich funktioniert, und - weil Nachbauen eine der besten Möglichkeit ist etwas zu verstehen - habe mir mein eigenes kleines System geschrieben. Es geht nicht darum ein „Suppa-Duppa“ OS zu schreiben, sondern zu verstehen wie größere (RTOS-&amp;gt;Linux-&amp;gt;Windows) funktionieren. &amp;lt;br /&amp;gt;&lt;br /&gt;
Von: Sebastian Balz &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Warnung |&lt;br /&gt;
&#039;&#039;&#039;Warnung&#039;&#039;&#039;  &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Es werden gute Kenntnisse in C und Assembler, sowie gute Kenntnisse der CPU benötigt. Des Weiteren ersetzt ein selbst geschriebenes OS keinesfalls ein herkömmliches OS (RTOS …), da diese zuverlässiger und effizienter laufen und mehr Funktionen haben.&lt;br /&gt;
&lt;br /&gt;
}}&amp;lt;br /&amp;gt;&lt;br /&gt;
Alle Beispiele beziehen sich auf einen ARM-Cortex-M4 (SAM4SD32C), sollten jedoch auf alle gängigen µC portiert werden können. Um den Kontext-Switch zu vereinfachen werden keine Gleitkomma Berechnungen unterstützt.  &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
= Voraussetzungen =&lt;br /&gt;
 &amp;lt;br /&amp;gt;&lt;br /&gt;
* Gute C und Assembler Kenntnisse &lt;br /&gt;
* Gute Kenntnisse des UC‘s&lt;br /&gt;
* Viel Zeit und Motivation :)&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Zielsetzung= &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Das beschriebene System soll in der Lage sein:&lt;br /&gt;
* Zwischen verschiedenen Aufgaben (Tasks) zu wechseln(Context-Switch). D.h. jeder Task hat das Gefühl, dass der UC ihm gehört. &lt;br /&gt;
* Fähigkeit der Task’s sich selber zu beenden oder zu pausieren, um so CPU-Ressourcen zu sparen. &lt;br /&gt;
* Keinerlei Auswirkung aufs Interrupt Handling.&lt;br /&gt;
* Ein Zeit Management&lt;br /&gt;
* Tasks und Threads mit Return-Wert und Kill&lt;br /&gt;
* Kommunikation zwischen den Tasks mit Schreib-Kontrolle &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Grundlagen = &lt;br /&gt;
&lt;br /&gt;
Die Hauptaufgabe des Systems ist es, zwischen den verschiedenen Tasks wechseln zu können. &lt;br /&gt;
Um dies realisieren zu können, muss man erst einmal verstehen, wie überhaupt ein Kontext ausschaut.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Register== &lt;br /&gt;
Register sind die Speicherzellen, die direkt mit der CPU verbunden sind. Sie haben die besten Lese- und Schreibraten, sind jedoch „teuer“, weshalb in einer CPU nur relativ wenige Register vorhanden sind. &lt;br /&gt;
In der ARM-Cortex-M4 Serie sind es 12 sog. „General-Purpose Register“ und ein paar Spezial-Register. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:Register Balz.PNG|900px]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quelle: Datenblatt Register&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Stack == &lt;br /&gt;
&lt;br /&gt;
Der Stack ist ein LIFO (Last in, First out), d.h. der zuletzt hinzugefügte Wert wird als erstes wieder ausgelesen. Über Push (Speicher) und POP (Laden) kann man Register-Inhalte auf den Stack speichern und laden.&lt;br /&gt;
Des Weiteren gibt es einen Stack-Pointer. Dieser zeigt immer auf die letzte Adresse im Stack. &lt;br /&gt;
Der Stack baut sich von einer Speicherzelle aus nach unten auf. D.h., wenn ein Wert auf den Stack geschrieben wird, verringert sich die Stack-Adresse. &lt;br /&gt;
&lt;br /&gt;
Jedes Programm schreibt und erstellt seine lokalen Variablen auf dem Stack (RAM). Bei einem Funktionsaufruf werden Übergabeparameter und die Rücksprungadresse im Stack hinterlegt. &lt;br /&gt;
Die aufgerufene Funktion des Speichers (Push) hat also so viele Register auf dem Stack, wie sie selber Register benötigt, damit beim „Return“ wieder die Start-Register vom Stack geholt (POP) werden können und damit der „vor-Funktion-Zustand“ wieder hergestellt ist. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exception Call ==&lt;br /&gt;
Wird eine Funktion durch einen Interrupt unterbrochen, werden R0-R3,R12, LR, PC und xPSR (eine Verbindung aus “Interrupt Program Status Register“, “Application Program Status Register“, „Program Status Register“ und „Execution Program Status Register“) auf den Stack gepusht.&lt;br /&gt;
[[Datei:Stack Balz.PNG]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quelle Datenblatt: Interrupt Stack &amp;lt;br /&amp;gt;&lt;br /&gt;
Der µC schreibt beim “Interrupt entry“ eine EXC_Return_Value ins Link um zu signalisieren, dass gerade eine Interrupt-Routine aktiv ist.   &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:EXC Return Balz.PNG |700px]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quelle: Datenblatt Exc_Return &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Beim Verlassen des ISRs müssen nun nur noch die Register R0-R3, LR,SP und die Status-Register wieder hergestellt werden.   &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Context-Switch =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Theorie==&lt;br /&gt;
Um nun den aktuellen Kontext zu wechseln, müssen in einem Interrupt sämtliche Register gespeichert werden (PUSH R0-R12) und der Stack-Pointer auf den Stack des neuen Task‘s verschoben werden. Nun können die Register wieder hergestellt werden (POP R0-R12). Das Link-Register kann hier außer Acht gelassen werden, da es immer den Wert 0xFFFFFF9 (Return to Thread mode without floating point calculation) hat. &lt;br /&gt;
Wenn man nun das ISR von außen betrachtet, darf man keinen Unterschied zum letzten Speicherzeitpunkt feststellen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Move Stack Balz.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Praxis ==&lt;br /&gt;
=== Speicher ===&lt;br /&gt;
Die Praxis ist leider etwas komplizierter: Zunächst einmal muss der Task-Stack im Speicher reserviert werden. Hierfür kann entweder malloc() verwendet werden - um dynamisch zur Laufzeit den Speicher zu reservieren - oder man „belegt“ den Speicher über Arrays. Da ein Stack-Overflow mit, dass Schlimmste ist, was unserem System passieren kann (Überschreibung der anderen Stacks/globalen Variablen), sollte die Größe des Stacks eher großzügig definiert sein.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stackerzeugen=== &lt;br /&gt;
Da ein Stack sich von oben nach unten (aus Sicht des Speichers) aufbaut, muss der Stack-Pointer auf die Speicheradresse des letzten Array-Elementes zeigen.&lt;br /&gt;
Da beim Kontext-Switch der letzte Zustand wiederhergestellt wird, muss nun der Stack befüllt werden: &lt;br /&gt;
&lt;br /&gt;
* Programm Counter: hier wird die Startadresse des Task‘s eingetragen &lt;br /&gt;
* Link–Register: Da die Task-Ansicht keine Funktion ist und im Normalfall nicht irgendwann verlassen wird, kann dieses Feld freigelassen werden. Alternativ kann auch auf die Adresse eines Dummy-Handlers verwiesen werden, der sich dann um die Beendigung des Tasks kümmert.&lt;br /&gt;
* Program Status Register: Im Status Register (xPSR) wird der Wert hinterlegt, der der CPU signalisiert, dass der aktuelle Programmabschnitt sich gerade in einem Interrupt befindet.&lt;br /&gt;
* Register 0-3,12 sind die Register, die vor einem Interrupt gesichert und nach dem Interrupt wieder hergestellt werden. Da der Task noch keine Registerwerte verwendet hat, können diese Zellen frei bleiben. &lt;br /&gt;
&lt;br /&gt;
Wenn nun ein Kontext-Switch ausführt wird, wird man relativ schnell feststellen, dass etwas noch nicht passt. &lt;br /&gt;
Die Interrupt-Routine hat selber auch Variablen, die auf dem „alten“ Stack gespeichert und nach Verlassen des Stacks wieder vom Stack „gelöscht“ werden müssen. Diese müssen in dem neuen Stack berücksichtigt werden. Leider kann man hier keinen pauschalen Wert nennen, was dazu führt, dass jede Veränderung an der Interrupt-Routine Folgen haben kann. So muss z.B. bei dem neuem Stack die Anzahl der lokalen Register einbezogen werden. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Kontext wechseln ===&lt;br /&gt;
Nun, da der Speicher reserviert und der Stack aufgebaut worden ist, kann man den Kontext wechseln. &lt;br /&gt;
Hierfür müssen alle General-Purpose-Register auf den Stack gespeichert werden. &lt;br /&gt;
Da zu einem späteren Zeitpunkt der Stack wieder zurück gewechselt werden soll, muss nun der aktuelle Stack-Pointer gesichert werden, z.B. in der Task_List (siehe Task_Liste).&lt;br /&gt;
Der „alte“ Kontext ist nun gesichert, und so kann der „Neue“ geladen werden. Zunächst muss der Stack-Pointer umgezogen werden.&lt;br /&gt;
Um sicher zu stellen, dass der µC nun den neuen Stack auch verwendet, muss ein „Pipeline flush“ getätigt werden. Hierfür ist im TUMB2-Befehlssatz der Befehl „ISB“ (Instruction Synchronization Barrier) vorhanden, der direkt nach dem Stack-Pointer-Tausch ausgeführt werden sollte. &lt;br /&gt;
Nun können die Register 0-12 wieder hergestellt werden. Das Linkregister verändert sich nicht, da das Exc_return Value immer gleich ist.&lt;br /&gt;
&lt;br /&gt;
Wird nun die Interrupt Routine verlassen, werden die lokalen Variablen vom Stack gelöscht und die ISR-Inhalte gePOP’t. Der Prozessor springt dann „zurück“ in den neuen Task.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== BSP1 ==== &lt;br /&gt;
Im folgenden Bild kann man gut sehen, wie zwei Tasks (weiße Kästen: PWM) abwechselnd aufgerufen werden. Dargestellt ist die Aktivität der Tasks als Funktion der Zeit; alle 50 ms wird in diesem Beispiel der Task gewechselt: &amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Datei:Context Switch.JPG | 900px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Task-Liste==&lt;br /&gt;
Damit das System weiß, wie viele und welche Tasks gerade ausgeführt werden, muss eine Liste erstellt werden, in der die jeweiligen IDs der Tasks enthalten sind, sowie:&lt;br /&gt;
* Stack-Pointer&lt;br /&gt;
* Stack Start Adresse&lt;br /&gt;
* Stack-Size&lt;br /&gt;
Optional kann in dieser Liste auch noch: &lt;br /&gt;
* Task Status/Message&lt;br /&gt;
* Thread Return_Value&lt;br /&gt;
enthalten sein.&lt;br /&gt;
=== Stack Pointer === &lt;br /&gt;
Um bei einem Kontext Switch den alten Task wieder herzustellen, muss bekannt sein, an welcher Stelle im Speicher der Stack liegt. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Stack Start Adresse === &lt;br /&gt;
Ist relevant, wenn überprüft werden soll, ob es einen Stack Overflow gab. Sollte es ein Stack-Overflow geben muss dies gemeldet und das System wieder auf den Ursprungszustand gesetzt werden.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Stack-Size === &lt;br /&gt;
Wird in Verbindung mit der Stack_Start Adresse für die Overflow-Erkennung benötigt.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Task Status === &lt;br /&gt;
Hier kann ein Task seinen Status mitteilen&lt;br /&gt;
* IDLE&lt;br /&gt;
* Started(läuft der Task gerade?)&lt;br /&gt;
* Oder soll der Stack des Task‘s aufgebaut werden&lt;br /&gt;
* Lese Fehler (siehe Speicher Management)&lt;br /&gt;
&lt;br /&gt;
=== Return Value === &lt;br /&gt;
wird ein Thread auf geplante Weise verlassen – (d.h. er beendet sich selber) –kann dieser auch ein Return_Value als Ergebnis hinterlegen. Hat der Thread z.B. die Aufgabe, eine Nutzereingabe zu erkennen und zu analysieren, so kann der erstellende Task (der die ID kennt) über das Ergebnis informiert werden.  &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
== Zeitmanagement ==&lt;br /&gt;
&lt;br /&gt;
=== System-Zeit ===&lt;br /&gt;
Oftmals kommt es vor, dass ein Task eine Tätigkeit alle x ms ausführen soll. Da jedoch die Tasks möglichst unabhängig sein sollen (sie wissen also nicht mit welcher Taktrate der Prozessor läuft), ist es sinnvoll, über eine RTT oder einen Timer/Counter die Zeit mitzuzählen und diese über eine Funktion allen Tasks und Threads zur Verfügung zu stellen. &lt;br /&gt;
Auch ist es sinnvoll, eine Funktion bereit zu stellen, die überprüft ob eine bestimmt Zeit vergangen ist; unter Berücksichtigung, dass die System-Zeit irgendwann wieder bei 0 anfängt. &lt;br /&gt;
Eine solche Funktion könnte wie folgt aussehen:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int vergangene_zeit(int os_lasttime, int soll_time){&lt;br /&gt;
	int time_know = get_os_time(); // hole die aktuelle Systhem Zeit&lt;br /&gt;
	int delta;&lt;br /&gt;
	if (zeit-lasttime &amp;lt;0) // hat ein System-Zeit Wraparound stattgefunden &lt;br /&gt;
	{&lt;br /&gt;
		zeit += os_max_time; // addiere Max SysthemZeit drauf&lt;br /&gt;
	}&lt;br /&gt;
	delta = zeit-lasttime; &lt;br /&gt;
	return delta &amp;gt;= sollzeit;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So kann ein Task einfach in einer  &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt; while(!(vergangene_zeit(lasttime,soll_time))){}&amp;lt;/syntaxhighlight&amp;gt; darauf warten, dass die Soll Zeit abgelaufen ist. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Kontext-Switch ===&lt;br /&gt;
Natürlich ist es auch wichtig, dass der Kontext-Switch zentral gesteuert wird. Hier ist es empfehlenswert, den Real-Time-Timer oder einen Timer/Counter zu verwenden, der die Systemzeit managt. Über ein Static counter kann/soll eine bestimmte Anzahl an Zyklen bestimmt werden, bei denen der Kontext-Switch getriggert wird. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== IDLE ===&lt;br /&gt;
Hat man mehrere Tasks die darauf warten, dass Zeit vergeht, wird viel Rechenleistung verbraucht, da die Tasks mit Nichtstun beschäftigt sind, während andere Tasks diese Rechenzeit gut brauchen könnten. &lt;br /&gt;
Um diesem Problem zu entgehen, sollte ein Task in der Lage sein, sich als inaktiv zu deklarieren. Dies könnte über einen Status-Bit geschehen, welches der Time_manager bei jedem Erhöhen der Systemzeit überprüft und den Kontext-Switch triggert.&lt;br /&gt;
Eine bessere Lösung wäre jedoch, zusätzlich zur IDLE Funktion einen Software Interrupt auszulösen, welcher den TC_Handler oder RTT_Handler des Zeitmanagements triggert. &lt;br /&gt;
So kann im Zeitmanagement geprüft werden, ob ein Task IDLE ist, oder ob der Interrupt auf herkömmliche Weise generiert worden ist. &lt;br /&gt;
Sollten ein Großteil oder alle Task IDLE sein, sollte die CPU in ein LOW-Power-Mode wechseln. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Beispiel 1====&lt;br /&gt;
&lt;br /&gt;
Im folgenden Beispiel kann gut erkannt werden, wie sich Task1 zur Hälfte der möglichen Laufzeit als IDLE deklariert und einen Kontext-Switch triggert. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Task IDLE.JPG|900px]]&lt;br /&gt;
Saleae Logic Analyser: Task IDLE &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Tasks und Threads zur Laufzeit erstellen und beenden =&lt;br /&gt;
&lt;br /&gt;
Eine weite Stärke eines solchen Systems ist es, dass dann ohne großen Aufwand einfach ein neuer Task oder Thread hinzugefügt werden kann.&lt;br /&gt;
Ein Thread hat eine feste Aufgabe die er erfüllen soll. Ist diese erfüllt, können weitere Ereignisse getriggert werden, oder der Thread kann beendet werden. &lt;br /&gt;
 &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Starten ===&lt;br /&gt;
Hierfür muss lediglich ein neuer Stack mit Linkregister, Einsprung-Adresse etc. hinzugefügt werden und über die Task_Liste dem Zeitmanagement mitgeteilt werden, sodass es einen neuen Taskeintrag gibt, der gestartet werden soll. &lt;br /&gt;
==== Beispiel 2 ====&lt;br /&gt;
&lt;br /&gt;
Hier kann gut erkannt werden, wie Thread 1 während der Laufzeit erstellt wird und von nun an vom Scheduler aufgerufen wird. Hierdurch werden jedoch Task1 und Task2 seltener aufgerufen.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Thread start.JPG |900px]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beenden ===&lt;br /&gt;
Ein Thread kann auf zwei Arten beendet werden. Die reguläre Art ist, dass er sich selber schließt. Hierfür kann eine Funktion geschrieben werden, die der Task_Liste mitteilt, dass der Task beim nächsten Kontext-Switch nicht mehr aufgerufen werden soll. Optional kann in der Task_List ein Return Value hinterlegt werden, damit der Ersteller des Tasks z. B. ein Ergebnis erhält. Hierbei ist wichtig, zuerst den Return_value zu setzen bevor der Task als beendet definiert wird, da ansonsten ein ungünstiges Timing mit dem Kontext-Switch das Schreiben des Return_Values verhindert. Nachdem Return_value und der Task als beendet definiert worden sind, sollte der Task einen Task_IDLE an den Zeitmanager senden, um so den Task direkt zu verlassen und keine Rechenzeit zu vergeuden.&lt;br /&gt;
Auch ist es nötig, dass der Ersteller des Threads die ID des Threads in der Task_Liste erhält, da hinter der ID des Threads auch der Return_Value gespeichert wird. &lt;br /&gt;
Eine andere Art ein Thread zu beenden ist, ihn zu killen. Wenn z. B. die Ausführung des Threads nicht mehr relevant ist, weil das Ergebnis zu spät kommen würde (Real-Time-OS), oder die Ausführung des Threads nicht mehr benötigt wird, kann man einen Thread auch über die Task-Liste von außen beenden. Hierbei muss nur das Task_Active-Bit gelöscht werden.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Beispiel 3 ====&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
[[Datei:Thread closing.JPG|900px]]&lt;br /&gt;
&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
Hier kann gut erkannt werden, wie Thread1 wieder geschlossen wird. Dadurch werden Task 1 und Task 2 wieder öfter aufgerufen.  &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Interrupte =&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Eigentlich sollte es keinerlei Probleme bereiten, einen Interrupt auszuführen, da dieser den aktuellen Task nicht berührt. &lt;br /&gt;
Es muss lediglich auf zwei Punkte Rücksicht genommen werden:&lt;br /&gt;
* Der Zeitmanager muss in der niedrigsten Priorität laufen. Würde er mit einer höheren Priorität laufen während gerade ein anderer Interrupt aktiv ist, würden die gespeicherten Register in den falschen Stack abgelegt. Die wieder herzustellenden Register kämen aus einem Stack, in dem keine Register gesichert worden sind. Dieser Vorgang würde beide Stacks zerstören.&lt;br /&gt;
* Während des Kontext Switches dürfen keine anderen Interrupts aktiv werden, da es auch hier zu Problemen mit den Stacks kommen könnte.&lt;br /&gt;
Deshalb ist es empfehlenswert, den Zeitmanager in der niedrigsten Priorität laufen zu lassen und während der Ausführung andere Interrupts zu unterbinden. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Erweiterung zum OS =&lt;br /&gt;
Von nun an sind die Übergänge zu einem Betriebssystem fließend. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
== Priorisierung ==&lt;br /&gt;
in Arbeit!&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Speicher Management == &lt;br /&gt;
Der erste Schritt in Richtung Betriebssystem ist ein Speicher-Management, welches in der Lage ist, Speicher zu reservieren und gegebenenfalls auch zu blockieren, sowie freizugeben. Hier kommt wieder – wie beim Stack-Aufbau - malloc() oder ein Array zum Einsatz. Der Einfachheit halber werden die einzelnen Speicher über ID’s angesprochen. Auch muss zentral geregelt werden, ob die jeweilige ID bereits in Verwendung ist. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Erstellen ===&lt;br /&gt;
Möchte ein Task oder Thread einen solchen Speicher erstellen, muss zunächst überprüft werden, ob noch Speicherplätze frei sind. In diesem Fall kann die ID der Speicherzelle zurückgegeben werden (return-Wert). Andernfalls sollte ein Error_Value zurück geliefert werden.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
=== Freigeben ===&lt;br /&gt;
Um Speicher zu sparen, müssen Task und Threads in der Lage sein, den Speicher wieder frei zu geben. Sollte ein Task der beim Speicher durch einen Kontext –Switch unterbrochen worden ist, auf denselben Speicher zugreifen, sollte vor dem Freigeben überprüft werden, ob und warum der Speicher gesperrt worden ist. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Speichern ===&lt;br /&gt;
Um ein ungünstiges Timing zu verhindern (z. B. ein Prozess beschreibt eine Speicherzelle und wird während des Schreibvorganges durch einen Kontext-Switch unterbrochen), sollte nun der Speicher durch einen anderen Task wieder freigegeben werden. Hierzu muss vor dem Schreibvorgang signalisiert werden, dass die jeweilige Zelle blockiert ist. Als Return kann hier dann entweder ein Error_value oder ein Success_Value übertragen werden.  &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lesen === &lt;br /&gt;
Zum Lesen muss lediglich überprüft werden, ob der Speicher der angegebenen ID reserviert ist. Als Return kann hier dann entweder der gespeicherte Wert oder ein Error_Value verwendet werden. Um zu erkennen ob es sich hier um einen Fehler handelt oder um einen gespeicherten Wert, kann über die Task_Liste (ID sollte bekannt sein!) ein Statusbit gesetzt werden.  &amp;lt;br /&amp;gt;&lt;br /&gt;
 &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kommunikation mit anderen Task‘s ==&lt;br /&gt;
Oftmals ist es notwendig, dass die Tasks in der Lage sind, miteinander zu kommunizieren und so Ergebnisse auszutauschen. Hierfür kann ein weiterer Eintrag in der Task-Liste weiterhelfen, der einen anderen Task darüber informiert unter welcher Speicher-ID neue Informationen verfügbar sind. Die jeweiligen Tasks müssen dazu jedoch über die ID der jeweils anderen Task Bescheid wissen. &lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Realtime == &lt;br /&gt;
Je nach Anwendungsfall kann es wichtig sein, dass manche Threads innerhalb einer bestimmten Zeit ausgeführt werden müssen. Hierzu werden für die Threads Prioritäten vergeben, welche gewährleisten, dass die Threads länger oder häufiger ausgeführt werden (je nach Definition). Möglicherweise ergibt die Ausführung/Beendigung eines Threads auch nach einem bestimmten Zeitpunkt keinen Sinn mehr.&lt;br /&gt;
Beispiel: Ein Sensor soll alle 10 ms ausgelesen werden. Der Sensor liefert immer das aktuelle Messergebnis. Wird nun der Thread (der alle 10 ms getriggert wird um einen Sensor auszulesen) von einem wichtigeren Ereignis unterbrochen und so z. B. über 50ms verzögert, so warten dann 5 getriggerte Threads darauf, CPU Zeit zugewiesen zu bekommen. Da aber immer nur der aktuelle Sensorwert ausgegeben werden kann, liefern alle 5 Threads dasselbe Ergebnis. Um nun Ressourcen zu sparen, muss erkannt werden, ob die Ausführung dieses Threads noch sinnvoll ist. Andernfalls sollten die Threads beendet werden und es kann eine Fehlermeldung generiert werden. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Fehlersuche und Kontrolle =&lt;br /&gt;
== Register Kontrolle ==&lt;br /&gt;
Zunächst ist es wichtig zu überprüfen, ob alle Variablen und Register denselben Wert wie nach einem Kontext Switch haben. Hier ist es empfehlenswert, beim Erstellen des Tasks lokale Variablen mit eindeutigen Werten zu erstellen und anschließend in einer while(1)-Schleife laufen zu lassen. &lt;br /&gt;
Die einfachste Überprüfung ist hier: Mit dem Debugger einen Breakpoint in der while(1)-Schleife des Programms zu setzen und nach dem Kontext-Switch anzuhalten, um auf diese Weise die Variablen zu überprüfen.&lt;br /&gt;
&lt;br /&gt;
Mögliche Fehlerquellen: &lt;br /&gt;
* Stack Pointer zeigt auf die falsche Adresse&lt;br /&gt;
* Zuviele oder nicht ausreichend lokale Variablen -der ISR-  nach Verlassen der ISR gelöscht&lt;br /&gt;
* Register in falscher Reihenfolge wiederhergestellt&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Void Test_Task1(){&lt;br /&gt;
Start_task();&lt;br /&gt;
int a = 3; &lt;br /&gt;
	int b = 1;&lt;br /&gt;
	int c = 2; &lt;br /&gt;
	int d = 3; &lt;br /&gt;
	int e = 4;&lt;br /&gt;
	int f = 5;&lt;br /&gt;
	int g = 6;&lt;br /&gt;
	int h = 7;&lt;br /&gt;
while(1){&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rechenoperationen  ==&lt;br /&gt;
Wenn sichergestellt wurde, dass die Register und Variablen nach einem Kontext Switch unverändert bestehen, kann mit einer einfachen Rechenoperation, die je nach Ausgangswert ein anderes Ergebnis liefert, überprüft werden, ob die Wiedereinsprungsadresse stimmt. &lt;br /&gt;
Da lokale Variablen zerstört werden können, sollten globale Variablen hierfür verwendet werden, da diese eben nicht im Stack gespeichert werden. Zusätzlich sollte ein Fehlercounter inkrementiert werden.&lt;br /&gt;
&lt;br /&gt;
Mögliche Fehlerquellen: &lt;br /&gt;
* Falsches Link Register &lt;br /&gt;
* Falscher PC &lt;br /&gt;
* Fehlerhafte Register und/oder Variablen&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
Hier eignet sich die Berechnung der ersten Fibonacci-Zahlen, da hier jedes weitere Ergebnis vom Vorherigen abhängt.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Int error;&lt;br /&gt;
Void Test_Task2(){&lt;br /&gt;
Start_Task();&lt;br /&gt;
int a = 1;&lt;br /&gt;
	int b = 1;&lt;br /&gt;
	int c;&lt;br /&gt;
int counter = 0;&lt;br /&gt;
while(1){&lt;br /&gt;
		c = a;&lt;br /&gt;
		a = b+a;&lt;br /&gt;
		b = c;	&lt;br /&gt;
switch(counter){&lt;br /&gt;
		case 0:if(!(b==1)){&lt;br /&gt;
				error++;&lt;br /&gt;
				}break;&lt;br /&gt;
		case 1:if(!(b==2)){&lt;br /&gt;
				error++;}break;&lt;br /&gt;
		case 2:if(!(b==3)){&lt;br /&gt;
				error++;}break;&lt;br /&gt;
		case 3:if(!(b==5)){&lt;br /&gt;
		                error++;}break;&lt;br /&gt;
&lt;br /&gt;
        ...&lt;br /&gt;
        ...&lt;br /&gt;
        ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
                default:counter = -1; b = 1; a = 1;break;&lt;br /&gt;
             }&lt;br /&gt;
          counter ++;&lt;br /&gt;
     }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Funktionskaskade == &lt;br /&gt;
Um zu überprüfen, ob Linkregister und Programmcounter richtig gesichert wurden, kann man via Funktionkaskaden überprüfen, ob alle Funktionen in der richtigen Reihenfolge aufgerufen werden, und ob sie auch wieder richtig verlassen werden. Auch wichtig sind Übergabeparameter und return values. &lt;br /&gt;
Sollte es hier zu einem Fehler kommen, kann es sein, dass nur die lokalen Variablen verloren gehen. Es kann jedoch auch passieren, dass nach dem Verlassen der Funktion zu viel oder zu wenig vom Stack geladen wird, wodurch eine falsche Rücksprungadresse geladen wird. Mit etwas Glück erkennt der µC dies und springt dann in einen Fault-Handler.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Möglichen Fehler Quellen: &lt;br /&gt;
* Link Register hatt die Falsche Adresse&lt;br /&gt;
* Fehlerhafte Register  und/oder Variablen&lt;br /&gt;
* Falscher Programcounter&lt;br /&gt;
* Register 7 (kann von UC, Compiler oder IDE unterschiedlich sein) bei einem Funktions Call wird in einem Register der alte Stackpointer hinterlegt, ob zu zeigen, wie viele Lokale Variablen nach Verlassen der aktuellen Funktion auf dem Stack nicht mehr benötigt werden. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beispiel&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int tester;&lt;br /&gt;
int error;&lt;br /&gt;
void Task_test3(){&lt;br /&gt;
	while(1){&lt;br /&gt;
		tester = 1;&lt;br /&gt;
		int dummy = test1(5,6);&lt;br /&gt;
		&lt;br /&gt;
		if(dummy != 9 || tester != 4){&lt;br /&gt;
			error ++;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
int test1(int a, int b){&lt;br /&gt;
		if(tester != 1){&lt;br /&gt;
			error++;&lt;br /&gt;
		}&lt;br /&gt;
		tester = 2;&lt;br /&gt;
		int dummy = test2(7);&lt;br /&gt;
		if(a != 5 || b != 6 || dummy != 8 || tester != 3){&lt;br /&gt;
			error++;&lt;br /&gt;
		}&lt;br /&gt;
		tester = 4;&lt;br /&gt;
		return 9;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
int test2(int a)&lt;br /&gt;
{&lt;br /&gt;
		if(a != 7 || tester != 2){&lt;br /&gt;
			error ++;&lt;br /&gt;
		}&lt;br /&gt;
		tester = 3;&lt;br /&gt;
		return 8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight &amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Kein Kontext Switch mehr ==&lt;br /&gt;
Sollten plötzlich keine Kontext-Switche mehr stattfinden(ein Task wird nicht mehr verlassen) sollten man im Interrupt_Manager –„ Nested Vectored Interrupt Controller“ (NVIC) -  nachschauen, ob das Interrupt_Active_Bit gesetzt ist. Sollte dies der Fall sein, wurde der Kontext-Switch nicht richtig verlassen und der Prozessor glaubt, er würde noch immer den Interrupt ausführen. Viele Prozessoren - unter anderem ARM - erlauben kein Repending(doppeltes Ausführen) eines Interruptes.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
Mögliche Fehlerquellen: &lt;br /&gt;
* Linkregister: Bei einem Interrupt Aufruf wird das Link Register mit einem Exp_return_Value beschreiben. Dieser sagt aus, auf welche Art und ob nach Verlassen der Funktion das Interrupt abgeschlossen wurde. So weiss der UC, ob z.B. noch ein Interrupt mit einer niedrigeren Priorität unterbrochen wurde.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Lektüre = &lt;br /&gt;
*	µC/OS-III: The Real-Time Kernel https://www.micrium.com/books/ucosiii/ &lt;br /&gt;
*	http://infocenter.arm.com  &lt;br /&gt;
*	Datenblatt&lt;br /&gt;
*       &#039;&#039;&#039;Grundlagen:&#039;&#039;&#039; https://www.mikrocontroller.net/articles/Multitasking&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Quellen =&lt;br /&gt;
*	µC/OS-III: The Real-Time Kernel&lt;br /&gt;
*	SAM4S-Datenblatt  http://www.atmel.com/Images/Atmel-11100-32-bit%20Cortex-M4-Microcontroller-SAM4S_Datasheet.pdf &lt;br /&gt;
&lt;br /&gt;
= Link Sammlung = &lt;br /&gt;
* https://www.mikrocontroller.net/topic/381051&lt;br /&gt;
* https://www.mikrocontroller.net/topic/389195?goto=4457089#4457089&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Autor = &lt;br /&gt;
Sebastian Balz&lt;br /&gt;
[[Kategorie:ARM]]&lt;br /&gt;
[[Kategorie:Betriebssysteme]]&lt;/div&gt;</summary>
		<author><name>8023</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=PIC&amp;diff=92356</id>
		<title>PIC</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=PIC&amp;diff=92356"/>
		<updated>2016-03-13T19:00:30Z</updated>

		<summary type="html">&lt;p&gt;8023: Bitte mit Duden erneut versuchen.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein PIC ist ein [[Mikrocontroller]] der Firma Microchip. Zu aller erst möchte ich die Aufteilung der PICs veranschaulichen. Die PIC-Familien werden fast immer wie folgt bezeichnet: als Beispiel „PIC18“ oder „18er PIC“ bedeutet, es handelt sich um ein PIC18Fxxxx Microcontroller. Alle PICs haben die [[Harvard-Architektur]]. Es können auch alle PICs mittels dem ICSP-Adapter programmiert werden. ICSP steht für In-Ciruit-Serial-Programmer, also ist mittels diesem Anschluss ein brennen möglich, wenn der PIC schon in der Schaltung eingebaut ist. Zudem haben alle PICs, wie auch Microcontroller anderer Hersteller, interne Module. Ein Modul übernimmt eine spezielle Aufgabe, die von der Software nur konfiguriert und nicht zusätzlich ausgeführt wird. Ein Beispiel ist das PWM-Modul. Man kann eine PWM mit der Software generieren (SoftPWM), aber einfacher geht es mit dem Modul, dass nur konfiguriert werden muss. Die Ausgabe der PWM erfolgt anschließend allein durch das Modul und nicht der Software. Da die PICs aber sonst sehr unterschiedlich sind, sollten sie getrennt aufgeführt werden. Grob unterteilt werden sie anhand ihrer Datenbreite.&lt;br /&gt;
&lt;br /&gt;
== 8 Bit ==&lt;br /&gt;
&lt;br /&gt;
Die 8 Bit Microcontroller-Familien sind &#039;&#039;&#039;PIC10, PIC12, PIC16 und PIC18&#039;&#039;&#039;. Bei den 8-bittigen PICs gibt es einmal den Buchstaben „F“ hinter der Familienbezeichnung und den Buchstaben „C“. Die mit einem „F“ in der Bezeichnung haben einen [http://www.mikrocontroller.net/articles/Flash-ROM Flash]-Programmspeicher, dieser ist somit mehrmals beschreibbar. Das „C“ bedeutet, dass der Programmspeicher entweder ein [http://www.mikrocontroller.net/articles/OTP-ROM OTP]-Speicher (One-Time-Programable – Nur ein mal beschreibbar), oder aber ein [[EPROM]]-Speicher ist, den man nur mit Hilfe von UV-Licht löschen kann. Aus diesem Grund sind die „C“-Varianten uninteressant für Hobby-Elektroniker, zudem sind die C-Varianten ziemlich alt und sogut wie alle PICs sind ausschließlich mit Flash-Speicher verfügbar. Die Typen der Familien haben unterschiedliche Ausstattung, dennoch kann man sagen, je höher die Zahl, desto Leistungsfähiger ist der PIC. Jedoch: Ein Typ der PIC10 Familie mag zwar deutlich schwächer sein, als ein PIC18, dafür gibt es den PIC10 in einem SOT23-Gehäuse, wohingegen der kleinste PIC18 ein SOIC18 ist. Zudem ist der PIC10 billiger, als ein PIC18. Es kommt also immer auf den Anwendungsfall an.&lt;br /&gt;
&lt;br /&gt;
8 Bit PICs können folgendes beinhalten:&lt;br /&gt;
* bis zu 128k [[Byte]] ROM&lt;br /&gt;
* bis zu 4k [[Byte]] [[RAM]]&lt;br /&gt;
* bis zu 1024 [[Byte]] [[EEPROM]]&lt;br /&gt;
* 6 bis 100 Pins / 4 bis 70 IOs&lt;br /&gt;
* Internen Oscillator&lt;br /&gt;
* 8/10/12-bit [[ADC]]&lt;br /&gt;
* 5/8-bit [[DAC]]&lt;br /&gt;
* [[SPI]]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/I2C I²C]&lt;br /&gt;
* [[UART]]&lt;br /&gt;
* [[CAN]]&lt;br /&gt;
* [[USB]]&lt;br /&gt;
* [[PWM]]&lt;br /&gt;
* [[Komparator]]&lt;br /&gt;
* [[Opamp]]&lt;br /&gt;
* 8x8 Hardware Multiplier&lt;br /&gt;
* CTMU (Charge Time Measurement Unit, für Cap-Touch-Anwendungen)&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Ethernet Ethernet]&lt;br /&gt;
&lt;br /&gt;
Eine Sonderform der 8 Bit Microcontroller ist der rfPIC12F675. Dieser ist extra für RF, also Funkanwendungen ausgelegt und besitzt einen internen [http://de.wikipedia.org/wiki/Dezimeterwelle UHF] [http://de.wikipedia.org/wiki/Amplitude_Shift_Keying ASK]/[http://de.wikipedia.org/wiki/Frequenzumtastung FSK] Transmitter. Eine weitere Sonderform ist der PIC16HV785, der kompatibel zum PIC16F785 ist. Allerdings geht der Spannungsbereich von 2V bis hin zu 15V. Somit kann man diesen auch direkt in ein 12V-System stecken und spart sich ggf. Levelshifter und Spannungsregler. Eine detailiertere Übersicht findet man auf der [http://www.microchip.com/en_US/family/8bit/architecture/ Microchip-Seite] und eine Liste aller Typen ist für jede Familie verfügbar: [http://www.microchip.com/ParamChartSearch/chart.aspx?branchID=1009&amp;amp;mid=10&amp;amp;lang=en&amp;amp;pageId=74 PIC10], [http://www.microchip.com/ParamChartSearch/chart.aspx?branchID=1001&amp;amp;mid=10&amp;amp;lang=en&amp;amp;pageId=74 PIC12], [http://www.microchip.com/ParamChartSearch/chart.aspx?branchID=1002&amp;amp;mid=10&amp;amp;lang=en&amp;amp;pageId=74 PIC16], [http://www.microchip.com/ParamChartSearch/chart.aspx?branchID=1004&amp;amp;mid=10&amp;amp;lang=en&amp;amp;pageId=74 PIC18].&lt;br /&gt;
&lt;br /&gt;
== 16 Bit ==&lt;br /&gt;
Die Vertreter der 16 Bit Microcontroller sind &#039;&#039;&#039;PIC24E, PIC24F, PIC24H, dsPIC30F, dsPIC33E, dsPIC33F&#039;&#039;&#039;. Trotz dessen nicht überall ein „F“ in der Bezeichnung ist, haben diese Familien dennoch einen Flash-Speicher. Die dsPICs haben, wie der Name schon vermuten lässt, eine zusätzliche [[DSP]]-Einheit, die extra für komplexere Berechnungen wie [http://de.wikipedia.org/wiki/Schnelle_Fourier-Transformation FFT] oder [http://de.wikipedia.org/wiki/Digitales_Filter Digital-Filter] benutzt werden können. &lt;br /&gt;
&lt;br /&gt;
16 Bit PICs können folgendes beinhalten:&lt;br /&gt;
* bis zu 70 [[MIPS]]&lt;br /&gt;
* bis zu 536k [[Byte]] Rom&lt;br /&gt;
* bis zu 96k [[Byte]] Ram&lt;br /&gt;
* bis zu 4k [[Byte]] [[EEPROM]]&lt;br /&gt;
* 14 bis 144 Pins / 12 bis 122 IOs&lt;br /&gt;
* “Single Cycle” Multiplikation 16x16 und 32/16 sowie 16/16 Division&lt;br /&gt;
* bis zu 32 Channel 10/12-bit [[ADC]]&lt;br /&gt;
* 10/16-bit [[DAC]]&lt;br /&gt;
* Digital Power, Motor Control und Audio Peripherals&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/I2C I²C]&lt;br /&gt;
* [[SPI]]&lt;br /&gt;
* [[CAN]]&lt;br /&gt;
* [[PWM]]&lt;br /&gt;
* PMP (Parallel Master Port)&lt;br /&gt;
* [[USB]]-OTG&lt;br /&gt;
* CTMU&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Echtzeituhr RTCC] (Real Time Clock&amp;amp;Calendar)&lt;br /&gt;
* [[DMA]] Channels für schnelleren Datentransfer&lt;br /&gt;
&lt;br /&gt;
Die Übersicht ist wieder unter der [http://www.microchip.com/en_US/family/16bit/architecture/ Microchip-Seite] zu finden und auch hier gibt es die Typenlisten für die Familien [http://www.microchip.com/ParamChartSearch/chart.aspx?branchID=8187&amp;amp;mid=14&amp;amp;lang=en PIC24E], [http://www.microchip.com/ParamChartSearch/chart.aspx?branchID=8181&amp;amp;mid=14&amp;amp;lang=en&amp;amp;pageId=75 PIC24F]&lt;br /&gt;
[http://www.microchip.com/ParamChartSearch/chart.aspx?branchID=8186&amp;amp;mid=14&amp;amp;lang=en&amp;amp;pageId=75 PIC24H], [http://www.microchip.com/ParamChartSearch/chart.aspx?branchID=8182&amp;amp;mid=14&amp;amp;lang=en&amp;amp;pageId=75 dsPIC30F], [http://www.microchip.com/ParamChartSearch/chart.aspx?branchID=8188&amp;amp;mid=14&amp;amp;lang=en dsPIC33E], [http://www.microchip.com/ParamChartSearch/chart.aspx?branchID=8183&amp;amp;mid=14&amp;amp;lang=en&amp;amp;pageId=75 dsPIC33F].&lt;br /&gt;
&lt;br /&gt;
== 32 Bit ==&lt;br /&gt;
Der 32 Bit Microcontroller hat nicht mehr viel mit den anfänglichen PICs gemeinsam. Er besitzt einen „MIPS M4K“-Kern aber ist trotzdem Pin-Kompatibel zu den 16 Bit PICs. Die Typen der PIC32-Familie unterstützen zusätzlich das [[JTAG]]-Interface. Es wurde außerdem auf PIC32-Basis eine [http://de.wikipedia.org/wiki/Arduino-Plattform Arduino]-Alternative entwickelt, die dadurch deutlich leistungsfähiger ist. Genannt wurde dies „chipKIT“ und ist im Moment in 2 Varianten verfügbar. Die Entwicklungsumgebung für die chipKITs basiert auf der Arduino-Software und somit sollen auch alle für den Arduino programmierten Progamme auf dem chipKIT laufen. Es gibt auch PIC32er im DIP-Gehäuse. Somit kann man auch den 32bit Microcontroller von Microchip auf z.B. eine Lochrasterkarte bringen und hat nicht soviele (evtl sogar überflüssige) Pins, wie in den kleinen TQFP/N- oder BGA-Gehäusen.&lt;br /&gt;
&lt;br /&gt;
32 Bit PICs können folgendes beinhalten:&lt;br /&gt;
* 80 MHz, 1.56 DMIPS/MHz&lt;br /&gt;
* bis zu 512k [[Byte]] Rom&lt;br /&gt;
* bis zu 128k [[Byte]] Ram&lt;br /&gt;
* Full-speed [[USB]] Host/Device/OTG&lt;br /&gt;
* 10/100 [http://de.wikipedia.org/wiki/Ethernet Ethernet] MAC mit MII/RMII Interfaces&lt;br /&gt;
* [[CAN]] 2.0B&lt;br /&gt;
* [[UART]]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/I2C I²C]&lt;br /&gt;
* [[SPI]]&lt;br /&gt;
* bis zu 8 Channel [[DMA]]&lt;br /&gt;
* Analoger [[Komparator]]&lt;br /&gt;
* [[PWM]]&lt;br /&gt;
* 16-Channel 10bit [[ADC]]&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Echtzeituhr RTCC]&lt;br /&gt;
&lt;br /&gt;
Die Übersicht ist wieder unter der [http://www.microchip.com/en_US/family/32bit/architecture/ Microchip-Seite] zu finden und auch hier gibt es eine Typenliste für die Familie: [http://www.microchip.com/ParamChartSearch/chart.aspx?branchID=211&amp;amp;mid=10&amp;amp;lang=en&amp;amp;pageId=74 PIC32MX].&lt;br /&gt;
&lt;br /&gt;
Neu hinzugekommen ist die Serie PIC32MZXXX mit u. a. folgenden wichtigen Neuerungen zu den bestehenden&lt;br /&gt;
PIC32MX:&lt;br /&gt;
* 200 MHz / 330DMIPS&lt;br /&gt;
* teilweise mit FPU (FloatingPointUnit)&lt;br /&gt;
* bis zu 2MB Flash&lt;br /&gt;
* bis zu 512K RAM&lt;br /&gt;
* EBI (External Bus Interface)&lt;br /&gt;
* SQI (Serial Quad Interface)&lt;br /&gt;
* crypto engine&lt;br /&gt;
&lt;br /&gt;
== Dokumentation ==&lt;br /&gt;
&lt;br /&gt;
Bei den PICs gibt es zu jedem Mikrocontroller ein Datenblatt. Bei den Familien 10F, 12F, 16F und 18F wird in diesem Datenblatt jeweils der ganze Controller incl. seiner Peripherie ausführlich beschrieben. Bei den 16 &amp;amp; 32 Bit Familien (PIC24F und aufwärts) gibt es hingegen zu jedem Controller ein Kurzdatenblatt das die genauen Leistungsmerkmale  sowie die wichtigsten Informationen für den alltäglichen Gebrauch enthält. Da bestimmte Peripherie (bspw. I2C, SPI, ... ) aber sehr komplex ist und innerhalb einer Familie (PIC24/dSPic/32) sich identisch verhält, gibt es bei diesen Familien zu jeder Familie die sogenannten Family-Datasheets, welche alle Module im Detail beschreiben.&lt;br /&gt;
&lt;br /&gt;
== Compiler und IDE ==&lt;br /&gt;
=== MPLAB ===&lt;br /&gt;
&lt;br /&gt;
MPLAB ist die freie [http://de.wikipedia.org/wiki/Integrierte_Entwicklungsumgebung IDE] von Microchip und unterstützt von vornherein alle Brenner, Debugger, Emulatoren von Microchip. Zudem kann das Programm in der IDE per Software emuliert werden. Um Programme in [[C]] zu schreiben, können [[C]]-[[Compiler]], sofern die Software das unterstützt, in die [http://de.wikipedia.org/wiki/Integrierte_Entwicklungsumgebung IDE] eingebettet werden, wie z.B. der HI-TECH C-Compiler. Genaueres kann man auf der [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469 Microchip-Seite] anschauen.&lt;br /&gt;
&lt;br /&gt;
=== MPLAB X ===&lt;br /&gt;
MPLAB X ist ist eine Weiterentwicklung von MPLAB. Es beinhaltet alle Funktionen von MPLAB (v8). Jedoch wurde die Software komplett neu gestaltet. Vom Simulator bis zum Projektmanagement ist alles modernisiert worden. MPLAB X ist für alle gängigen Betriebssysteme erhältlich (Windows, Linux und OS X).&lt;br /&gt;
Weitere Informationen findet man auf der [http://www.microchip.com/pagehandler/en-us/family/mplabx/ Produktseite von MPLAB X].&lt;br /&gt;
&lt;br /&gt;
=== C-Compiler ===&lt;br /&gt;
Microchip bietet direkt [[C]]-[[Compiler]] an. Diese wären C18 (für PIC18 Typen), C30 (für 16bit Typen) und C32 (für 32bit Typen). Diese [[Compiler]] können als nicht-kommerzielle Freeware-Version heruntergeladen werden. Dabei wird nach einer gewissen Zeit die Optimierung eingeschränkt. Diese ist für Hobby-Bastler allerdings nicht unbedingt kritisch. Da die [[C]]-[[Compiler]] C30 und C32 von Microchip auf Open-Source aufbauen, sollte der Sourcecode direkt von deren Seite heruntergeladen und die Aufhebung entfernt werden können (sofern man die Möglichkeit hat, die Software danach wieder zu kompilieren).&lt;br /&gt;
Es gibt auch andere [[Compiler]], wie z.B. der [[C]]-[[Compiler]] von HI-TECH.&lt;br /&gt;
Andere wären noch CC5X oder Compiler der Firma mikroElektronika. Letzterer unterstützt nicht nur alle PICs, sondern ist auch für [[AVR]]s, [[8051]]er und [[ARM]] Microcontroller, sowie jeweils auch in [[Basic]] und [http://de.wikipedia.org/wiki/Pascal_%28Programmiersprache%29 Pascal] erhältlich. MikroE-Compiler, sowie der CC5X sind in der Freeware-Version allerdings Codegrößenbegrenzt, was gerade bei 16bit oder 32bit PICs schnell eng werden kann.&lt;br /&gt;
&lt;br /&gt;
Mit der Einführung von MPLAB X wurden auch die neuen [http://www.microchip.com/pagehandler/en_us/promo/mplabxc/ XC] Compiler von Microchip veröffentlicht. XC8 für 8Bit PICs, XC16 für [[PIC24]] und [[dsPIC]]s und XC32 für [[PIC32]] Mikrocontroller. Auch hier sind Free-Versionen erhältlich.&lt;br /&gt;
&lt;br /&gt;
Ein Vergleich einiger C-Compiler ist in diesem Artikel zu sehen:&lt;br /&gt;
[[PIC C-Compilervergleich]]&lt;br /&gt;
&lt;br /&gt;
== Programmiergeräte ==&lt;br /&gt;
Um das Programm auf einen PIC zu bekommen, muss dieses per Gerät auf den PIC „gebrannt“ werden. Microchip bietet dazu das PICKIT2 und PICKIT3 an. Das PICKIT3 ist das aktuellere, was bedeutet, dass Firmwareupdates hauptsächlich für diese Version entwickelt werden. Spürbar ist das jetzt schon bei den PIC32MX, die nur vom PICKIT3 unterstützt werden. Wenn man aber kein PIC32 benutzen möchte, kann man bis jetzt aber auch noch zum PICKIT2 greifen, das zusätzlich noch als kleiner Logik-Analyzer dienen kann. Das nächst bessere, was Microchip bietet, ist ein ICD (In-Circuit-Debugger), das eine erweiterte Debuggermöglichkeit bietet. Das „Flagschiff“ ist der REAL-ICE (In-Circuit-Emulator), der zusätzlich noch in der Hardware emulieren kann. Eine Übersicht ist [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=2519&amp;amp;param=en534451&amp;amp;page=wwwdevMPLABEmulatorDebuggers hier] zu sehen.&lt;br /&gt;
&lt;br /&gt;
Wie für andere Microcontroller, gibt es auch für den PIC Selbstbaubrenner. Der wohl Bekannteste ist der [http://sprut.de/electronic/pic/brenner/ Brenner8] von der [http://sprut.de Sprut-Seite]. Doch allgemein gilt für Third-Party-Brenner: Es werden neue Microcontroller-Typen, wenn überhaupt, erst später unterstützt, als bei einem originalen Brenner und es führt zu zusätzlichen, möglichen Fehlerquellen durch den Bau. Denn wer kommt schon auf die Idee den Fehler im Brenner zu suchen und nicht in der Schaltung. Hier im Forum sind schon mehrere solcher Fälle vorgekommen. Außerdem bekommt man das &amp;quot;Henne oder Ei&amp;quot;-Problem zu spüren, denn für den Brenner8 muss man einen PIC18 brennen, d.h. man muss sich irgendwo seinen PIC brennen lassen, bevor man es selbst tun kann. Zudem wird nicht jeder bzw. kaum ein Selbst-Bau-Brenner von der IDE unterstützt, was bedeutet, dass man mindestens 2 Programme braucht - Eine zum brennen und eine zum programmieren. Der Brenner8 unterstützt auch kein Debugging, wie es das PICKIT3 jedoch tut. Die Hilfestellung bei einem verbreitetem Programmiergerät ist selbstverständlich besser als bei einem opensource Selbsbau-Brenner. Zudem wird so ein Brenner und die Software meist von einer Einzelperson gepflegt. Dies bedeutet aber auch, dass die Updates usw von dieser Person abhängig ist. Fällt dieser aus (Krankheit oder persönliche Gründe), geht erstmal nichts weiter voran. Es muss also jeder selbst abwägen, ob einem das die ca. 10€ weniger Wert ist. Wenn es jemanden darum geht, den Brenner selbst zu bauen, der kann auch das PICKIT2 nachbauen, denn [http://ww1.microchip.com/downloads/en/DeviceDoc/51553E.pdf Schaltplan] (Seite 77+78) und [http://ww1.microchip.com/downloads/en/DeviceDoc/PK2V023200.zip Firmware] sind offen auf der Herstellerseite verfügbar. Hier ist zwar immer noch die mögliche Fehlerquelle beim Zusammenbau vorhanden, jedoch hat man damit einen besseren Brenner. Wenn einem der originale Brenner zu teuer ist, kann man sich bei Ebay auch nach einem Clone vom PICKIT2 oder PICKIT3 umsehen. Diese kosten im Moment zwischen 15€ und 25€.&lt;br /&gt;
&lt;br /&gt;
== Missverständnisse und Eigenheiten ==&lt;br /&gt;
Es gibt einiges, was einen PIC-Neuling abschrecken oder verwirren könnte. Manchmal hört man z.B. dass kaum oder schlechte Peripherie verbaut wurde, wobei dies meist, wenn überhaupt zutreffend, für sehr alte PICs gilt (90er Jahre). Neue PICs habe oft mehr/bessere Peripherie als ATmegas. Es wird auch oft bemängelt, dass der Quarz-Takt bei 8bit PICs durch 4 und bei 16bit PICs durch 2 geteilt wird. Dafür werden so gut wie alle Befehle in einem System-Takt ausgeführt, wo andere mehr brauchen. 8bit PICs gibt es mit bis zu 64MHz (16 MIPS).&lt;br /&gt;
Fallen für Neulinge gibt es nur wenige und unkritische (im Vergleich zum „verfusen“ eines [[AVR]]s). Es muss zum Beispiel bedacht werden, dass, um auf manche Register zugreifen zu können, die Bank gewechselt werden muss - dies macht ein [[C]]-[[Compiler]] aber automatisch. Außerdem muss die geplante Vierteilung von oben bedacht werden, um Zeitschleifen zu berechnen. Verwirrend kann gerade für Leute, die den [[AVR]] gewohnt sind sein, dass das Register zum Konfigurieren der IOs eine 1 für einen Eingang braucht, und keine 0. Doch merken kann man sich, dass die 1 wie ein großes I aussieht und für Input -&amp;gt; Eingang steht. Andersrum steht die 0 für ein großes O wie Output -&amp;gt; Ausgang.&lt;br /&gt;
&lt;br /&gt;
Wer sich hier im Forum schon mal rumgetrieben hat, kann eventuell auch den „kleinen Krieg“ zwischen [[AVR]] und PIC mitbekommen haben. Dazu will ich auch nur sagen, dass an sich jeder Microcontroller seine Daseinsberechtigung hat. Ob PIC oder [[AVR]], ob 8 Bit oder 32 Bit. Deswegen sollte man einfach die Microcontroller ausprobieren und selbst entscheiden. Wenn jemand sich einen, meiner Meinung nach guten Vergleich zwischen [[AVR]] und PIC angucken will, kann sich das -&amp;gt;[http://www.youtube.com/watch?v=DBftApUQ8QI EEVBlog #63]&amp;lt;- Video auf Youtube angucken. Da wird auch erläutert, warum es keinen Grund gibt, einen der beiden Microcontroller zu meiden. Zudem ist es auch etwas unprofessionell, ohne selbst eigene Erfahrung gesammelt zu haben, eine Familie oder sogar einen ganzen Hersteller abzuschreiben.&lt;br /&gt;
&lt;br /&gt;
== Alte und neue PICs ==&lt;br /&gt;
Microchip stellt schon seit Anfang der 90er Microcontroller her. Damals war die Technik logischerweise noch nicht auf dem Stand wie heute. Es wird immer kleiner und dennoch schneller und stromsparender. Doch da manche wohl einfach nicht von den alten PICs loskommen, werden diese Heutzutage auch noch teilweilse eingesetzt. Außerdem gibt es mehrere (oft alte) fertige Projekte, die eben so einen alten PIC verwenden und da viele die Projekte nachbauen und nichts neu programmieren (wollen), sind diese PICs immer wieder oft zu finden. Die neuen PICs sind nicht nur Stromsparender und haben mehr Platz, sondern sind auch noch billiger. Ich hab mal zwei alte/ältere und oft zu findende PICs rausgesucht (PIC16F84A und PIC16F887) und einfach mal mit neuen PICs der selben Pinzahl und Bauform(DIP) verglichen:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;PIC16F84A vs. PIC16F1827&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! || PIC16F84A || PIC16F1827&lt;br /&gt;
|-&lt;br /&gt;
| ROM/Flash || 1k Word || 4k Word&lt;br /&gt;
|-&lt;br /&gt;
| SRAM || 68 Byte || 384 Byte&lt;br /&gt;
|-&lt;br /&gt;
| EEPROM || 64 Byte || 256 Byte&lt;br /&gt;
|-&lt;br /&gt;
| Pins/IOs || 18/13 || 18/16&lt;br /&gt;
|-&lt;br /&gt;
| Max. Frequenz || 20MHz || 32MHz&lt;br /&gt;
|-&lt;br /&gt;
| Internal Oscillator || - || 32MHz, 32kHz&lt;br /&gt;
|-&lt;br /&gt;
| Comparators || 0 || 2&lt;br /&gt;
|-&lt;br /&gt;
| ADC-Channels || 0 || 12&lt;br /&gt;
|-&lt;br /&gt;
| Communication || - || 1xUART, 2xI²C/SPI&lt;br /&gt;
|-&lt;br /&gt;
| CCP || - || 2xECCP, 2xCCP&lt;br /&gt;
|-&lt;br /&gt;
| Timer || 1x8bit || 4x8bit, 1x16bit&lt;br /&gt;
|-&lt;br /&gt;
| Preis Reichelt (30.03.2012) || 3,15€ || 1,60€&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;PIC16F887 vs. PIC16F1939&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! || PIC16F887 || PIC16F1939&lt;br /&gt;
|-&lt;br /&gt;
| ROM/Flash || 8k Word || 16k Word&lt;br /&gt;
|-&lt;br /&gt;
| SRAM || 368 Byte || 1024 Byte&lt;br /&gt;
|-&lt;br /&gt;
| EEPROM || 256 Byte || 256 Byte&lt;br /&gt;
|-&lt;br /&gt;
| Pins/IOs || 40/36 || 40/36&lt;br /&gt;
|-&lt;br /&gt;
| Max. Frequenz || 20MHz || 32MHz&lt;br /&gt;
|-&lt;br /&gt;
| Internal Oscillator || 8MHz, 32kHz || 32MHz, 32kHz&lt;br /&gt;
|-&lt;br /&gt;
| Comparators || 2 || 2&lt;br /&gt;
|-&lt;br /&gt;
| ADC-Channels || 14 || 14&lt;br /&gt;
|-&lt;br /&gt;
| Communication || 1xUART, 1xI²C/SPI || 1xUART, 1xI²C/SPI&lt;br /&gt;
|-&lt;br /&gt;
| CCP || 1xECCP, 1xCCP || 3xECCP, 2xCCP&lt;br /&gt;
|-&lt;br /&gt;
| Timer || 2x8bit, 1x16bit || 4x8bit, 1x16bit&lt;br /&gt;
|-&lt;br /&gt;
| Preis Reichelt (30.03.2012)|| 2,65€ || 2,15€&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Hier sieht man gerade bei dem verbreitetem PIC16F84A, dass dieser aus heutiger Sicht total klein, schlecht und dafür überteuert ist und man für das gleiche Geld 2 bessere bekommt. Der einzige Grund, der für ältere PICs spricht, ist der, dass man eine vorhandene Software benutzen und nicht umschreiben will. Sollte es aber ein neues, eigenes Projekt werden, tut euch einen Gefallen, spart Geld und kauf neue PICs ;)&lt;br /&gt;
&lt;br /&gt;
== Bezugsquellen ==&lt;br /&gt;
&lt;br /&gt;
=== Controller ===&lt;br /&gt;
&lt;br /&gt;
Versandhäuser für Privatpersonen&lt;br /&gt;
* [http://reichelt.de/PIC-Microcontroller/2/index.html?;ACTION=2;LA=2;GROUPID=2961;SHOW=1; Reichelt]&lt;br /&gt;
* [http://de.rs-online.com/web/c/?sra=oss&amp;amp;searchTerm=pic&amp;amp;x=0&amp;amp;y=0 RS-Online]&lt;br /&gt;
* [https://www.distrelec.de/ishopWebFront/search/luceneSearch.do?dispatch=show&amp;amp;fromCatalog=true&amp;amp;filterHierarchyNodeId=178072&amp;amp;filterHierarchyLevel=5&amp;amp;hierarchyDepth=0&amp;amp;autoAttributeEnabled=false Distrelec]&lt;br /&gt;
&lt;br /&gt;
=== Evaluation Boards ===&lt;br /&gt;
&lt;br /&gt;
* [http://de.farnell.com/jsp/search/browse.jsp?N=2008+202682&amp;amp;Ntk=gensearch&amp;amp;Ntt=pic&amp;amp;Ntx=mode+matchallpartial Farnell] Microchip Boarde&lt;br /&gt;
* [http://thinkembedded.ch/PIC:::12.html Thinkembedded Webshop] Olimex Boarde&lt;br /&gt;
* [http://www.futurlec.com/Boards.shtml Futurelec]&lt;br /&gt;
* [http://pic-projekte.de/wordpress/?p=653 StartPIC18]&lt;br /&gt;
&lt;br /&gt;
== Links und Literatur ==&lt;br /&gt;
* [http://www.microchip.com/ Microchip Homepage]&lt;br /&gt;
* [http://www.htsoft.com/ Hi-TECH Homepage]&lt;br /&gt;
* [http://www.bknd.com/cc5x/ CC5X Homepage]&lt;br /&gt;
* [http://www.mikroe.com/eng/home/index MikroElektronika Homepage]&lt;br /&gt;
* [http://pic-projekte.de/phpBB3/ PIC-Forum (deutsch)]&lt;br /&gt;
* [http://sprut.de/ Sprut Homepage]&lt;br /&gt;
* [http://pic-projekte.de/ Tutorials (PIC/C) und PIC-Forum]&lt;br /&gt;
* [http://sprut.de/electronic/pic/projekte/brenner8/index.htm Brenner8 Projektseite]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Mikrocontroller]]&lt;br /&gt;
[[Kategorie:PIC| ]]&lt;/div&gt;</summary>
		<author><name>8023</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Zoll_und_Abgaben&amp;diff=92354</id>
		<title>Zoll und Abgaben</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Zoll_und_Abgaben&amp;diff=92354"/>
		<updated>2016-03-13T15:27:56Z</updated>

		<summary type="html">&lt;p&gt;8023: müll&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Grundsätzlich==&lt;br /&gt;
Grundsätzlich gilt: &lt;br /&gt;
* Sitzt der Versender in der EU, ist für Privatpersonen alles harmlos. Der Versender zahlt die Umsatzsteuer (Mehrwertsteuer) in seinem Land und fertig. Der Zoll kommt gar nicht ins Spiel.&lt;br /&gt;
&lt;br /&gt;
Der Rest dieses Wiki-Eintrags beschäftigt sich hauptsächlich mit dem Versand aus dem nicht-EU Ausland.&lt;br /&gt;
&lt;br /&gt;
* Der Zoll ist nicht doof und kennt die gängigen und weniger gängigen Tricks. Das ist deren Job. Da sind die gut drin.&lt;br /&gt;
:Wenn ein asiatischer Versender auf ein Paket in der Zollerklärung &amp;quot;&#039;&#039;Geschenk, Wert $40&#039;&#039;&amp;quot; schreibt, dann ist es fast sicher, dass sich der deutsche Zoll das genauer ansieht. Ebenso glaubt der Zoll nicht an kostenlosen Versand und nimmt regelmäßig ziemlich saftige Versandgebühren an, die dann versteuert werden. Passiert das, und kann man die echten Kosten nachweisen, kann man gegen den Steuerbescheid Widerspruch einlegen. Wie das geht, sollte in einer Rechtsbehelfsbelehrung auf dem Steuerbescheid stehen.&lt;br /&gt;
&lt;br /&gt;
* Gültige Informationen finden sich unter http://www.zoll.de.&lt;br /&gt;
&lt;br /&gt;
* Unterlagen, Mails, etc. gut durchlesen und entsprechend handeln. Wegschauen, den kleinen Doofen spielen, ignorieren usw. hilft nicht.&lt;br /&gt;
&lt;br /&gt;
==Kosten==&lt;br /&gt;
Bei einem Angebot aus dem Ausland (besonders Nicht-EU) sollten folgende Kosten auf jeden Fall mit einkalkuliert werden:&lt;br /&gt;
* Einfuhrumsatzsteuer&lt;br /&gt;
::Vereinfacht ausgedrückt das Äquivalent zur Mehrwertsteuer das bei der Einfuhr anfällt [http://www.zoll.de/DE/Fachthemen/Steuern/Einfuhrumsatzsteuer/einfuhrumsatzsteuer_node.html]. Zur Zeit 19%.&lt;br /&gt;
&lt;br /&gt;
* Einfuhrzoll&lt;br /&gt;
::Hängt von der Warenart ab und ist in der EU einheitlich in der TARIC-Liste geregelt [http://ec.europa.eu/taxation_customs/dds2/taric/taric_consultation.jsp]. Die gute Nachricht ist, dass viele für den Bastler interessante Waren einen niedrigen Zollsatz oder sogar gar keinen haben.&lt;br /&gt;
&lt;br /&gt;
* Bankgebühren (Währungsumrechnung, Kreditkartengebühren, Transfergebühren, etc.)&lt;br /&gt;
::Beliebter Beschiss eines Marktplatzes mit eigenem Zahlungsdienst: Auf dem Marktplatz werden unverbindliche &amp;quot;ca.&amp;quot; Umrechnungskurse verwendet, die &amp;quot;zufälligerweise&amp;quot; immer günstiger sind als die Umrechnungskurse, die der eigene Zahlungsdienstleister nur Sekunden später verwendet.&lt;br /&gt;
::Beliebte Falle bei Kreditkarten: Es wird mit einer günstigen prozentualen Gebühr für die Währungsumrechnung geworben, die aber wegen einer saftigen Mindestgebühr gar nicht zum Tragen kommt.&lt;br /&gt;
&lt;br /&gt;
* Versandgebühren (Versand, Zollpapiere)&lt;br /&gt;
&lt;br /&gt;
* Bearbeitungsgebühren, Servicegebühren des Kurierdienstes&lt;br /&gt;
::Kurierdienste, auch DHL &#039;&#039;&#039;Express&#039;&#039;&#039;, schlagen diese Gebühren nachträglich für fiktive oder reale Tätigkeiten drauf. So zum Beispiel dafür, dass sie eine Sendung vorgeblich oder wirklich beim Zoll zur Abfertigung vorstellen und die entsprechenden Papieren vorgeblich oder wirklich ausfüllen. Warum diese Gebühren nicht Teil der Versandkosten sind, bleibt das Geheimnis der Kurierdienste.&lt;br /&gt;
&lt;br /&gt;
::Einige Kurierdienste sind für ihre extrem hohen Gebühren berüchtigt. Darunter zum Beispiel alle, die ihre Einfuhr in Deutschland durch die [https://www.gdsk.de/ger/index.html GDSK] erledigen lassen, wie zum Beispiel EMS China oder manchmal FEDEX. Ebenso DHL &#039;&#039;&#039;Express&#039;&#039;&#039; (siehe unten).&lt;br /&gt;
&lt;br /&gt;
:Einige Kurierdienste sind dafür bekannt, dass deren Mitarbeiter schlicht und ergreifend nicht wissen was sie tun. Da werden dann mehr oder weniger zufällig Gebühren aus der Preisliste berechnet. Beliebt ist zum Beispiel, dass für jeden Einzelposten Gebühren berechnet werden, statt für die gesamte Sendung. Ebenso beliebt ist es, Gebühren, die bereits abgebucht wurden, nochmals bei Auslieferung an der Haustür zu erheben.&lt;br /&gt;
&lt;br /&gt;
::Eigentlich ist es so, dass ein Kurierdienst vom Empfänger mit der Verzollung beauftragt werden muss, sonst kann er sich die Gebühren in die Haare schmieren. In der Praxis wird das manchmal noch ignoriert. Alternativ versuchen manche Kurierdienste den Kunden dadurch unter Druck zu setzen, dass sie eine entsprechende Benachrichtigung mit der Bitte um Auftragserteilung extrem spät versenden. So hat der Kunde praktisch keine andere Wahl, als den Auftrag zu erteilen oder es entstehen zusätzliche Lagergebühren oder die Ware geht zurück.&lt;br /&gt;
&lt;br /&gt;
::Wer solche Gebühren vermeiden möchte, kann unter Umständen eine &#039;&#039;Selbstverzollung&#039;&#039; durchführen, die allerdings einige Mühe macht. Das funktioniert natürlich nur, wenn man genug Zeit hat, siehe oben. Allerdings haben Kurierdienste neben der späten Benachrichtigung noch einen Trick auf Lager:&lt;br /&gt;
::*Gebühr für die Übergabe zur Selbstverzollung&lt;br /&gt;
:::Sie kassieren also dafür, dass sie eine Leistung nicht erbringen.&lt;br /&gt;
&lt;br /&gt;
::Eine Sonderregelung gibt es bei der Post, aber nicht für alle Teile des Postkonzerns. Die Post berechnet bei per &amp;quot;echter&amp;quot; Post versendeter Waren keine Gebühren für die Vorführung zur Verzollung. Der zur Post gehörende Kurierdienst DHL &#039;&#039;&#039;Express&#039;&#039;&#039; berechnet seit dem 1.6.2014 eine &#039;&#039;Kapitalbereitstellungsprovision&#039;&#039; von 2%, aber mindestens 10€ + 19% MWSt = 11,90€. &lt;br /&gt;
&lt;br /&gt;
Das sind aber noch nicht alle Kosten, die anfallen können. Im schlimmsten falls entstehen z.B. noch &lt;br /&gt;
* Zollkosten durch Amtshandlungen oder Lagerung.&lt;br /&gt;
::Schon deshalb sollte man auf Schreiben oder andere Nachrichten unverzüglich reagieren.&lt;br /&gt;
&lt;br /&gt;
==Checkliste==&lt;br /&gt;
Checkliste für den Kauf im Ausland:&lt;br /&gt;
* Artikelbeschreibung genau lesen&lt;br /&gt;
* ist der Import überhaupt legal (Plagiat, Konformität) bzw. anmeldepflichtig&lt;br /&gt;
* Einfuhrabgaben, z.B. Einfuhrumsatzsteuer&lt;br /&gt;
* Zollgebühren (basieren auf der )&lt;br /&gt;
* Bankgebühren (Währungsumrechnung, Transferkosten)&lt;br /&gt;
* Versandkosten (bzw. was der Zoll bei kostenlosem Versand veranschlagt)&lt;br /&gt;
* Versandart und Dienstleister (hat großen Einfluss auf den Zolldurchlauf, ggf kassiert der Dienstleister die Gebühren einfach bei Lieferung an der Haustür)&lt;br /&gt;
&lt;br /&gt;
==Praktisches==&lt;br /&gt;
===Post, DHL===&lt;br /&gt;
====Unterschied Post/DHL/Post-Paketdienst zu DHL Express====&lt;br /&gt;
&lt;br /&gt;
DHL war ursprüngliche eine Spedition, die die Post übernommen hat. DHL enthielt auch einen Kurierdienst, der mit der Übernahme von DHL als DHL &#039;&#039;&#039;Express&#039;&#039;&#039; zur Post kam. Darüber hinaus begann die Post die Bezeichnung DHL auch für andere Bereiche, wie ihren ganz normalen Paketdienst zu verwenden.&lt;br /&gt;
&lt;br /&gt;
Wenn es um Zoll und Abgaben beim Import aus dem Nicht-EU-Ausland geht, muss man zwei DHL-Bereiche innerhalb der Post unterscheiden, da die Abläufe in diesen Bereichen völlig verschieden sind:&lt;br /&gt;
&lt;br /&gt;
;DHL: Der normale Post-Paketdienst&lt;br /&gt;
:Diese hat, wie weiter unter beschrieben, noch Sonderrechte aus der alten Zeit der Post als Behörde (Bundespost).&lt;br /&gt;
&lt;br /&gt;
;DHL &#039;&#039;&#039;Express&#039;&#039;&#039;: Der mit DHL zur Post gekommene Kurierdienst&lt;br /&gt;
:DHL &#039;&#039;&#039;Express&#039;&#039;&#039; verhält sich wie ein Kurierdienst und hat (oder nutzt) die Sonderrechte der Post bei der Einfuhr nicht.&lt;br /&gt;
&lt;br /&gt;
Man hat zwar ein gemeinsames Logo und die selbe Konzernfarbe, aber beide dieser DHLs, der Post-Paketdienst und der Kurierdienst, arbeiten im Postkonzern so nebeneinander her. Sie haben unterschiedliche Abläufe, Verfahren und Preise. DHL &#039;&#039;&#039;Express&#039;&#039;&#039; ist eine eigene Welt innerhalb des Postkonzerns. DHL &#039;&#039;&#039;Express&#039;&#039;&#039; unterteilt sich intern nochmal in einen nationalen und internationalen Bereich. Dazu scheint es einen oder mehrere spezielle Bereiche an den &#039;Hubs&#039; für den Import und die Zollabwicklung zu geben. Bei all diesen Bereichen hat man den Eindruck, dass sie so nebeneinander her arbeiten und man nicht viel miteinander redet, reden möchte oder reden darf. &lt;br /&gt;
&lt;br /&gt;
Selbstverständlich wird vom Kunden erwartet, dass er die interne Organisation im Detail kennt. Wehe dem Kunden, der versehentlich bei der falschen Hotline anruft oder im falschen Bereich landet. Da wird schon mal behauptet, dass eine Abteilung kein Telefon hätte.&lt;br /&gt;
&lt;br /&gt;
====DHL Express====&lt;br /&gt;
DHL Express ist ein Kurierdienst, eine Spedition. So verhält sich DHL Express auch. Im Gegensatz zur Post, mit ihrem Paketdienst DHL, hat DHL Express keine Sonderrechte beim Import von Lieferungen aus dem Ausland (oder sie nutzen diese nicht).&lt;br /&gt;
&lt;br /&gt;
DHL Express liefert nicht an DHL Packstationen und hat keinen Zugang zu DHL Paketkästen. DHL Express gibt Lieferungen auch nicht bei der nächsten Post oder Postagentur zur Selbstabholung ab. Ebenso funktioniert der DHL Wunschfilialen-Service nicht bei Lieferungen per DHL Express.&lt;br /&gt;
&lt;br /&gt;
DHL Express fährt nicht zustellbare Lieferungen lieber 100 km oder 200 km zu ihrer nächsten &#039;&#039;DHL Express Station&#039;&#039; zurück. Es gibt von diesen &#039;&#039;DHL Express Stationen&#039;&#039; nur 30 in ganz Deutschland. Wer nicht wirklich das Glück hat zufällig in der Nähe der richtigen Station zu wohnen hat keine Möglichkeit der Selbstabholung.&lt;br /&gt;
&lt;br /&gt;
Insgesamt ist die nicht-Integration von DHL Express in den normalen DHL-Service ein ziemliches Armutszeugnis für das Post/DHL-Management.&lt;br /&gt;
&lt;br /&gt;
DHL Express erhebt seit dem 1.6.2014 sehr kreative Gebühren. Seit dieser Zeit verlangt DHL Express eine &#039;&#039;Kapitalbereitstellungsprovision&#039;&#039;&amp;lt;ref&amp;gt;[http://www.dhl.de/content/dam/dhlde/downloads/express/dhl-express-preise-und-laufzeiten-012015.pdf DHL Express Preisliste]&amp;lt;/ref&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;Provision für die Benutzung des DHL Express eigenen Aufschubkontos zum Zwecke der Kapitalbereitstellung für anfallende Steuern und Zölle | 2 % der verauslagten Einfuhrabgaben; mind. 10,00 EUR&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Darauf fallen noch 19% Mehrwertsteuer an, also mindestens 11,90€ Kapitalbereitstellungsprovision. Angeblich kann man das ominöse Aufschubkonto dadurch umgehen, dass man bei DHL Express ein Kundenkonto eröffnet und DHL die Abbuchung vom eigenen Bankkonto erlaubt. Nach diversen Berichten braucht man dazu angeblich eine [http://www.zoll.de/DE/Fachthemen/Zoelle/EORI-Nummer/eori-nummer_node.html EORI Nummer] und muss damit bei DHL Express mittels Post-Ident-Verfahren ein SEPA-Mandat erteilen.&lt;br /&gt;
&lt;br /&gt;
DHL Express&#039; Verhalten macht DHL Express für Privatpersonen sehr unattraktiv. Vielleicht ist dies durchaus gewollt.&lt;br /&gt;
&lt;br /&gt;
====Post, Post-Paketdienst DHL - aber nicht DHL Express====&lt;br /&gt;
&lt;br /&gt;
Die Post, mit ihrem Paketdienst DHL (aber nicht DHL Express) genießt bei der Einfuhr einige Sonderrechte, im Gegensatz zu Kurierdiensten wie DHL Express. Diese stammen noch aus der Zeit als die Post eine Behörde war. Daher kann es von Vorteil sein, Waren mit der Post versenden zu lassen. Allerdings vermindert sich der Vorteil immer mehr, da die Post für die frühere Amtshandlung der nachträglichen Postverzollung nun auch gebühren verlangt.&lt;br /&gt;
&lt;br /&gt;
Unter anderem darf die Post selber entscheiden, ob eine Sendung dem Zoll vorgeführt werden muss oder nicht. Wenn entschieden wurde eine Sendung nicht dem Zoll vorzuführen erhält sie einen grünen Aufkleber&lt;br /&gt;
&lt;br /&gt;
:&#039;&#039;&#039;Von zollamtlicher Behandlung befreit - Deutsche Post &#039;&#039;&amp;lt;Name des Postamts&amp;gt;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
und wird einfach zugestellt.&lt;br /&gt;
&lt;br /&gt;
Führt die Post eine Sendung beim Zoll vor, und können die entsprechenden Abgaben bestimmt werden, dann kassiert die Post diese Abgaben für den Zoll bei der Auslieferung der Sendung an der Haustüre. Dafür berechnet die Post keine Gebühren. (Siehe http://www.zoll.de/SharedDocs/Boxen/DE/Fragen/0074_sendungen_direkt_zugestellt.html)&lt;br /&gt;
&lt;br /&gt;
Führt die Post eine Sendung beim Zoll vor, und die entsprechenden Abgaben können nicht bestimmt werden, weil zum Beispiel keine glaubhafte Rechnung vorliegt, oder es besteht der Verdacht die Einfuhr ist nicht legal [http://www.mikrocontroller.net/attachment/249800/CCI06032015_00000.jpg], übergibt die Post die Sendung an ein Zollamt. Im Gegensatz zu Kurierdiensten, bei denen die Sendungen immer beim nächsten Zoll am Einfuhrort (Flughafen, Seehafen) landet, ist dies ein dem Empfänger relativ naheliegendes, zuständiges Zollamt. Die Sendung kommt also schon mal halbwegs in die richtige Richtung und bleibt, im Gegensatz zu Kurierdiensten, nicht am Flughafen oder im Hafen liegen.&lt;br /&gt;
&lt;br /&gt;
In diesem Fall erhält man von der Post eine Aufforderung entsprechende Unterlagen beim Zollamt einzureichen (siehe http://www.zoll.de/SharedDocs/Boxen/DE/Fragen/0075_sendung_liegt_beim_zoll.html) Reicht man die Unterlagen persönlich ein werden diese überprüft, man zahlt direkt und nimmt die Sendung mit. &lt;br /&gt;
&lt;br /&gt;
Alternativ kann man die Post mit der sogenannten nachträglichen Postverzollung beauftragen. Die Post verlangt dafür seit August 2015 eine Gebühr von 28,50 Euro. Dazu kommen die eigentlichen Zollgebühren, Abgaben und Steuern. Man muss natürlich trotzdem die vom Zoll geforderten Unterlagen bereitstellen. Der Zoll übergibt nach der Berechnung der Abgaben die Sendung wieder der Post. Die stellt die Sendung zu und kassiert.&lt;br /&gt;
&lt;br /&gt;
===Diverses===&lt;br /&gt;
Praktische Regelungen (Stand Anfang 2014):&lt;br /&gt;
* Geschenke von Privatpersonen bis 45 EUR gehen meist ohne weitere Abgaben durch.&lt;br /&gt;
* Waren bis 150€ sind zollfrei, ab 22€ fallen jedoch 19% Umsatzsteuer an.&lt;br /&gt;
* Einfuhrabgaben von weniger als 5 Euro werden nicht erhoben.&lt;br /&gt;
* ... manchmal hat man einfach Glück. Da hatte der Zoll dann wohl was wichtigeres zu tun.&lt;br /&gt;
&lt;br /&gt;
===Merkwürdigkeiten===&lt;br /&gt;
====Diverses====&lt;br /&gt;
Gerade bei asiatischen Versendern kann man immer wieder diverse Merkwürdigkeiten erleben&lt;br /&gt;
&lt;br /&gt;
* Es wird behauptet die Ware sei bereits in Deutschland oder der EU. In Wirklichkeit wird sie dann z.B. aus China versendet und man wird unvorhergesehen mit zusätzlichen Abgaben konfrontiert. Eventuell hilft eine Beschwerde beim Marktplatz über den man gekauft hat. &lt;br /&gt;
&lt;br /&gt;
* Der Absender der Sendung stimmt nicht mit dem Verkäufer überein.&lt;br /&gt;
:Das ist bei chinesischen Verkäufern völlig normal. Die agieren gerne mit mehreren Fantasienamen gleichzeitig auf Marktplätzen wie eBay und/oder der Verkäufer betreibt Dropshipping [http://de.wikipedia.org/wiki/Streckengesch%C3%A4ft].  &lt;br /&gt;
&lt;br /&gt;
* Die Zollinhaltserklärung auf der Sendung hat rein gar nichts mit dem Inhalt der Sendung zu tun.&lt;br /&gt;
:Leider ist das bei chinesischen Versendern auch völlig normal. Zum Teil ist es einfach Schlamperei, zu Teil ist es der Versuch Zölle zu umgehen. Einige chinesische Versender preisen eine falsche Zolldeklaration sogar als Service an. Natürlich kennt der deutsche Zoll diesen &amp;quot;Trick&amp;quot; nur allzu gut (siehe [http://www.zoll.de/DE/Privatpersonen/Post-Internet/Sendungen-aus-einem-Nicht-EU-Staat/Zoll-und-Steuern/Geschenksendungen/frage_6.html]). Bestenfalls nützt er nichts, im schlimmsten Fall erregt die Sendung damit die besondere Aufmerksamkeit des Zolls. Leider kann man chinesischen Versendern diese Unsitte nicht ausreden. &lt;br /&gt;
  &lt;br /&gt;
* Fehlen von jeglichen Versandpapieren (Rechnung, Lieferschein, etc.)&lt;br /&gt;
:Auch das ist bei chinesischen Versendern völlig normal und verzögert eventuell die Zollabfertigung. Auch diese Unsitte kann man chinesischen Versendern nicht ausreden.&lt;br /&gt;
&lt;br /&gt;
* Die Sendung enthält eine dubiose (unbekannte Firma, Postfach) Rücksendeadresse in Deutschland. &lt;br /&gt;
:Der Versender benutzt einen Dienstleiter, der für ihn nicht zustellbare Sendungen einsammelt. Versendet wurde trotzdem aus dem Ausland. Der Dienstleister hinter der Adresse will mit irgendwelchen Problemen bei der Einfuhr nichts zu tun haben.&lt;br /&gt;
&lt;br /&gt;
* Der Versand dauert lange und der Versender behauptet die Ware liegt beim Zoll.&lt;br /&gt;
:Das ist eine beliebte Ausrede, die aber nicht stimmt. Der Zoll sammelt keine Ware um sie später zu kontrollieren, sollte man sich beim Zoll langweilen. Der Zoll ist permanent ausgelastet oder überlastet. Der muss sich nichts &amp;quot;für schlechte Zeiten aufheben&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
:Wahrscheinlicher ist dass die Ware (noch) nicht versendet wurde, sie verloren ging, der Spediteur/Kurier überlastet ist und die Ware noch gar nicht beim Zoll vorgeführt hat (Ware liegt im Container im Lager des Spediteurs) oder die angeblich per Luftpost versendete Ware dümpelt noch in irgendeinem Seecontainer auf einem Seelenverkäufer herum.&lt;br /&gt;
&lt;br /&gt;
:Das man vom Versender mit einer Lüge bedacht wurde, merkt man zum Beispiel dann, wenn die Ware ohne Trackingnummer versendet wurde. Woher will der Versender ohne Tracking wissen, wo sich die Ware gerade befindet?&lt;br /&gt;
&lt;br /&gt;
* Es kann passieren, dass ein Versender mit seiner lokalen Post versendet und die Auslieferung in Deutschland trotzdem durch einen Kurierdienst und nicht durch die deutsche Post erfolgt - mit für Kurierdiensten üblichen Zusatzgebühren. Beispiel EMS China -&amp;gt; GDSK.&lt;br /&gt;
:In diesem Fall hat die Post des Absenders aus Kostengründen eine Vereinbarung mit dem Kurierdienst und hat die Sendung an den Kurierdienst übergeben. Der Zoll sieht nur die Einfuhr durch den Kurierdienst und behandelt die Einfuhr entsprechend.&lt;br /&gt;
&lt;br /&gt;
* &#039;Querschläger&#039;&lt;br /&gt;
:Da kommt eine Lieferung aus China plötzlich mit der Post zum Beispiel aus Singapur, den Niederlanden oder Großbritannien. Das ist ein Zeichen für die Kreativität chinesischer Versender wenn es um das Einsparen von Versandgebühren geht. Der Versender hat die Ware auf anderem Weg (Seefracht, Kurier) in das entsprechende Land verbracht und der dortigen Post übergeben. Ein solches Vorgehen bricht regelmäßig das Tracking. &lt;br /&gt;
:Beim diesem Weiterversand per Post kann es passieren, dass die Auslands-Post die Sendung ebenfalls an ein deutsches Binnenzollamt übergibt wenn sie das für nötig hält. Dann erhält man vom Zollamt eine Benachrichtigung über eine Sendung aus einem Land aus dem man eventuell gar keine Sendung erwartet.&lt;br /&gt;
 &lt;br /&gt;
* Manche Versender übernehmen mit ihren Versandgebühren auch die Umsatzsteuer, Zoll und Kuriergebühren. Leider kommt es immer wieder vor, dass der Kurierdienst sich nicht an die Vereinbarung mit dem Versender gebunden fühlt und trotzdem noch Gebühren für die Vorführung beim Zoll und Zollgebühren verlangt. Der einzige, der einem in so einem Fall helfen kann ist der Versender. Als Empfänger wird man von Kurierdiensten nicht ernst genommen, es lohnt sich nicht mit denen zu diskutieren.&lt;br /&gt;
&lt;br /&gt;
====eBay Global Shipping Program, Pitney Bowes====&lt;br /&gt;
eBay bietet für US-Versender einen Dienst an, bei dem ein Dienstleister, Pitney Bowes, den Versand nach Deutschland übernimmt (&#039;&#039;Global Shipping Program&#039;&#039;). Da viele US-Versender sich bei dem Gedanken an einen Versand ins Ausland ins Hemd scheißen, nehmen sie immer häufiger diese Dienstleistung in Anspruch.&lt;br /&gt;
&lt;br /&gt;
Der Dienstleister wird vom Käufer, also von uns, bezahlt. Die in eBay-Angeboten angezeigten Gebühren sind nur unverbindliche Schätzungen und man verpflichtet sich laut AGB [http://pages.ebay.de/shipping/globalshipping/buyer-tnc.html#programfees] alles zu zahlen was später verlangt wird. Ebenso stimmt man zu, die zolltarifliche Einstufung der Ware durch den Dienstleiter nicht zu hinterfragen. Man liefert sich auf Gedeih und Verderben dem Dienstleister aus, der irgendwo in Kentucky seine Entscheidungen fällt.&lt;br /&gt;
&lt;br /&gt;
Hinzu kommt, dass der Dienstleister den Transport nicht selbst durchführt, sondern eigenständig einen Kurier aussucht. Man hat keine Kontrolle darüber mit welchem Kurierdienst die Ware geliefert wird und was der beim deutschen Zoll veranstaltet. Es gibt Berichte im Internet, dass der Dienstleister gut verpackte Ware umpackte und die Verpackung aus Kostengründen durch eine leichte, aber ungeeignete ersetzte. Die Ware wurde dann einem billigen Kurier ohne Transportversicherung übergeben. &lt;br /&gt;
&lt;br /&gt;
Pitney Bowes Kerngeschäft ist die Herstellung von Frankiermaschinen und anderen Gerätschaften für die Sortierung und den Transport von Post. Man hat es mit der geballten Kompetenz eines Herstellers von Stempelsystemen im internationalen Zollsystem zu tun. Ähm ja ...&lt;br /&gt;
&lt;br /&gt;
Völlig unklar ist, ob Pitney Bowes die über das System kassierte Einfuhrumsatzsteuer an den deutschen Fiskus entrichtet. In den AGBs ist der Käufer dafür verantwortlich. Bei ebay wird man aber darüber getäuscht, es heisst, dass &amp;quot;Keine zusätzlichen Gebühren bei Lieferung!&amp;quot; anfallen würden.&lt;br /&gt;
Tatsächlich interessiert das das Zollamt nicht, und die Einfuhrumsatzsteuer musste erneut entrichtet werden!&lt;br /&gt;
&lt;br /&gt;
====Dynamic Currency Conversion (DCC)==== &lt;br /&gt;
&lt;br /&gt;
Bietet ein Verkäufer in einem Nicht-Euroland eine Kartenzahlung in Euro an sollte man vorsichtig sein. Wahrscheinlich verwendet er Dynamic Currency Conversion (DCC) &lt;br /&gt;
&lt;br /&gt;
DCC ist ein Verfahren bei der Bezahlung mit Kreditkarte oder anderen Karten, bei Zahlungen in ausländischer Währung (also nicht Euro), welches häufig zu Ungunsten des Zahlenden ausgenutzt wird. Der Trick liegt in&lt;br /&gt;
&lt;br /&gt;
* der Verwendung sehr ungünstiger Wechselkurse,&lt;br /&gt;
* dem Aufschlagen von diversen erfundenen Gebühren für den Service, &lt;br /&gt;
* der Unwissenheit des Käufers über den offiziellen Wechselkurs und möglicher Gebühren,&lt;br /&gt;
* dem verklausulierten Angebot von DCC &amp;quot;Do you want to pay in Euros?&amp;quot;. Der Zahlende soll nicht merken dass er DCC &amp;quot;gewählt&amp;quot; hat.&lt;br /&gt;
&lt;br /&gt;
Normalerweise rechnen bei Auslandszahlungen der Verkäufer in seiner Landeswährung gegenüber dem Käufer und Kreditkartenunternehmen ab. Erst das Kreditkartenunternehmen rechnet die Landeswährung in die Währung des Käufers (Euro) um. Dabei ist das Kreditkartenunternehmen an gesetzliche Vorgaben zum Währungskurs gebunden. Zusätzlich erhebt das Kreditkartenunternehmen eine Gebühr. Auch bei der Gebühr gibt es gesetzliche Beschränkungen.&lt;br /&gt;
&lt;br /&gt;
Bei DCC bietet der Verkäufer dem Käufer eine Abrechnung in Euro, also nicht in seiner Landeswährung, an. Die Umrechnungskurse, die dabei verwendet werden sind typischerweise sehr ungünstig. Die Abrechnung erfolgt nicht direkt gegenüber dem Kreditkartenunternehmen, sondern einem Dritten, einem sog. Acquirer. &lt;br /&gt;
&lt;br /&gt;
Der Acquirer legt den für den Kaufer ungünstigen Umrechnungskurs willkürlich fest. Er zahlt den Verkäufer in seiner Landeswährung aus, plus einem Bonus (&amp;quot;Schmiergeld&amp;quot;). Der Bonus soll den Verkäufer animieren so viele Kunden wie möglich zu DCC zu bewegen. &lt;br /&gt;
&lt;br /&gt;
Der Acquirer rechnet die Landeswährung in Euro um. Dabei berechnet er, zusätzlich zum ungünstigen Wechselkurs willkürlich Gebühren in Euro. Er belastet dann die Kreditkarte des Kunden in Euro, einschließlich seiner Gebühren.&lt;br /&gt;
&lt;br /&gt;
In der Summe ist es sehr wahrscheinlich, dass die bei DCC anfallenden Gebühren und der ungünstige Wechselkurs höher sind, als wenn das Kreditkartenunternehmen umrechnet und Gebühren erhebt.&lt;br /&gt;
&lt;br /&gt;
=Beschwerden=&lt;br /&gt;
&lt;br /&gt;
Kurierdienste, die Post, DHL, etc. sind alle ziemlich immun gegen Beschwerden oder Bitten um Hilfe. Sie haben kein Problem damit Beschwerden hartnäckig zu ignorieren. Man kann es als &amp;quot;Erfolg&amp;quot; werten, wenn man wenigstens so weit vorgedrungen ist, dass man nach ein paar Wochen einen nutzlosen, nicht unterschriebenen Formbrief &amp;quot;&#039;&#039;Was mit der an Sie gerichteten Sendung geschehen ist, können wir nicht feststellen.&#039;&#039;&amp;quot;&amp;lt;ref&amp;gt;Zitat Kundenservice Deutsche Post.&amp;lt;/ref&amp;gt; erhält.&lt;br /&gt;
&lt;br /&gt;
Was je nach Situation helfen kann:&lt;br /&gt;
&lt;br /&gt;
* Beim Absender beschweren&lt;br /&gt;
:Kurierdienste, die Post, DHL etc. nehmen Absender ernster als Empfänger. Aus deren Sicht ist der Absender, nicht der Empfänger, der Kunde. Denn formal beauftragt der Absender und zahlt die Gebühr an den Kurierdienst.&lt;br /&gt;
&lt;br /&gt;
* Öffentlich über Facebook oder Twitter beschweren&lt;br /&gt;
:Aus Gründen, die sie vermutlich nicht einmal selbst kennen, werden die Unternehmen bei öffentlichen Beschwerden über Facebook oder Twitter plötzlich sehr aktiv. So antwortet DHL auf Twitter häufig mit einer speziellen E-Mail Adresse, über die die Beschwerde dann bearbeitet wird, während Beschwerden an DHLs offizielle Serviceadresse unbeantwortet bleiben.&lt;br /&gt;
&lt;br /&gt;
:Gelegentlich fahren Kurierdienste irgendwelche Imagekampagnen. Diese Kampagnen sollte man nicht allzu ernst nehmen. Sollte die Kampagne im &amp;quot;Social Web&amp;quot; laufen kann man sie allerdings nutzen um eine Beschwerde noch öffentlichkeitswirksamer anzubringen.&lt;br /&gt;
&lt;br /&gt;
=Hilfreiche Links=&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
* http://www.zoll.de/&lt;br /&gt;
* Muster: http://www.zoll.de/DE/Fachthemen/Zoelle/Zollbefreiungen/Aussertarifliche-Zollbefreiung/Absatzfoerderung/Warenmuster-und-proben/warenmuster-und-proben_node.html&lt;br /&gt;
* Geschenke: http://www.zoll.de/DE/Privatpersonen/Post-Internet/Sendungen-aus-einem-Nicht-EU-Staat/Verfahren/frage_4.html?nn=115522&lt;br /&gt;
* geringer Wert: http://www.zoll.de/DE/Privatpersonen/Post-Internet/Sendungen-aus-einem-Nicht-EU-Staat/Zoll-und-Steuern/Sendungen-mit-geringem-Wert/sendungen-mit-geringem-wert.html&lt;br /&gt;
* Kosten allgemein: http://www.zoll.de/DE/Privatpersonen/Post-Internet/Sendungen-aus-einem-Nicht-EU-Staat/Zoll-und-Steuern/zoll-und-steuern_node.html&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Lieferanten]]&lt;/div&gt;</summary>
		<author><name>8023</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Nachttischlampe&amp;diff=92353</id>
		<title>Nachttischlampe</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Nachttischlampe&amp;diff=92353"/>
		<updated>2016-03-13T15:27:37Z</updated>

		<summary type="html">&lt;p&gt;8023: müll&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von [http://www.mikrocontroller.net/user/show/mclausen Martin Clausen]&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
Ausgehend von den von den Unzulänglichkeiten meiner bisherigen Nachttischlampe und der mich nicht überzeugenden Funktion einer Beleuchtung für den Schlafraum eines niederländischen Herstellers, entstand die Idee zu diesem Projekt.&lt;br /&gt;
Im Ergebnis ergeben sich ein angenehmeres Aufstehen, mehr Komfort und die Möglichkeit bei einem von zwei Personen bewohntem Schlafzimmer einander weniger zu stören.&lt;br /&gt;
=== Features für den Nutzer ===&lt;br /&gt;
* Zwei separate Beleuchtungskanäle&lt;br /&gt;
** Hintergrundbeleuchtung&lt;br /&gt;
** Leselicht&lt;br /&gt;
* Intuitive Bedienung über einen Drehencoder mit Tastfunktion&lt;br /&gt;
** Dynamische Schrittweitenanpassung für die schnelle und genaue Einstellung der Helligkeit und anderer Werte&lt;br /&gt;
* Anzeige mit 16x2 hintergrundbeleuchtetem LCD&lt;br /&gt;
* Anpassung der Helligkeitssteuerung an die Empfindlichkeitskurve des menschlichen Auges&lt;br /&gt;
* Anpassung der Helligkeit an das Umgebungslicht&lt;br /&gt;
* Fernbedienbar&lt;br /&gt;
* Vernetzbar innerhalb eines Raumes&lt;br /&gt;
** Synchronlauf der Helligkeiten von Lampen aktivierbar&lt;br /&gt;
** Alarmfunktion kann andere Lampen aktivieren&lt;br /&gt;
* Weck-Funktion&lt;br /&gt;
** Bis zu 7 wochentagsabhängige oder - unabhängige Alarme&lt;br /&gt;
** Alarme überspringbar&lt;br /&gt;
** Alarmsignal durch&lt;br /&gt;
*** separat in Zeit und Helligkeit einstellbares Eindimmen von Hintergrund- und Leselicht&lt;br /&gt;
*** angenehmes akustisches Signal mit einstellbarer Verzögerung zum Alarmstart und ansteigender Lautstärke&lt;br /&gt;
&lt;br /&gt;
=== Technische Eigenschaften ===&lt;br /&gt;
* LEDs&lt;br /&gt;
** Nichia NS6W183 auf Star-Platine&lt;br /&gt;
** 4 Stück warmweis für die Hintergrundbeleuchtung&lt;br /&gt;
** 2 Stück kaltweiss für das Leselicht&lt;br /&gt;
** andere LED Bestückungen bis 5 LED je Strang bei 24V Eingangsspannung möglich&lt;br /&gt;
* LED-Treiber&lt;br /&gt;
** Zwei unabhängige PWM-gesteuerte Kanäle&lt;br /&gt;
** Nachführung der PWM-Frequenz zur Vergrößerung des dynamischen Bereiches der LED-Treiber ohne Flackern der Beleuchtung&lt;br /&gt;
** Zwei verschiedene Treiber möglich:&lt;br /&gt;
*** Diodes ZXLD1362&lt;br /&gt;
*** Diodes ZXLD1374&lt;br /&gt;
** Hysteric Step-Down-LED-Driver&lt;br /&gt;
** maximal 60V, 1A bzw. 1,5A; 24V, 500mA in diesem Projekt&lt;br /&gt;
* Step-Down Regler für Steuer-Modul&lt;br /&gt;
** Zwei verschieden Schaltregler möglich&lt;br /&gt;
*** LM2674 ADJ auf 3,3V eingestellt, maximale Eingangsspannung 40V&lt;br /&gt;
*** LT1676 auf 3,3V eingestellt, maximale Eingangsspannung 60V&lt;br /&gt;
* MCU &lt;br /&gt;
** NXP 89LPC936, 8051 mit 2-Takt Kern&lt;br /&gt;
** 16k Byte Flash (ca. 10k Byte belegt), 768 Byte RAM, 512 Byte EEPROM, ISP&lt;br /&gt;
** 3,3 Volt, niedriger Stromverbrauch&lt;br /&gt;
** 6 MHz Takt mittels Resonator, 18 MHz maximal&lt;br /&gt;
** 8 Bit DAC und ADC&lt;br /&gt;
** 16 Bit CCU mit PLL und 4 Kanälen&lt;br /&gt;
* LCD&lt;br /&gt;
** Electronic Assembly DOGM162W-A mit amber-farbener Hintergrundbeleuchtung&lt;br /&gt;
** Hintergrundbeleuchtung mit PWM-Ansteuerung&lt;br /&gt;
** Anschluss an MCU via SPI&lt;br /&gt;
* RTC RV 3029-C2 mit integriertem Quarz&lt;br /&gt;
* Erzeugung des akustischen Signals&lt;br /&gt;
** DDS zur Erzeugung eines sauberen und angenehmen Sinussignals&lt;br /&gt;
** Alternativ: Hardware vorbereitet für das Abspielen von unkomprimierten Audiodaten aus 4M Byte Flash&lt;br /&gt;
** Ausgabe über DAC im MCU&lt;br /&gt;
** Tiefpassfilter 3. Ordnung, 8,6kHz Frequenz , mit 3/4 MCP6404&lt;br /&gt;
** Einstellung der Lautstärke in 4 Stufen mit CMOS-Schalter 1/2 74HC4052&lt;br /&gt;
** Lautsprecheransteuerung durch Brückenverstärker LM4861&lt;br /&gt;
* Messung der Umgebungshelligkeit&lt;br /&gt;
** Linearer I-U Wandler mit 1/4 MCP6404&lt;br /&gt;
** Widerstand über CMOS-Schalter 1/2 74HC4052 1:1000 umschaltbar in 4 Stufen&lt;br /&gt;
** 8-Bit ADC der MCU&lt;br /&gt;
** Gesamtdynamikbereich von 1:256000&lt;br /&gt;
** Moving-Average-Filter mit 64 Datenpunkten&lt;br /&gt;
* Kommunikation&lt;br /&gt;
** Empfängt und sendet IR-Signale gemäß RC5-Protokoll&lt;br /&gt;
* Stromversorgung&lt;br /&gt;
** Phihong, PSAA 30R-240 (30W, 24V)&lt;br /&gt;
** Niedrige Standby-Leistung von 300mW&lt;br /&gt;
** Ausreichend für zwei Lampen&lt;br /&gt;
** Messung der Leistungsaufnahme von der 24V Versorgung am Prototypen mit LM2674 und 2x ZXLD1362:&lt;br /&gt;
*** Standby: 170mW&lt;br /&gt;
*** Volllast: 11,5W&lt;br /&gt;
** Messung der Leistungsaufnahme von der 230V Versorgung an einem Netzteil mit zwei Prototypen mit LM2674 und 2x ZXLD1362:&lt;br /&gt;
*** Standby: 0,5W&lt;br /&gt;
*** Volllast: 26W&lt;br /&gt;
** Messung der Leistungsaufnahme von der 24V Versorgung am Prototypen mit LT1676 und 2x ZXLD1374:&lt;br /&gt;
*** Standby: 72mW&lt;br /&gt;
&lt;br /&gt;
* Struktur&lt;br /&gt;
** Steuerplatine 36x100mm², doppelseitig&lt;br /&gt;
** Leistungsplatine 80x100mm², einseitig&lt;br /&gt;
** Verbindung über einzelnes 10 pol. Flachbandkabel&lt;br /&gt;
** Stromversorgung über Steckernetzteil&lt;br /&gt;
&lt;br /&gt;
* Mechanik&lt;br /&gt;
** Konstruktion aus eloxierten Aluminium Profilen von Item&lt;br /&gt;
&lt;br /&gt;
* Software&lt;br /&gt;
** Open Source C für SDCC 3.2&lt;br /&gt;
** Verwendet Stromsparmodi der MCU&lt;br /&gt;
** State-Machines für Drehencoder und RC5-Dekodierung&lt;br /&gt;
&lt;br /&gt;
== Bilder ==&lt;br /&gt;
&lt;br /&gt;
=== Design ===&lt;br /&gt;
* Symmetrisches Pärchen, Vorder- und Rückseite&lt;br /&gt;
[[Bild:Symmetrisches Pärchen.jpg|200px]]&lt;br /&gt;
[[Bild:Symmetrisches Pärchen Rückseite.jpg|200px]]&lt;br /&gt;
* Detail Ansteuerung, Vorder- und Rückseite&lt;br /&gt;
[[Bild:Detail Ansteuerung.jpg|200px]]&lt;br /&gt;
[[Bild:Detail Ansteuerung Rückseite.jpg|200px]]&lt;br /&gt;
* Detail Leselicht&lt;br /&gt;
[[Bild:Detail Leselicht.jpg|200px]]&lt;br /&gt;
&lt;br /&gt;
=== Lichtwirkung ===&lt;br /&gt;
* Leselicht allein mit 10% Helligkeit&lt;br /&gt;
[[Bild:Leselicht 10%.jpg|300px]]&lt;br /&gt;
* Leselicht allein mit 100% Helligkeit&lt;br /&gt;
[[Bild:Leselicht 100%.jpg|300px]]&lt;br /&gt;
* Hintergrundlicht allein mit 10% Helligkeit&lt;br /&gt;
[[Bild:Hintergrundlicht 10%.jpg|300px]]&lt;br /&gt;
* Lese- und Hintergrundlicht zusammen mit 100% Helligkeit&lt;br /&gt;
[[Bild:Lese- und Hintergrundlicht 100%.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Die Bilder wurden alle bei den gleichen fixen Kamera-Einstellungen aufgenommen. Der effektive dimmbare Bereich liegt zwischen 3 und 100%. Zur PWM-Ansteuerung der LEDs wird der quadrierte Wert verwendet.&lt;br /&gt;
&lt;br /&gt;
== Beschreibung ==&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
&lt;br /&gt;
Die Software besteht aus folgenden Teilen:&lt;br /&gt;
* Hauptschleife&lt;br /&gt;
&lt;br /&gt;
* Interrupt-Routinen&lt;br /&gt;
** RC5 Decoder, ausgelöst durch Timer 0&lt;br /&gt;
** Update der Zeit, jede Minute durch RTC ausgelöst&lt;br /&gt;
** Drehencoder, ausgelöst durch Timer 1 bei 366Hz&lt;br /&gt;
** Update PWM-Werte und einlesen der Tasten, ausgelöst durch Timer aus RTC der MCU bei 25Hz&lt;br /&gt;
&lt;br /&gt;
* Ansteuerung des Display via SPI&lt;br /&gt;
&lt;br /&gt;
* Initialisierung der MCU&lt;br /&gt;
** Core Funktionen, hauptsächliche Stromsparfunktionen&lt;br /&gt;
** I/O Pins&lt;br /&gt;
** SPI auf Master mit 1,5MHz Takt, MSB first&lt;br /&gt;
** I2C auf 375kHz&lt;br /&gt;
** ADC fixed channel, single conversion mode für ADC0 bei 3MHz&lt;br /&gt;
** DAC&lt;br /&gt;
** Interne RTC als 25Hz Taktgeber: 6*10^6/128/25=1875 reload&lt;br /&gt;
** Watchdog wird abgeschaltet&lt;br /&gt;
** CCU output compare: non-inverted PWM, PLL: auf Lock-in abwarten&lt;br /&gt;
** Interrupts freischalten&lt;br /&gt;
&lt;br /&gt;
* Auswertung Drehencoder&lt;br /&gt;
&lt;br /&gt;
* Helligkeitsmessung&lt;br /&gt;
&lt;br /&gt;
* I2C und RTC&lt;br /&gt;
Die Funktionen stellen einerseits die Kommunikation via I2C sicher und sind anderseits in der Lage, die RTC nach einem Batteriewechsel automatisch zu konfigurieren, die Zeit zu lesen und zu schreiben.&lt;br /&gt;
Die Kommunikation via I2C nutzt bisher nicht den zugehörigen Interrupt und ist nicht fehlertolerant.&lt;br /&gt;
&lt;br /&gt;
* RC5 Decoder und Sender&lt;br /&gt;
Der RC5 Decoder beruht auf einer State-Machine, die schrittweise die einzelnen Bits erkennt und dann in Adresse und Daten zerlegt. Nach der Erkennung eines kompletten Komandos wird steht rCounter auf dem Wert 12 und das Hauptprogramm beginnt mit der Decodierung (Aufruf &amp;quot;DecodeRemote()&amp;quot;).&lt;br /&gt;
Der Sender ist mittels Bit-Banging realisiert. Aufgrund des strikten Timings werden alle Interrupts abgeschaltet. Die Adresse für die Fernbedienung kann vom Benutzer eingestellt werden oder angelernt werden. Die Adressen für die Kommunikation der Lampen untereinander lauten 27, 28, 29.&lt;br /&gt;
&lt;br /&gt;
* Optionsmenü&lt;br /&gt;
&lt;br /&gt;
* Setzen der Helligkeit&lt;br /&gt;
&lt;br /&gt;
* Auswertung Tasten&lt;br /&gt;
Es werden die Tasten entprellt und die Dauer des Tastendrucks wird festgestellt.&lt;br /&gt;
&lt;br /&gt;
* Erzeugung des akustischen Signals in &amp;quot;AcusticDDSAlarm()&amp;quot;&lt;br /&gt;
Das Sinussignal wird mittels direkter digitaler Signalsynthese erzeugt. Dazu erzeugt ein in einer Schleife laufender Akkumulator mit Hilfe einer Tabelle von Sinuswerten einen Datenstrom der dem DAC zugeführt wird. Frequenz und Dauer der einzelnen Töne wird in einem zweidimensionalen Array in Code abgelegt.&lt;br /&gt;
Aufgrund des strikten Timings werden alle Interrupts abgeschaltet. Die Helligkeitsmessung wird auch unterbrochen, da die gleichen Pins die Lautstärke steuern.&lt;br /&gt;
Parallel werden nur die Tasten überwacht.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Menüstruktur V2.svg|400px]]&lt;br /&gt;
&lt;br /&gt;
=== Elektronik ===&lt;br /&gt;
Die Elektronik gliedert sich in zwei Teile:&lt;br /&gt;
* Leistungsteil&lt;br /&gt;
* Steuerung&lt;br /&gt;
&lt;br /&gt;
Der Leistungsteil entspricht im wesentlichen den Applikationsvorschlägen der Hersteller. Um Wechselwirkungen zwischen den Schaltreglern zu reduzieren wurden in den Stromzuführungen PI-Filter mit Feriten und Keramikkondensatoren eingesetzt und die gemeinsame Versorgung über einen größeren schaltfesten Elko abgeblockt.&lt;br /&gt;
Zur Erhöhung der Betriebssicherheit sind ferner eine Suppressor-Diode und ein Verpolschutz vorgesehen.&lt;br /&gt;
&lt;br /&gt;
Variante für ZXLD1362&lt;br /&gt;
Die einseitige Leiterplatte kann weitestgehend in SMD aufgebaut werden. Wo möglich wurde die Bauform 1206 verwendet, damit auch selbst gefertigte Platinen verwendbar sind. Große Masseflächen dienen auch zur Verteilung der Wärme. Die Anschlussklemmen und der Elko sind so platziert, dass sie im Inneren des Aluminium-Profils Platz finden.&lt;br /&gt;
&lt;br /&gt;
Variante für ZXLD1374&lt;br /&gt;
Gegenüber dem Entwurf mit ZXLD1362 wurde ein sparsamer Schaltregler (LT1676) für die Versorgung der Steuerung verwendet. Mit diesem Chip erhöht sich, wenn Kondensatoren und Suppressordiode angepasst werden auch die maximale zulässige Eingangsspannung.&lt;br /&gt;
Der LED-Treiber lässt sich deutlich besser kühlen und bietet eine bessere Dynamik in der PWM-Ansteuerung bei gleichzeitig höherer Wiederhohlrate. Letzteres reduziert den Stroboskop-Effekt beim Dimmen. Das Gehäuse erfordert jedoch eine doppelseitige Platine mit Durchkontaktierung.&lt;br /&gt;
&lt;br /&gt;
Die Steuerung gruppiert sich um eine MCU von NXP der 8051 Serie. Praktisch ist die 4-kanalige 16-bit CCU mit PLL, die sowohl die beiden LED-Stränge als auch die Hintergrundbeleuchtung des LCD steuern. Das kärgliche On-Chip der klassischen 8051 hat NXP um 512 Byte aufgebessert, was die Programmierung mit dem SDCC erleichtert. Die Einstellungen vom Benutzers werden im internen EEPROM abgelegt. Ein Resonator sorgt für einen genaueren Takt als der interne RC-Oszilator und eine &amp;quot;bequeme, glatte&amp;quot; Frequenz von 6MHz.&lt;br /&gt;
Als RTC kommt ein externer Baustein mit integriertem Quarz, Temperaturkompensation und Batterieumschaltung zum Einsatz. Damit lässt sich eine sehr gute Frequenzkonstanz erreichen. Die Lithiumbatterie sollte eine Zeit von 220mAh/1µA = 220kh = 25a erreichen. Die Stützbatterie wird durch einen Reihenwiderstand vor Defekten in der Schaltung die zu einem Stromfluss in die Batterie führen könnten geschützt. Der Anschluss der RTC zum Datenaustausch erfolgt über die I2C-Hardware des MCU. Die interne RTC des MCU wird als Timer verwendet.&lt;br /&gt;
Als Display kommt eine moderne Variante des klassischen 16x2 Zeichen LCD zum Einsatz. Die Modernisierungen betreffen die digitale Kontrast-Einstellung, 3,3V-Betrieb und das SPI mit passend zur MCU geringer Pin-Anzahl.&lt;br /&gt;
Die Kommunikation per IR erfordert nur das entsprechende Empfangsmodul und einen kleinen MOSFET zur Ansteuerung der Sendediode. Es sind zwei positionen auf der Platine vorgesehen, damit die Richtung der Abstrahlung gewählt werden kann. Falls beide Sendedioden bestückt werden, sollten die Vorwiderstände auf je 10 Ohm verdoppelt werden. Um das den 3,3V Schaltregler und den MOSFET nicht zu überfordern wird die Sendediode nur mit 300mA bei 25% Duty-Cycle betrieben. Ferner sind großzügige keramische Stützkondensatoren vorgesehen. Die Empfänger können parallel betrieben werden, um der Schaltung eine Rund-um-Sicht zu ermöglichen.&lt;br /&gt;
Recht aufwändig sind dagegen die Messung der Umgebungshelligkeit und die Erzeugung des akustischen Signales geraten. Zu nächst zur Helligkeitsmessung: Für diese Aufgabenstellung gibt es spezialisierte IC, die jedoch schwer erhältlich sind. Deshalb wurde ein Transimpedanzverstärker mit umschaltbarem Rückkoppelwiderstand aufgebaut. Die MCU ist zwar mit einem ADC ausgestattet, jedoch ist deren Dynamikbereich allein nicht ausreichend. Zusammen wird jedoch ein Bereich von 1:255000 entsprechend 108dB abgedeckt. In Software wird das Signal noch gefiltert und die Messwerte, zu die von der Hintergrundbeleuchtung des LCDs oder der IR-Sendediode beeinflusst worden sein könnten, übersprungen.&lt;br /&gt;
Die das akustische Signal sollte einen möglichst angenehmen Klang haben. Daher läuft auf der MCU eine DDS mit ca. 20kHz zur Erzeugung eines Sinussignals, welches über den ADC ausgegeben wird. Dann folgt zu nächst ein Buffer und eine Pegelanpassung, die ein Übersteuern der OPVs im folgenden Tiefpass mit ca. 7kHz verhindern. Über einen CMOS Schalter lässt sich das Signal in drei 10dB Stufen abgeschwächt dem ausgangsseitigen Brückenverstärker zuführen. Dieser wird zur Reduktion des Stromverbrauches von der MCU nur bei Bedarf aktiviert. Er ist auch auf eine Bandbreite von 8kHz begrenzt, um die Oberwellen weiter zu reduzieren.&lt;br /&gt;
Die beiden letztgenannten Schaltungsteile profitieren besonders von einem PI-Filter mit einer 4,7µH Drossel und größeren keramischen Kondensatoren. So werden Störungen aus Schaltreglern und der PWM-Ansteuerung der Hintergrundbeleuchtung ferngehalten.&lt;br /&gt;
RC-Glieder schützen die MCu vor Störeinstrahlung- und leitung durch die Kabel zu Drehencoder und Leistungsteil.&lt;br /&gt;
Die recht hohe Packungsdichte, der enge Pin-Abstand von MCU, OPV und RTC und die notwendigen Masseflächen erfordern eine professionelle doppelseitige Platine. Die Masseflächen wurden durch eine Vielzahl von vergrößerten und verteilten Vias verbunden. Die Entstörkondensatoren an den Halbleitern sind mit 1µF recht groß gewählt. Ob die Störfestigkeit unter der gegenüber 100nF reduzierten Resonanzfrequenz der Kondensatoren geringer ist, wurde nicht untersucht. (Es funktioniert.) Ein keramischer 1nF Kondensator hält Störungen vom Reset-Pin der MCU fern.&lt;br /&gt;
&lt;br /&gt;
Die Steuerplatine trägt zwei 5*2 polige Pfostenleisten. Die äußere dient primär zur Programmierung der MCU, kann aber auch für Erweiterungen mit I2C-Anschluss verwendet werden. Die innere stellt die Anschlüsse für Drehencoder und Leistungsteil zur Verfügung. Dazu muss somit ein Flachbandkabel mit drei Enden gepresst werden: 5*2 polig (Steuerung), offen (Drehencoder), 3*2 polig (Leistungsteil)&lt;br /&gt;
&lt;br /&gt;
Die MCU wird mit der kostenlosen Software [http://www.flashmagictool.com/ FlashMagic] und einer [http://www.keil.com/mcb900/mcb900-schematics.pdf Schaltung von Keil] über RS232 geflasht. Bei der Inbetriebnahme müssen folgende Punkte beachtet werden:&lt;br /&gt;
* Die Kondensatoren auf der Steuerungsplatine müssen schnell genug entladen werden können, damit die MCU beim Start in den Programmiermodus gebracht werden kann. Eine zusätzliche Last von z.B. 100 Ohm über die Betriebsspannung hilft.&lt;br /&gt;
* Es muss keine &amp;quot;echte&amp;quot; RS232 Schnittstelle sein. Ein USB-RS232 Adapter mit FTDI-Chip funktioniert bei mir auch.&lt;br /&gt;
* Einstellungen Flash Magic:&lt;br /&gt;
** Select: 89LPC936&lt;br /&gt;
** Baud Rate: 7200&lt;br /&gt;
** Interface: None (ISP)&lt;br /&gt;
** Oscillator (MHz): 7,373&lt;br /&gt;
** Erase block used by Hex File&lt;br /&gt;
* Unter ISP, Device Configuration wird die MCU konfiguriert:&lt;br /&gt;
** Statt des internen Oszillators muss ein externer High-Speed Oszillator gewählt werden. Die in FlashMagic einzustellende Frequenz ändert sich dann von 7.373 MHz auf 6 MHz&lt;br /&gt;
** Der Reset-Pin muss ausgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
Das Netzteil ist so ausgelegt, dass zwei Lampen mittels eines Y-Kabels versorgt werden können. Dadurch entfallen die Leerlaufverluste, Kosten und Platzbedarf des zweiten Netzteils.&lt;br /&gt;
&lt;br /&gt;
Kosten der Steuerplatine (Teile: Reichelt, MCU: Ebay, 5 Platinen von PCB-Pool): ca. 56€ je Stück&lt;br /&gt;
&lt;br /&gt;
=== Optoelektronik ===&lt;br /&gt;
&lt;br /&gt;
Die Auswahl der LEDs wird primär von den Wünschen nach der Lichtwirkung bestimmt. Hier ist nur ein Vorschlag angegeben. Daneben gibt es noch die Schnittstellen zur Mechanik und zur Elektronik.&lt;br /&gt;
Die Ansteuerung kann bei Versorgung mit 24V 1 bis 5 LEDs je Strang bedienen. Der Strom ist auf 500mA eingestellt, auch wenn der ZXLD1362 auch größere Ströme verkraften sollte. Beim SOT23-5 Gehäuse hatte ich jedoch dann in einem anderen Projekt insbesondere bei höheren Spannungen Probleme mit der Wärmeabführung. Mittlerweile können auch andere Gehäuseformen mit geringerem Wärmewiderstand bzw. leistungsfähigere Chips wie der ZXLD1374 eingesetzt werden. Der ZXLD1374 kann auch kürzere PWM-Impulse noch sauber in Stromimpulse für die LEDs umsetzen, womit ein größerer dimbarer Bereich erzielt wird. Jedoch muss der PWM-Pin von einem Push-Pull- statt einem Open-Drain-Ausgang angesteuert werden, da der interne Pull-Up des LED-Treibers sehr schwach ist und der Chip dann nur bei relativ langen Pulsen aus dem Standby aufwacht. Zum ZXLD1374 ist ein zusätzlicher Schaltplan mit Layout im Repository abgelegt. Der LM267X musste bei diesem Entwurf einem sparsameren und spannungsfesteren LT1676 weichen.&lt;br /&gt;
Sollen mehr als 5 LEDs je Strang angesteuert werden, muss die Supressor-Diode am Stromversorgungseingang angepasst und der LT1676 zur Versorgung der Steuerplatine verwendet werden. Die ZXLD1362 vertragen bis zu 60V, sollten jedoch mit mindestens 17V versorgt werden, damit der Schalt-MOSFET voll durchschaltet.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Teile von Leds.de&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Anzahl || Artikel-Nr. || Bezeichnung || Kommentar&lt;br /&gt;
|-&lt;br /&gt;
| 4  || 65659 || Nichia NS6L183BT, warmweiß, CRI 80, mit Platine (Star) || bessere Farbwiedergabe bei schlechterer Effizienz: austauschbar gegen NS6L183AT-H3 (CRI 85) oder NS6L183AT-H1 (CRI 90+)&lt;br /&gt;
|-&lt;br /&gt;
| 2  || 65656 || Nichia NS6W183BT, weiß, CRI 80, mit Platine (Star) ||&lt;br /&gt;
|-&lt;br /&gt;
| 2  || 60354 || Carclo Linse für Luxon Rebel, frosted wide || passt auch für Nichia NS6_183T&lt;br /&gt;
|-&lt;br /&gt;
| 2  || 60456 || Linsenhalter rund für Luxon Rebel, transparent || muss deutlich mit Säge und Feile angepasst werden&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Kosten ca. 27€&lt;br /&gt;
&lt;br /&gt;
=== Mechanik ===&lt;br /&gt;
Bei einer Nachttischlampe ist natürlich auch das Design eine wichtiges Merkmal. Ich bevorzuge ein klares einfaches Design und Materialien wie Glas und eloxiertes Aluminium. Die verwendeten Profile (Item, Profil X 8, leicht) ermöglichen es die Kabel und die Leistungselektronik im Inneren zu verstecken.&lt;br /&gt;
Es haben aber auch einige Kunststoffteile Verwendung gefunden, da sie mir den Verschluss der Aluminiumprofile ohne sichtbare Schrauben ermöglichen.&lt;br /&gt;
&lt;br /&gt;
Der sichere Stand wird durch die Füllung des Profil X 8 80x80 mit kleinen Kieseln für Aquarien gewährleistet. Die Oberen 1 bis 2cm bleiben frei und dienen dem Lautsprecher als Resonanzraum.&lt;br /&gt;
&lt;br /&gt;
Die Frontplatte wird laut Zeichnung von der Schaeffer AG (Datei bei Downloads) gefertigt. Sie &amp;quot;schwebt&amp;quot; auf vier Distanzhülsen über der Steuerungselektronik. Dadurch bleibt umlaufend ein Spalt von 12mm Höhe, durch den die Steuerung per RC5 kommuniziert, die Umgebungshelligkeit gemessen wird und der Schall vom Lautsprecher abgestrahlt wird.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Teile von Item&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Anzahl || Länge || Art.-Nr. || Bezeichnung&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 160mm || 0.0.493.04 || Profil X 8 80x80 8N leicht&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 160mm || 0.0.492.88 || Profil X 8 40x40 4N leicht&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 480mm || 0.0.492.88 || Profil X 8 40x40 4N leicht&lt;br /&gt;
|-&lt;br /&gt;
| 1 || - || 0.0.601.13 || Gelenk X 8 40x40 mit Klemmhebel&lt;br /&gt;
|-&lt;br /&gt;
| 4 || - || 0.0.026.07 || Standard-Verbindungssatz 8&lt;br /&gt;
|-&lt;br /&gt;
| 1 || - || 0.0.489.98 || Abdeckkappe X 8 80x80 grau&lt;br /&gt;
|-&lt;br /&gt;
| 1 || - || 0.0.489.61 || Abdeckkappe X 8 80x40 grau&lt;br /&gt;
|-&lt;br /&gt;
| 1 || - || 0.0.489.60 || Abdeckkappe X 8 40x40 grau&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Kosten: Item ca. 90€, Schaeffer AG ca. 25€&lt;br /&gt;
&lt;br /&gt;
Der Klemmhebel kann bei ästhetischen Bedenken auch gegen eine Schraube getauscht werden. Von zwei Standard-Verbindungssätzen wird nur die Schraube zur Befestigung des Gelenks verwendet.&lt;br /&gt;
&lt;br /&gt;
Die Bohr- und Fräsarbeiten habe ich durch [http://dw-metall.de/ Daniel Wulfänger] durchführen lassen.&lt;br /&gt;
&lt;br /&gt;
Ein 3D-Model für FreeCAD befindet sich im SVN-Repository (s.u.).&lt;br /&gt;
&lt;br /&gt;
2D-Zeichnungen auf Anfrage per PM bei [http://www.mikrocontroller.net/user/show/mclausen Martin Clausen]&lt;br /&gt;
&lt;br /&gt;
== Montage ==&lt;br /&gt;
&lt;br /&gt;
Wenn alle Teile laut Zeichnung bearbeitet worden sind, werden zunächst die Standard-Verbinder für die Verbindung von Arm und Fuß eingeschraubt. Da aus optischen Gründen kein Loch zum Festziehen der Schrauben vorhanden ist, werden die Standardverbinder vorsichtig angezogen, so dass der Arm beim Aufschieben beginnt zu klemmen. Dann wir die Fläche zwischen Arm und Fuß mit Alkohol geschmiert und der Arm mit einigen Hammerschlägen montiert. Dabei sollte eine Unterlage (z.B. ein Stück Holz) verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Nun wird der Drehencoder verdrahtet und in die große Abdeckkappe geschraubt und mit Heißkleber versiegelt.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Drehencoder mit Kabel.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Im folgenden wird die Stromversorgungsbuchse in die 80x40 Abdeckkappe geschraubt und diese in den Fuß gepresst.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Durchführung Kabel.jpg|200px]]&lt;br /&gt;
&lt;br /&gt;
Dann werden die LEDs mit etwas Wärmeleitpaste und einer Isolierscheibe unter jeder Schraube montiert. Kabel werden in das Profil gefädelt und an gelötet. Ein fester Draht kann dabei nützlich sein. Dann wird die Leistungselektronik im Fuß platziert. Für die Positionierung sorgen 10 und 12 mm Distanzbuchsen jeweils mit und ohne Außengewinde.&lt;br /&gt;
Jetzt bietet sich ein kurzer Funktionstest an.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Montage LEDs.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
Für die Front-LEDs werden nun die Halter modifiziert und aufgeklemmt. Dann werden die Linsen eingerastet.&lt;br /&gt;
&lt;br /&gt;
Nun wird grober Aquarien-Kies gewaschen, gründlich getrocknet und in den Fuß gefüllt. Dabei muss ausreichend Raum für die Halter der großen Abdeckkappe gelassen werden. Diese wird nun aufgepresst. Dann wird der Fuß weiter verfüllt.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Verfüllung Fuß.jpg|200px]]&lt;br /&gt;
&lt;br /&gt;
Jetzt werden noch Steuerelektronik mit 5mm Distanzbuchsen und M3x10 Schrauben montiert. Zum Schluss wird die Frontplatte mit M3x20 Edelstahl Senk-Inbusschrauben und 12mm Distanzbuchsen befestigt.&lt;br /&gt;
&lt;br /&gt;
== Downloads ==&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/martinclausen2/Nachttischlampe.git Link zum Repository für Software, Schaltpläne, Platinen und Mechanik]&lt;br /&gt;
* [[Datei:Hex-File Nachttischlampe.zip|Hex-File jeweils für ZXLD1374 ZXLD1362 V5]]&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[Wake-Up Light]]&lt;br /&gt;
* [[LED-Pendellampe]]&lt;br /&gt;
* [[LED]]&lt;br /&gt;
* Diskussion zu diesem Projekt: http://www.mikrocontroller.net/topic/297859#3182303&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Projekte]]&lt;br /&gt;
[[Kategorie:8051]]&lt;br /&gt;
[[Kategorie:Timer und Uhren]]&lt;/div&gt;</summary>
		<author><name>8023</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=LED-Pendellampe&amp;diff=92352</id>
		<title>LED-Pendellampe</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=LED-Pendellampe&amp;diff=92352"/>
		<updated>2016-03-13T15:27:06Z</updated>

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

		<summary type="html">&lt;p&gt;8023: /* Bezugsquellen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Datei:ESP8266.jpg|thumb|300px|ESP8266, Funkmodul]]&lt;br /&gt;
Das [[ESP8266]] von dem Hersteller Espressif ist ein programmierbarer WLAN-SoC mit [[UART]]- und [[SPI]]-Schnittstelle. &#039;&#039;&#039;WLAN&#039;&#039;&#039;-Funkmodule mit ESP8266 sind ab 3€ verfügbar. Die UART-Schnitttstelle ermöglicht eine einfache Integration in Mikrocontrollerprojekte.&lt;br /&gt;
&lt;br /&gt;
== Spezifikation ==&lt;br /&gt;
Laut Hersteller &amp;lt;ref&amp;gt;[http://espressif.com/en/products/esp8266 &#039;&#039;Herstellerseite -  unter Details&#039;&#039;] Abgerufen am 26. August 2014.&amp;lt;/ref&amp;gt;. :&lt;br /&gt;
* 802.11 b/g/n&lt;br /&gt;
* Wi-Fi Direct (P2P), soft-AP&lt;br /&gt;
* Integrated TCP/IP protocol stack&lt;br /&gt;
* Integrated TR switch, balun, LNA, power amplifier and matching network&lt;br /&gt;
* Integrated PLLs, regulators, DCXO and power management units&lt;br /&gt;
* +19.5dBm output power in 802.11b mode&lt;br /&gt;
* Power down leakage current of &amp;lt;10uA&lt;br /&gt;
* Integrated low power 32-bit CPU could be used as application processor&lt;br /&gt;
* SDIO 1.1/2.0, SPI, UART&lt;br /&gt;
* STBC, 1×1 MIMO, 2×1 MIMO&lt;br /&gt;
* A-MPDU &amp;amp; A-MSDU aggregation &amp;amp; 0.4ms guard interval&lt;br /&gt;
* Wake up and transmit packets in &amp;lt; 2ms&lt;br /&gt;
* Standby power consumption of &amp;lt; 1.0mW (DTIM3)&lt;br /&gt;
* VCC: 3,3V (Achtung: Eingänge sind &#039;&#039;&#039;NICHT 5V TOLERANT&#039;&#039;&#039;!)&lt;br /&gt;
Weiterhin:&lt;br /&gt;
* GPIOs, ADC&lt;br /&gt;
&lt;br /&gt;
=== Datendurchsatz/Performanz ===&lt;br /&gt;
[https://www.mikrocontroller.net/topic/342240?page=single#3857630 Beitrag im Forum mit Tests: TCP: bis zu 7 MBit/s]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://bbs.espressif.com/viewtopic.php?f=7&amp;amp;t=24 Beitrag Espressif-Form: UART loopback: 4.5 Mbps]&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
Bei den chinesischen Modulen mit Firmware 0.9.1 werden Ping Befehle unabhängig von der Paketgröße typischerweise in 30-150ms beantwortet. Datenpakete, die man vom PC aus an das Modul sendet werden unabhängig von der Paketgröße typischerweise nach 100-200ms quittiert.&lt;br /&gt;
&lt;br /&gt;
=== Power-/Sleep-Modes ===&lt;br /&gt;
Der Stromverbrauch des ESP8266 ist abhängig von vielen Faktoren, er läßt sich aber durch geschickte Programmierung durchaus deutlich senken.&amp;lt;br/&amp;gt;&lt;br /&gt;
So ist es nicht notwendig, dass das WIFI-Modem oder der Mikrocontroller ständig läuft um z.B. eine WLAN-Türklingel zu realisieren. Im &amp;quot;Deep-Sleep&amp;quot; würde der ESP8266 dann nur 10uA verbrauchen, bis er über einen GPI-Interrupt geweckt wird und die Meldung absetzt.&amp;lt;br/&amp;gt;&lt;br /&gt;
Zu beachten ist, dass in diesem Moment die WLAN und Netzwerkanmeldung neu startet und hierfür eine gewisse Zeit benötigt wird.&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://bbs.espressif.com/viewtopic.php?f=6&amp;amp;t=133 detailierte Übersicht der verschieden Modi und deren Stromverbrauch von Espressif]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== WLAN-Module mit ESP8266 ==&lt;br /&gt;
Es existieren ca. 11 Varianten von chinesischen Herstellern. Beispielsweise mit PCB- oder Keramik-Antenne oder mit u.fl.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Die Firmware 0.9.1 unterstützt bis zu vier gleichzeitige TCP oder UDP Verbindungen. Sie kann sich in vorhandene WLAN Netze einbuchen, aber auch selbst Access-Point mit DHCP Server sein. Der Access-Point ist zu Android kompatibel (mit 4.1.2 getestet).&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
Die Firmware enthält jedoch keinen Router. Mehrere Computer, die mit dem Modul als Access-Point verbunden sind, können keine Verbindung zueinander aufbauen.&lt;br /&gt;
Das Feature nennt sich AP Isolation.&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
#Produktbeschreibung: [[http://playground.boxtec.ch/doku.php/wireless/esp8266]]&lt;br /&gt;
&lt;br /&gt;
=== Pinbelegung einiger ESP8266-Module ===&lt;br /&gt;
====ESP8266-01====&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
Datei:ESP8266-PinBelegung1.jpg|Pinbelegung - Groß mit PCB-Antenne&lt;br /&gt;
Datei:ESP8266-PinBelegung2.jpg|Pinbelegung - Klein mit Keramik-Antenne&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
Quelle &amp;lt;ref&amp;gt;[http://pan.baidu.com/share/link?shareid=727869034&amp;amp;uk=1900861665 &#039;&#039;Seller Information&#039;&#039;] Abgerufen am 26. August 2014.&amp;lt;/ref&amp;gt;.&lt;br /&gt;
====ESP8266-07====&lt;br /&gt;
Achtung, beim ESP8266-07 Modul sind einige mit vertauschten Beschriftungen von GPIO4 und GPIO5 unterwegs!!.&lt;br /&gt;
&lt;br /&gt;
== Möglichkeiten der Nutzung und Programmierung ==&lt;br /&gt;
===== Benutzung einer Firmware =====&lt;br /&gt;
Verschiedene Projekte betreiben die Entwicklung einer Firmware. Man kann die Firmware &amp;quot;einfach nur&amp;quot; flashen und benutzen oder sich auch aktiv an der Entwicklung beteiligen. Es gibt unter anderem folgende Projekte:&lt;br /&gt;
* AT-Befehle: Firmware, mit welcher das Modul über UART angesprochen wird.&lt;br /&gt;
* Micropython: Firmware, die das Ablaufen von Python Scripts ermöglicht&lt;br /&gt;
* NodeMCU: Firmware, die das Ablaufen von Lua-Scripts ermöglicht ([https://github.com/nodemcu/nodemcu-firmware Github])&lt;br /&gt;
* smartJS: Firmware, die das Ausführen von JavaScript erlaubt ([https://github.com/cesanta/smart.js Github])&lt;br /&gt;
* Arduino core for ESP8266 WiFi chip: Programmierumgebung &amp;amp; Firmware, die das Ausführen von C Programmen ermöglicht, im Stil der bekannten Arduino Plattform. [https://github.com/esp8266/Arduino Github - ink. Anleitung]&lt;br /&gt;
* ESP8266 Basic: Firmware, die das Ausführen von Basic Programmen und das Editieren über WLAN erlaubt [http://www.esp8266basic.com/]&lt;br /&gt;
&lt;br /&gt;
===== Erstellen (Kompilieren) einer Firmware =====&lt;br /&gt;
Für die Erstellung einer individuellen Firmware gibt es zwei Möglichkeiten:&lt;br /&gt;
* Software Development Kit (SDK): Erstellen einer Firmware mit einer GCC-Toolchain&lt;br /&gt;
* Arduino IDE: Erstellen einer Firmware mit einer Arduino IDE&lt;br /&gt;
Projekte, die eine Firmware für das ESP8266 entwickeln (siehe vorheriger Abschnitt), benutzen eine dieser beiden Möglichkeiten.&lt;br /&gt;
&lt;br /&gt;
=== Firmware flashen/updaten ===&lt;br /&gt;
Typischerweise wird eine kompilierte Firmware per UART-Bootloader des ESP8266-SoC auf einen Flash-Chip eines ESP8266-Moduls geladen. Von dort startet der ESP8266-SoC anschließend die Firmware.&lt;br /&gt;
&lt;br /&gt;
[http://bbs.espressif.com/viewtopic.php?f=5&amp;amp;t=433 Flash Download Tool vom Hersteller] &amp;lt;br&amp;gt;&lt;br /&gt;
[http://github.com/themadinventor/esptool Python Tool zum Flashen (von Fredrik Ahlberg)] &amp;lt;br&amp;gt;&lt;br /&gt;
[http://github.com/3s1d/esp_prog Extension zum Tool von Fredrik Ahlberg] &amp;lt;br&amp;gt;&lt;br /&gt;
[http://www.mikrocontroller.net/topic/342240?page=2#3857075 Tool zum Flashen (von Christian Klippel)] &amp;lt;br&amp;gt;&lt;br /&gt;
[http://defcon-cc.dyndns.org/wiki/ESP8266#Update Anleitung, extern] &amp;lt;br&amp;gt;&lt;br /&gt;
[http://www.mikrocontroller.net/topic/342240?page=3#3810559 Anleitung, Forum]&lt;br /&gt;
&lt;br /&gt;
Der Hersteller veröffentlich regelmässig [http://bbs.espressif.com/viewforum.php?f=5 Firmwareupdates] als Bestandteil des esp_iot_sdk. Die Firmware-Dateien befinden sich im Verzeichnis bin. Das Update wird beispielweise für Firmware 0.9.5 folgendermaßen durchgeführt: &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python esptool.py --baud 9600 --port com6 write_flash 0x00000 boot_v1.2.bin 0x01000 at/user1.512.new.bin 0x3e000 blank.bin 0x7e000 blank.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Abhängig von der Flashgröße muß man die Firmware ab Version 1.0.1 selbst compilieren. Siehe Diskussion [http://www.esp8266.com/viewtopic.php?p=16515 hier] und [http://bbs.espressif.com/viewtopic.php?f=16&amp;amp;t=400 hier].&lt;br /&gt;
&lt;br /&gt;
== AT-Befehle für eine Firmware auf Basis des SDK-Beispiels &amp;quot;AT&amp;quot;==&lt;br /&gt;
&lt;br /&gt;
Einstellen des Moduls als AP&lt;br /&gt;
&lt;br /&gt;
Da wir nicht wissen, in welchem Modus sich das Modul gerade befindet, fragen wir diesen ab mit dem &lt;br /&gt;
Befehl AT+CWMODE?  Das Modul antwortet mit &lt;br /&gt;
&lt;br /&gt;
    AT+CWMODE?&amp;lt;\r&amp;gt;&amp;lt;\r&amp;gt;&amp;lt;\n&amp;gt;+CWMODE:1&amp;lt;\r&amp;gt;&amp;lt;\n&amp;gt;&lt;br /&gt;
    &amp;lt;\r&amp;gt;&amp;lt;\n&amp;gt;&lt;br /&gt;
    OK&amp;lt;\r&amp;gt;&amp;lt;\n&amp;gt;&lt;br /&gt;
In diesem Fall ist das Modul aktuell im Modus 1 ( Station) eingestellt. Also ändern wir den Modus auf 2 ( AP)&lt;br /&gt;
mit dem Befehl AT+CWMODE=2. Nach diesem Befehl ist ein Reset des Moduls erforderlich, damit die Änderung &lt;br /&gt;
sichtbar wird. Mit dem Befehl AT+RST führen wir diesen durch. Das Modul startet neu und die Stromaufnahme&lt;br /&gt;
steigt auf ca 80 mA. Das Modul ist jetzt als WLAN AP im Wireless Lan sichtbar. &lt;br /&gt;
&lt;br /&gt;
Jetzt müssen wir noch einstellen, dass wir mehrere Verbindungen gleichzeitig haben wollen und den TCP Server starten und einstellen. Mit dem Befehl AT+CIPMUX=1 sagen wir dem Modul, dass wir mehrere Verbindungen haben wollen. Und mit dem Befehl AT+CIPSERVER=1,2526 starten wir den TCP Server und lassen ihn auf Port 2526 laufen. Sobald sich ein Client verbindet, sendet das Modul &#039;Link&#039; + LF + CR. Beim Trennen einer Verbindung vom Client kommt &#039;Unlink&#039; + LF + CR.&lt;br /&gt;
&lt;br /&gt;
Ab hier können wir uns über einen TCP Socket auf Port 2526 mit dem Modul verbinden und Daten austauschen. Empfangene Daten werden folgendermaßen angezeigt. Gesendet wurde  &amp;quot;Hallo Leute&amp;quot; + LF + CR.&lt;br /&gt;
&lt;br /&gt;
     &amp;lt;\r&amp;gt;&amp;lt;\n&amp;gt;&lt;br /&gt;
     +IPD,0,11:Hallo Leute&amp;lt;\r&amp;gt;&amp;lt;\n&amp;gt;&lt;br /&gt;
     OK&amp;lt;\r&amp;gt;&amp;lt;\n&amp;gt;&lt;br /&gt;
&lt;br /&gt;
+IPD kommt immer, 0 ist die erste Verbindung. Wenn 2 Geräte gleichzeitig eine Verbindung aufgebaut haben, steht dort eine 1. 11 Zeichen wurden empfangen, dann kommen die Daten.&lt;br /&gt;
&lt;br /&gt;
Zum Senden von Daten vom Modul zum Client geht man folgenderweise vor. Erstmal sagen wir dem Modul, wieviele Daten wir an welche Verbindung schicken wollen. Mit dem Befehl AT+CIPSEND=0,5 z. B. sagen wir dem Modul wir möchten 5 Bytes an Verbindung 0 senden. Nach diesem Befehl werden die nächsten 5 Zeichen direkt an die Verbindung weitergereicht.&lt;br /&gt;
Sollte keine aktive Verbindung bestehen, sendet das Modul &lt;br /&gt;
     AT+CIPSEND=0,5&amp;lt;\r&amp;gt;&amp;lt;\r&amp;gt;&amp;lt;\n&amp;gt;link is not&amp;lt;\r&amp;gt;&amp;lt;\n&amp;gt;&lt;br /&gt;
ansonsten kommt &lt;br /&gt;
     &amp;lt;\r&amp;gt;&amp;lt;\n&amp;gt; &amp;gt;&lt;br /&gt;
und man kann Daten senden. Nach dem absenden der Daten &#039;Leute&#039; + LF + CR sendet das Modul &lt;br /&gt;
    Leute&amp;lt;\r&amp;gt;&amp;lt;\r&amp;gt;&amp;lt;\n&amp;gt;busy&amp;lt;\r&amp;gt;&amp;lt;\n&amp;gt;&lt;br /&gt;
    &amp;lt;\r&amp;gt;&amp;lt;\n&amp;gt;&lt;br /&gt;
    busy&amp;lt;\r&amp;gt;&amp;lt;\n&amp;gt;&lt;br /&gt;
    &amp;lt;\r&amp;gt;&amp;lt;\n&amp;gt;&lt;br /&gt;
    SEND OK&amp;lt;\r&amp;gt;&amp;lt;\n&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Einstellen des Moduls als Station&lt;br /&gt;
&lt;br /&gt;
== Software Development Kit (SDK) ==&lt;br /&gt;
Mit dem SDK können eigene Applikationen programmiert und die im SDK vorhandenen Beispiele &amp;quot;AT&amp;quot; und &amp;quot;IoT&amp;quot; verändert werden. Das SDK wird vom Hersteller zur Verfügung gestellt (Stand 25.10.2014). Passend zum SDK existiert eine virtuelle Maschine mit eingerichtetem gcc zum Kompilieren. Insbesondere der nun verfügbare gcc basiert auf einer Community-Entwicklung.&lt;br /&gt;
&lt;br /&gt;
[http://bbs.espressif.com/viewforum.php?f=5&amp;amp;sid=3cf7540ab17805367e6a45d2c4682fc9 SDK0.9.2 + virtuelle Linuxmaschine mit eingerichtetem gcc]&lt;br /&gt;
&lt;br /&gt;
[https://drive.google.com/folderview?id=0B5bwBE9A5dBXaExvdDExVFNrUXM&amp;amp;usp=sharing Alternativlink für die virtuelle Maschine + Anleitung/HOWTO für das Setup sowie für das Kompilieren]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Anmerkung ===&lt;br /&gt;
Mit dem SDK wird der Mikrocontroller progammiert, der sich direkt auf dem ESP8266-SoC-Chip befindet. Dies ist nicht zu verwechseln mit Programmieranleitungen zur UART-Ansteuerung des ESP8266-SoC (meist mit AT-Firmware) mit einem anderen Mikrocontroller.&lt;br /&gt;
&lt;br /&gt;
==Checkliste bei Problemen mit dem Modul/Compiler/SDK==&lt;br /&gt;
Bitte berücksichtige bei der Frage nach Hilfestellung zu Deinem Problem die folgende Checkliste.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bei Problemen mit der AT-Firmware/UART-Ansteuerung mit Mikrocontroller&#039;&#039;&#039;&lt;br /&gt;
# Was nutzt Du für die Stromversorgung?&amp;lt;br/&amp;gt;(Ganz knapp benennen, so dass Rückschlüsse auf Spannung und Stromstärke möglich sind)&lt;br /&gt;
# Welche Firmware-Version verwendest Du und von woher hast Du sie?&lt;br /&gt;
# Welchen Mikrocontroller verwendest Du?&lt;br /&gt;
# Welche Baudrate verwendest Du?&lt;br /&gt;
# &amp;quot;Sieht&amp;quot; das Modul den AP, &amp;quot;sieht&amp;quot; der PC das Modul?&lt;br /&gt;
# Funktioniert ein Connect?&lt;br /&gt;
# Welche AT-Befehlssequenz verwendest Du und was antwortet das Modul?&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bei Problemen mit dem SDK/Compiler&#039;&#039;&#039;&lt;br /&gt;
# Benutzt Du die neuste, offizielle VM?&amp;lt;br/&amp;gt;(Diese ist ausgelegt für das neueste SDK)&lt;br /&gt;
# Benutzt Du das neueste, offizielle SDK? Welche Version benutzt Du?&amp;lt;br/&amp;gt;(Es werden regelmäßig Bugfixes und Erweiterungen eingepflegt)&lt;br /&gt;
# Kannst Du die SDK-Beispiele (IoT,AT) entsprechend der offiziellen Anleitung kompilieren, flashen und läuft es?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
[https://en.wikipedia.org/wiki/ESP8266 ESP8266-Eintrag auf en.wikipedia.org]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.esp8266.com/ ESP8266 Community Forum]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://github.com/esp8266 ESP8266 Github mit Wiki und Source-Code Samples]&amp;lt;br/&amp;gt;&lt;br /&gt;
[https://hackaday.com/tag/esp8266/ Hackaday Posts zu ESP8266]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://espressif.com/en/products/esp8266/ ESP8266-Seite des Herstellers]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://bbs.espressif.com/ ESP8266-Forum des Herstellers]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://www.mikrocontroller.net/topic/348772 Topic neu im mikrocontroller.net-Forum]&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[http://www.mikrocontroller.net/topic/342240 Topic alt im mikrocontroller.net-Forum]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.mikrocontroller.net/topic/342878 Sammelbestellungen im mikrocontroller.net-Forum]&lt;br /&gt;
&lt;br /&gt;
[http://blog.thomasheldt.de/ Viele Projekte und Informationen zum ESP8266]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://stefanfrings.de/wlan_io/ Projekt I/O Schnittstellen Modul mit WLAN]&lt;br /&gt;
&lt;br /&gt;
=== Dokumente === &lt;br /&gt;
[http://neilkolban.com/tech/esp8266/ Kolban’s book on the ESP8266] Sehr empfehlenswert!&amp;lt;br/&amp;gt;&lt;br /&gt;
[https://drive.google.com/folderview?id=0B5bwBE9A5dBXaExvdDExVFNrUXM&amp;amp;usp=sharing Anleitung/HOWTO für das Setup der virtuellen Maschine (SDK) sowie für das Kompilieren]&amp;lt;br/&amp;gt;&lt;br /&gt;
[https://nurdspace.nl/ESP8266 Übersetztes Datenblatt]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://www.electrodragon.com/w/Wi07c AT Instructions Set (English)] und [http://www.electrodragon.com/w/Wi07c#First_time_use_guide Anleitung zum Betrieb an einem Arduino (inkl. Code)]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://thomaspfeifer.net/esp8266_wlan_seriell_modul_at_kommandos.htm Beschreibung der AT-Kommandos mit Beispielen]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.mikrocontroller.net/attachment/229016/Espressif_IoT_AT____v0.1.5.906.pdf Espressif AT Instruction Set(Chinese)]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.seeedstudio.com/document/pdf/ESP8266%20Specifications(Chinese).pdf ESP8266 Specifications(Chinese)]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://nodemcu.readthedocs.org/en/dev/ NodeMCU Documentation]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://cknodemcu.wordpress.com/2015/11/24/building-an-iot-node-for-less-than-15/ Building an IoT Node for less than 15$] (Paper, Kindle via Amazon)&lt;br /&gt;
&lt;br /&gt;
===Daten===&lt;br /&gt;
[http://bbs.espressif.com/viewforum.php?f=5&amp;amp;sid=3cf7540ab17805367e6a45d2c4682fc9 SDK0.9.2 + virtuelle Linuxmaschine mit eingerichtetem gcc]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://drive.google.com/folderview?id=0B5bwBE9A5dBXaExvdDExVFNrUXM&amp;amp;usp=sharing Alternativlink für die virtuelle Maschine]&amp;lt;br/&amp;gt;&lt;br /&gt;
[https://onedrive.live.com/#cid=C4DDF72E6EEA3826&amp;amp;id=C4DDF72E6EEA3826%21631 Dateien (Xplorer+SDK+PDF+etc.)]&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.mikrocontroller.net/attachment/230185/esp8266_config_v050.exe Config-Tool] &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bezugsquellen ===&lt;br /&gt;
[http://espressif.com/en/company/contact/buy-a-sample/ Offizieller Espressif Vertriebskanal] (Sample Purchase)&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.aliexpress.com/wholesale?SearchText=ESP8266 aliexpress.com] ~ 2€&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.banggood.com/?zf=283997 banggood.com] ~ 3.50€&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.ebay.de/ Ebay]&lt;br /&gt;
ab 3€ inkl. Versand, Einzelstückpreis: ESP-01/02/03/04/05&amp;lt;br/&amp;gt;&lt;br /&gt;
(Suchbegriff: ESP8266, Option Artikelstandort: &amp;quot;Weltweit&amp;quot;)&amp;lt;br/&amp;gt;&lt;br /&gt;
(10 Stück ab 27 EUR inkl. Versand; Suchbegriff: 10pcs ESP8266)&amp;lt;br/&amp;gt;&lt;br /&gt;
ab 3.20€ inkl. Versand, Einzelstückpreis: ESP-07/08/09/11&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.electrodragon.com/?s=esp8266&amp;amp;post_type=product electrodragon.com] ~ 3.50€ (zzgl. Versand)&amp;lt;br/&amp;gt;&lt;br /&gt;
[https://ex-store.de/advanced_search_result.php?keywords=esp8266&amp;amp;x=0&amp;amp;y=0 eX-store.de] (ESP-01/02/03/05/07/12/13) ab 3.35€ (zzgl. Versand)&amp;lt;br/&amp;gt;&lt;br /&gt;
[https://www.it-wns.de/themes/suche/index.php?suchekategorie=&amp;amp;sucheallgemein=esp8266 IT-WNS.de] (ESP-01/02/03/06/07/12E) je 3.99€ (zzgl. Versand)&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.seeedstudio.com/depot/WiFi-Serial-Transceiver-Module-w-ESP8266-p-1994.html seeedstudio.com] ~ 5.50€&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://shop.in-circuit.de/index.php?cPath=21 In-Circuit.de] ESP-ADC DIL Modul mit ESP8266EX 9.90€ Einzelpreis&amp;lt;br/&amp;gt;&lt;br /&gt;
[http://www.watterott.com/index.php?page=search&amp;amp;desc=off&amp;amp;sdesc=off&amp;amp;keywords=ESP8266 watterott.com] ab ~ 4€ (zzgl. Versand)&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Anderes==&lt;br /&gt;
*[http://www.mikrocontroller.net/articles/ESP8266-CPCB PCB für Community-Modul (Vorschlag)]&lt;br /&gt;
*[http://fkainka.de/esp8266-in-der-arduino-ide/ ESP8266 mit Arduino IDE programmieren]&lt;br /&gt;
*[http://www.arduinesp.com Arduino IDE Integration (ab 1.6.x)]&lt;br /&gt;
*[https://cknodemcu.wordpress.com/ NodeMCU (Lua) Anwendungen]&lt;br /&gt;
&lt;br /&gt;
== Einzelnachweise ==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--von [[axhieb]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Bauteile]]&lt;br /&gt;
[[Kategorie:Funk]]&lt;br /&gt;
[[Kategorie:Wlan]]&lt;/div&gt;</summary>
		<author><name>8023</name></author>
	</entry>
</feed>