<?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=87.178.118.194</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=87.178.118.194"/>
	<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/articles/Spezial:Beitr%C3%A4ge/87.178.118.194"/>
	<updated>2026-04-11T01:28:02Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=FIFO&amp;diff=90822</id>
		<title>FIFO</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=FIFO&amp;diff=90822"/>
		<updated>2015-12-28T22:53:58Z</updated>

		<summary type="html">&lt;p&gt;87.178.118.194: hierarchie&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein FIFO (&amp;lt;b&amp;gt;F&amp;lt;/b&amp;gt;irst-&amp;lt;b&amp;gt;I&amp;lt;/b&amp;gt;n-&amp;lt;b&amp;gt;F&amp;lt;/b&amp;gt;irst-&amp;lt;b&amp;gt;O&amp;lt;/b&amp;gt;ut) ist ein Pufferspeicher nach dem &amp;quot;Warteschlangen-Prinzip&amp;quot;. Pufferspeicher dienen dazu, Daten aufzufangen, die noch nicht sofort verarbeitet werden können. Ein FIFO funktioniert definitionsgemäß so, dass das erste Element (First In), welches &amp;quot;hinten&amp;quot; in die Warteschlange eingefügt wird, später auch als erstes &amp;quot;vorne&amp;quot; herausgeholt wird (First Out). Das Gegenstück zum FIFO ist [[LIFO]].&lt;br /&gt;
