<?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=Ingo+k2</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=Ingo+k2"/>
	<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/articles/Spezial:Beitr%C3%A4ge/Ingo_k2"/>
	<updated>2026-04-11T17:30:48Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=LED-Fading&amp;diff=104611</id>
		<title>LED-Fading</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=LED-Fading&amp;diff=104611"/>
		<updated>2021-07-26T15:30:40Z</updated>

		<summary type="html">&lt;p&gt;Ingo k2: /* FAQ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Das Problem ==&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe klingt eigentlich recht einfach. Eine [[LED]] soll mittels [[PWM]] in ihrer Helligkeit gesteuert werden. Und weils so schön ist, möchte man sie geheimnisvoll aufleuchten lassen, sprich langsam heller und dunkler werden lassen. Der Fachmann nennt das Fading. Das Problem zeigt sich allerdings recht schnell. Wenn man eine 8-Bit-PWM linear zwischen 0..255 laufen lässt, dann scheint die LED nicht linear gedimmt zu werden. Sie wird relativ schnell hell und bleibt lange hell.&lt;br /&gt;
&lt;br /&gt;
== Die Theorie ==&lt;br /&gt;
&lt;br /&gt;
Des Rätsels Lösung liegt in der Kennline des menschlichen Auges. Diese ist nichtlinear, genauer gesagt: sie ist nahezu logarithmisch. Das ermöglicht die Wahrnehmung eines sehr großen Helligkeitsbereichs, angefangen von Vollmond mit ~1/4 [http://de.wikipedia.org/wiki/Lux_%28Einheit%29 Lux] über eine normale Schreibtischbeleuchtung mit ca. 750 Lux bis zu einem hellen Sommertag mit bis zu 100.000 Lux. Solche hochdynamischen Signale sind nur mit einer logarithmischen Kennlinie in den Griff zu kriegen, auch von Mutter Natur und Erfinder Papa.&lt;br /&gt;
&lt;br /&gt;
=== Die Kennlinie des Auges genau betrachtet ===&lt;br /&gt;
&lt;br /&gt;
Die Kennlinie des menschlichen Auges ist annähernd logarithmisch. Das wurde vor langer Zeit durch das [http://de.wikipedia.org/wiki/Weber-Fechner-Gesetz Weber-Fechner-Gesetz] beschrieben. Genauere Untersuchungen zur [http://de.wikipedia.org/wiki/Gammakorrektur Gammakorrektur] führten jedoch zur [http://de.wikipedia.org/wiki/Stevenssche_Potenzfunktion Stevenschen Potenzfunktion]. Diese beschreibt das menschliche Auge etwas besser. (s. auch [[Talk:LED-Fading#Diskussion wissenschaftl.-technischer Hintergrund|Diskussionsseite]]). Die Unterschiede sind jedoch marginal.&lt;br /&gt;
&lt;br /&gt;
Praktisch heißt das, dass wir unserem Auge große physikalische Helligkeitsunterschiede präsentieren müssen, damit es das als lineare Helligkeitsteigerung erkennt. Etwas wissenschaftlicher formuliert heißt das, wir müssen durch Verkettung der logarithmischen Kennlinie des Auges mit einer exponentiellen Kennlinie eine physiologisch lineare Helligkeitsverteilung erzielen.&lt;br /&gt;
&lt;br /&gt;
Berechnet werden kann eine passende Tabelle beispielsweise mit folgender Funktion:&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;y=\frac{b^{\,x/r_x}-1}{b-1}\cdot r_y&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dabei sind x und y die Ein-, bzw. Ausgabewerte der Funktion, jeweils im Bereich von 0 bis r–1. b ist die Basis der Exponentialfunktion und bestimmt, wann und wie stark die Kurve ansteigen soll. Hier ist etwas Ausprobieren erforderlich, gute Ergebnisse liefern Werte im Bereich 10–100.&lt;br /&gt;
&lt;br /&gt;
== Das Demoprogramm ==&lt;br /&gt;
&lt;br /&gt;
Das folgende Beispielprogramm demonstriert die Wirkung verschiedener PWM-Auflösungen. Eine 8-Bit PWM wird mit 4/8/16 und 32 nichtlinearen Stufen betrieben, welche über eine Exponentialfunktion berechnet wurden. Dazu dient die [[media:pwm_table.zip|Exceltabelle]]&amp;lt;ref&amp;gt;Anmerkung: Bitte die Exceltabelle nochmal erklären, die Werte in der Tabelle stimmen nicht mit denen im Programm überein&amp;lt;/ref&amp;gt; - überarbeitet, inkl. neuer Varianten der Berechnung als [[media:pwm_table-r101.ods|LibreOffice Calc Sheet]] / [[media:pwm_table-r101.pdf|PDF Vorschau]]&amp;lt;ref&amp;gt;Download alternativ von ftp://ftp.fl.priv.at/pub/mikrocontroller.net/led-fading/&amp;lt;/ref&amp;gt;. Die einzelnen, benachbarten Werte haben zueinander ein konstantes Verhältnis, das in der Exceltabelle als &#039;&#039;Factor&#039;&#039; berechnet wird. Ausserdem werden eine 10-Bit PWM mit 64 Stufen sowie eine 16-Bit PWM mit 256 Stufen betrieben.&lt;br /&gt;
&lt;br /&gt;
Eine neue [[media:LED-PWM.xlsm|Excel 2000 Tabelle]] ist ebenfalls verfügbar. Die Schaltflächen kopieren die Arraywerte in die Zwischenablage.&lt;br /&gt;
&lt;br /&gt;
Das Programm ist ursprünglich auf einem [[AVR]] vom Typ ATmega32 entwickelt und getestet worden. Aber es ist leicht auf jeden AVR portierbar, welcher eine PWM zur Verfügung hat. Der AVR muss mit etwa 8 MHz getaktet werden, egal ob mit internem Oszillator oder von aussen mit Quarz. Man muss nur noch eine [[LED]] mittels Vorwiderstand von ca. 1 kΩ an Pin D5 anschliessen und los gehts. Es sollte hier noch erwähnt werden, dass das Programm mit eingeschalteter Optimierung compiliert werden muss, sonst stimmen die Zeiten der Warteschleifen aus &amp;lt;tt&amp;gt;util/delay.h&amp;lt;/tt&amp;gt; nicht.&lt;br /&gt;
&lt;br /&gt;
Bei Verwendung der LEDs auf dem STK500 bzw. bei der Verwendung von invertierenden Treiberstufen ist das&lt;br /&gt;
 #define STK500 0&lt;br /&gt;
durch&lt;br /&gt;
 #define STK500 1&lt;br /&gt;
zu ersetzen.&lt;br /&gt;
&lt;br /&gt;
Das Programm durchläuft alle 6 PWMs und lässt dabei die LED jeweils 3 mal glimmen. Mit 4 Schritten Auflösung ist das natürlich ruckelig, mit 8 schon wesentlich besser. Mit 16 Stufen sieht man bei langsamen Änderungen noch Stufen, dreht man die Ein- und Ausblendzeiten runter, ist der Übergang schon recht flüssig. Die 8-Bit PWM mit 32 Stufen unterscheidet sich praktisch nicht von der 10-Bit PWM mit 64 Stufen, es sei denn, man macht extrem langsame Einblendungen. Hier schlägt die Stunde der 16-Bit PWM. Diese wird bewußt sehr langsam ausgeführt um zu demonstrieren, daß hiermit praktisch keine Stufen mehr sichtbar sind, egal wie langsam gedimmt wird. Wie man auch sieht sind die drei höherauflösenden PWMs im unteren Bereich an ihrer Auflösungsgrenze, da einige PWM-Werte mehrfach vorkommen. Da heißt gleichzeitig, daß eine Steigerung der Stufenanzahl relativ sinnlos ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
//**************************************************************************&lt;br /&gt;
//*&lt;br /&gt;
//*  LED fading test&lt;br /&gt;
//*  uses exponential PWM settings to achive visual linear brightness&lt;br /&gt;
//*&lt;br /&gt;
//*  ATmega32 @ 8 MHz&lt;br /&gt;
//*                  &lt;br /&gt;
//**************************************************************************&lt;br /&gt;
 &lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define F_CPU 8000000L&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define STK500 0&lt;br /&gt;
&lt;br /&gt;
#if STK500&lt;br /&gt;
// inverted PWM on OC1A for STK500&lt;br /&gt;
#define INVERT_PWM (1 &amp;lt;&amp;lt; COM1A0)&lt;br /&gt;
#else&lt;br /&gt;
// non-inverted PWM on OC1A&lt;br /&gt;
#define INVERT_PWM 0&lt;br /&gt;
#endif // STK500&lt;br /&gt;
&lt;br /&gt;
const uint16_t pwmtable_8A[4]  PROGMEM = { 0, 16, 64, 255 };&lt;br /&gt;
const uint16_t pwmtable_8B[8]  PROGMEM =&lt;br /&gt;
{&lt;br /&gt;
    0, 4, 8, 16, 32, 64, 128, 255&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
const uint16_t pwmtable_8C[16] PROGMEM =&lt;br /&gt;
{&lt;br /&gt;
    0, 2, 3, 4, 6, 8, 11, 16, 23, 32, 45, 64, 90, 128, 181, 255&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
const uint16_t pwmtable_8D[32] PROGMEM =&lt;br /&gt;
{&lt;br /&gt;
    0, 1, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 10, 11, 13, 16, 19, 23,&lt;br /&gt;
    27, 32, 38, 45, 54, 64, 76, 91, 108, 128, 152, 181, 215, 255&lt;br /&gt;
};&lt;br /&gt;
 &lt;br /&gt;
const uint16_t pwmtable_10[64] PROGMEM =&lt;br /&gt;
{&lt;br /&gt;
    0, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9, 10,&lt;br /&gt;
    11, 12, 13, 15, 17, 19, 21, 23, 26, 29, 32, 36, 40, 44, 49, 55,&lt;br /&gt;
    61, 68, 76, 85, 94, 105, 117, 131, 146, 162, 181, 202, 225, 250,&lt;br /&gt;
    279, 311, 346, 386, 430, 479, 534, 595, 663, 739, 824, 918, 1023&lt;br /&gt;
};&lt;br /&gt;
 &lt;br /&gt;
const uint16_t pwmtable_16[256] PROGMEM =&lt;br /&gt;
{&lt;br /&gt;
    0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,&lt;br /&gt;
    3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7,&lt;br /&gt;
    7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15,&lt;br /&gt;
    15, 16, 17, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,&lt;br /&gt;
    31, 32, 33, 35, 36, 38, 40, 41, 43, 45, 47, 49, 52, 54, 56, 59,&lt;br /&gt;
    61, 64, 67, 70, 73, 76, 79, 83, 87, 91, 95, 99, 103, 108, 112,&lt;br /&gt;
    117, 123, 128, 134, 140, 146, 152, 159, 166, 173, 181, 189, 197,&lt;br /&gt;
    206, 215, 225, 235, 245, 256, 267, 279, 292, 304, 318, 332, 347,&lt;br /&gt;
    362, 378, 395, 412, 431, 450, 470, 490, 512, 535, 558, 583, 609,&lt;br /&gt;
    636, 664, 693, 724, 756, 790, 825, 861, 899, 939, 981, 1024, 1069,&lt;br /&gt;
    1117, 1166, 1218, 1272, 1328, 1387, 1448, 1512, 1579, 1649, 1722,&lt;br /&gt;
    1798, 1878, 1961, 2048, 2139, 2233, 2332, 2435, 2543, 2656, 2773,&lt;br /&gt;
    2896, 3025, 3158, 3298, 3444, 3597, 3756, 3922, 4096, 4277, 4467,&lt;br /&gt;
    4664, 4871, 5087, 5312, 5547, 5793, 6049, 6317, 6596, 6889, 7194,&lt;br /&gt;
    7512, 7845, 8192, 8555, 8933, 9329, 9742, 10173, 10624, 11094,&lt;br /&gt;
    11585, 12098, 12634, 13193, 13777, 14387, 15024, 15689, 16384,&lt;br /&gt;
    17109, 17867, 18658, 19484, 20346, 21247, 22188, 23170, 24196,&lt;br /&gt;
    25267, 26386, 27554, 28774, 30048, 31378, 32768, 34218, 35733,&lt;br /&gt;
    37315, 38967, 40693, 42494, 44376, 46340, 48392, 50534, 52772,&lt;br /&gt;
    55108, 57548, 60096, 62757, 65535&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
&lt;br /&gt;
  Diese Tabellen sind nicht nach der Theorie (s. oben) berechnet, sondern wie folgt:&lt;br /&gt;
  a = Anzahl an Schritte (4, 8, 16, 32, 64, 256)&lt;br /&gt;
  b = Auflösung des PWM&#039;s (256, 1024, 65536)&lt;br /&gt;
  y = Errechneter Wert an einer stelle x&lt;br /&gt;
      y = 0 wenn x = 0&lt;br /&gt;
      y = pow(2, log2(b-1) * (x+1) / a) wenn x &amp;gt; 0&lt;br /&gt;
&lt;br /&gt;
  Gerne wird auch diese alternative Formel genutzt:&lt;br /&gt;
      y = pow(2, log2(b) * (x+1) / a) - 1&lt;br /&gt;
&lt;br /&gt;
  Obige Funktionen wurden in den LibreOffice Calc Sheet eingearbeitet.&lt;br /&gt;
*/&lt;br /&gt;
 &lt;br /&gt;