&lt;br /&gt;
== Funktion ==&lt;br /&gt;
Ein bekanntes Beispiel für einen FIFO-Speicher ist der des [[UART]]s im PC. Dieser sammelt ankommende Daten solange, bis er fast voll ist (meist 14 Bytes). Dann wird ein [[Interrupt]] ausgelöst und der Prozessor kann &amp;quot;auf einen Rutsch&amp;quot; alle Daten auf einmal schnell auslesen. Ganz am Anfang hatten UARTs keinen FIFO und erzeugten für jedes empfangene Byte einen Interrupt, so wie es heute noch die meisten Mikrocontroller machen. Damit ist aber die CPU-Belastung wesentlich höher, was bei höheren Datenraten zu Problemen führen kann. In Senderichtung ist das Problem auch vorhanden, wenn gleich unkritischer. Mit einem FIFO kann die CPU sehr viele Dutzende bis Hunderte Bytes in sehr kurzer Zeit (wenige Dutzend Mikrosekunden) hineinschreiben, welche dann relativ langsam mittels [[Interrupt]] Byte für Byte mit dem UART gesendet werden. Die CPU muss nicht warten, bis jedes einzelne Zeichen versendet wurde. Zum Vergleich. Ein AVR mit 16 MHz Takt macht während der Übertragung von 1 Byte bei 115200 Baud (86,8us) 1389 CPU-Takte. Damit kann man sehr viel anstellen! Bei schnelleren CPUs bzw. niedrigeren Baudraten ist das Mißverhältnis noch deutlich größer. Im Idealfall werden die Daten aus dem FIFO mittels [[DMA]] an den UART übertragen, dann hat der Prozessor gar nichts mehr damit zu tun.&lt;br /&gt;
&lt;br /&gt;
Die Umsetzung eines FIFOs in Software heißt Ringpuffer und weist auch eine feste Puffergröße auf. Wesentlicher Vorteil gegenüber der verketteten Liste ist die schnellere Ausführungszeit und der geringere Aufwand.&lt;br /&gt;
&lt;br /&gt;
== Standard-Ringpuffer ==&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* Simpel&lt;br /&gt;
* Leicht verständlich&lt;br /&gt;
* Daten können auch vom Typ struct sein&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* Schnell aber nicht optimal&lt;br /&gt;
&lt;br /&gt;
=== Beschreibung ===&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Ringpuffer.png|300px]]&lt;br /&gt;
|&lt;br /&gt;
[[Bild:Circular buffer.png|200px]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Die Inhalte des Puffers werden in einem schlichten Array gespeichert und der Zugriff erfolgt über einen Integer-Index. Erreicht ein Index die Obergrenze springt dieser auf Null zurück. Topologisch ist dies äquivalent zu einem Ringschluss, bei dem man ja auch nach dem letzten Element wieder beim ersten angelangt ist. Man denke zb an das Zifferblatt einer Uhr, bei der nach der 59 wieder die 0 kommt. Ein größer-gleich statt nur eines ist-gleich Vergleichs ist sicherer gegenüber Programmfehlern, bei denen der Index verstellt wurde.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
write = write + 1;&lt;br /&gt;
if (write &amp;gt;= BUFFER_SIZE)&lt;br /&gt;
  write = 0;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Haben Lese- und Schreib-Index den gleichen Wert wird der Puffer als leer angesehen und es kann kein Element aus dem Puffer entnommen werden. Wenn write+1 und read identisch sind wird der Puffer als voll angesehen und es kann kein weiteres Element mehr im Puffer gespeichert werden. Nun fehlt noch der Sonderfall bei dem read gleich Null ist, hier funktioniert der write+1-Vergleich nicht mehr (wegen dem &#039;Überlauf&#039; am Ende des Arrays, der den Ringschluss bewirkt) und die Abfrage einer zusätzlichen Bedingung ist zur Voll-Abfrage erforderlich.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
read == write =&amp;gt; leer&lt;br /&gt;
write + 1 == read || read == 0 &amp;amp;&amp;amp; write+1 == BUFFER_SIZE =&amp;gt; voll&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Bei gleichzeitigem Zugriff zwischen dem Befüller (zb. einer [[Interrupt#UART_mit_Interrupts | UART-ISR]]) und dem Entnahmecode (zb. der Code in der Hauptschleife) muss ausgeschlossen werden, dass der Entnahmecode beim Lesen aus dem Puffer nicht durch den Interrupt unterbrochen werden kann. Denn während diese Funktion läuft, ist zwischenzeitlich der read-Index in einem inkonsistenten Zustand. Erst nach Beendigung der Funktion spiegelt der read-Index wieder die Realität des Füllgrades wieder. Als Abhilfe dienen [[Interrupt#Atomarer_Datenzugriff|Atomare Abschnitte]], solche können durch keinen Interrupt unterbrochen werden. Die Radialkur deaktiviert alle Interrupts, besser ist die Deaktivierung eines einzelnen Interrupts. Es geht aber meistens auch so, da die FIFO-Funktionen sehr kurz sind und daher auch die Interrupts nur kurz abgeschaltet werden. Im Allgemeinen werden versäumte Interrupts nach erneuter Aktivierung nachgeholt und gehen nicht verloren, so dass bereits anstehende Interrupts nur kurz verzögert werden. Solange die Interruptperiodendauer größer als die Ausführungsgeschwindigkeit der FIFO Funktionen ist, stellt das Abschalten der Interrupts daher auch in der Praxis meist kein allzugroßes Problem dar.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
cli()&lt;br /&gt;
ret = BufferOut(&amp;amp;var);&lt;br /&gt;
sei()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hilfreich ist die Initialisierung der Indizes (read, write) mit -1, denn damit kann man einen leere Ringpuffer von einem vollen unterscheiden. Initialisiert man nur mit 0, kann man einen leeren nicht von einem vollen mit read=write=0 unterscheiden. &lt;br /&gt;
&lt;br /&gt;
Eine weitere Möglichkeit der Vereinfachung entsteht durch die Einführung einer &amp;quot;Counter&amp;quot; Variable, die den Füllstand des Buffers wiedergibt. Bei Einschreiben wird diese um +1 erhöht, beim Auslesen um 1 erniedrigt. Ist sie 0 ist der Buffer leer. Damit lässt sich die Codeeffizienz steigern, da die obigen Vergleiche kürzer ausfallen und sich auf nur diese eine Variable beschränken. Nachteilig ist allerdings, dass man eine weitere Variable im System hat und natürlich benötigen die entsprechenden Operationen zum Erhöhen bzw. Erniedrigen dieser Variable ja auch Ausführungszeit. Benötigt man im restlichen Code den Füllgrad der FIFO nicht als explizite Zahl, dann lohnt daher eine derartige Counter-Variable meistens nicht.&lt;br /&gt;
&lt;br /&gt;
=== Code-Beispiel ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BUFFER_FAIL     0&lt;br /&gt;
#define BUFFER_SUCCESS  1&lt;br /&gt;
&lt;br /&gt;
#define BUFFER_SIZE 23&lt;br /&gt;
&lt;br /&gt;
struct Buffer {&lt;br /&gt;
  uint8_t data[BUFFER_SIZE];&lt;br /&gt;
  uint8_t read; // zeigt auf das Feld mit dem ältesten Inhalt&lt;br /&gt;
  uint8_t write; // zeigt immer auf leeres Feld&lt;br /&gt;
} buffer = {{}, 0, 0};&lt;br /&gt;
&lt;br /&gt;
//&lt;br /&gt;
// Stellt 1 Byte in den Ringbuffer&lt;br /&gt;
//&lt;br /&gt;
// Returns:&lt;br /&gt;
//     BUFFER_FAIL       der Ringbuffer ist voll. Es kann kein weiteres Byte gespeichert werden&lt;br /&gt;
//     BUFFER_SUCCESS    das Byte wurde gespeichert&lt;br /&gt;
//&lt;br /&gt;
uint8_t BufferIn(uint8_t byte)&lt;br /&gt;
{&lt;br /&gt;
  //if (buffer.write &amp;gt;= BUFFER_SIZE)&lt;br /&gt;
  //  buffer.write = 0; // erhöht sicherheit&lt;br /&gt;
&lt;br /&gt;
  if ( ( buffer.write + 1 == buffer.read ) ||&lt;br /&gt;
       ( buffer.read == 0 &amp;amp;&amp;amp; buffer.write + 1 == BUFFER_SIZE ) )&lt;br /&gt;
    return BUFFER_FAIL; // voll&lt;br /&gt;
&lt;br /&gt;
  buffer.data[buffer.write] = byte;&lt;br /&gt;
&lt;br /&gt;
  buffer.write++;&lt;br /&gt;
  if (buffer.write &amp;gt;= BUFFER_SIZE)&lt;br /&gt;
    buffer.write = 0;&lt;br /&gt;
&lt;br /&gt;
  return BUFFER_SUCCESS;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//&lt;br /&gt;
// Holt 1 Byte aus dem Ringbuffer, sofern mindestens eines abholbereit ist&lt;br /&gt;
//&lt;br /&gt;
// Returns:&lt;br /&gt;
//     BUFFER_FAIL       der Ringbuffer ist leer. Es kann kein Byte geliefert werden.&lt;br /&gt;
//     BUFFER_SUCCESS    1 Byte wurde geliefert&lt;br /&gt;
//    &lt;br /&gt;
uint8_t BufferOut(uint8_t *pByte)&lt;br /&gt;
{&lt;br /&gt;
  if (buffer.read == buffer.write)&lt;br /&gt;
    return BUFFER_FAIL;&lt;br /&gt;
&lt;br /&gt;
  *pByte = buffer.data[buffer.read];&lt;br /&gt;
&lt;br /&gt;
  buffer.read++;&lt;br /&gt;
  if (buffer.read &amp;gt;= BUFFER_SIZE)&lt;br /&gt;
    buffer.read = 0;&lt;br /&gt;
&lt;br /&gt;
  return BUFFER_SUCCESS;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== FIFO als Bibliothek ===&lt;br /&gt;
&lt;br /&gt;
Hier sollen FIFO-Funktionen bereitgestellt werden, welche folgende Eigenschaften besitzen.&lt;br /&gt;
&lt;br /&gt;
* Mehrfache FIFOs einfach anlegen und benutzen&lt;br /&gt;
* Leistungsfähiger Zugriff auf FIFO-Daten (Blockzugriff)&lt;br /&gt;
* Interruptfester FIFO-Zugriff&lt;br /&gt;
&lt;br /&gt;
Diese FIFOs sind auf so ziemlich allen Plattformen nutzbar, entwickelt wurde sie jedoch auf einem AVR. Daher ist im FIFO im Moment auch noch eine Begrenzung der FIFO-Größe auf 64kiB vorhanden, welche aber leicht per typedef in fifo.h abgeändert werden kann. Ebenso kann die Größe der FIFO-Elemente eingestellt werden (8, 16, 32 Bit, ebenfalls structs). Alle FIFO-Funktionen sind interruptsicher aufgebaut, d.h. die kritschen Zugiffe auf die FIFO-Kontrolldaten erfolgen [[Interrupt#Atomarer_Datenzugriff | atomar]]. Damit ist der Einsatz im Hauptprogramm und in [[Interrupt]]s sicher möglich. Bei anderen Plattformen muss ggf. der atomare Zugriff angepasst werden. Der Datenzugriff erfolgt direkt über Pointer, das erhöht die Geschwindigkeit gegenüber Indexoperationen. Die folgenden Funktionen sind im wesentlichen verfügbar:&lt;br /&gt;
&lt;br /&gt;
* fifo_init(): FIFO initialisieren&lt;br /&gt;
* fifo_write_busy(): wartet bis mindesten 1 Element im FIFO frei ist und schreibt es in den FIFO&lt;br /&gt;
* fifo_write(): schreibt ein Element in den FIFO, ohne Prüfung ob genügend Platz vorhanden ist&lt;br /&gt;
* fifo_read_busy(): wartet bis mindesten 1 Element im FIFO vorhanden ist und liest es aus dem FIFO&lt;br /&gt;
* fifo_read(): liest ein Element es aus dem FIFO, ohne Prüfung ob Daten vorhanden sind&lt;br /&gt;
* fifo_get_level(): liefert die Anzahl der Elemente im FIFO zurück&lt;br /&gt;
* fifo_get_free(): liefert die Anzahl der noch frei verfügbaren Elemente im FIFO zurück&lt;br /&gt;
&lt;br /&gt;
Die Funktionen fifo_write_busy() und fifo_read_busy() warten solange vor dem FIFO-Zugriff, bis Speicher bzw. Daten im FIFO verfügbar sind. Das kann bisweilen lange dauern (blockierende Funktionen).&lt;br /&gt;
Die Funktionen fifo_write() und fifo_read() greifen ohne weitere Prüfung auf den FIFO zu. Die Prüfung muss vorher erfolgen. Damit ist eine nicht blockierende Arbeitsweise möglich ([[Multitasking]]).&lt;br /&gt;
&lt;br /&gt;
==== Leistungsverbesserung ====&lt;br /&gt;
&lt;br /&gt;
Die Funktionen zum Lesen und Schreiben einzelner Elemente sind einfach und klar. Aber was ist, wenn man mehrere Elemente aus dem FIFO lesen will? Oder noch viel schlimmer, wenn Bibliotheksfunktionen mehrere Elemente über einen Zeiger lesen wollen? Hier kommen die restlichen Funktionen ins Spiel.&lt;br /&gt;
&lt;br /&gt;
* fifo_write_bursted(): korrigiert den Schreibzeiger des FIFOs nach einem Blockzugriff&lt;br /&gt;
* fifo_read_bursted(): korrigiert den Lesezeiger des FIFOs nach einem Blockzugriff&lt;br /&gt;
&lt;br /&gt;
D.h. eine Funktion wie z.B. memcpy() liest eine Anzahl X Bytes aus dem FIFO und kopiert sie woanders hin. Danach wird der Lesezeiger um die Anzahl X korrigiert. Damit muss nicht X mal die Funktion fifo_read() aufgerufen werden, was deutlich an CPU-Leistung spart. Ein derartiger Blockzugriff spart auch Zwischenspeicher, wenn z.B. eine Funktion zum Schreiben von Daten auf SD-Karte direkt auf diese zugreifen kann, ohne dass sie weiß, dass diese in einem FIFO stecken!&lt;br /&gt;
&lt;br /&gt;
Doch Vorsicht, so einfach ist es nicht! Denn unser FIFO ist ein Ringpuffer! Am Ende des Datenbereichs muss der Schreib- bzw. Lesezeiger immer wieder auf den Anfang des Datenbereichs zurück springen. Allerdings wissen Funktionen wie memcpy() und andere nichts von einem Ringpuffer! Sie erwarten die Daten immer in linearer Anordnung im Speicher. D.h. man muss vor einem Blocktransfer immer erst prüfen, ob die gewünschte Menge Daten linear an einem Stück im FIFO liegt oder ob zwischendrin ein Überlauf des Schreib- oder Lesezeiger statt findet. In diesem Fall muss man den Blockzugriff auf zwei Zugriffe aufteilen. Dazu dienen die beiden Funktionen&lt;br /&gt;
&lt;br /&gt;
*fifo_get_read_wrap(): liefert die Anzahl Elemente bis zu Überlauf des Lesezeigers&lt;br /&gt;
*fifo_get_write_wrap(): liefert die Anzahl Elemente bis zu Überlauf des Schreibzeigers&lt;br /&gt;
&lt;br /&gt;
Die Anwendung aller Funktionen ist in einem kurzen Beispielprogramm demonstriert und mit Doxygen dokumentiert (/doxygen/html/index.html). Dabei ist vor allem zu beachten, dass die Funktionen des FIFOs immer mit der Anzahl von Elementen arbeiten, wogegen viele andere Funktionen mit der Anzahl von Bytes arbeiten. Die kleine Bibliothek ist als [[media: fifo.zip | Archiv]] verfügbar. Für die Simulation muss man die Optimierung des Compilers ausschalten, um alle Variablen anzeigen zu können.&lt;br /&gt;
&lt;br /&gt;
== 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt;-Ringpuffer - die schnellste Lösung ==&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* Durch Bitmaske auf den Feld-Index &#039;&#039;write&#039;&#039; kann der nicht &amp;quot;Amoklaufen&amp;quot; und beliebige Inhalte im Speicher überschreiben&lt;br /&gt;
* Sehr einfach, sehr schnell&lt;br /&gt;
Nachteile:&lt;br /&gt;
* Nur Größenfaktoren von 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt; möglich&lt;br /&gt;
* Nur in speziellen Fällen Pointerreferenz möglich&lt;br /&gt;
&lt;br /&gt;
=== Beschreibung ===&lt;br /&gt;
&lt;br /&gt;
Wenn der Index am oberen Ende angekommen ist springt er an den Anfang zurück. Die Definition der Obergrenze wird nicht durch einen Vergleich realisiert, sondern durch Modulo-Arithmetik. Dies kann sehr einfach und schnell durch Maskieren des Index-Werts umgesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
( write + 1 ) &amp;amp; MASK&lt;br /&gt;
&lt;br /&gt;
15 = 0b00001111&lt;br /&gt;
15 + 1 = 16 = 0b000010000&lt;br /&gt;
16 &amp;amp; MASK = 0b000010000 &amp;amp; 0b000001111 = 0b000000000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Daraus folgt das &#039;&#039;write&#039;&#039; nur einen Wert zwischen 0 und 15 einnehmen kann. Das ganze funktioniert nur mit Zahlen der Reihe 2&amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Da der Puffer nur eine endliche Größe aufweist, muss eine voll/leer Indikation verfügbar sein. read == write bedeutet Puffer leer, entsprechend bedeutet write + 1 == read, dass keine weiteren Elemente mehr hinzugefügt werden können, denn sonst würde das Hinzufügen weiterer Daten einen Pufferüberlauf hervorrufen. Für die Behandlung des Pufferüberlaufs gibt es zwei Methoden, nichts tun und Fehler zurück geben oder ältesten Puffer-Inhalt verwerfen (read+1).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
read == ((write + 1) &amp;amp; MASK)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier verhindert die Bitmaske einen möglichen Überlauf. Weiter zu beachten ist, dass ein Byte durch die voll/leer Indikation verloren geht, der Puffer hat hier nur eine größe von 15 statt 16 Byte&lt;br /&gt;
&lt;br /&gt;
Und noch ein kleiner Trick. Bei einer Zahl der Reihe 2^n lässt sich auf einfache Weise immer eine passende Bitmaske erzeugen und man sieht gleichzeitig klar die Anzahl der genutzten Bytes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
# define SIZE 16&lt;br /&gt;
# define MASK (SIZE-1)&lt;br /&gt;
&lt;br /&gt;
16     = 0b010000&lt;br /&gt;
16 - 1 = 0b001111&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Normalbetrieb sollte der Puffer nie voll ausgereizt sein und wenn der Puffer bereits überläuft ist es für die Systemstabilität und Fehleranlyse oft schon zu spät, denn von einem nicht mehr funktionierenden Gerät lässt sich nur wenig Information herauskitzeln. Da kann ein Frühwarnsystem mehr bieten, wobei zwei Ausprägungen typisch sind, Höchstwert merken und eine Meldeschwelle einführen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 freeMemory =  (read - write - 1 ) &amp;amp; MASK);&lt;br /&gt;
 if (freeMemory &amp;lt; floodmark)&lt;br /&gt;
   floodmark = freeMemory;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 if ( (read - write - 1 ) &amp;amp; MASK) &amp;lt;= FLOODMARK;&lt;br /&gt;
   FloodmarkExcess();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine entsprechende Auswertung kann z.B. bei einer UART zur Steuerung des Handshakes benutzt werden, bei dem die Gegenstelle aufgefordert wird, das Senden kurzfristig einzustellen, damit man nicht Gefahr läuft, übertragene Zeichen zu verlieren, weil die FIFO voll wird. Dabei ist allerdings auch zu berücksichtigen, dass die Gegenstelle das Senden nicht sofort einstellen kann, da sich beispielsweise bereits Zeichen in der Sendehardware befinden können, die der Sender nicht mehr stoppen kann. Hier heißt es also rechtzeitig zu reagieren und nicht erst, wenn der FIFO propevoll ist. Fällt der Füllgrad einer darartigen UART-FIFO wieder unter eine gewisse Schwelle, dann wird der Gegenstelle signalisiert, dass sie mit dem Senden fortfahren kann.&lt;br /&gt;
&lt;br /&gt;
=== Code-Beispiel ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define BUFFER_FAIL     0&lt;br /&gt;
#define BUFFER_SUCCESS  1&lt;br /&gt;
 &lt;br /&gt;
#define BUFFER_SIZE 16 // muss 2^n betragen (8, 16, 32, 64 ...)&lt;br /&gt;
#define BUFFER_MASK (BUFFER_SIZE-1) // Klammern auf keinen Fall vergessen&lt;br /&gt;
&lt;br /&gt;
struct Buffer {&lt;br /&gt;
  uint8_t data[BUFFER_SIZE];&lt;br /&gt;
  uint8_t read; // zeigt auf das Feld mit dem ältesten Inhalt&lt;br /&gt;
  uint8_t write; // zeigt immer auf leeres Feld&lt;br /&gt;
} buffer = {{}, 0, 0};&lt;br /&gt;
&lt;br /&gt;
//&lt;br /&gt;
// Stellt 1 Byte in den Ringbuffer&lt;br /&gt;
//&lt;br /&gt;
// Returns:&lt;br /&gt;
//     BUFFER_FAIL       der Ringbuffer ist voll. Es kann kein weiteres Byte gespeichert werden&lt;br /&gt;
//     BUFFER_SUCCESS    das Byte wurde gespeichert&lt;br /&gt;
//&lt;br /&gt;
uint8_t BufferIn(uint8_t byte)&lt;br /&gt;
{&lt;br /&gt;
  uint8_t next = ((buffer.write + 1) &amp;amp; BUFFER_MASK);&lt;br /&gt;
&lt;br /&gt;
  if (buffer.read == next)&lt;br /&gt;
    return BUFFER_FAIL; // voll&lt;br /&gt;
&lt;br /&gt;
  buffer.data[buffer.write] = byte;&lt;br /&gt;
  // buffer.data[buffer.write &amp;amp; BUFFER_MASK] = byte; // absolut Sicher&lt;br /&gt;
  buffer.write = next;&lt;br /&gt;
&lt;br /&gt;
  return BUFFER_SUCCESS;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//&lt;br /&gt;
// Holt 1 Byte aus dem Ringbuffer, sofern mindestens eines abholbereit ist&lt;br /&gt;
//&lt;br /&gt;
// Returns:&lt;br /&gt;
//     BUFFER_FAIL       der Ringbuffer ist leer. Es kann kein Byte geliefert werden.&lt;br /&gt;
//     BUFFER_SUCCESS    1 Byte wurde geliefert&lt;br /&gt;
//&lt;br /&gt;
uint8_t BufferOut(uint8_t *pByte)&lt;br /&gt;
{&lt;br /&gt;
  if (buffer.read == buffer.write)&lt;br /&gt;
    return BUFFER_FAIL;&lt;br /&gt;
&lt;br /&gt;
  *pByte = buffer.data[buffer.read];&lt;br /&gt;
&lt;br /&gt;
  buffer.read = (buffer.read+1) &amp;amp; BUFFER_MASK;&lt;br /&gt;
&lt;br /&gt;
  return BUFFER_SUCCESS;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== FIFO mit C-Präprozessor ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#ifndef FIFO_H_&lt;br /&gt;
#define FIFO_H_&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
typedef struct {&lt;br /&gt;
        uint8_t _read;&lt;br /&gt;
        uint8_t _write;&lt;br /&gt;
        uint8_t _buffer[64];&lt;br /&gt;
} FIFO64_t;&lt;br /&gt;
&lt;br /&gt;
typedef struct {&lt;br /&gt;
        uint8_t _read;&lt;br /&gt;
        uint8_t _write;&lt;br /&gt;
        uint8_t _buffer[128];&lt;br /&gt;
} FIFO128_t;&lt;br /&gt;
&lt;br /&gt;
#define FIFO_init(fifo)         { fifo._read = 0; fifo._write = 0; }&lt;br /&gt;
&lt;br /&gt;
#define FIFO_available(fifo)    ( fifo._read != fifo._write )&lt;br /&gt;
&lt;br /&gt;
#define FIFO_read(fifo, size) (                                         \&lt;br /&gt;
        (FIFO_available(fifo)) ?                                        \&lt;br /&gt;
        fifo._buffer[fifo._read = (fifo._read + 1) &amp;amp; (size-1)] : 0      \&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
#define FIFO_write(fifo, data, size) {                                                          \&lt;br /&gt;
        uint8_t tmphead = ( fifo._write + 1 ) &amp;amp; (size-1);       /* calculate buffer index */    \&lt;br /&gt;
        if(tmphead != fifo._read) {                             /* if buffer is not full */     \&lt;br /&gt;
                fifo._buffer[tmphead] = data;                   /* store data in buffer */      \&lt;br /&gt;
                fifo._write = tmphead;                          /* store new index */           \&lt;br /&gt;
        }                                                                                       \&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#define FIFO64_read(fifo)			FIFO_read(fifo, 64)&lt;br /&gt;
#define FIFO64_write(fifo, data)		FIFO_write(fifo, data, 64)&lt;br /&gt;
&lt;br /&gt;
#define FIFO128_read(fifo)			FIFO_read(fifo, 128)&lt;br /&gt;
#define FIFO128_write(fifo, data)		FIFO_write(fifo, data, 128)&lt;br /&gt;
&lt;br /&gt;
#endif /*FIFO_H_*/&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hinweis: viele C-Compiler übersetzen automatisch eine Modulo-Division mit einem Divisor einer 2-er Potenz in Form einer entsprechenden Bitmaskierung. Zum einen erspart man sich dadurch das Bestimmen der entsprechenden Maske, zum anderen hat man dann den &#039;Bonus&#039;, dass der Code immer noch korrekt funktioniert (wenn auch langsamer), wenn der Anwender einen Fehler macht und die Array-Länge nicht als 2-er Potenz definiert. Die Operation&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
	fifo._buffer[fifo._read = (fifo._read + 1) &amp;amp; (size-1)] : 0	\&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
kann dann durch die in diesem Sinne gleichwertige Operation&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
	fifo._buffer[fifo._read = (fifo._read + 1) % size] : 0	\&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
ausgedrückt werden, bzw.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
	uint8_t tmphead = ( fifo._write + 1 ) &amp;amp; (size-1);       /* calculate buffer index */	\&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
durch&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
	uint8_t tmphead = ( fifo._write + 1 ) % size;           /* calculate buffer index */	\&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Circular_buffer Circular buffer], englische Wikipedia&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Grundlagen]]&lt;br /&gt;
[[Kategorie:Datenübertragung]]&lt;br /&gt;
[[Kategorie:Algorithmen und Arithmetik]]&lt;br /&gt;
[[Kategorie:Speicher und Dateisysteme]]&lt;/div&gt;</summary>
		<author><name>87.178.118.194</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Mini-Jakobsleiter&amp;diff=90821</id>
		<title>Mini-Jakobsleiter</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Mini-Jakobsleiter&amp;diff=90821"/>
		<updated>2015-12-28T22:47:56Z</updated>

		<summary type="html">&lt;p&gt;87.178.118.194: kleines&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;----&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
|[[Bild:High voltage warning.svg|100px]]&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;big&amp;gt;&#039;&#039;&#039;Achtung, hier wird mit lebensgefährlicher Netzspannung gearbeitet. Dieses Projekt ist nur für Personen geeignet, die mit den notwendigen Sicherheitsvorkehrungen vertraut sind.&#039;&#039;&#039;&lt;br /&gt;
|[[Bild:High voltage warning.svg|100px]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/big&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
[[Bild:Jakobsleiter in Aktion.jpg|thumb|Jakobsleiter in Aktion (Aufbau entspricht nicht exakt den Angaben)]]&lt;br /&gt;
&lt;br /&gt;
Schlagen irgendwo Funken über, so erregt man die Aufmerksamkeit aller Anwesenden und Jeder versteht: Hier fließt Strom! Besonders faszinierend sind die kletternden Lichtbögen der sogenannten &#039;&#039;&#039;Jakobsleiter&#039;&#039;&#039;, doch selbst Hochspannung zu erzeugen trauen sich die Wenigsten zu. Dabei macht es gar nicht so viel Aufwand, sobald der richtige Weg bekannt ist. Grundstein dieses Projekts bildete das Datenblatt für den Zündtrafo ZS&amp;amp;nbsp;1052 auf Conrad.de. Das Ergebnis ist ein Mini-Jakobsleiter im Lochrasteraufbau.&lt;br /&gt;
&lt;br /&gt;
== Funktionsprinzip ==&lt;br /&gt;
&lt;br /&gt;
=== Hochspannung erzeugen ===&lt;br /&gt;
&lt;br /&gt;
Der Brückengleichrichter mit dem Elko erzeugt eine Gleichspannung in Höhe von 315 Volt. Der Widerstand (≈560&amp;amp;nbsp;k&amp;amp;Omega;) parallel zum Elko entlädt diesen nach dem Ausschalten des Hochspannungsgenerators zügig. Bei offenem Schalter lädt sich der Schwingkreiskondensator über den Widerstand auf und bei geschlossenem Schalter bildet der Kondensator mit der Induktivität des Trafos einen Parallelschwingkreis und transformiert die Netzspannung zu etwa 11&amp;amp;nbsp;kV Hochspannung. Der Ladewiderstand hängt an 315&amp;amp;nbsp;Volt und hat keinen Einfluss auf den Schwingkreis.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Hochspannungsschwingkreis.svg]]&lt;br /&gt;
&lt;br /&gt;
Dass der Ladewiderstand mit dem Kondensator direkt gegen Masse geschaltet wird, vereinfacht den Aufbau erheblich, so ist kein Wechselschalter von Nöten. Dafür darf der Schalter nur kurz geschlossen werden. Da Elektronik zum Einsatz kommt, ist das aber kein nennenswertes Problem. &lt;br /&gt;
&lt;br /&gt;
Die Resonanz spielt für die Funktion keine Rolle und stellt nur einen Nebeneffekt dar. Der Kondensator bietet zwei wesentliche Vorteile: er wird mit einer definierten Energiemenge aufgeladen und liefert eine definierte Spannung. Dadurch haben Kurzschlüsse, dazu zählen auch Lichtbögen, keine gravierenden Auswirkungen auf den Trafo. Der Trafo übersetzt die Kondensatorspannung gemäß seines Übersetzungsverhältnisses auf die Sekundärseite.&lt;br /&gt;
&lt;br /&gt;
Eine genauen Berechnung der Bauteile im voraus ist nicht möglich, denn für Jakobsleitern gibt es keine spezielle Theorie. Die Ausgangsbasis bildet der Zündtrafo, dessen Datenblatt legt einen Kondensator mit Kapazität 47 nF fest. Ein Oszillogramm zeigt, dass bis zum Abklingen der Resonanz etwa 100 µs vergehen. Solange sollte also der Schalter mindestens geschlossen bleiben, aber auch nicht länger um den Ladewiderstand zu schonen. Die Ladespannung für den Kondensator wird dort mit 300 Volt angegeben, also im Bereich des Gleichrichtwerts der Netzspannung. Somit war klar, woraus die Spannungsversorgung erzeugt wird.&lt;br /&gt;
&lt;br /&gt;
Nun kommt der wesentliche Praxiswert: eine Kondensatorladung enthält eine definierte Energiemenge. Daher kommt es bei der Leistungsbemessung nur noch auf die Schaltfrequenz an. Die minimale Ladezeit, Schalter offen, für den Kondensator beträgt 3*&amp;amp;nbsp;&amp;amp;tau;, sprich 3 *Ladewiderstand*Schwingkreiskondensator. Anfangs war dies ein 22&amp;amp;nbsp;k&amp;amp;Omega;/1&amp;amp;nbsp;W Widerstand. Ein kleiner Funke sprang über, es reichte aber nicht für eine Jakobsleiter und so kamen 22&amp;amp;nbsp;k&amp;amp;Omega; Parallel dazu, womit die Ladezeit sank. Jetzt zeigte der Aufbau seine volle Pracht.&lt;br /&gt;
&lt;br /&gt;
Der Geruch verriet allerdings, die Widerstände wurden zu heiß, denn beim Materialeinkauf wurde großzügig mit einem Tastverhältnis von 1:100 gerechnet und erst bei der Praxiserprobung auf 1:10 reduziert, wodurch wesentlich mehr Ladezyklen pro Zeit erfolgten mit wesentlich höhere Verlusten am Widerstand. Daher sei hier das Parallelschalten von drei bis vier 33&amp;amp;nbsp;k&amp;amp;Omega;/1&amp;amp;nbsp;W Widerständen  empfohlen (genaue Berechnungen stehen noch aus). Insgesamt ergibt sich damit eine Ladezeit von 1&amp;amp;nbsp;ms und eine Schwingzeit von 100&amp;amp;nbsp;µs.&lt;br /&gt;
&lt;br /&gt;
Statt eines richtigen Schalters befindet sich in der Schaltung ein MOSFET (z.&amp;amp;nbsp;B. BUZ91A) der für 300 Volt ausgelegt ist. Eine Zeitgeberelektronik steuert die Gatespannung, siehe nächster Abschnitt.&lt;br /&gt;
&lt;br /&gt;
Die Experimentierfreude soll jedem selbst überlassen bleiben in Form weiterer Tuningmaßnahmen durch mehr Widerstände und in Folge geringer Ladezeit nach dem Prinzip mehr Leistung = mehr Spaß. Eine Halbierung sollte noch drin sein, die Verlustleistung steigt aber mit der Schaltfrequenz weiter und der Wert der einzelnen Widerstände sollte auf 39&amp;amp;nbsp;k&amp;amp;Omega; oder 39&amp;amp;nbsp;k&amp;amp;Omega; erhöht werden.&lt;br /&gt;
&lt;br /&gt;
Statt eines Trafos können sekundärseitig auch zwei in Serie geschaltet werden und die Spannung verdoppelt sich. Mehrere geht nicht, da ansonsten die Potentialdifferenz zur Primärseite zu hoch wird und der Trafo durchschlägt.&lt;br /&gt;
&lt;br /&gt;
=== Zeitgeber NE555 ===&lt;br /&gt;
&lt;br /&gt;
Als Zeitgeber kommt der allseits-bekannte NE555 als astabiler Multivibrator zum Einsatz. Der obere Teil bildet die Spannungsversorgung mit 78xx in Standardschaltung.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Hochspannung ne555.svg]]&lt;br /&gt;
&lt;br /&gt;
Zur Spannungsversorgung muss nichts weiter erklärt werden.&lt;br /&gt;
&lt;br /&gt;
Die Schaltung an Output dient als Inverter da die Multivibratorschaltung lange Pulse mit kurzen Pausen erzeugt, der MOSFET genau umgekehrt lange aus und kurz ein sein soll. Der Arbeitswiderstand beträgt 470&amp;amp;nbsp;&amp;amp;Omega; der Basisvorwiderstand 10&amp;amp;nbsp;k&amp;amp;Omega;. Der Kondensator parallel beträgt 500 pF und soll die Basis-Emitter-Kapazität füllen, damit der Transistor schneller durchschaltet. Keine Ahnung, ob das überhaupt notwendig ist, aber wer will schon sein Oszi mit Hochspannungsmessungen zerstören? Der Bipolar-Transistor ist ein BC557B also pnp. Signal-Masse ist mit der Source vom MOSFET verbunden der Inverter-Ausgang mit Gate.&lt;br /&gt;
&lt;br /&gt;
Der Kern des Multivibrators besteht aus zwei Widerständen und einem Kondensator. Die Puls und Pausenzeit ergibt sich grob nach folgender Formel:&lt;br /&gt;
:&amp;lt;math&amp;gt;t = 0{,}7 \cdot R \cdot C&amp;lt;/math&amp;gt;&lt;br /&gt;
:&amp;lt;math&amp;gt;R = \frac {t}{0{,}7 \cdot C} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Kapazität beträgt 100 nF. Bei 1 ms Pausenzeit beträgt der Widerstand an Versorgungsspannung 14 k&amp;amp;Omega; und der zum Disch-Eingang 1,4 k&amp;amp;Omega;. Letztenlich zum Einsatz kam die Paarung 10 k&amp;amp;Omega;/1 k&amp;amp;Omega;.&lt;br /&gt;
&lt;br /&gt;
=== Jakobsleiter ===&lt;br /&gt;
&lt;br /&gt;
Aufgrund der geringen Leistung wird die Jakobsleiter nicht überdimensional groß. Als Leiter genügt der für den Lochrasteraufbau übliche Silberdraht. Das untere Ende muss einen sanften Übergang zu den Versorgungsleitungen bilden, ein scharfer Knick führt zu Verzerrungen im elektrischen Feld und der Lichtbogen kommt nicht vom Fleck. Damit der Lichtbogen genug beschleunigt, so dass er auch am oberen Ende abreißt, muss er genug Anlauf bekommen. Die Jakobsleiter darf dabei nicht zu weit auseinander gehen, da sonst kein Speed zustande kommt. Ein leichtes Öffnen ist trotzdem wichtig, denn es hat sich gezeigt, dass ansonsten der Lichtbogen gerne zu weit oben zündet. Die Abriss sollte nicht zu lange sein, sonst tritt wieder der Effekt des einschlafenden Lichtbogens auf, aber auch nicht zu schroff, denn ein Knick bewirkt Zündungen an der falschen Stelle. Nicht nur aus ästhetischen Gründen ist daher das obere Ende bei manchen Aufbauten gekringelt. Einfache gebogene Konstruktionen funktionieren auch.&lt;br /&gt;
&lt;br /&gt;
Insgesamt ist die Konstruktion der Jakobsleiter der fieseligste Teil des Aufbau. Bevor die Funken dauerhaft steigen und nicht ständig einschlafen braucht es eine gewisse Probier- und Lernphase.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Jakobsleiter.svg]]&lt;br /&gt;
&lt;br /&gt;
=== Inbetriebnahme ===&lt;br /&gt;
&lt;br /&gt;
Für das Lochraster-Layout sei hier kein Plan vorgegeben und kann sich jeder selbst zusammenreimen. &lt;br /&gt;
&lt;br /&gt;
Hochspannungsteil aufbauen und Gate, Drain und Source mit Lötbrücke kurzschließen. Wenn alles in Ordnung ist leuchtet die LED permanent. Lötbrücke zwischen Drain und Gate auftrennen dann darf die LED nicht mehr leuchten. Ansonsten ist der MOSFET defekt.&lt;br /&gt;
&lt;br /&gt;
Nun den Schaltungsteil für den Zeitgeber aufbauen, aber noch nicht mit dem MOSFET verbinden. Leuchtet die LED der Versorgungsspannung ist alles in Ordnung. Jetzt Zeitgeber und MOSFET verbinden und Lötbrücke auftrennen. Der Luftspalt zwischen der Jakobsleiter sollte anfangs eher klein sein. Nach dem einstecken leuchten beide LEDs und Funken schlagen über, die Schaltung ist Einsatzbereit.&lt;br /&gt;
&lt;br /&gt;
Bei der Fehlersuche helfen zusätzliche LEDs etwa mit Vorwiderstand Parallel zum Arbeitswiderstand des Inverters oder am Output vom NE555.&lt;br /&gt;
&lt;br /&gt;
Die gesamte Schaltung ist mit der Netzspannung verbunden vor dem Berühren der Schaltung immer Netzstecker ziehen, da Kabelschalter meist nur ein-polig Trennen.&lt;br /&gt;
&lt;br /&gt;
==Material==&lt;br /&gt;
* Schraubklemme RM 5,0 zum Netzkabel anschließen&lt;br /&gt;
* Sicherung&lt;br /&gt;
* Lochrasterplatine ca. 10cm x 10cm&lt;br /&gt;
* Netzkabel (Vorsicht: Kabelschalter trennen meist nur einpolig)&lt;br /&gt;
* 4x M3 Schraube 25mm und Mutter als Füßchen&lt;br /&gt;
&lt;br /&gt;
=== Hochspannungsteil ===&lt;br /&gt;
&lt;br /&gt;
* 5x 33 kOhm 1W Metallschichtwiderstände zum Kondensatoraufladen&lt;br /&gt;
* LED mit 10mA Nennstrom in Reihe zu einem der Ladewiderstände als Funktionsanzeige&lt;br /&gt;
* [[FET]] (BUZ90, BUZ91, IRF730 o.ä)&lt;br /&gt;
* Zündspule (ZS 1052, Conrad/Voelkner) und passenden Kondensator mit 47 nF/X2 für Schwingkreis&lt;br /&gt;
* Brückengleichrichter (B250C800 o.ä.)&lt;br /&gt;
* Siebkondensator ≈ 4,7µF/350V&lt;br /&gt;
* Entladewiderstand mit ≈ 560 k&amp;amp;Omega; für den Siebkondensator &lt;br /&gt;
&lt;br /&gt;
=== Taktgenerator ===&lt;br /&gt;
* NE555&lt;br /&gt;
* Brückengleichrichter (B250C800 o.ä.)&lt;br /&gt;
* Siebkondensator ≈ 100 µF&lt;br /&gt;
* LED mit passendem Vorwiderstand als Betriebsanzeige&lt;br /&gt;
* Stabi LM7812&lt;br /&gt;
* Kondensator 0.1µF für Stabi-Ausgang&lt;br /&gt;
* Trafo 12V/30 mA o.ä.&lt;br /&gt;
* Zeitgeber-Kondensator 0.1 µF &lt;br /&gt;
* Zeitgeber-Widerstände 1k&amp;amp;Omega; + 10k&amp;amp;Omega;&lt;br /&gt;
* BC557B als Inverter für NE555 Ausgang&lt;br /&gt;
* Boostkondensator für BC557B 500 pF&lt;br /&gt;
* 10 k&amp;amp;Omega; Basisvorwiderstand für BC557B&lt;br /&gt;
* 560 &amp;amp;Omega; Arbeitswiderstand  für BC557B&lt;br /&gt;
&lt;br /&gt;
== Sicherheitshinweise ==&lt;br /&gt;
&lt;br /&gt;
* Trotz Trafo hängt die gesamte Schaltung an Netzpotential.&lt;br /&gt;
* Nach dem Ausstecken noch 10 Sekunden warten bis die Kondensatoren sicher entladen sind.&lt;br /&gt;
* Kabelschalter trennen nicht immer allpolig, also lieber den Stecker ziehen.&lt;br /&gt;
* Um den Hochspannungsanschluss herum die überflüssigen Lötaugen entfernen, sonst verkürzt sich die Funkenstrecke zur Primärseite.&lt;br /&gt;
* Vor der Erstinbetriebnahme den Hochspannungsbereich mit Spiritus gründlich von Lötfett befreien&lt;br /&gt;
* Beim Lochrasteraufbau ist darauf zu achten, das genügen Abstand zwischen Primär und Hochspannungsseite eingehalten wird.&lt;br /&gt;
* Für Schäden durch Hochspannung ist jeder selbst verantwortlich&lt;br /&gt;
&lt;br /&gt;
== Alternativen ==&lt;br /&gt;
* Zeilentrafo aus dem Fernseher&lt;br /&gt;
* Kfz-Zündspule vom Schrottplatz&lt;br /&gt;
* Hochspannungskaskade&lt;br /&gt;
* Zwei Mikrowellentrafos (MOT) für ca. 4 kV, vom Schrott&lt;br /&gt;
* Neon Sign Transformer (NST), bei Ebay&lt;br /&gt;
* Messwandler für Hochspannungsmessung (Potential-Transformer), wenn man sowas hat&lt;br /&gt;
* Elektor-Projekt Jakobsleiter (03/2006), für Leute mit Geld&lt;br /&gt;
* (Netzteil einer Kaltkathodenröhre (CCFL), meist aber zu schwach)&lt;br /&gt;
* Labornetzgerät für Hochspannung, für Leute mit ganz viel Geld&lt;br /&gt;
&lt;br /&gt;
Zündkabel, Anodenkabel, und Laborleitungen haben eine hohe Isolationsspannung, so kann Spannung sicher transportiert werden.&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://www.hcrs.at/TVLINE.HTM Hochspannung erzeugen mit Zeilentrafo]&lt;br /&gt;
* [http://geocities.com/CapeCanaveral/Lab/5322/hv2.html Snock&#039;s High Voltage Page]&lt;br /&gt;
;Videos&lt;br /&gt;
* &#039;&#039;&#039;[http://de.youtube.com/watch?v=DhWgCMReGKk&amp;amp;feature=channel_page Dieses Projekt in Aktion]&#039;&#039;&#039;&lt;br /&gt;
* [http://de.youtube.com/watch?v=GNbvg9jfDr8&amp;amp;feature=related Jakobsleiter mit NST]&lt;br /&gt;
* [http://de.youtube.com/watch?v=CUxbIuxqQl8&amp;amp;feature=related CD mit Hochspannungsbehandlung]&lt;br /&gt;
* [http://de.youtube.com/watch?v=CRLCW6alEwc&amp;amp;feature=related Hochspannungslabor]&lt;br /&gt;
* [http://de.youtube.com/watch?v=aAYGNcA34UI&amp;amp;feature=related Zeilentrafo im Einsatz]&lt;br /&gt;
* [http://www.andreas-kilchenmann.ag.vu/jakobsleiter.html Mikrowellentrafo]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Projekte]]&lt;br /&gt;
[[Kategorie:Spannungsversorgung und Energiequellen]]&lt;/div&gt;</summary>
		<author><name>87.178.118.194</name></author>
	</entry>
</feed>