// long, variable delays&lt;br /&gt;
 &lt;br /&gt;
void my_delay (uint16_t milliseconds)&lt;br /&gt;
{&lt;br /&gt;
    for (; milliseconds &amp;gt; 0; milliseconds--)&lt;br /&gt;
        _delay_ms (1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void pwm_up_down (const uint16_t pwm_table[], int16_t size, uint16_t delay)&lt;br /&gt;
{&lt;br /&gt;
    int16_t tmp;&lt;br /&gt;
&lt;br /&gt;
    for (tmp = 0; tmp &amp;lt; size; tmp++)&lt;br /&gt;
    {&lt;br /&gt;
        OCR1A = pgm_read_word (&amp;amp; pwm_table[tmp]);&lt;br /&gt;
        my_delay (delay);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    for (tmp = size-1; tmp &amp;gt;= 0; tmp--)&lt;br /&gt;
    {&lt;br /&gt;
        OCR1A = pgm_read_word (&amp;amp; pwm_table[tmp]);&lt;br /&gt;
        my_delay (delay);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
// 8-Bit PWM with only 4 different settings&lt;br /&gt;
 &lt;br /&gt;
void pwm_8_4 (uint16_t delay)&lt;br /&gt;
{&lt;br /&gt;
    // 8 Bit Fast PWM&lt;br /&gt;
    TCCR1A = 0x81 | INVERT_PWM;&lt;br /&gt;
    // prescaler 256 -&amp;gt; ~122 Hz PWM frequency&lt;br /&gt;
    TCCR1B = (1 &amp;lt;&amp;lt; WGM12) | 4;&lt;br /&gt;
    &lt;br /&gt;
    pwm_up_down (pwmtable_8A, 4, delay);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
// 8-Bit PWM with 8 different settings&lt;br /&gt;
 &lt;br /&gt;
void pwm_8_8 (uint16_t delay)&lt;br /&gt;
{&lt;br /&gt;
    // 8 Bit Fast PWM&lt;br /&gt;
    TCCR1A = 0x81 | INVERT_PWM;&lt;br /&gt;
    // prescaler 256 -&amp;gt; ~122 Hz PWM frequency&lt;br /&gt;
    TCCR1B = (1 &amp;lt;&amp;lt; WGM12) | 4;&lt;br /&gt;
 &lt;br /&gt;
    pwm_up_down (pwmtable_8B, 8, delay);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
// 8-Bit PWM with 16 different settings&lt;br /&gt;
 &lt;br /&gt;
void pwm_8_16 (uint16_t delay)&lt;br /&gt;
{&lt;br /&gt;
    // 8 Bit Fast PWM&lt;br /&gt;
    TCCR1A = 0x81 | INVERT_PWM;&lt;br /&gt;
    // prescaler 256 -&amp;gt; ~122 Hz PWM frequency&lt;br /&gt;
    TCCR1B = (1 &amp;lt;&amp;lt; WGM12) | 4;&lt;br /&gt;
 &lt;br /&gt;
    pwm_up_down (pwmtable_8C, 16, delay);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
// 8-Bit PWM with 32 different settings&lt;br /&gt;
 &lt;br /&gt;
void pwm_8_32 (uint16_t delay)&lt;br /&gt;
{&lt;br /&gt;
    //  8 Bit Fast PWM&lt;br /&gt;
    TCCR1A = 0x81 | INVERT_PWM;&lt;br /&gt;
    // prescaler 256 -&amp;gt; ~122 Hz PWM frequency&lt;br /&gt;
    TCCR1B = (1 &amp;lt;&amp;lt; WGM12) | 4;&lt;br /&gt;
 &lt;br /&gt;
    pwm_up_down (pwmtable_8D, 32, delay);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
// 10-Bit PWM with 64 different settings&lt;br /&gt;
 &lt;br /&gt;
void pwm_10_64 (uint16_t delay)&lt;br /&gt;
{ &lt;br /&gt;
    // 10 Bit Fast PWM&lt;br /&gt;
    TCCR1A = 0x83 | INVERT_PWM;&lt;br /&gt;
    // prescaler 64 -&amp;gt; ~122 Hz PWM frequency&lt;br /&gt;
    TCCR1B = (1 &amp;lt;&amp;lt; WGM12) | 3;&lt;br /&gt;
 &lt;br /&gt;
    pwm_up_down (pwmtable_10, 64, delay);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
// 16-Bit PWM with 256 different settings&lt;br /&gt;
 &lt;br /&gt;
void pwm_16_256 (uint16_t delay)&lt;br /&gt;
{&lt;br /&gt;
    // 16 Bit Fast PWM&lt;br /&gt;
    TCCR1A = 0x82 | INVERT_PWM;&lt;br /&gt;
    // stop timer&lt;br /&gt;
    TCCR1B = 0;&lt;br /&gt;
    // TOP for PWM, full 16 Bit&lt;br /&gt;
    ICR1 = 0xFFFF;&lt;br /&gt;
    // prescaler 1 -&amp;gt; ~122 Hz PWM frequency&lt;br /&gt;
    TCCR1B = (1 &amp;lt;&amp;lt; WGM12) | (1 &amp;lt;&amp;lt; WGM13) | 1;&lt;br /&gt;
 &lt;br /&gt;
    pwm_up_down (pwmtable_16, 256, delay);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    int8_t i;&lt;br /&gt;
    // delay in milliseconds for one fading step&lt;br /&gt;
    int16_t step_time = 400;&lt;br /&gt;
 &lt;br /&gt;
    // LED uses OC1A&lt;br /&gt;
    DDRD |= 1 &amp;lt;&amp;lt; PD5;&lt;br /&gt;
 &lt;br /&gt;
    // test all fading routines&lt;br /&gt;
 &lt;br /&gt;
    while (1)&lt;br /&gt;
    {&lt;br /&gt;
        for (i=0; i&amp;lt;3; i++) pwm_8_4 (step_time);&lt;br /&gt;
        my_delay (1000);&lt;br /&gt;
        &lt;br /&gt;
        for (i=0; i&amp;lt;3; i++) pwm_8_8 (step_time/2);&lt;br /&gt;
        my_delay (1000);    &lt;br /&gt;
        &lt;br /&gt;
        for (i=0; i&amp;lt;3; i++) pwm_8_16 (step_time/4);&lt;br /&gt;
        my_delay (1000);&lt;br /&gt;
        &lt;br /&gt;
        for (i=0; i&amp;lt;3; i++) pwm_8_32 (step_time/8);&lt;br /&gt;
        my_delay (1000);&lt;br /&gt;
        &lt;br /&gt;
        for (i=0; i&amp;lt;3; i++) pwm_10_64 (step_time/16);&lt;br /&gt;
        my_delay (1000);&lt;br /&gt;
        &lt;br /&gt;
        for (i=0; i&amp;lt;3; i++) pwm_16_256 (step_time/16);&lt;br /&gt;
        my_delay (1000);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== FAQ ==&lt;br /&gt;
&lt;br /&gt;
; Wieso geht die LED nie ganz aus?: Es ist normal, dass die LED selbst bei OCR1A = 0 immer noch ganz schwach leuchtet. Die Hardware-PWM funktioniert so, dass bei einem Timerwert von 0 auf jeden Fall der Ausgang eingeschaltet wird. Danach kommt der Compare Match bei 0 und schaltet gleich wieder aus. Daher ist der Ausgang für einen PWM-Takt eingeschaltet. Um das zu ändern, muss man entweder invertierte PWM nutzen, dann ist allerdings der Ausgang nie zu 100% High, sondern hat immer einen Takt Low beim maximalem PWM-Wert. Oder man schaltet bei 0 einfach die PWM-Funktion ab und setzt den Ausgang normal auf Low. [http://www.mikrocontroller.net/topic/200173#1965686].&lt;br /&gt;
&lt;br /&gt;
; Wieso dimmt man eine LED nicht besser mit einer variablen Stromquelle?: Nur so ist es möglich, die LEDs von nahezu 0 bis 100% zu dimmen, ohne dass es zu Farbänderungen kommt, was besonders bei RGB-Anwendungen wichtig ist.&lt;br /&gt;
&lt;br /&gt;
; Wie stimmen die Werte im LibreOffice Calc Sheet mit denen im Programm überein?: Basis = (Max/Factor)^(1/(Steps-1))&amp;lt;br&amp;gt;pwmtable_xx[0] = 0&amp;lt;br&amp;gt;pwmtable_xx[Index] = Round(Factor * Basis^Index); for Index=1..Steps-1&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;pwmtable_8A - Max=255,&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;Steps=4,&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;Factor=4&amp;lt;br&amp;gt;pwmtable_8B - Max=255,&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;Steps=8,&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;Factor=2&amp;lt;br&amp;gt;pwmtable_8C - Max=255,&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;Steps=16,&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;Factor=1.435&amp;lt;br&amp;gt;pwmtable_8D - Max=255,&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;Steps=32,&amp;amp;nbsp;&amp;amp;nbsp;Factor=1.21&amp;lt;br&amp;gt;pwmtable_10 - Max=1023,&amp;amp;nbsp;&amp;amp;nbsp;Steps=64,&amp;amp;nbsp;&amp;amp;nbsp;Factor=1.118&amp;lt;br&amp;gt;pwmtable_16 - Max=65535,&amp;amp;nbsp;Steps=256,&amp;amp;nbsp;Factor=1.04427&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;Anmerkung 1: Dies ist nur ein Reverse-Engineering, es ist derzeit nicht bekannt, warum der jeweilige Faktor so gewählt wurde wie oben angeführt.&amp;lt;br&amp;gt;Anmerkung 1.1: Mit der gefitteten Funktion Faktor(Steps) = 0,983118 + 18,061952 / ( 1+ (LOG10(steps)/0,3515028)^2,985948 ) lassen sich die Faktor-Werte für beliebige Schrittzahlen ausreichend genau berechnen, auch wenn sie keinen zusätzlichen Erklärungsgehalt bietet.&amp;lt;br&amp;gt;Anmerkung 2: Für das LibreOffice Calc Sheet siehe oben [[#Das_Demoprogramm|Das Demoprogramm]].&amp;lt;br&amp;gt;Anmerkung 3: Der für die Tabelle benötigte EEPROM-Speicher entspricht log_2(MAX+1)*steps bit.&lt;br /&gt;
&lt;br /&gt;
== Fußnoten ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [[PWM]]&lt;br /&gt;
* [[AVR-GCC-Tutorial/Analoge_Ein-_und_Ausgabe#PWM (Pulsweitenmodulation)|AVR-GCC-Tutorial: PWM]]&lt;br /&gt;
* [[Soft-PWM]] - optimierte Software-PWM in C&lt;br /&gt;
* [http://www.b-kainka.de/bastel108.htm Eine LED weich blinken lassen ohne Mikrocontroller]&lt;br /&gt;
* [http://www.solstice.de/cms/upload/pdf/Veroeffentlichungen/Weber-Fechner-PHidS-1994.pdf [PDF&amp;lt;nowiki&amp;gt;]&amp;lt;/nowiki&amp;gt; &amp;quot;Experimente zur logarithmischen Empfindlichkeitsskala - Das Weber-Fechnersche Gesetz&amp;quot;] - Download Nr. 50 von [http://www.solstice.de/initiatoren/werner-schneider/veroeffentlichungen.html Solstice - Veröffentlichungen von Prof. Dr. Werner B. Schneider]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:AVR-Projekte]]&lt;br /&gt;
[[Category:Displays und Anzeigen]]&lt;/div&gt;</summary>
		<author><name>Ingo k2</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Transistor&amp;diff=100507</id>
		<title>Transistor</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Transistor&amp;diff=100507"/>
		<updated>2019-04-21T20:23:05Z</updated>

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

		<summary type="html">&lt;p&gt;Ingo k2: /* Die Formel */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Bild:attiny2313.jpg|thumb|right|ATtiny2313 im [[IC-Gehäuseformen|DIL]]-Gehäuse]]&lt;br /&gt;
Als neulich im Foren nach einem&lt;br /&gt;
: &#039;&#039;&amp;quot;rechenintensiven Beispielprogramm für den kleinen ATtiny2313 in C oder ASM&amp;quot;&#039;&#039;&amp;lt;ref&amp;gt;[http://www.mikrocontroller.net/topic/248373 Forum: AVR Atiny2313: &#039;&#039;&amp;quot;Suche rechenintensivs Beispielprogramm für ATtiny2313&amp;quot;&#039;&#039;]&amp;lt;/ref&amp;gt;&lt;br /&gt;
gesucht wurde und als Vorschlag ein&lt;br /&gt;
: &#039;&#039;&amp;quot;Pi auf 1000 Stellen&amp;quot;&#039;&#039;&amp;lt;ref&amp;gt;[http://www.mikrocontroller.net/topic/248373#2544249 Forum: AVR Atiny2313: &#039;&#039;&amp;quot;Pi auf 1000 Stellen&amp;quot;&#039;&#039;]&amp;lt;/ref&amp;gt;&lt;br /&gt;
kam, wolle ich es genauer wissen. Auch wenn der Vorschlag eher als Scherz aufzufassen ist — sind C-Compiler inzwischen so gut, daß damit π auf tausende Stellen berechnet werden kann? Bei einem Assembler-Programm hätte ich da keine Bedenken; aber C?&lt;br /&gt;
&lt;br /&gt;
Der [[AVR]] ATtiny2313 ist bekanntlich ein 8-Bit [[Mikrocontroller]] mit 2048 Bytes an Programmspeicher und 128 Bytes RAM. Die Aufgabe erfordert also eine spezielle Herangehensweise, denn nicht alle zu berechnenden Stellen sind gleichzeitig im RAM des µC speicherbar: bereits berechnete Stellen sollen ausgegeben werden, und an der Ausgabe-Schnittstelle sollen Ziffernweise die Nachkommastellen von π heraus purzeln.&lt;br /&gt;
&lt;br /&gt;
== Die Formel ==&lt;br /&gt;
&lt;br /&gt;
Das theoretisch-algorithmische Rüstzeug dafür ist lange bekannt und das Web ist voll davon: Eine 1995 von Simon Plouffe gefundene Reihendarstellung&amp;lt;ref&amp;gt;Für einen Beweis siehe [http://www.pi314.net/eng/plouffe.php The World of π: Proof: Formula BBP].&amp;lt;/ref&amp;gt; für&amp;amp;nbsp;π:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\pi=\sum_{k=0}^\infty \frac1{16^k}&lt;br /&gt;
\left(\frac4{8k+1}-\frac2{8k+4}-\frac{1}{8k+5}-\frac1{8k+6}\right)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
Die Anwendung der Darstellung besteht dabei nicht in stupidem Auswerten bis zur gewünschten Genauigkeit, sondern es wird die n-te Nachkommastelle von π damit bestimmt &#039;&#039;ohne&#039;&#039; vorherige oder nachfolgende Ziffern der Darstellung zu bestimmen.&lt;br /&gt;
Der einzige Wermutstropfen ist, daß die Darstellung zur Basis&amp;amp;nbsp;16 erhalten wird und nicht wie gewohnt zur Basis&amp;amp;nbsp;10 — aber immerhin liefert die Formel &#039;&#039;überhaupt&#039;&#039; erst einen Weg, um die Berechnung auf einer kleinen Hardware mit 2k Programmspeicher ausführen zu können.&lt;br /&gt;
Auch dieser Weg ist hinreichend oft im Internet erklärt — je nach Seite mehr oder weniger gut. Eine gute Erklärung findet sich etwa in der Wikipedia&amp;lt;ref&amp;gt;[http://fr.wikipedia.org/wiki/Formule_BBP#Exploitation_de_la_formule_pour_calculer_les_chiffres_apr.C3.A8s_la_virgule_de_.CF.80 Wikipédia: Formule BBP]: Exploitation de la formule pour calculer les chiffres après la virgule de π&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die ganze Aufgabe besteht also nur noch darin, den Algorithmus hinzuschreiben und zu compilieren — und zu hoffen, dass das erzeugte Programm in den kleinen Programmspeicher eines ATtiny hineinpasst.&lt;br /&gt;
&lt;br /&gt;
Gerade der letzte Punkt ist nicht selbstverständlich, denn die Anwendung der obigen Formel verlangt den Einsatz von Fließkomma-Arithmetik. Zwar ist auch eine&lt;br /&gt;
Implementierung mittels Festkomma-Zahlen möglich, aber ich wollte mit den Bordmitteln der C-Sprache auskommen: Ohne Inline-Assembler Hacks, ohne umständliches Hin-und-Herwandeln und Skalieren, ohne Implementierung eigener Divisionroutinen, etc.  Das Programm kann daher auch als Stresstest für die Tools verstanden werden.&lt;br /&gt;
&lt;br /&gt;
Als Sprache wählte ich C99 und als Compiler avr-gcc&amp;lt;ref&amp;gt;[http://gcc.gnu.org/ GCC]: The GNU Compiler Collection&amp;lt;/ref&amp;gt; 4.7 oder neuer, so daß ein Executable erzeugen wird, das in die 2k Programmspeicher eines ATtiny2313 hineinpasst.&lt;br /&gt;
&lt;br /&gt;
== Der Quelltext: C99 == &lt;br /&gt;
&lt;br /&gt;
Zur Implementierung ist hier nicht viel zu sagen; die Quellen sind ausführlich kommentiert. Nur noch einige Anmerkungen:&lt;br /&gt;
* Die Quellen sind so allgemein gehalten, dass das Programm auch für einen PC übersetzt und dort ausgeführt werden kann.&lt;br /&gt;
* Wird für AVR übersetzt, erfolgt die Ausgabe der berechneten Ziffern auf der UART-Schnittstelle. Für Compiler- und Linker-Optionen siehe die Quellkommentare.&lt;br /&gt;
* Bei einer Taktfrequenz von 20 MHz dauert die Berechnung der ersten 1000 hex-Ziffern etwa 3–4 Minuten. Verdoppelt man die Anzahl der Ziffern, ist die 4-fache Rechenzeit zu erwarten.&lt;br /&gt;
* Der Algorithmus liefert brauchbare Resultate für die ersten 4096 Nachkommastellen von&amp;amp;nbsp;π. Danach reichten die verwendeten 16-Bit int für ganze Zahlen nicht mehr aus, und für 32-Bit Zahlen ist der Programmspeicher des ATtiny2313 zu klein.&lt;br /&gt;
* Der Algorithmus berechnet wie gesagt Nachkommastellen der Hexadezimaldarstellung von π. 4000 hex-Nachkommastellen entsprechen übrigens ca. 4800 Dezimalstellen: log 16 / log 10 ≈ 6/5.&lt;br /&gt;
* Die Ausgabe lässt sich etwa vergleichen mit &amp;quot;First 8366 Hex Digits of PI&amp;quot;&amp;lt;ref&amp;gt;[http://www.herongyang.com/Cryptography/Blowfish-First-8366-Hex-Digits-of-PI.html www.herongyang.com]: First 8366 Hex Digits of π&amp;lt;/ref&amp;gt;&lt;br /&gt;
* Den Quelltext gibt es auch hier als bereits fertig kompiliertes Atmel Studio 6.1 SP2 Project (inkl. Hex und ELF): [[Medium:4000Pi.zip]] (60KB)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* pi.c: Compute the first 4000 hexadecimal digits of pi&lt;br /&gt;
         on an AVR ATtiny2313 microcontroller. */&lt;br /&gt;
/*&lt;br /&gt;
    Language: C99&lt;br /&gt;
    Compiler: An AVR toolchain based on avr-gcc 4.7 or newer and AVR-Libc&lt;br /&gt;
              if you like to compile for AVR ATtiny2313, or a C99-compliant&lt;br /&gt;
              compiler if you like to run this program on a PC.&lt;br /&gt;
              &lt;br /&gt;
    Hardware: AVR ATtiny2313 which is an 8-bit microcontroller with&lt;br /&gt;
              128 Bytes of RAM and 2048 Bytes of program memory.&lt;br /&gt;
              http://www.atmel.com/Images/doc2543.pdf  (Manual,  PDF, 4 MB)&lt;br /&gt;
              http://www.atmel.com/Images/doc2543S.pdf (Summary, PDF, 500 kB)&lt;br /&gt;
              &lt;br /&gt;
    Compile:  You need a reasonably optimizing compiler and floating point&lt;br /&gt;
              implementation, or otherwise the program won&#039;t fit into the&lt;br /&gt;
              tiny silicon.  Notice that the code below is *vanilla* C with&lt;br /&gt;
              IEEE-754 floating point arithmetic and without assembler or&lt;br /&gt;
              fixed-point hacks.  &lt;br /&gt;
              &lt;br /&gt;
              The program is generic enough to run on a PC.  If you use GCC,&lt;br /&gt;
              just compile with the following command line and run pi.exe&lt;br /&gt;
            &lt;br /&gt;
                  gcc pi.c -o pi.exe -std=c99 -O2 -lm&lt;br /&gt;
        &lt;br /&gt;
              The only compiler that produces code small enough for the&lt;br /&gt;
              AVR ATtiny2313 is avr-gcc 4.7+ together with AVR-Libc.&lt;br /&gt;
&lt;br /&gt;
                 avr-gcc pi.c -o pi.elf $(CFLAGS) $(OPT) $(DEFS) $(LDFLAGS)&lt;br /&gt;
    &lt;br /&gt;
              with the following abbreviations for convenience:&lt;br /&gt;
    &lt;br /&gt;
              CFLAGS  = -std=c99 -mmcu=attiny2313&lt;br /&gt;
              OPT     = -Os -mcall-prologues -fno-split-wide-types&lt;br /&gt;
                        -fno-caller-saves -fno-tree-loop-optimize &lt;br /&gt;
              LDFLAGS = -Wl,--relax -Wl,--gc-sections -lm&lt;br /&gt;
              DEFS    = -DF_CPU=22118400 -DBAUDRATE=115200 -DHOST_WINDOWS&lt;br /&gt;
    &lt;br /&gt;
              For documentation of GCC see http://gcc.gnu.org/onlinedocs&lt;br /&gt;
&lt;br /&gt;
              DEFS represents the UART setup.  In my circuit I use a&lt;br /&gt;
              22.1184 MHz quartz which is a bit of overclocking but is so&lt;br /&gt;
              convenient with baud rates.  Depending on your configuration,&lt;br /&gt;
              you will use other values for F_CPU and BAUDRATE, see below.&lt;br /&gt;
    &lt;br /&gt;
    The first 1000 digits of pi take about 3 minutes at 22 MHz.&lt;br /&gt;
    For 4000 digits, multiply this time by 16.&lt;br /&gt;
&lt;br /&gt;
    The time to get the first n digits of pi with this method is roughly&lt;br /&gt;
&lt;br /&gt;
        T(n) = K * n^2&lt;br /&gt;
&lt;br /&gt;
    so that, given the time for the computation of n digits, you can easily&lt;br /&gt;
    compute K and estimate how long the computation will take for other&lt;br /&gt;
    values of n.  K will depend on the clock speed you use, for example.&lt;br /&gt;
    &lt;br /&gt;
    Some software metrics for the AVR binary compiled as above:&lt;br /&gt;
    &lt;br /&gt;
    Program Size:  Less than 2000 of 2048 bytes&lt;br /&gt;
&lt;br /&gt;
    RAM Usage:&lt;br /&gt;
        Static storage     :    0 bytes&lt;br /&gt;
        Static stack usage : ~ 50 bytes&lt;br /&gt;
        Dynamic            :    0 bytes&lt;br /&gt;
        Total              : 40% of 128 bytes&lt;br /&gt;
&lt;br /&gt;
    Coding Style: Stroustrup&lt;br /&gt;
    Indentation:  4 Space&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;math.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Factor out some platform/compiler dependencies&lt;br /&gt;
&lt;br /&gt;
#if defined (__AVR__) &amp;amp;&amp;amp; defined (__GNUC__)&lt;br /&gt;
&lt;br /&gt;
// Running on AVR&lt;br /&gt;
#   include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#   include &amp;lt;avr/wdt.h&amp;gt;&lt;br /&gt;
#   define cput(C) uart_putc(C)&lt;br /&gt;
static void uart_init (void);&lt;br /&gt;
static void uart_putc (const char);&lt;br /&gt;
&lt;br /&gt;
#else // ! avr-gcc&lt;br /&gt;
&lt;br /&gt;
// Running on PC&lt;br /&gt;
#   include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#   define wdt_reset() (void) 0&lt;br /&gt;
#   define uart_init() (void) 0&lt;br /&gt;
static void cput (char c) &lt;br /&gt;
{&lt;br /&gt;
    fputc (c, stdout);&lt;br /&gt;
    fflush (stdout);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#endif // avr-gcc&lt;br /&gt;
&lt;br /&gt;
// return a * b mod n&lt;br /&gt;
//   &lt;br /&gt;
// 0 &amp;lt;= a &amp;lt; n &lt;br /&gt;
// 0 &amp;lt;= b &amp;lt; n&lt;br /&gt;
//&lt;br /&gt;
// This is a school-book implementation of multiplication that allows for&lt;br /&gt;
// larger moduli compared to (a * b) % n.&lt;br /&gt;
//&lt;br /&gt;
// The implementation widens the range of valid moduli from&lt;br /&gt;
// \sqrt{1+UINT_MAX} to (1+UINT_MAX)/2.  Or vice versa, it allows us&lt;br /&gt;
// to use a smaller type for the modulus -- 16 bits in the AVR case.&lt;br /&gt;
//&lt;br /&gt;
// Moreover, ATtiny2313 has no hardware multiplyer or divider, anyway.&lt;br /&gt;
// We have to cope with 2048 bytes of program memory and are happy&lt;br /&gt;
// to avoid dragging in library routines if possible.&lt;br /&gt;
&lt;br /&gt;
static unsigned mod_mul (unsigned a, unsigned b, unsigned n)&lt;br /&gt;
{&lt;br /&gt;
    unsigned ab = 0;&lt;br /&gt;
    &lt;br /&gt;
    while (1)&lt;br /&gt;
    {&lt;br /&gt;
        if (a % 2 == 1)&lt;br /&gt;
        {&lt;br /&gt;
            ab += b;&lt;br /&gt;
            if (ab &amp;gt;= n)&lt;br /&gt;
                ab -= n;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        a = a / 2;&lt;br /&gt;
        if (a == 0)&lt;br /&gt;
            return ab;&lt;br /&gt;
            &lt;br /&gt;
        b = b * 2;&lt;br /&gt;
        if (b &amp;gt;= n)&lt;br /&gt;
            b -= n;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Return 16^k mod n&lt;br /&gt;
//&lt;br /&gt;
// Exponentiation with the same approach as above except&lt;br /&gt;
// that we binary-expand the exponent instead of a factor.&lt;br /&gt;
&lt;br /&gt;
static unsigned mod_pow16 (unsigned k, unsigned n)&lt;br /&gt;
{&lt;br /&gt;
    unsigned p = 1;&lt;br /&gt;
    unsigned _16 = 16;&lt;br /&gt;
    &lt;br /&gt;
    if (n == 1)&lt;br /&gt;
        return 0;&lt;br /&gt;
        &lt;br /&gt;
    while (_16 &amp;gt;= n)&lt;br /&gt;
        _16 -= n;&lt;br /&gt;
    &lt;br /&gt;
    while (1)&lt;br /&gt;
    {&lt;br /&gt;
        if (k % 2 == 1)&lt;br /&gt;
            p = mod_mul (_16, p, n);&lt;br /&gt;
            &lt;br /&gt;
        k = k / 2;&lt;br /&gt;
        if (k == 0)&lt;br /&gt;
            break;&lt;br /&gt;
            &lt;br /&gt;
        _16 = mod_mul (_16, _16, n);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return p;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Helper for the function below.  Return a value in (-2,2) that&lt;br /&gt;
// is equivalent to s mod 1.&lt;br /&gt;
&lt;br /&gt;
static float tame (float s)&lt;br /&gt;
{&lt;br /&gt;
    int8_t si = (int8_t) lrintf (s);&lt;br /&gt;
    &lt;br /&gt;
    if (si &amp;lt;= -2 || si &amp;gt;= 2)&lt;br /&gt;
        s -= si;&lt;br /&gt;
    &lt;br /&gt;
    return s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// The finite part mod 1 of sigma_j, i.e. partial sum where the exponent&lt;br /&gt;
// of 16 is &amp;gt;= 0.  By &amp;quot;mod 1&amp;quot; we always mean &amp;quot;up to some integer&amp;quot;,&lt;br /&gt;
// i.e. the result needs not to be normalized to [0,1).&lt;br /&gt;
&lt;br /&gt;
static float sigma_a (unsigned n, uint8_t j)&lt;br /&gt;
{&lt;br /&gt;
    float s = 0.0f;&lt;br /&gt;
    &lt;br /&gt;
    for (unsigned k = n-1; k+1 != 0; k--)&lt;br /&gt;
    {&lt;br /&gt;
        unsigned j_8k = j + 8*k;&lt;br /&gt;
        &lt;br /&gt;
        s += mod_pow16 (n-k, j_8k) / (float) j_8k;&lt;br /&gt;
&lt;br /&gt;
        // Cut down the sum and don&#039;t let it grow too big.&lt;br /&gt;
        // The bigger the number grows the less precision is&lt;br /&gt;
        // left for the fractional part we are interested in.&lt;br /&gt;
        &lt;br /&gt;
        s = tame (s);&lt;br /&gt;
        &lt;br /&gt;
        wdt_reset();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#define MARGIN 10&lt;br /&gt;
&lt;br /&gt;
static float sigma_b (unsigned n, uint8_t j)&lt;br /&gt;
{&lt;br /&gt;
    float s = 0;&lt;br /&gt;
    float _16 = 1.0f;&lt;br /&gt;
   &lt;br /&gt;
    for (unsigned k = n; k &amp;lt;= n + MARGIN; k++)&lt;br /&gt;
    {&lt;br /&gt;
        s += _16 / (8*k + j);&lt;br /&gt;
        _16 /= 16;&lt;br /&gt;
        &lt;br /&gt;
        wdt_reset();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Compute an approximation of 16^n * sigma(j)  mod 1&lt;br /&gt;
// where&lt;br /&gt;
//&lt;br /&gt;
// sigma_j = \sum_0^oo  1 / (16^k * (8k + j))&lt;br /&gt;
//&lt;br /&gt;
// The sum is split into two parts:&lt;br /&gt;
// sigma_a is the finite sum up to n.&lt;br /&gt;
// sigma_b is the finite sum from n+1 to oo&lt;br /&gt;
// and approximated by a sum from n+1 to n+MARGIN&lt;br /&gt;
&lt;br /&gt;
float sigma (unsigned n, uint8_t j)&lt;br /&gt;
{&lt;br /&gt;
    return sigma_a (n, j) + sigma_b (n, j);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Compute  pi * 16^n  up to some integer&lt;br /&gt;
// using a Bailey-Borwein-Plouffe formula for pi: &lt;br /&gt;
//&lt;br /&gt;
//     pi = 4*sigma_1 - 2*sigma_4 - sigma_5 - sigma_6&lt;br /&gt;
//&lt;br /&gt;
// with the definition of sigma_j from above.  All this&lt;br /&gt;
// is explained very nicely in the French wikipedia at&lt;br /&gt;
// http://fr.wikipedia.org/wiki/Formule_BBP&lt;br /&gt;
// &lt;br /&gt;
// For a proof define the power series&lt;br /&gt;
//&lt;br /&gt;
//     sigma_j (x) = \sum x^{8k} / (8k + j)&lt;br /&gt;
//&lt;br /&gt;
// write the sum as an integral and evaluate it at&lt;br /&gt;
// x = sqrt(1/2), see http://www.pi314.net/eng/plouffe.php&lt;br /&gt;
&lt;br /&gt;
float pi_n (unsigned n)&lt;br /&gt;
{&lt;br /&gt;
    float s = 0.0;&lt;br /&gt;
&lt;br /&gt;
    for (uint8_t i = 0; i &amp;lt; 4; i++)&lt;br /&gt;
    {&lt;br /&gt;
        // j[i] = 1, 4, 5, 6&lt;br /&gt;
        uint8_t j = i ? i + 3 : 1;&lt;br /&gt;
&lt;br /&gt;
        // c[i] = 4, -2, -1, -1&lt;br /&gt;
        int8_t c = -1;&lt;br /&gt;
        if (i == 0) c = 4;&lt;br /&gt;
        if (i == 1) c = -2;&lt;br /&gt;
        &lt;br /&gt;
        s += c * sigma (n, j);&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    return s;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// We computed pi_n = 16^n * pi  mod 1.&lt;br /&gt;
// Get the first fractional hexadecimal digit by multiplying&lt;br /&gt;
// with 16 and extracting digit 0 of the result.  Voila!&lt;br /&gt;
&lt;br /&gt;
static uint8_t pi_dig16 (unsigned n)&lt;br /&gt;
{&lt;br /&gt;
    return 15 &amp;amp; lrintf (floorf (16 * pi_n (n)));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Map 0 &amp;lt;= n &amp;lt; 16 to its hexadecimal ASCII digit&lt;br /&gt;
// &#039;0&#039;, &#039;1&#039;, ... &#039;F&#039;&lt;br /&gt;
&lt;br /&gt;
static uint8_t hexdigit (uint8_t n)&lt;br /&gt;
{&lt;br /&gt;
    n += &#039;0&#039;;&lt;br /&gt;
    return n &amp;gt; &#039;9&#039; ? n + &#039;A&#039;-&#039;0&#039;-10 : n;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    uart_init();&lt;br /&gt;
&lt;br /&gt;
    cput (&#039;\n&#039;);&lt;br /&gt;
    cput (&#039;3&#039;);&lt;br /&gt;
    cput (&#039;.&#039;);&lt;br /&gt;
    &lt;br /&gt;
    // As explained above, 16-bit integers limitate us to moduli &amp;lt;= 2^15.&lt;br /&gt;
    // The biggest modulus for n is 8n+6 so that for n &amp;gt;= 4096 we expect&lt;br /&gt;
    // garbage from the implementation if 16-bit integers are used like&lt;br /&gt;
    // with avr-gcc.  In fact, we get garbage for n &amp;gt; 4100.&lt;br /&gt;
    // It&#039;s not exacly 4095 because of the denominators in sigma_a that&lt;br /&gt;
    // delay the garbage for some values of n.&lt;br /&gt;
    &lt;br /&gt;
    // Easy going 4000 hex-digits of pi.&lt;br /&gt;
&lt;br /&gt;
    for (unsigned n = 0; n &amp;lt; 4000; n++)&lt;br /&gt;
    {&lt;br /&gt;
        // Print a line break after every 64 digits.  That way the output&lt;br /&gt;
        // can easily be compared with, e.g. the hexadecimal representation&lt;br /&gt;
        // of pi from blowfish listed in &amp;quot;First 8366 Hex Digits of PI&amp;quot; from&lt;br /&gt;
        // http://www.herongyang.com/Cryptography/&lt;br /&gt;
&lt;br /&gt;
        if (n % 64 == 0)&lt;br /&gt;
            cput (&#039;\n&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Get the n+1-th hexadecimal digit of pi and&lt;br /&gt;
        // output it as ASCII character.&lt;br /&gt;
        &lt;br /&gt;
        cput (hexdigit (pi_dig16 (n)));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    cput (&#039;\n&#039;);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/************************************************************************/&lt;br /&gt;
// We are running on ATtiny2313 bare metal, of course.&lt;br /&gt;
// Provide some minimalist output routine that writes to UART.&lt;br /&gt;
/************************************************************************/&lt;br /&gt;
&lt;br /&gt;
#ifdef __AVR__&lt;br /&gt;
&lt;br /&gt;
// !!! You must have set the fuses appropriately to run the    !!!&lt;br /&gt;
// !!! controller at desired F_CPU.  Defining F_CPU is needed  !!!&lt;br /&gt;
// !!! to get correct values to set up the UART.               !!!&lt;br /&gt;
// !!!                                                         !!!&lt;br /&gt;
// !!! DEFINING F_CPU WILL NOT CHANGE THE FREQUENCY!           !!!&lt;br /&gt;
&lt;br /&gt;
void uart_init (void)&lt;br /&gt;
{&lt;br /&gt;
    // Define F_CPU and BAUDRATE depending on your hardware setup.&lt;br /&gt;
    // For my setup, it&#039;s the followin defines in avr-gcc&#039;s command line:&lt;br /&gt;
    //    -DF_CPU=22118400 -DBAUDRATE=115200&lt;br /&gt;
&lt;br /&gt;
    unsigned ubrr = -.6 + F_CPU / (8L * BAUDRATE);&lt;br /&gt;
&lt;br /&gt;
    UBRRH = ubrr &amp;gt;&amp;gt; 8;&lt;br /&gt;
    UBRRL = ubrr;&lt;br /&gt;
&lt;br /&gt;
    // Enable UART transmitter, data mode 8N1, asynchronous.&lt;br /&gt;
&lt;br /&gt;
    UCSRA = (1 &amp;lt;&amp;lt; U2X) | (1 &amp;lt;&amp;lt; TXC);&lt;br /&gt;
    UCSRB = (1 &amp;lt;&amp;lt; TXEN);&lt;br /&gt;
    UCSRC = (1 &amp;lt;&amp;lt; UCSZ1) | (1 &amp;lt;&amp;lt; UCSZ0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
// Write one char to UART (non-buffered, blocking version).&lt;br /&gt;
&lt;br /&gt;
void uart_putc (char c)&lt;br /&gt;
{&lt;br /&gt;
    while (!(UCSRA &amp;amp; (1 &amp;lt;&amp;lt; UDRE)))&lt;br /&gt;
        wdt_reset();&lt;br /&gt;
    UDR = c;&lt;br /&gt;
&lt;br /&gt;
#ifdef HOST_WINDOWS&lt;br /&gt;
    if (c == &#039;\n&#039;)&lt;br /&gt;
        uart_putc (&#039;\r&#039;);&lt;br /&gt;
#endif // HOST_WINDOWS&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void exit (int x)&lt;br /&gt;
{&lt;br /&gt;
    (void) x;&lt;br /&gt;
&lt;br /&gt;
    while (1)&lt;br /&gt;
        wdt_reset();&lt;br /&gt;
}&lt;br /&gt;
#endif // __AVR__&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Projekte]]&lt;br /&gt;
[[Kategorie:AVR-Arithmetik]]&lt;br /&gt;
[[Kategorie:PC-Programmierung]]&lt;/div&gt;</summary>
		<author><name>Ingo k2</name></author>
	</entry>
</feed>