<?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=Philipp+burch</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=Philipp+burch"/>
	<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/articles/Spezial:Beitr%C3%A4ge/Philipp_burch"/>
	<updated>2026-04-11T03:33:41Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=LED-Fading&amp;diff=39121</id>
		<title>LED-Fading</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=LED-Fading&amp;diff=39121"/>
		<updated>2009-09-19T14:51:01Z</updated>

		<summary type="html">&lt;p&gt;Philipp burch: /* Die Kennlinie des Auges genau betrachtet */ Formel ergänzt&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 Erklärung ==&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 Kennline 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 duch das [http://de.wikipedia.org/wiki/Weber-Fechner-Gesetz Weber-Fechner-Gesetz] beschrieben. Genauere Untersuchungen zur [http://de.wikipedia.org/wiki/Gamma-Korrektur Gammakorrektur] führten jedoch zur [http://de.wikipedia.org/wiki/Stevenssche_Potenzfunktion Stevenschen Potenzfunktion]. Diese beschreibt das menschliche Auge etwas besser. Die Unterschiede sind jedoch marginal. Vorsicht! Der Artikel Gamma-Korrektur in Wikipedia verweist fälschlicherweise auf das Weber-Fechner Gesetz.&lt;br /&gt;
&lt;br /&gt;
Praktisch heißt das, daß 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^{\frac{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 wird in dem unten gezeigten Beispielprogramm gemacht. Dabei wird die Wirkung verschiedener PWM-Auflösungen demonstriert. 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]] (Anmerkung: Bitte die Exceltabelle nochmal erklären, die Werte in der Tabelle stimmen nicht mit denen im Programm überein). Die einzelnen benachbarten Werte haben zueinander ein konstantes Verhältnis, das in der Exceltabelle als &#039;Factor&#039; berechnet wird. Ausserdem werden eine 10-Bit PWM mit 64 Stufen sowie, als die Königsklasse, eine 16-Bit PWM mit 256 Stufen betrieben.&lt;br /&gt;
&lt;br /&gt;
Das Programm ist urprünglich auf einem [[AVR]] vom Typ ATmega32 entwickelt und getestet. 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 kOhm an Pin PD5 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 nicht.&lt;br /&gt;
&lt;br /&gt;
Bei Verwendung der LEDs auf dem STK500 bzw. bei der Verwendung von invertierenden Treiberstufen ist das &amp;quot;#define STK500 false&amp;quot; durch &amp;quot;#define STK500 true&amp;quot; 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;c&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;
&lt;br /&gt;
#define F_CPU 8000000L&lt;br /&gt;
&lt;br /&gt;
#define true 1&lt;br /&gt;
#define false 0&lt;br /&gt;
&lt;br /&gt;
#define STK500 false&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;inttypes.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// global variables&lt;br /&gt;
&lt;br /&gt;
uint16_t pwmtable_8A[4]   PROGMEM = {0, 16, 64, 255};&lt;br /&gt;
uint16_t pwmtable_8B[8]   PROGMEM = {0, 4,  8, 16, 32, 64,  128, 255};&lt;br /&gt;
uint16_t pwmtable_8C[16]  PROGMEM = {0, 2, 3, 4, 6, 8, 11, 16, 23, 32, 45, 64,&lt;br /&gt;
                                    90, 128, 181, 255};&lt;br /&gt;
uint16_t pwmtable_8D[32]  PROGMEM = {0, 1, 2, 2, 2, 3, 3, 4, 5, 6, 7, 8, 10, 11,&lt;br /&gt;
                                    13, 16, 19, 23, 27, 32, 38, 45, 54, 64, 76,&lt;br /&gt;
                                    91, 108, 128, 152, 181, 215, 255};&lt;br /&gt;
&lt;br /&gt;
uint16_t pwmtable_10[64]  PROGMEM = {0, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5,&lt;br /&gt;
                                    5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 15, 17,&lt;br /&gt;
                                    19, 21, 23, 26, 29, 32, 36, 40, 44, 49, 55,&lt;br /&gt;
                                    61, 68, 76, 85, 94, 105, 117, 131, 146, 162,&lt;br /&gt;
                                    181, 202, 225, 250, 279, 311, 346, 386, 430,&lt;br /&gt;
                                    479, 534, 595, 663, 739, 824, 918, 1023};&lt;br /&gt;
&lt;br /&gt;
uint16_t pwmtable_16[256] PROGMEM = {0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,&lt;br /&gt;
                                     2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,&lt;br /&gt;
                                     4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6,&lt;br /&gt;
                                     6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11,&lt;br /&gt;
                                     11, 12, 12, 13, 13, 14, 15, 15, 16, 17, 17,&lt;br /&gt;
                                     18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,&lt;br /&gt;
                                     29, 31, 32, 33, 35, 36, 38, 40, 41, 43, 45,&lt;br /&gt;
                                     47, 49, 52, 54, 56, 59, 61, 64, 67, 70, 73,&lt;br /&gt;
                                     76, 79, 83, 87, 91, 95, 99, 103, 108, 112,&lt;br /&gt;
                                     117, 123, 128, 134, 140, 146, 152, 159, 166,&lt;br /&gt;
                                     173, 181, 189, 197, 206, 215, 225, 235, 245,&lt;br /&gt;
                                     256, 267, 279, 292, 304, 318, 332, 347, 362,&lt;br /&gt;
                                     378, 395, 412, 431, 450, 470, 490, 512, 535,&lt;br /&gt;
                                     558, 583, 609, 636, 664, 693, 724, 756, 790,&lt;br /&gt;
                                     825, 861, 899, 939, 981, 1024, 1069, 1117,&lt;br /&gt;
                                     1166, 1218, 1272, 1328, 1387, 1448, 1512,&lt;br /&gt;
                                     1579, 1649, 1722, 1798, 1878, 1961, 2048,&lt;br /&gt;
                                     2139, 2233, 2332, 2435, 2543, 2656, 2773,&lt;br /&gt;
                                     2896, 3025, 3158, 3298, 3444, 3597, 3756,&lt;br /&gt;
                                     3922, 4096, 4277, 4467, 4664, 4871, 5087,&lt;br /&gt;
                                     5312, 5547, 5793, 6049, 6317, 6596, 6889,&lt;br /&gt;
                                     7194, 7512, 7845, 8192, 8555, 8933, 9329,&lt;br /&gt;
                                     9742, 10173, 10624, 11094, 11585, 12098,&lt;br /&gt;
                                     12634, 13193, 13777, 14387, 15024, 15689,&lt;br /&gt;
                                     16384, 17109, 17867, 18658, 19484, 20346,&lt;br /&gt;
                                     21247, 22188, 23170, 24196, 25267, 26386,&lt;br /&gt;
                                     27554, 28774, 30048, 31378, 32768, 34218,&lt;br /&gt;
                                     35733, 37315, 38967, 40693, 42494, 44376,&lt;br /&gt;
                                     46340, 48392, 50534, 52772, 55108, 57548,&lt;br /&gt;
                                     60096, 62757, 65535};&lt;br /&gt;
&lt;br /&gt;
// long delays&lt;br /&gt;
&lt;br /&gt;
void my_delay(uint16_t milliseconds) {&lt;br /&gt;
    for(; milliseconds&amp;gt;0; milliseconds--) _delay_ms(1);&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;
    int16_t tmp;&lt;br /&gt;
&lt;br /&gt;
#if STK500&lt;br /&gt;
    TCCR1A = 0xC1;          // inverted PWM on OC1A, 8 Bit Fast PWM&lt;br /&gt;
#else&lt;br /&gt;
    TCCR1A = 0x81;          // non-inverted PWM on OC1A, 8 Bit Fast PWM&lt;br /&gt;
#endif&lt;br /&gt;
    TCCR1B = 0x08;&lt;br /&gt;
&lt;br /&gt;
    TCCR1B &amp;amp;= ~0x7;         // clear clk setting&lt;br /&gt;
    TCCR1B |= 4;            // precaler 256 -&amp;gt; ~122 Hz PWM frequency&lt;br /&gt;
&lt;br /&gt;
    for(tmp=0; tmp&amp;lt;=3; tmp++){&lt;br /&gt;
      OCR1A =  pgm_read_word(pwmtable_8A+tmp);&lt;br /&gt;
      my_delay(delay);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(tmp=3; tmp&amp;gt;=0; tmp--){&lt;br /&gt;
      OCR1A = pgm_read_word(pwmtable_8A+tmp);&lt;br /&gt;
      my_delay(delay);&lt;br /&gt;
    }&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;
    int16_t tmp;&lt;br /&gt;
&lt;br /&gt;
#if STK500&lt;br /&gt;
    TCCR1A = 0xC1;          // inverted PWM on OC1A, 8 Bit Fast PWM&lt;br /&gt;
#else&lt;br /&gt;
    TCCR1A = 0x81;          // non-inverted PWM on OC1A, 8 Bit Fast PWM&lt;br /&gt;
#endif&lt;br /&gt;
    TCCR1B = 0x08;&lt;br /&gt;
&lt;br /&gt;
    TCCR1B &amp;amp;= ~0x7;         // clear clk setting&lt;br /&gt;
    TCCR1B |= 4;            // precaler 256 -&amp;gt; ~122 Hz PWM frequency&lt;br /&gt;
&lt;br /&gt;
    for(tmp=0; tmp&amp;lt;=7; tmp++){&lt;br /&gt;
      OCR1A = pgm_read_word(pwmtable_8B+tmp);&lt;br /&gt;
      my_delay(delay);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    for(tmp=7; tmp&amp;gt;=0; tmp--){&lt;br /&gt;
      OCR1A = pgm_read_word(pwmtable_8B+tmp);&lt;br /&gt;
      my_delay(delay);&lt;br /&gt;
    }&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;
    int16_t tmp;&lt;br /&gt;
&lt;br /&gt;
#if STK500&lt;br /&gt;
    TCCR1A = 0xC1;          // inverted PWM on OC1A, 8 Bit Fast PWM&lt;br /&gt;
#else&lt;br /&gt;
    TCCR1A = 0x81;          // non-inverted PWM on OC1A, 8 Bit Fast PWM&lt;br /&gt;
#endif&lt;br /&gt;
    TCCR1B = 0x08;&lt;br /&gt;
&lt;br /&gt;
    TCCR1B &amp;amp;= ~0x7;         // clear clk setting&lt;br /&gt;
    TCCR1B |= 4;            // precaler 256 -&amp;gt; ~122 Hz PWM frequency&lt;br /&gt;
&lt;br /&gt;
    for(tmp=0; tmp&amp;lt;=15; tmp++){&lt;br /&gt;
      OCR1A = pgm_read_word(pwmtable_8C+tmp);&lt;br /&gt;
      my_delay(delay);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(tmp=15; tmp&amp;gt;=0; tmp--){&lt;br /&gt;
      OCR1A = pgm_read_word(pwmtable_8C+tmp);&lt;br /&gt;
      my_delay(delay);&lt;br /&gt;
    }&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;
    int16_t tmp;&lt;br /&gt;
&lt;br /&gt;
#if STK500&lt;br /&gt;
    TCCR1A = 0xC1;          // inverted PWM on OC1A, 8 Bit Fast PWM&lt;br /&gt;
#else&lt;br /&gt;
    TCCR1A = 0x81;          // non-inverted PWM on OC1A, 8 Bit Fast PWM&lt;br /&gt;
#endif&lt;br /&gt;
    TCCR1B = 0x08;&lt;br /&gt;
&lt;br /&gt;
    TCCR1B &amp;amp;= ~0x7;         // clear clk setting&lt;br /&gt;
    TCCR1B |= 4;            // precaler 256 -&amp;gt; ~122 Hz PWM frequency &lt;br /&gt;
&lt;br /&gt;
    for(tmp=0; tmp&amp;lt;=31; tmp++){&lt;br /&gt;
      OCR1A = pgm_read_word(pwmtable_8D+tmp);&lt;br /&gt;
      my_delay(delay);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(tmp=31; tmp&amp;gt;=0; tmp--){&lt;br /&gt;
      OCR1A = pgm_read_word(pwmtable_8D+tmp);&lt;br /&gt;
      my_delay(delay);&lt;br /&gt;
    }&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;
    int16_t tmp;&lt;br /&gt;
&lt;br /&gt;
#if STK500&lt;br /&gt;
    TCCR1A = 0xC3;          // inverted PWM on OC1A, 10 Bit Fast PWM&lt;br /&gt;
#else&lt;br /&gt;
    TCCR1A = 0x83;          // non-inverted PWM on OC1A, 10 Bit Fast PWM&lt;br /&gt;
#endif&lt;br /&gt;
    TCCR1B = 0x08;&lt;br /&gt;
&lt;br /&gt;
    TCCR1B &amp;amp;= ~0x7;         // clear clk setting&lt;br /&gt;
    TCCR1B |= 3;            // precaler 64 -&amp;gt; ~122 Hz PWM frequency&lt;br /&gt;
&lt;br /&gt;
    for(tmp=0; tmp&amp;lt;=63; tmp++){&lt;br /&gt;
      OCR1A = pgm_read_word(pwmtable_10+tmp);&lt;br /&gt;
      my_delay(delay);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(tmp=63; tmp&amp;gt;=0; tmp--){&lt;br /&gt;
      OCR1A = pgm_read_word(pwmtable_10+tmp);&lt;br /&gt;
      my_delay(delay);&lt;br /&gt;
    }&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;
    int16_t tmp;&lt;br /&gt;
&lt;br /&gt;
#if STK500&lt;br /&gt;
    TCCR1A = 0xC2;          // inverted PWM on OC1A, 16 Bit Fast PWM&lt;br /&gt;
#else&lt;br /&gt;
    TCCR1A = 0x82;          // non-inverted PWM on OC1A, 16 Bit Fast PWM&lt;br /&gt;
#endif&lt;br /&gt;
    TCCR1B = 0x18;&lt;br /&gt;
    ICR1 = 0xFFFF;          // TOP for PWM, full 16 Bit&lt;br /&gt;
&lt;br /&gt;
    TCCR1B &amp;amp;= ~0x7;         // clear clk setting&lt;br /&gt;
    TCCR1B |= 1;            // precaler 1 -&amp;gt; ~122 Hz PWM frequency&lt;br /&gt;
&lt;br /&gt;
    for(tmp=0; tmp&amp;lt;=255; tmp++){&lt;br /&gt;
      OCR1A = pgm_read_word(pwmtable_16+tmp);&lt;br /&gt;
      my_delay(delay);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for(tmp=255; tmp&amp;gt;=0; tmp--){&lt;br /&gt;
      OCR1A = pgm_read_word(pwmtable_16+tmp);&lt;br /&gt;
      my_delay(delay);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    int16_t i;&lt;br /&gt;
    int16_t step_time=400;      // delay in millisecond for one fading step&lt;br /&gt;
&lt;br /&gt;
    DDRD |= (1&amp;lt;&amp;lt;PD5);           // LED uses OC1A&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;
      for(i=0; i&amp;lt;3; i++) pwm_8_8(step_time/2);&lt;br /&gt;
      my_delay(1000);    &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;
      for(i=0; i&amp;lt;3; i++) pwm_8_32(step_time/8);&lt;br /&gt;
      my_delay(1000);&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;
      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;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
[[Category:AVR]]&lt;br /&gt;
[[Category:Displays und Anzeigen]]&lt;/div&gt;</summary>
		<author><name>Philipp burch</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=LPC2000&amp;diff=36184</id>
		<title>LPC2000</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=LPC2000&amp;diff=36184"/>
		<updated>2009-05-18T14:12:24Z</updated>

		<summary type="html">&lt;p&gt;Philipp burch: /* Weblinks */  typos&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die LPC2000 von NXP (ehemals Philips) waren die ersten wegen ihrer einfachen Handhabung hobbytauglichen [[ARM]]-basierten Mikrocontroller. Entsprechend sind auch zum LPC2000 mehr Informationen verfügbar als z.B. zum [[AT91SAM]]7, und man findet leichter Hilfe bei Problemen. Ein weiterer Vorteil des LPC2000 ist der einfach zu benutzende serielle Bootloader, mit dem sich der Controller auch ohne JTAG-Interface einfach programmieren lässt. Ansonsten ist die Hardwareausstattung recht ähnlich im Vergleich zum AT91SAM7. Hervorzuhebende Unterschiede sind das schnellere Flash-ROM des LPC2000, die etwas höhere Taktfrequenz, beim gleichen Gehäuse mehr I/O-Pins und die größere Auswahl von Modellen im Low-End-Bereich (LPC2103).&lt;br /&gt;
&lt;br /&gt;
* 2-64 kB [[RAM|SRAM]].&lt;br /&gt;
* bis zu 512 kB [[Flash-ROM]]-Programmspeicher (LPC2138/2148/2368/2378)&lt;br /&gt;
* vorinstallierter serieller [[Bootloader]] mit automatischer [[Baud]]rate-Erkennung&lt;br /&gt;
* [[JTAG]]-Interface&lt;br /&gt;
* ETM Trace-Interface&lt;br /&gt;
* 2-4 [[UART]]-Schnittstellen (bei einigen Modellen auch mit allen &amp;quot;Modem&amp;quot;-Leitungen (Handshake, Ring, DTR etc.)&lt;br /&gt;
* 1-2 [[SPI]]-Schnittstelle(n), bei einigen Modellen auch SSP-Schnittstelle(n) (erweiterte Konfigurationsmöglichkeiten und Funktionen)&lt;br /&gt;
* Hardware-[[I2C]](I²C)-Schnittstelle(n)&lt;br /&gt;
* teilw. mit CAN-Schnittstellen&lt;br /&gt;
* Mit Ausnahme der ersten Chips LPC2104/5/6 haben alle Typen einen integrierten A/D-Wandlern&lt;br /&gt;
* teilw. mit D/A-Wandler (LPC2132/34/36/38, LPC2142/44/46/48)&lt;br /&gt;
* 2 32 Bit [[Timer]], zusätzlicher 32-bit [[Timer]] mit 6 [[Pulsweitenmodulation|PWM]]-Ausgängen, RTC, [[Watchdog]]&lt;br /&gt;
* bis 75 MHz Taktfrequenz&lt;br /&gt;
* [[IC-Gehäuseformen|LQFP48]]-Gehäuse (LPC210x) bis LQFP144 (LPC22xx)&lt;br /&gt;
* LPC213x und LPC214x benötigen zum Betrieb 3V&lt;br /&gt;
* Für die anderen Typen werden Core-Spannung 1,65-1,95V und IO-Spannung 3,0-3,6V benötigt (d.h. zum Betrieb sind 2 Versorgungsspannungen erforderlich)&lt;br /&gt;
* geringe Leistungsaufnahme (ca. 60 mW bei 60 MHz und Endlosschleife)&lt;br /&gt;
* 5V-tolerante IOs&lt;br /&gt;
* USB 2.0 (LPC214x und LPC23xx/24xx)&lt;br /&gt;
* Ethernet MAC (LPC23xx/24xx)&lt;br /&gt;
* Jeweils eigene DMA und eigener AHB-Bus für Ethernet, USB und sonstige schnelle Schnittstellen (LPC23xx und LPC24xx)&lt;br /&gt;
* RTC (teilweise mit eigenem Oszillator)&lt;br /&gt;
&lt;br /&gt;
== Verwendung des Bootloaders ==&lt;br /&gt;
&lt;br /&gt;
Benötigte Software gibt es unter http://groups.yahoo.com/group/lpc21isp &lt;br /&gt;
(Registrierung nötig, Source Code und Binaries in der File Section dieser Gruppe)&lt;br /&gt;
&lt;br /&gt;
# BSL-Jumper setzen&lt;br /&gt;
# Reset-Knopf drücken&lt;br /&gt;
# lpc21isp starten&lt;br /&gt;
#* Linux: lpc21isp programm.hex /dev/ttyS0 115200 14746&lt;br /&gt;
#* Windows: lpc21isp programm.hex com1 115200 14746&lt;br /&gt;
&lt;br /&gt;
Die Übertragung des Programms zum Controller sollte jetzt beginnen. Um das Programm zu starten den &#039;&#039;&#039;BSL-Jumper entfernen&#039;&#039;&#039; und Reset drücken.&lt;br /&gt;
&lt;br /&gt;
Alternativ kann unter MS-Windows das von Philips bereitgestellte &amp;quot;Flash-Tool&amp;quot; oder Flash Magic von Embedded Systems Academy genutzt werden. Diese Programmiersoftware bieten eine grafische Benutzeroberfläche.&lt;br /&gt;
&lt;br /&gt;
Sowohl lpc21isp also auch das Philips-Tool und Flash Magic können Reset und BSL per DTR/RTS-Signal steuern, bei entsprechender Beschaltung auf dem Board muss man somit keine Jumper setzen (vgl. z.B. Schaltpläne der Evaluation-Boards von [http://www.keil.com Keil]).&lt;br /&gt;
&lt;br /&gt;
Eine weitere Alternative ist [http://home.arcor.de/bernhard.michelis/LPC/index.html LPCProg 0.3], welches speziel für auf die Verwendung eines FTDI-232 Chips hin optimiert wurde. Auf der Website gibt es auch ein Layout für einen USB-zu-Seriel-Adapter. Die Software/Hardware ist zu den obigen Programmen Pinkompatibel und kann beliebig damit gemixt werden.&lt;br /&gt;
&lt;br /&gt;
== Allgemeine Hinweise ==&lt;br /&gt;
* Der Softwareschutz bei den LPC2104/5/6 ist nicht implementiert (Stand 4/2005). Dies wird Anfang 2007 geändert. Ein Schutz des geistigen Eigentums ist also bei diesen 3 Controllern derzeit nicht gewährleistet. Andere Controller aus der LPC2000-Serie sind davon nicht betroffen.&lt;br /&gt;
* Auf vielen (Stand 4/2005) LPC2000 existiert ein Fehler bei der Verwaltung der Interrupt-Flags (&amp;quot;race condition&amp;quot;, &amp;quot;timer issue&amp;quot;). Der Fehler und mögliche Abhilfen sind in den Errata von NXP erläutert.&lt;br /&gt;
* Die CAN Controller in den LPC2100,2200 sind so gründlich mit Bugs und Designfehlern gespickt, dass letztlich nur ein kleiner Bruchteil der dokumentierten Funktionen nutzbar ist. Die Bugs finden sich im Errata Sheet, die Konstruktionsfehler darf man selber finden. &lt;br /&gt;
* Bei Nutzung des SPI-Interfaces im &amp;quot;Master-Mode&amp;quot; ist bei einigen LPC2000-Typen auf die richtige Beschaltung des &amp;quot;Chip-Select&amp;quot;-Pins zu achten (vgl. Manuals und Erratas). &lt;br /&gt;
* Viele Fehler in der &amp;quot;ersten Generation&amp;quot; der ICs wurden bei neueren Versionen behoben. Vgl. Datenblätter/Errata zu LPC2xxx/01.&lt;br /&gt;
* Bei neueren LPCs (LPC213x/4x) sollte die aktuelle Fassung der NXP ISP-Software genutzt werden (Stand 3/2006: V2.2.2, erhältlich auf der NXP Web-Site). Ältere Versionen funktionieren nicht zuverlässig oder garnicht.&lt;br /&gt;
* LPC23xx/24xx werden von der Philips ISP-Software nicht unterstützt. Alternativen: Flashmagic oder lpc21isp.&lt;br /&gt;
* Bei Problemen immer auch das Archiv der LPC2000 yahoo-Gruppe absuchen. Dort finden sich, leider oft etwas zerstreut, sehr nützliche Hinweise. Die Anmeldung bei der Gruppe (yahoo-Account erforderlich) gewährt Zugang zum Download-Bereich der Gruppe. Dort finden sich sehr nützliche Beispielprogramme, Libraries und Dokumente.&lt;br /&gt;
* Bei Entwicklungen mit der GNU-Toolchain erweisen sich Beispiele von kommerziellen Compiler/IDE-Anbietern, die ebenfalls den GNU-Compiler nutzen, oft als gute Informationsquelle vor allem bei Einstellungen zum Startup-Code oder im Linker-Script. (vgl. u.a. Rowley, Keil, Anglia-Designs)&lt;br /&gt;
* siehe auch: [http://www.open-research.org.uk/ARMuC/index.cgi?LPC2100Tips LPC2100-Tips] im ARMuC Wiki (englisch)&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[ARM-elf-GCC-Tutorial]]&lt;br /&gt;
* [[Linksammlung#ARM|Linksammlung Abschnitt ARM]]&lt;br /&gt;
* [[LPC2000-Boards von Olimex]]&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://www.standardics.nxp.com/products/lpc2000/all/ Philips / NXP LPC2000]&lt;br /&gt;
* [http://groups.yahoo.com/group/lpc2000/ LPC2000 Yahoo Group]&lt;br /&gt;
* [http://www.dreamislife.com/arm/ LPC210x ARM7 Microcontroller Tutorial]&lt;br /&gt;
* [http://www.dontronics-shop.com/tutorials.html Dontronics Tutorials] u.a. &amp;quot;ARM Cross Development with Eclipse Version 3&amp;quot; von James P. Lynch&lt;br /&gt;
* [http://www.hitex.co.uk/arm/lpc2000book/free_downloadpage.html The Insider&#039;s Guide To The Philips ARM7-Based Microcontrollers (LPC21xx)] bei http://www.hitex.co.uk&lt;br /&gt;
* [http://groups.yahoo.com/group/lpc21isp lpc21isp] -  Kommandozeilen-ISP-Tool für Linux und MS-Windows&lt;br /&gt;
* [http://www.esacademy.com/software/flashmagic/ Flash Magic] ISP-Tool&lt;br /&gt;
* [http://www.pjrc.com/arm/lpc2k_pgm/ LPC2K_PGM] - ISP-Tool mit GUI für Linux/GTK&lt;br /&gt;
* [http://www.sandring-systems.de/index.php5?lang=en&amp;amp;p=lf4l lpcflash4linux] - ISP-Tool für Linux (Kommandozeile)&lt;br /&gt;
* [http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/ ARM projects] - LPC2000-Projekte und -Beispiele von Martin Thomas&lt;br /&gt;
* [http://www.jandspromotions.com/philips2005/DE-list.htm LPC2138 Design Contest] - Viele Beispiele mit Hard- and Software&lt;br /&gt;
* [http://www.ixbat.de/index.php?page_id=94 LPC2103 unter Linux entwickeln] - LED blink mit gcc unter Linux&lt;br /&gt;
* [http://www.thegnar.org/nav/LPCgettingstarted.html Bringing up the LPC-P212x] - Bauen einer Toolchain mit Newlib, ISP, JTAG&lt;br /&gt;
* [http://home.arcor.de/bernhard.michelis/LPC/index.html LPCProg 0.3] - Geschwindigkeitsoptimierte Version für USB-zu-Seriell-Wandler, Kommandozeilen-ISP-Tool für MS-Windows; Einfaches Demo-Board verfügbar &lt;br /&gt;
&lt;br /&gt;
[[Category:ARM]] [[Category:Mikrocontroller]]&lt;br /&gt;
__NOTOC__&lt;/div&gt;</summary>
		<author><name>Philipp burch</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Versorgung_aus_einer_Zelle&amp;diff=36159</id>
		<title>Versorgung aus einer Zelle</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Versorgung_aus_einer_Zelle&amp;diff=36159"/>
		<updated>2009-05-17T08:01:06Z</updated>

		<summary type="html">&lt;p&gt;Philipp burch: /* ICs */ ATtiny43U ergänzt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Bei batteriebetriebenen Anwendungen stellt sich oft das Problem der Spannungsversorgung. Darauf soll hier näher eingegangen werden.&lt;br /&gt;
&lt;br /&gt;
= Erste Ideen =&lt;br /&gt;
&lt;br /&gt;
=== 9V-Block mit Linearregler ===&lt;br /&gt;
&lt;br /&gt;
Die erste Idee, einen 9V-Block herzunehmen und einen Linearregler a la 7805 hinzuhängen mag zwar einfach erscheinen, hat aber jedoch einen extrem schlechten Wirkungsgrad (bei Runterregelung auf 5V muss der Regler immerhin 45% verbraten =&amp;gt; 55% Wirkungsgrad, bei 3,3V nur noch 36%), und auch der Platzbedarf ist vergleichsweise alles andere als gering. Auch braucht der klassische 7805 ca. 5mA für sich selber. Das ist meist mehr als ein Mikrocontroller! Bei weitem besser sind hier Low Power Linearregler wie z.B. der [http://www.national.com/mpf/LP/LP2950.html LP2950]. Dieser benötigt ca. 75&amp;amp;mu;A. Als Extrembeispiel sei hier der [http://focus.ti.com/docs/prod/folders/print/tps71501.html TPS715xx] von [http://www.ti.com Texas Instuments] genannt, der mit unglaublichen 3,2 &amp;amp;mu;A auskommt!&lt;br /&gt;
Statt des Linearreglers könnte man natürlich auch einen Step-Down-Schaltregler benutzen, dann hätte man zumindest einen besseren Wirkungsgrad von 80-90%. Last but not least muss man auch sagen, dass die Energiedichte von 9V-Blocks eher gering ist im Verhältnis zu Mignonzellen.&lt;br /&gt;
&lt;br /&gt;
http://data.energizer.com/ (Auf Technical Info oben rechts clicken, dann die Batteriefamilie links auswählen, z.B. Alkaline)&lt;br /&gt;
&lt;br /&gt;
{| border =&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;18%&amp;quot; | Batterietyp &lt;br /&gt;
! Volumen [cm³] &lt;br /&gt;
! Kapazität [mAh] &lt;br /&gt;
! mittlere&amp;lt;BR&amp;gt;Ausgangs-&amp;lt;BR&amp;gt;spannung [V] &lt;br /&gt;
! Energiegehalt [mWh] &lt;br /&gt;
! Energiedichte [mWh/cm³] &lt;br /&gt;
! Masse [g]&lt;br /&gt;
|-&lt;br /&gt;
|9V Alkaline&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 21,1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 625&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 7&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 4375&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 207&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 45,6&lt;br /&gt;
|-&lt;br /&gt;
|Mono Alkaline [D]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 56&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 20500&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1,3&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 26650&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 475&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 148&lt;br /&gt;
|-&lt;br /&gt;
|Baby Alkaline [C]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 26,9&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 8350&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1,3&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 10855&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 404&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 26,2&lt;br /&gt;
|-&lt;br /&gt;
|Mignon Alkaline [AA]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 8,1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 2850&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1,3&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 3705&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 457&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 23&lt;br /&gt;
|-&lt;br /&gt;
|Micro Alkaline [AAA]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 3,8&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1250&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1,3&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1625&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 428&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 11,5&lt;br /&gt;
|-&lt;br /&gt;
|Lithiumzelle, 2032&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 240&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 2,9&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 496&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 653&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Vier Mignonzellen mit LowDrop-Linearregler ===&lt;br /&gt;
&lt;br /&gt;
Als weitere Möglichkeit wären vier Mignonzellen (= 6V) zu verwenden und dahinter einen LowDrop-Linearregler zu schalten. Der Platzbedarf ist immer noch gross, der Wirkungsgrad besser (ca 90%). Allerdings bleibt ein Nachteil: Die Batterien werden nie wirklich geleert, nichtmal annähernd, weil sie bereits bei 1,25V pro Zelle zusammen gerade noch 5V ergeben, der Regler aber auch gern noch seinen Teil abhaben will (Dropout Voltage). Zu bedenken sind hierbei die Entladekennlinien von Batterien, oder noch schlimmer die von Akkus.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; &lt;br /&gt;
|+ Sparsame Spannungsregler&lt;br /&gt;
|-&lt;br /&gt;
!Bezeichnung&lt;br /&gt;
!Ausgangsspannung [V]&lt;br /&gt;
!Stromverbrauch [uA]&lt;br /&gt;
|-&lt;br /&gt;
|LP2950&lt;br /&gt;
| align=&amp;quot;center&amp;quot; |3/3,3/5&lt;br /&gt;
| align=&amp;quot;center&amp;quot; |75&lt;br /&gt;
|-&lt;br /&gt;
|LF33&lt;br /&gt;
| align=&amp;quot;center&amp;quot; |3,3&lt;br /&gt;
| align=&amp;quot;center&amp;quot; |500&lt;br /&gt;
|-&lt;br /&gt;
|LF50&lt;br /&gt;
| align=&amp;quot;center&amp;quot; |5&lt;br /&gt;
| align=&amp;quot;center&amp;quot; |500&lt;br /&gt;
|-&lt;br /&gt;
|TPS715&lt;br /&gt;
| align=&amp;quot;center&amp;quot; |1,2..5&lt;br /&gt;
| align=&amp;quot;center&amp;quot; |3.2&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Drei Mignonzellen ohne Spannungsregler ===&lt;br /&gt;
&lt;br /&gt;
Die meisten modernen [[Mikrocontroller]] haben einen sehr weiten Versorgungsspannungsbereich, teilweise von 1,8V bis 5,5V. Damit ist es möglich, sie direkt mit drei in Reihe geschalteten Zellen zu betreiben. Während der Entladung sinkt die Betriebsspannung (3x0,8V=2,4V), was der Mikrocontroller aber verkraftet, sofern er nicht mit maximalem Takt läuft. Wenn keine weiteren ICs in der Schaltung benötigt werden, oder diese ebenso tolerant bezüglich einer veränderlichen Versorgungsspannung sind, ist diese Methode die einfachste und günstigste (100% Wirkungsgrad). Vor allem bei [[Ultra low power | Low Power]] Anwendungen mit [[Sleep Mode]] wird hier kein Mikroampere für einen Spannungsregler verschwendet.&lt;br /&gt;
&lt;br /&gt;
=== Lithiumzelle ===&lt;br /&gt;
&lt;br /&gt;
Diese haben eine sehr geringe Selbstentladung und hohe Spannung von typisch 3V. Damit kann man einen sparsamen Mikrocontroller betreiben. Meist werden diese Zellen für Echtzeituhren und zum Datenerhalt von RAMs genutzt, da hier nur sehr geringe Ströme im Mikroamperebereich benötigt werden. Darauf sind diese Zellen ausgelegt. Aus den meisten kann man nur einige mA entnehmen, bei 10mA und mehr sinkt die verfügbare Kapazität rapide.&lt;br /&gt;
&lt;br /&gt;
Um ein Gerät nur im Notfall mit einer Lithiumzelle zu betreiben (Pufferbetrieb, Netzausfallsicherung), braucht man eine unterbrechungsfrei Umschaltung zwischen Netzteilbetrieb und Batteriebetrieb. Kritisch ist das vor allem für die Lithiumzelle (damit ist kein Lithiumakku gemeint!), da diese nicht aufgeladen werden darf. Sie wird dabei mit heftiger Reaktion zerstört! Eine einfache Schaltung ist die Nutzung von zwei Schottkydioden zur Entkopplung von Batterie und Netzteil wie es im Artikel &#039;&#039;Speicher&#039;&#039; über  [[Speicher#EEPROM_Schreibzugriffe_minimieren | EEPROM]] gezeigt wird. Der Nachteil dieser Lösung ist der relativ hohe Spannungsabfall von 300..400mV über den Dioden. Besser ist der Einsatz eines P-Kanal MOSFETs zum Schalten der Batteriespannung. Dadurch kann der Spannungsabfall auf wenige Millivolt gesenkt werden. Die Schaltung dazu ist im diesem [http://www.mikrocontroller.net/topic/72275#591483 Beitrag] zu finden.&lt;br /&gt;
&lt;br /&gt;
= Bessere Lösungsansätze =&lt;br /&gt;
&lt;br /&gt;
Wie man sehen kann sind oben dargestellte Methoden nur bedingt zufriedenstellend. Vor allem der Platzbedarf dürfte ein KO-Kriterium sein. Besser wäre es nur eine oder zwei Zellen zu verwenden.&lt;br /&gt;
&lt;br /&gt;
== Step-Up-Schaltregler ==&lt;br /&gt;
&lt;br /&gt;
Step-Up-Schaltregler bringen die Spannung, wie der Name schon sagt, &#039;einen Schritt nach oben&#039;. Ideal also um aus 1,5V oder 3V z.B. 5V zu machen. Desweiteren sind sie auch geeignet, um höhere Ströme (bis 0,5A, je nach Aufbau und Spule) zu entnehmen. Das Arbeitsprinzip bei Step-Up-Schaltreglern ist immer gleich: Eine Spule wird ständig an- und abgeschaltet und durch Eigeninduktion eine höhere Spannung erzeugt. Um einen Step-Up-Schaltregler aufzubauen, gibt es verschiedene Möglichkeiten:&lt;br /&gt;
&lt;br /&gt;
=== ICs ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* zuverlässig&lt;br /&gt;
* meist wenig Außenbeschaltung nötig&lt;br /&gt;
* geringe Größe, auch der Spule, da hohe Schaltfrequenzen verwendet werden&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteile:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* teuer, vor allem die ab 1V arbeiten&lt;br /&gt;
* teilweise schwer zu bekommen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Auflistung von Schaltregler-ICs:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Bauteile]]&lt;br /&gt;
* [http://www.tranzistoare.ro/datasheets/2300/57048_DS.pdf LT1073-5] (PDF): 1V (1 Zelle) auf 5V, 40mA&lt;br /&gt;
* [http://www.ortodoxism.ro/datasheets/lineartechnology/lt1301.pdf LT1301] (PDF): 2V (2 Zellen) auf 5V oder 12V, 250mA (erhältlich bei Conrad)&lt;br /&gt;
* [http://www.ortodoxism.ro/datasheets/lineartechnology/lt1302.pdf LT1302] (PDF): 2V (2 Zellen) auf 5V oder 12V, 250mA (erhältlich bei Reichelt und Conrad)&lt;br /&gt;
* [http://www.ortodoxism.ro/datasheets/lineartechnology/3401fa.pdf LTC3401]  (PDF) - ziemlich geniales Teil, weil es mit hoher Schaltfrequenz arbeitet, dadurch kann eine kleine Spule verwendet und ein sehr hoher Wirkungsgrad erzielt werden.&lt;br /&gt;
* [http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1003,C1042,C1031,C1060,P13393,D9338 LTC3525-5] (PDF)&lt;br /&gt;
* [http://www.ortodoxism.ro/datasheets/maxim/MAX1722-MAX1724.pdf MAX1724] (PDF)&lt;br /&gt;
* [http://www.ortodoxism.ro/datasheets/maxim/MAX1674-MAX1676.pdf MAX1674] (PDF) - bis zu ein Ampere, bei einer Zelle ist aber bei 100mA Schluss, und das auch nur, wenn die Spannung beim &amp;quot;Hochfahren&amp;quot; höher war und die richtige Spule verwendet wird&lt;br /&gt;
* [http://www.sipex.com/Files/DataSheets/sp6648.pdf SP6648] (PDF)&lt;br /&gt;
* [http://focus.ti.com/lit/ds/symlink/tps61200.pdf TPS61200/201/202] (PDF) - 1,8..5,5V out, Quellspannung bis herunter auf 0,3V, ?&amp;gt;90%, 0,5mm Pinabstand, 3,15*3,15mm&lt;br /&gt;
* TPS6030x, TPS6031x, [http://www.ortodoxism.ro/datasheets/lineartechnology/15023f.pdf LTC1502-3.3]  (PDF) (typ. 3,x V bei 15-20 mA)&lt;br /&gt;
* [http://www.ortodoxism.ro/datasheets2/7/0y1y62f9lzj79rs7uuf28jq4xtwy.pdf LM2621] (PDF)&lt;br /&gt;
* [[MC34063]]&lt;br /&gt;
* [http://atmel.com/dyn/products/product_card.asp?part_id=4523 ATtiny43U] - AVR-Microcontroller, der einen Boost-Converter eingebaut hat und damit eine Batterie bis auf 0.7V aussaugen kann.&lt;br /&gt;
&lt;br /&gt;
=== Diskrete Schaltungen ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile:&#039;&#039;&#039;&lt;br /&gt;
* größtmögliche Anpassung an Verwendungszweck&lt;br /&gt;
* teilweise schon mit Standardhühnerfutter aufzubauen&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteile:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* kompliziert&lt;br /&gt;
* nicht garantierte Funktion (z.B. wegen gepulster Gleichspannung)&lt;br /&gt;
* schlechte EMV-Eigenschaften&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Auflistung diskreter Step-Up-Schaltregler:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* http://www.elektronik-kompendium.de/forum/forum_entry.php?id=17395&lt;br /&gt;
* http://www.mikrocontroller.net/topic/73532#604774&lt;br /&gt;
* [http://www.nxp.com/acrobat_download/applicationnotes/AN10218_1.pdf NXP AN10218] (PDF) (Philips LPC900 microcontroller) single cell power supply&lt;br /&gt;
* [http://www.b-kainka.de/bastel36.htm Der LED-Spannungswandler] von B. Kainka&lt;br /&gt;
* [http://www.bigclive.com/joule.htm Make a Joule Thief] - Versorgung einer LED aus einer 1,5V Zelle&lt;br /&gt;
* Diskussionen von &#039;&#039;&#039;Joule-Thief&#039;&#039;&#039; Schaltungen im Forum&lt;br /&gt;
** [http://www.mikrocontroller.net/topic/47224 Sensor autark betreiben mit einem Thermogenerator]&lt;br /&gt;
** [http://www.mikrocontroller.net/topic/55041 LEDs mit Akku(s) effizient betreiben]&lt;br /&gt;
** [http://www.mikrocontroller.net/topic/38163 Wie kann man eine Knopfzellenspannung um ca. 1 Volt erhöhen]&lt;br /&gt;
** [http://www.mikrocontroller.net/topic/62158 Spannungsanhebung 1,2V -&amp;gt; 2V]&lt;br /&gt;
** [http://www.mikrocontroller.net/topic/77154 Step-Up Transistorschaltung für LED Lampe]&lt;br /&gt;
** [http://www.mikrocontroller.net/topic/56523 3x 2,9V LEDs mit 2xAAA versorgen]&lt;br /&gt;
** [http://www.mikrocontroller.net/topic/55962 Gibt es eine Möglichkeit LEDs bei 1V zu betreiben]&lt;br /&gt;
** [http://cappels.org/dproj/ledpage/leddrv.htm#Rusty_Nail_Night_Light Rusty Nail Night Light]&lt;br /&gt;
&lt;br /&gt;
== Ladungspumpen ==&lt;br /&gt;
&lt;br /&gt;
Ladungspumpen erhöhen die Spannung, indem sie Kondensatoren zyklisch parallel laden, umpolen und in Reihe entladen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile:&#039;&#039;&#039;&lt;br /&gt;
* geringer Stromverbrauch, deshalb für Low-Power-Anwendungen gut geeignet&lt;br /&gt;
* keine Spulen, deshalb kein magnetisches Störfeld&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteile:&#039;&#039;&#039;&lt;br /&gt;
* nur geringe Ausgangsströme möglich (100mA)&lt;br /&gt;
* ICs nur für höhere Eingangspannungen erhältlich, ab 3V&lt;br /&gt;
* Teilweise starke Strompulse beim Umladen der Kondensatoren, womit empfinfdliche Analogschaltungen gestört werden können (Funkempfänger etc.)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Auflistung von Ladungspumpen:&#039;&#039;&#039;&lt;br /&gt;
* TPS60300 - Vin 0,9-1,8V&lt;br /&gt;
* TPS60100 - Vin 1,8-3,6V (200mA)&lt;br /&gt;
* MAX1759 - Vin 1,6-5,5V (2-3 Zellen)&lt;br /&gt;
&lt;br /&gt;
= Forumsbeiträge zum Thema =&lt;br /&gt;
&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/45101#new 3v3 Volt aus einer 1v2 Volt Zelle]&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/18789#new Stromversorgung aus einer Zelle]&lt;br /&gt;
*[http://www.mikrocontroller.net/topic/73532#new Step-Up Mignon zu 5V]&lt;br /&gt;
&lt;br /&gt;
= Externe Links =&lt;br /&gt;
&lt;br /&gt;
* [http://www.powerdesigners.com/InfoWeb/ Powerdesigners InfoWeb] - Free tools, resources and education for power electronics designers and students (engl.)&lt;br /&gt;
* http://www.ti.com/power&lt;br /&gt;
* [http://focus.ti.com/lit/an/slaa105/slaa105.pdf TI Application Report SLAA 105] Simple 1.5-V Boost Converter for MSP430&lt;br /&gt;
* http://www.maxim-ic.com/products/power/&lt;br /&gt;
* 2-6V DC nach 5V DC Konverter auf der Basis des &#039;&#039;&#039;LT1302&#039;&#039;&#039; als  [http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=83&amp;amp;products_id=195 Fertigmodul] bzw. [http://www.shop.robotikhardware.de/shop/catalog/product_info.php?products_id=194 Platine] (Shop robotikhardware.de)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Bauteile]]&lt;/div&gt;</summary>
		<author><name>Philipp burch</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR-Tutorial:_UART&amp;diff=35751</id>
		<title>AVR-Tutorial: UART</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR-Tutorial:_UART&amp;diff=35751"/>
		<updated>2009-04-19T16:45:38Z</updated>

		<summary type="html">&lt;p&gt;Philipp burch: /* UART konfigurieren */  Anmerkung über UDRE/TXC-Problematik ergänzt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Wie viele andere Controller besitzen die meisten AVRs einen &#039;&#039;&#039;[[UART]]&#039;&#039;&#039; (&#039;&#039;&#039;U&#039;&#039;&#039;niversal &#039;&#039;&#039;A&#039;&#039;&#039;synchronous &#039;&#039;&#039;R&#039;&#039;&#039;eceiver and &#039;&#039;&#039;T&#039;&#039;&#039;ransmitter). Das ist eine serielle Schnittstelle, die meistens zur Datenübertragung zwischen Mikrocontroller und PC genutzt wird. Zur Übertragung werden zwei Pins am Controller benötigt: &#039;&#039;&#039;TXD&#039;&#039;&#039; und &#039;&#039;&#039;RXD&#039;&#039;&#039;. Über &#039;&#039;&#039;TXD&#039;&#039;&#039; (&amp;quot;Transmit Data&amp;quot;) werden Daten gesendet, &#039;&#039;&#039;RXD&#039;&#039;&#039; (&amp;quot;Receive Data&amp;quot;) dient zum Empfang von Daten.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
&lt;br /&gt;
Um den UART des Mikrocontrollers zu verwenden, muss der Versuchsaufbau um folgende Bauteile erweitert werden: &lt;br /&gt;
&lt;br /&gt;
[[Bild:AVR-RS232.png|640px]]&lt;br /&gt;
&lt;br /&gt;
Auf dem Board vom [http://shop.mikrocontroller.net/ Shop] sind diese Bauteile bereits enthalten, man muss nur noch die Verbindungen zwischen MAX232 (IC2) und AVR herstellen wie im [http://shop.mikrocontroller.net/images/avrplat28-app.jpg Bild] zu sehen.&lt;br /&gt;
&lt;br /&gt;
* Der MAX232 ist ein [[Pegelwandler]], der die -12V/+12V Signale an der seriellen Schnittstelle des PCs zu den 5V/0V des AVRs kompatibel macht.&lt;br /&gt;
* C1 ist ein kleiner Keramikkondensator, wie er immer wieder zur Entkopplung der Versorgungsspannungen an digitalen ICs verwendet wird.&lt;br /&gt;
* Die vier Kondensatoren C2..C5 sind Elektrolytkondensatoren (Elkos). Auf die richtige Polung achten! Minus ist der Strich auf dem Gehäuse. Der exakte Wert ist hier relativ unkritisch, in der Praxis sollte alles von ca. 1µF bis 47µF mit einer Spannungsfestigkeit von 16V und höher funktionieren.&lt;br /&gt;
* X1 ist ein weiblicher 9-poliger SUB-D-Verbinder.&lt;br /&gt;
* Die Verbindung zwischen PC und Mikrocontroller erfolgt über ein 9-poliges Modem-Kabel (also ein &#039;&#039;Verlängerungskabel&#039;&#039;, &#039;&#039;&#039;kein [http://de.wikipedia.org/wiki/Nullmodem-Kabel Nullmodem]-Kabel!)&#039;&#039;&#039;, das an den seriellen Port des PCs angeschlossen wird. Bei einem Modem-Kabel sind die Pins 2 und 3 des einen Kabelendes mit den Pins 2 und 3 des anderen Kabelendes durchverbunden. Bei einem Nullmodem-Kabel sind die Leitungen gekreuzt, sodass Pin 2 von der einen Seite mit Pin 3 auf der anderen Seite verbunden ist und umgekehrt.&lt;br /&gt;
* Als Faustregel kann man annehmen: Befinden sich an den beiden Enden des Kabels die gleiche Art von Anschlüssen (Männchen = Stecker; Weibchen = Buchse), dann benötigt man ein gekreuztes, also ein Nullmodem-Kabel. Am PC-Anschluss selbst befindet sich ein Stecker, also ein Männchen, sodaß am Kabel auf dieser Seite eine Buchse (also ein Weibchen) sitzen muss. Da am AVR laut obigem Schaltbild eine Buchse verbaut wird, muss daher an diesem Ende des Kabels ein Stecker sitzen. Das Kabel hat daher an einem Ende einen Stecker und am anderen Ende eine Buchse und ist daher ein normales Modem-Kabel ( = nicht gekreuzt).&lt;br /&gt;
&lt;br /&gt;
[[Bild:USART_Kabel.gif]]&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
=== UART konfigurieren ===&lt;br /&gt;
&lt;br /&gt;
Als erstes muss die gewünschte Baudrate im Register &#039;&#039;&#039;UBRR&#039;&#039;&#039; festgelegt werden. Der in dieses Register zu schreibende Wert errechnet sich nach der folgenden Formel: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;UBRR = \frac {Taktfrequenz} { 16 \cdot Baudrate } - 1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim AT90S4433 kann man den Wert direkt in das Register &#039;&#039;&#039;UBRR&#039;&#039;&#039; laden, beim ATmega8 gibt es für &#039;&#039;&#039;UBRR&#039;&#039;&#039; zwei Register: &#039;&#039;&#039;UBRRL&#039;&#039;&#039; (Low-Byte) und &#039;&#039;&#039;UBRRH&#039;&#039;&#039; (High-Byte). Im Normalfall steht in &#039;&#039;&#039;UBRRH&#039;&#039;&#039; 0, da der berechnete Wert kleiner als 256 ist und somit in &#039;&#039;&#039;UBRRL&#039;&#039;&#039; alleine passt. Beachtet werden muss, dass das Register &#039;&#039;&#039;UBRRH&#039;&#039;&#039; vor dem Register &#039;&#039;&#039;UBRRL&#039;&#039;&#039; beschrieben werden muss. Der Schreibzugriff auf &#039;&#039;&#039;UBRRL&#039;&#039;&#039; löst das Neusetzen des internen Taktteilers aus.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:#ff0000;&amp;quot;&amp;gt;&#039;&#039;&#039;WICHTIGER HINWEIS!&#039;&#039;&#039;&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auf Grund permanent wiederkehrender Nachfrage sei hier &#039;&#039;&#039;AUSDRÜCKLICH&#039;&#039;&#039; darauf hingewiesen, dass bei Verwendung des UART im asynchronen Modus dringend ein Quarz oder Ouarzoszillator verwendet werden sollte! Der interne RC-Oszillator der AVRs ist recht ungenau! Damit kann es in Ausnahmefällen funktionieren, muss es aber nicht! Auch ist der interne Oszillator temperaturempfindlich. Damit hat man dann den schönen Effekt, dass eine UART-Schaltung die im Winter noch funktionierte, im Sommer den Dienst verweigert.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss bei der Berechnung von &#039;&#039;&#039;UBRR&#039;&#039;&#039; geprüft werden, ob mit der verwendeten Taktfrequenz die gewünschte Baudrate mit einem Fehler von &amp;lt;1% generiert werden kann. Das Datenblatt bietet hier sowohl die Formel als auch Tabellen unter der Überschrift des U(S)ART an.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; Fehler_{Baudrate}[%] = (\frac{UBRR_{gerundet}+1}{UBRR_{genau}+1} -1 ) \cdot 100&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Siehe auch [[Baudratenquarz]]&lt;br /&gt;
&lt;br /&gt;
Wer es ganz einfach haben will, nimmt die folgenden Macros. Die rechnen sogar den Fehler aus und brechen die Assemblierung ggf. ab. Das ist dann praktisch idiotensicher.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt;&lt;br /&gt;
.equ F_CPU = 4000000                            ; Systemtakt in Hz&lt;br /&gt;
.equ BAUD  = 9600                               ; Baudrate&lt;br /&gt;
&lt;br /&gt;
; Berechnungen&lt;br /&gt;
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden&lt;br /&gt;
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate&lt;br /&gt;
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille&lt;br /&gt;
&lt;br /&gt;
.if ((BAUD_ERROR&amp;gt;10) || (BAUD_ERROR&amp;lt;-10))       ; max. +/-10 Promille Fehler&lt;br /&gt;
  .error &amp;quot;Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!&amp;quot;&lt;br /&gt;
.endif&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wer dennoch den internen RC-Oszillator verwenden will, muss diesen kalibrieren. Näheres findet man dazu im Datenblatt, Stichwort Register OSCCAL.  &lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
Um den Sendekanal des UART zu aktivieren, muss das Bit &#039;&#039;&#039;TXEN&#039;&#039;&#039; im UART Control Register &#039;&#039;&#039;UCSRB&#039;&#039;&#039; auf 1 gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
Danach kann das zu sendende Byte in das Register &#039;&#039;&#039;UDR&#039;&#039;&#039; eingeschrieben werden - vorher muss jedoch sichergestellt werden, dass das Register leer ist, die vorhergehende Übertragung also schon abgeschlossen wurde. Dazu wird getestet, ob das Bit &#039;&#039;&#039;UDRE&#039;&#039;&#039; (&amp;quot;UART Data Register Empty&amp;quot;) im Register &#039;&#039;&#039;UCSRA&#039;&#039;&#039; auf 1 ist.&lt;br /&gt;
&lt;br /&gt;
Genaueres über die UART-Register findet man im Datenblatt des Controllers.&lt;br /&gt;
&lt;br /&gt;
An dieser Stelle sei noch folgendes angemerkt: Das &#039;&#039;&#039;UDRE&#039;&#039;&#039;-Bit sagt nichts darüber aus, ob der Controller immer noch damit beschäftigt ist, Daten zu senden. Da das Senderegister mehrfach gepuffert ist, wird &#039;&#039;&#039;UDRE&#039;&#039;&#039; bereits gesetzt, obwohl das letzte Zeichen den AVR noch nicht komplett verlassen hat. Dies kann insbesondere bei der Verwendung von Sleep-Modes ein Problem werden, wenn der Controller schlafen gelegt wird, bevor das letzte Zeichen versendet wurde, da dies gezwungenermassen zu einem Frame-Error beim Empfänger führen wird. Um sicher zu gehen, dass der UART nicht mehr beschäftigt ist, kann das Bit &#039;&#039;&#039;TXC&#039;&#039;&#039; (&amp;quot;UART Transmit complete&amp;quot;) getestet werden. Dieses wird jedoch wirklich erst nach dem Senden eines Zeichens gesetzt, beinhaltet also auch nach dem Systemstart eine 0, obwohl der Controller nichts sendet.&lt;br /&gt;
&lt;br /&gt;
Der ATmega8 bietet noch viele weitere Optionen zur Konfiguration des UARTs, aber für die Datenübertragung zum PC sind im Normalfall keine anderen Einstellungen notwendig.&lt;br /&gt;
&lt;br /&gt;
=== Senden von Zeichen ===&lt;br /&gt;
&lt;br /&gt;
Das Beispielprogramm überträgt die Zeichenkette &amp;quot;Test!&amp;quot; in einer Endlosschleife an den PC.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hinweis&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Wenn man das nachfolgende Programm laufen lässt und Hyperterminal startet, scheint es problemlos zu funktionieren. Wenn man aber das RS232 Kabel zwischenzeitlich abzieht und wieder ansteckt wird es oft passieren, dass nur noch wirre Zeichen auf dem PC erscheinen. Das liegt daran, dass der PC aus einem ununterbrochen Zeichenstrom nicht den Anfang eines Zeichens erkennen kann. Darum muss in solchen Fällen periodisch eine kleine Pause von der Länge mindestens eines Zeichens eingelegt werden, damit der PC sich wieder synchronisieren kann.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die folgenden Beispiele sind für den ATmega8 geschrieben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt;&lt;br /&gt;
.include &amp;quot;m8def.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
.def temp    = r16                              ; Register für kleinere Arbeiten&lt;br /&gt;
.def zeichen = r17                              ; in diesem Register wird das Zeichen an die&lt;br /&gt;
                                                ; Ausgabefunktion übergeben&lt;br /&gt;
&lt;br /&gt;
.equ F_CPU = 4000000                            ; Systemtakt in Hz&lt;br /&gt;
.equ BAUD  = 9600                               ; Baudrate&lt;br /&gt;
&lt;br /&gt;
; Berechnungen&lt;br /&gt;
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden&lt;br /&gt;
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))      ; Reale Baudrate&lt;br /&gt;
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille&lt;br /&gt;
&lt;br /&gt;
.if ((BAUD_ERROR&amp;gt;10) || (BAUD_ERROR&amp;lt;-10))       ; max. +/-10 Promille Fehler&lt;br /&gt;
  .error &amp;quot;Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!&amp;quot;&lt;br /&gt;
.endif&lt;br /&gt;
&lt;br /&gt;
    ; Stackpointer initialisieren&lt;br /&gt;
&lt;br /&gt;
    ldi     temp, LOW(RAMEND)&lt;br /&gt;
    out     SPL, temp&lt;br /&gt;
    ldi     temp, HIGH(RAMEND)&lt;br /&gt;
    out     SPH, temp&lt;br /&gt;
&lt;br /&gt;
    ; Baudrate einstellen&lt;br /&gt;
&lt;br /&gt;
    ldi     temp, HIGH(UBRR_VAL)&lt;br /&gt;
    out     UBRRH, temp&lt;br /&gt;
    ldi     temp, LOW(UBRR_VAL)&lt;br /&gt;
    out     UBRRL, temp&lt;br /&gt;
&lt;br /&gt;
    ; Frame-Format: 8 Bit&lt;br /&gt;
&lt;br /&gt;
    ldi     temp, (1&amp;lt;&amp;lt;URSEL)|(3&amp;lt;&amp;lt;UCSZ0)&lt;br /&gt;
    out     UCSRC, temp&lt;br /&gt;
&lt;br /&gt;
    sbi     UCSRB,TXEN                  ; TX aktivieren&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    ldi     zeichen, &#039;T&#039;&lt;br /&gt;
    rcall   serout                      ; Unterprogramm aufrufen&lt;br /&gt;
    ldi     zeichen, &#039;e&#039;&lt;br /&gt;
    rcall   serout                      ; Unterprogramm aufrufen&lt;br /&gt;
    ldi     zeichen, &#039;s&#039;&lt;br /&gt;
    rcall   serout                      ; ...&lt;br /&gt;
    ldi     zeichen, &#039;t&#039;&lt;br /&gt;
    rcall   serout&lt;br /&gt;
    ldi     zeichen, &#039;!&#039;&lt;br /&gt;
    rcall   serout&lt;br /&gt;
    ldi     zeichen, 10&lt;br /&gt;
    rcall   serout&lt;br /&gt;
    ldi     zeichen, 13&lt;br /&gt;
    rcall   serout&lt;br /&gt;
    rcall   sync                        &lt;br /&gt;
    rjmp    loop&lt;br /&gt;
&lt;br /&gt;
serout:&lt;br /&gt;
    sbis    UCSRA,UDRE                  ; Warten bis UDR für das nächste&lt;br /&gt;
                                        ; Byte bereit ist&lt;br /&gt;
    rjmp    serout&lt;br /&gt;
    out     UDR, zeichen&lt;br /&gt;
    ret                                 ; zurück zum Hauptprogramm&lt;br /&gt;
&lt;br /&gt;
; kleine Pause zum Synchronisieren des Empfängers, falls zwischenzeitlich&lt;br /&gt;
; das Kabel getrennt wurde&lt;br /&gt;
                                    &lt;br /&gt;
sync:&lt;br /&gt;
    ldi     r16,0&lt;br /&gt;
sync_1:&lt;br /&gt;
    ldi     r17,0&lt;br /&gt;
sync_loop:&lt;br /&gt;
    dec     r17&lt;br /&gt;
    brne    sync_loop&lt;br /&gt;
    dec     r16&lt;br /&gt;
    brne    sync_1  &lt;br /&gt;
    ret&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Befehl &#039;&#039;&#039;rcall serout&#039;&#039;&#039; ruft ein kleines Unterprogramm auf, das zuerst wartet bis das Datenregister &#039;&#039;&#039;UDR&#039;&#039;&#039; von der vorhergehenden Übertragung frei ist, und anschließend das in zeichen (=r17) gespeicherte Byte an &#039;&#039;&#039;UDR&#039;&#039;&#039; ausgibt. &lt;br /&gt;
&lt;br /&gt;
Bevor &amp;lt;i&amp;gt;serout&amp;lt;/i&amp;gt; aufgerufen wird, wird zeichen jedesmal mit dem ASCII-Code des zu übertragenden Zeichens geladen (so wie in Teil 4 bei der LCD-Ansteuerung). Der Assembler wandelt Zeichen in einfachen Anführungsstrichen automatisch in den entsprechenden ASCII-Wert um. Nach dem Wort &amp;quot;Test!&amp;quot; werden noch die Codes 10 (New Line) und 13 (Carriage Return) gesendet, um dem Terminalprogramm mitzuteilen, dass eine neue Zeile beginnt.&lt;br /&gt;
&lt;br /&gt;
Eine Übersicht aller ASCII-Codes gibt es auf [http://www.asciitable.com/ www.asciitable.com].&lt;br /&gt;
&lt;br /&gt;
Die Berechnung der Baudrate wird übrigens nicht im Controller während der Programmausführung durchgeführt, sondern schon beim Assemblieren, wie man beim Betrachten der Listingdatei feststellen kann. &lt;br /&gt;
&lt;br /&gt;
Zum Empfang muss auf dem PC ein Terminal-Programm wie z.B. HyperTerminal gestartet werden. Der folgende Screenshot zeigt, welche Einstellungen im Programm vorgenommen werden müssen: &lt;br /&gt;
&lt;br /&gt;
http://www.mikrocontroller.net/images/hyperterminal.gif&lt;br /&gt;
&lt;br /&gt;
Linux-Benutzer können das entsprechende Device (z.B. /dev/ttyS0) mit stty konfigurieren und mit cat die empfangenen Daten anzeigen oder ein Terminalprogramm wie minicom nutzen.&lt;br /&gt;
&lt;br /&gt;
=== Senden von Zeichenketten ===&lt;br /&gt;
&lt;br /&gt;
Eine bequemere Methode um längere Zeichenketten (Strings) zu übertragen ist hier zu sehen. Dabei werden die Zeichenketten im Flash gespeichert. Als Abschluss des Strings wird der Wert 0x00 genutzt, so wie auch in der Programmiersprache C. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt;&lt;br /&gt;
.include &amp;quot;m8def.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
.def temp    = r16                              ; Register für kleinere Arbeiten&lt;br /&gt;
.def zeichen = r17                              ; in diesem Register wird das Zeichen an die&lt;br /&gt;
                                                ; Ausgabefunktion übergeben&lt;br /&gt;
&lt;br /&gt;
.equ F_CPU = 4000000                            ; Systemtakt in Hz&lt;br /&gt;
.equ BAUD  = 9600                               ; Baudrate&lt;br /&gt;
&lt;br /&gt;
; Berechnungen&lt;br /&gt;
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden&lt;br /&gt;
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate&lt;br /&gt;
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille&lt;br /&gt;
&lt;br /&gt;
.if ((BAUD_ERROR&amp;gt;10) || (BAUD_ERROR&amp;lt;-10))       ; max. +/-10 Promille Fehler&lt;br /&gt;
  .error &amp;quot;Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!&amp;quot;&lt;br /&gt;
.endif&lt;br /&gt;
&lt;br /&gt;
; hier geht unser Programm los&lt;br /&gt;
&lt;br /&gt;
    ; Stackpointer initialisieren&lt;br /&gt;
&lt;br /&gt;
    ldi     temp, LOW(RAMEND)&lt;br /&gt;
    out     SPL, temp&lt;br /&gt;
    ldi     temp, HIGH(RAMEND)&lt;br /&gt;
    out     SPH, temp&lt;br /&gt;
&lt;br /&gt;
    ; Baudrate einstellen&lt;br /&gt;
&lt;br /&gt;
    ldi     temp, HIGH(UBRR_VAL)&lt;br /&gt;
    out     UBRRH, temp&lt;br /&gt;
    ldi     temp, LOW(UBRR_VAL)&lt;br /&gt;
    out     UBRRL, temp&lt;br /&gt;
&lt;br /&gt;
    ; Frame-Format: 8 Bit&lt;br /&gt;
&lt;br /&gt;
    ldi     temp, (1&amp;lt;&amp;lt;URSEL)|(3&amp;lt;&amp;lt;UCSZ0)&lt;br /&gt;
    out     UCSRC, temp&lt;br /&gt;
&lt;br /&gt;
    sbi     UCSRB,TXEN                      ; TX aktivieren&lt;br /&gt;
&lt;br /&gt;
loop:&lt;br /&gt;
    ldi     zl,low(my_string*2);            ; Z Pointer laden&lt;br /&gt;
    ldi     zh,high(my_string*2);&lt;br /&gt;
    rcall   serout_string&lt;br /&gt;
    rjmp    loop&lt;br /&gt;
&lt;br /&gt;
; Ausgabe eines Strings aus dem Flash&lt;br /&gt;
&lt;br /&gt;
serout_string:&lt;br /&gt;
    lpm                             ; nächstes Byte aus dem Flash laden&lt;br /&gt;
    and     r0,r0                   ; = Null? &lt;br /&gt;
    breq    serout_string_ende      ; wenn ja, -&amp;gt; Ende&lt;br /&gt;
serout_string_wait:&lt;br /&gt;
    sbis    UCSRA,UDRE              ; Warten bis UDR für das nächste&lt;br /&gt;
                                    ; Byte bereit ist&lt;br /&gt;
    rjmp    serout_string_wait&lt;br /&gt;
    out     UDR, r0&lt;br /&gt;
    adiw    zl:zh,1                 ; Zeiger erhöhen&lt;br /&gt;
    rjmp    serout_string           ; nächstes Zeichen bearbeiten&lt;br /&gt;
serout_string_ende:&lt;br /&gt;
    ret                             ; zurück zum Hauptprogramm&lt;br /&gt;
&lt;br /&gt;
; Hier wird jetzt der String definiert und im Flash gespeichert&lt;br /&gt;
&lt;br /&gt;
my_string:  .db &amp;quot;Test!&amp;quot;,10,13,0&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Empfangen von Zeichen per Polling===&lt;br /&gt;
&lt;br /&gt;
Der AVR kann nicht nur Daten seriell senden, sondern auch empfangen. Dazu muss man, nachdem die Baudrate wie oben beschrieben eingestellt wurde, das Bit &#039;&#039;&#039;RXEN&#039;&#039;&#039; setzen. &lt;br /&gt;
&lt;br /&gt;
Sobald der UART ein Byte über die serielle Verbindung empfangen hat, wird das Bit &#039;&#039;&#039;RXC&#039;&#039;&#039; im Register &#039;&#039;&#039;UCSRA&#039;&#039;&#039; gesetzt, um anzuzeigen, dass ein Byte im Register &#039;&#039;&#039;UDR&#039;&#039;&#039; zur Weiterverarbeitung bereitsteht. Sobald es aus &#039;&#039;&#039;UDR&#039;&#039;&#039; gelesen wurde, wird &#039;&#039;&#039;RXC&#039;&#039;&#039; automatisch wieder gelöscht, bis das nächste Byte angekommen ist. &lt;br /&gt;
&lt;br /&gt;
Das erste einfache Testprogramm soll das empfangene Byte auf den an Port D angeschlossenen LEDs ausgeben. Dabei sollte man daran denken, dass PD0 (RXD) bereits für die Datenübertragung zuständig ist, so dass das entsprechende Bit im Register PORTD keine Funktion hat und damit auch nicht für die Datenanzeige verwendet werden kann. &lt;br /&gt;
&lt;br /&gt;
Nachdem der UART konfiguriert ist, wartet das Programm einfach in der Hauptschleife darauf, dass ein Byte über den UART ankommt (z.B. indem man im Terminalprogramm ein Zeichen eingibt), also &#039;&#039;&#039;RXC&#039;&#039;&#039; gesetzt wird. Sobald das passiert, wird das Register &#039;&#039;&#039;UDR&#039;&#039;&#039;, in dem die empfangenen Daten stehen, nach &amp;lt;i&amp;gt;temp&amp;lt;/i&amp;gt; eingelesen und an den Port D ausgegeben. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt; &lt;br /&gt;
.include &amp;quot;m8def.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
.def temp = R16&lt;br /&gt;
&lt;br /&gt;
.equ F_CPU = 4000000                            ; Systemtakt in Hz&lt;br /&gt;
.equ BAUD  = 9600                               ; Baudrate&lt;br /&gt;
&lt;br /&gt;
; Berechnungen&lt;br /&gt;
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden&lt;br /&gt;
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate&lt;br /&gt;
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille&lt;br /&gt;
&lt;br /&gt;
.if ((BAUD_ERROR&amp;gt;10) || (BAUD_ERROR&amp;lt;-10))       ; max. +/-10 Promille Fehler&lt;br /&gt;
  .error &amp;quot;Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!&amp;quot;&lt;br /&gt;
.endif&lt;br /&gt;
&lt;br /&gt;
    ; Stackpointer initialisieren&lt;br /&gt;
&lt;br /&gt;
    ldi     temp, LOW(RAMEND)&lt;br /&gt;
    out     SPL, temp&lt;br /&gt;
    ldi     temp, HIGH(RAMEND)&lt;br /&gt;
    out     SPH, temp&lt;br /&gt;
&lt;br /&gt;
    ; Port D = Ausgang&lt;br /&gt;
&lt;br /&gt;
    ldi     temp, 0xFF&lt;br /&gt;
    out     DDRD, temp&lt;br /&gt;
&lt;br /&gt;
    ; Baudrate einstellen&lt;br /&gt;
&lt;br /&gt;
    ldi     temp, HIGH(UBRR_VAL)&lt;br /&gt;
    out     UBRRH, temp&lt;br /&gt;
    ldi     temp, LOW(UBRR_VAL)&lt;br /&gt;
    out     UBRRL, temp&lt;br /&gt;
&lt;br /&gt;
    ; Frame-Format: 8 Bit&lt;br /&gt;
&lt;br /&gt;
    ldi     temp, (1&amp;lt;&amp;lt;URSEL)|(3&amp;lt;&amp;lt;UCSZ0)&lt;br /&gt;
    out     UCSRC, temp&lt;br /&gt;
&lt;br /&gt;
    sbi     UCSRB, RXEN                     ; RX (Empfang) aktivieren&lt;br /&gt;
&lt;br /&gt;
receive_loop:&lt;br /&gt;
   sbis     UCSRA, RXC                      ; warten bis ein Byte angekommen ist&lt;br /&gt;
   rjmp     receive_loop&lt;br /&gt;
   in       temp, UDR                       ; empfangenes Byte nach temp kopieren&lt;br /&gt;
   out      PORTD, temp                     ; und an Port D ausgeben.&lt;br /&gt;
   rjmp     receive_loop                    ; zurück zum Hauptprogramm&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Empfangen von Zeichen per Interrupt ===&lt;br /&gt;
&lt;br /&gt;
Dieses Programm lässt sich allerdings noch verfeinern. Statt in der Hauptschleife auf die Daten zu warten, kann man auch veranlassen dass ein Interrupt ausgelöst wird, sobald ein Byte angekommen ist. Das sieht in der einfachsten Form so aus: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt; &lt;br /&gt;
.include &amp;quot;m8def.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
.def temp = R16&lt;br /&gt;
&lt;br /&gt;
.equ F_CPU = 4000000                            ; Systemtakt in Hz&lt;br /&gt;
.equ BAUD  = 9600                               ; Baudrate&lt;br /&gt;
&lt;br /&gt;
; Berechnungen&lt;br /&gt;
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden&lt;br /&gt;
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate&lt;br /&gt;
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille&lt;br /&gt;
&lt;br /&gt;
.if ((BAUD_ERROR&amp;gt;10) || (BAUD_ERROR&amp;lt;-10))       ; max. +/-10 Promille Fehler&lt;br /&gt;
  .error &amp;quot;Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!&amp;quot;&lt;br /&gt;
.endif&lt;br /&gt;
&lt;br /&gt;
.org 0x00&lt;br /&gt;
        rjmp main&lt;br /&gt;
&lt;br /&gt;
.org URXCaddr                                   ; Interruptvektor für UART-Empfang&lt;br /&gt;
        rjmp int_rxc&lt;br /&gt;
&lt;br /&gt;
; Hauptprogramm&lt;br /&gt;
&lt;br /&gt;
main:&lt;br /&gt;
&lt;br /&gt;
    ; Stackpointer initialisieren&lt;br /&gt;
&lt;br /&gt;
    ldi     temp, LOW(RAMEND)&lt;br /&gt;
    out     SPL, temp&lt;br /&gt;
    ldi     temp, HIGH(RAMEND)&lt;br /&gt;
    out     SPH, temp&lt;br /&gt;
&lt;br /&gt;
    ; Port D = Ausgang&lt;br /&gt;
&lt;br /&gt;
    ldi     temp, 0xFF&lt;br /&gt;
    out     DDRD, temp&lt;br /&gt;
&lt;br /&gt;
    ; Baudrate einstellen&lt;br /&gt;
&lt;br /&gt;
    ldi     temp, HIGH(UBRR_VAL)&lt;br /&gt;
    out     UBRRH, temp&lt;br /&gt;
    ldi     temp, LOW(UBRR_VAL)&lt;br /&gt;
    out     UBRRL, temp&lt;br /&gt;
&lt;br /&gt;
    ; Frame-Format: 8 Bit&lt;br /&gt;
&lt;br /&gt;
    ldi     temp, (1&amp;lt;&amp;lt;URSEL)|(3&amp;lt;&amp;lt;UCSZ0)&lt;br /&gt;
    out     UCSRC, temp&lt;br /&gt;
&lt;br /&gt;
    sbi     UCSRB, RXCIE                    ; Interrupt bei Empfang&lt;br /&gt;
    sbi     UCSRB, RXEN                     ; RX (Empfang) aktivieren&lt;br /&gt;
    &lt;br /&gt;
    sei                                     ; Interrupts global aktivieren&lt;br /&gt;
    &lt;br /&gt;
loop:&lt;br /&gt;
    rjmp loop                               ; Endlosschleife&lt;br /&gt;
&lt;br /&gt;
; Interruptroutine: wird ausgeführt sobald ein Byte über das UART empfangen wurde&lt;br /&gt;
&lt;br /&gt;
int_rxc:&lt;br /&gt;
    push    temp                            ; temp auf dem Stack sichern&lt;br /&gt;
    in      temp, UDR                       ; empfangenes Byte lesen,&lt;br /&gt;
                                            ; dadurch wird auch der Interrupt gelöscht&lt;br /&gt;
    out     PORTD, temp                     ; Daten ausgeben&lt;br /&gt;
    pop     temp                            ; temp wiederherstellen&lt;br /&gt;
    reti                                    ; Interrupt beenden&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Methode hat den großen Vorteil, dass das Hauptprogramm (hier nur eine leere Endlosschleife) andere Dinge erledigen kann, während der Controller Daten empfängt. Auf diese Weise kann man mehrere Aktionen quasi gleichzeitig ausführen, da das Hauptprogramm nur kurz unterbrochen wird, um die empfangenen Daten zu verarbeiten. &lt;br /&gt;
&lt;br /&gt;
Probleme können allerdings auftreten, wenn in der Interruptroutine die gleichen Register verwendet werden wie im Hauptprogramm, da dieses ja an beliebigen Stellen durch den Interrupt unterbrochen werden kann. Damit sich aus der Sicht der Hauptschleife durch den Interruptaufruf nichts ändert, müssen alle in der Interruptroutine geänderten Register am Anfang der Routine gesichert und am Ende wiederhergestellt werden. Das gilt vor allem für das CPU-Statusregister (&#039;&#039;&#039;SREG&#039;&#039;&#039;)! Sobald ein einziger Befehl im Interrupt ein einziges Bit im SREG beeinflusst, muss das SREG gesichert werden. Das ist praktisch fast immer der Fall, nur in dem ganz einfachen Beispiel oben ist es überflüssig, weil die verwendeten Befehle das SREG nicht beeinflussen. In diesem Zusammenhang wird der [[Stack]] wieder interessant. Um die Register zu sichern, kann man sie mit &#039;&#039;&#039;push&#039;&#039;&#039; oben auf den Stapel legen und am Ende wieder in der umgekehrten Reihenfolge(!) mit &#039;&#039;&#039;pop&#039;&#039;&#039; vom Stapel herunternehmen.&lt;br /&gt;
&lt;br /&gt;
Im folgenden Beispielprogramm werden die empfangenen Daten nun nicht mehr komplett angezeigt. Stattdessen kann man durch Eingabe einer 1 oder einer 0 im Terminalprogramm eine LED (an PB0) an- oder ausschalten. Dazu wird das empfangene Byte in der Interruptroutine mit den entsprechenden ASCII-Codes der Zeichen 1 und 0 (siehe [http://www.asciitable.com/ www.asciitable.com]) verglichen.&lt;br /&gt;
&lt;br /&gt;
Für den [[AVR-Tutorial:_Vergleiche|Vergleich]] eines Registers mit einer Konstanten gibt es den Befehl &#039;&#039;&#039;cpi register, konstante&#039;&#039;&#039;. Das Ergebnis dieses Vergleichs kann man mit den Befehlen &#039;&#039;&#039;breq label&#039;&#039;&#039; (springe zu label, wenn gleich) und &#039;&#039;&#039;brne label&#039;&#039;&#039; (springe zu label, wenn ungleich) auswerten. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt; &lt;br /&gt;
.include &amp;quot;m8def.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
.def temp = R16&lt;br /&gt;
&lt;br /&gt;
.equ F_CPU = 4000000                            ; Systemtakt in Hz&lt;br /&gt;
.equ BAUD  = 9600                               ; Baudrate&lt;br /&gt;
&lt;br /&gt;
; Berechnungen&lt;br /&gt;
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden&lt;br /&gt;
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate&lt;br /&gt;
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille&lt;br /&gt;
&lt;br /&gt;
.if ((BAUD_ERROR&amp;gt;10) || (BAUD_ERROR&amp;lt;-10))       ; max. +/-10 Promille Fehler&lt;br /&gt;
  .error &amp;quot;Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!&amp;quot;&lt;br /&gt;
.endif&lt;br /&gt;
&lt;br /&gt;
.org 0x00&lt;br /&gt;
        rjmp main&lt;br /&gt;
&lt;br /&gt;
.org URXCaddr&lt;br /&gt;
        rjmp int_rxc&lt;br /&gt;
&lt;br /&gt;
; Hauptprogramm&lt;br /&gt;
main:&lt;br /&gt;
    &lt;br /&gt;
    ; Stackpointer initialisieren&lt;br /&gt;
&lt;br /&gt;
    ldi     temp, LOW(RAMEND)&lt;br /&gt;
    out     SPL, temp&lt;br /&gt;
    ldi     temp, HIGH(RAMEND)&lt;br /&gt;
    out     SPH, temp&lt;br /&gt;
&lt;br /&gt;
    ; Port B = Ausgang&lt;br /&gt;
&lt;br /&gt;
    ldi     temp, 0xFF&lt;br /&gt;
    out     DDRB, temp&lt;br /&gt;
&lt;br /&gt;
    ; Baudrate einstellen&lt;br /&gt;
&lt;br /&gt;
    ldi     temp, HIGH(UBRR_VAL)&lt;br /&gt;
    out     UBRRH, temp&lt;br /&gt;
    ldi     temp, LOW(UBRR_VAL)&lt;br /&gt;
    out     UBRRL, temp&lt;br /&gt;
&lt;br /&gt;
    ; Frame-Format: 8 Bit&lt;br /&gt;
&lt;br /&gt;
    ldi     temp, (1&amp;lt;&amp;lt;URSEL)|(3&amp;lt;&amp;lt;UCSZ0)&lt;br /&gt;
    out     UCSRC, temp&lt;br /&gt;
&lt;br /&gt;
    sbi     UCSRB, RXCIE                ; Interrupt bei Empfang&lt;br /&gt;
    sbi     UCSRB, RXEN                 ; RX (Empfang) aktivieren&lt;br /&gt;
    &lt;br /&gt;
    sei                                 ; Interrupts global aktivieren&lt;br /&gt;
    &lt;br /&gt;
loop:&lt;br /&gt;
    rjmp loop                           ; Endlosschleife&lt;br /&gt;
&lt;br /&gt;
; Interruptroutine: wird ausgeführt sobald ein Byte über das UART empfangen wurde&lt;br /&gt;
&lt;br /&gt;
int_rxc:&lt;br /&gt;
    push    temp                        ; temp auf dem Stack sichern&lt;br /&gt;
    in      temp, sreg                  ; SREG sichern&lt;br /&gt;
    push    temp&lt;br /&gt;
    &lt;br /&gt;
    in      temp, UDR                   ; UART Daten lesen&lt;br /&gt;
    cpi     temp, &#039;1&#039;                   ; empfangenes Byte mit &#039;1&#039; vergleichen&lt;br /&gt;
    brne    int_rxc_1                   ; wenn nicht gleich, dann zu int_rxc_1&lt;br /&gt;
    cbi     PORTB, 0                    ; LED einschalten, low aktiv&lt;br /&gt;
    rjmp    int_rxc_2                   ; Zu int_rxc_2 springen&lt;br /&gt;
int_rxc_1:&lt;br /&gt;
    cpi     temp, &#039;0&#039;                   ; empfangenes Byte mit &#039;0&#039; vergleichen&lt;br /&gt;
    brne    int_rxc_2                   ; wenn nicht gleich, dann zu int_rxc_2&lt;br /&gt;
    sbi     PORTB, 0                    ; LED ausschalten, low aktiv&lt;br /&gt;
int_rxc_2:&lt;br /&gt;
&lt;br /&gt;
    pop     temp&lt;br /&gt;
    out     sreg, temp                  ; SREG wiederherstellen&lt;br /&gt;
    pop     temp                        ; temp wiederherstellen&lt;br /&gt;
    reti&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://www.wormfood.net/avrbaudcalc.php WormFood&#039;s AVR Baud Rate Calculator] online.&lt;br /&gt;
&lt;br /&gt;
{{Navigation_zurückhochvor|&lt;br /&gt;
zurücktext=Mehrfachverzweigung|&lt;br /&gt;
zurücklink=AVR-Tutorial: Mehrfachverzweigung|&lt;br /&gt;
hochtext=Inhaltsverzeichnis|&lt;br /&gt;
hochlink=AVR-Tutorial|&lt;br /&gt;
vortext=Speicher|&lt;br /&gt;
vorlink=AVR-Tutorial: Speicher}}&lt;br /&gt;
&lt;br /&gt;
[[Category:AVR]][[Category:AVR-Tutorial]]&lt;/div&gt;</summary>
		<author><name>Philipp burch</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Wellenwiderstand&amp;diff=35744</id>
		<title>Wellenwiderstand</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Wellenwiderstand&amp;diff=35744"/>
		<updated>2009-04-18T11:01:10Z</updated>

		<summary type="html">&lt;p&gt;Philipp burch: Typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Schnelle Digitalschaltkreise bzw. hochfrequente Analogschaltungen stellen erhöhte Anforderungen an die Verbindungsleitungen zwischen ICs und Baugruppen. Wo ein langsamer CMOS-Baustein der 4000 Serie mit ein paar Megahertz noch problemlos auf dem Steckbrett mit wilder Klingeldrahtverkabelung funktioniert, dort versagt ein moderner, schneller IC seinen Dienst. Ähnliches passiert auf geätzten Leiterplatten. Nicht nur die Packungsdichte der Gehäuse, auch die immer kürzer werdenden Schaltzeiten der Signale verlangen mehr und mehr einen durchdachten, hochfrequenzgerechten Aufbau mit zwei, vier oder mehr Lagen. Die Verbindungsleitungen, welche bei niedrigen Frequenzen praktisch nicht auffallen, sind plötzlich sichtbare Bauelemente, welche die zwei wichtigen Parameter Wellenwiderstand und Laufzeit aufweisen.&lt;br /&gt;
&lt;br /&gt;
== Wellenwiderstand ==&lt;br /&gt;
&lt;br /&gt;
Eine elektrische Leitung muß man bei hohen Frequenzen als ein Netzwerk aus&lt;br /&gt;
&lt;br /&gt;
* Serienwiderstand Rs&lt;br /&gt;
* Parallelwiderstand Rp&lt;br /&gt;
* Serieninduktivität Ls&lt;br /&gt;
* Parallelkapazität Cp&lt;br /&gt;
&lt;br /&gt;
betrachten.&lt;br /&gt;
&lt;br /&gt;
[[bild:wellenwiderstand_ersatzschaltbild.png]]&lt;br /&gt;
&lt;br /&gt;
Praktisch kann man sich das so vorstellen. Jeder elektrische Leiter hat einen [[Widerstand|ohmschen Widerstand]] Rs. Vorsicht! Das ist nicht der Wellenwiderstand! Ebenso hat jede elektrische Leitung einen Widerstand zwischen den Leitern, denn der Isolator ist nie ideal. Praktisch kann man den allerdings meist vernachlässigen, da er im Bereich von Gigaohm liegt. Die unvermeidlichen und ausschlaggebenden Parameter sind jedoch Ls und Cp. Jeder elektrische Leiter, welcher von einem Strom durchflossen wird, erzeugt ein Magnetfeld. Das ist gleichbedeutend mit der Induktivität Lp. Ebenso besteht zwischen zwei isolierten Leitern immer ein elektrisches Feld, wodurch der Kondensator Cp gebildet wird. Ls und Cp sind die entscheidenden Grössen zur Bestimmung des Wellenwiderstandes. Je nach geometrischer Anordnung der Leiter kann man sie in gewissen Grenzen variieren (Koaxialkabel, Twisted Pair, Flachbandkabel etc.).&lt;br /&gt;
&lt;br /&gt;
Der Wellenwiderstand berechnet sich aus&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Z_0= \sqrt{\frac{Ls}{Cp}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Er ist eine charkteristische Grösse einer Leitung.&lt;br /&gt;
&lt;br /&gt;
Beispiele:&lt;br /&gt;
&lt;br /&gt;
* Koaxialkabel RG58 und RG174, 50&amp;amp;Omega; &lt;br /&gt;
* Koaxialkabel RG59, 75&amp;amp;Omega;&lt;br /&gt;
* Twisted Pair CAT3/5/7 für Ethernet, 100&amp;amp;Omega;&lt;br /&gt;
* Flachbandkabel, 150&amp;amp;Omega; typ.&lt;br /&gt;
* Leiterbahnen auf Platinen mit 30...150&amp;amp;Omega;&lt;br /&gt;
&lt;br /&gt;
== Laufzeit ==&lt;br /&gt;
&lt;br /&gt;
Elektrische Signale haben eine sehr hohe, aber dennoch begrenzte Ausbreitungsgeschwindigkeit. In Luft bzw. im Vakuum breiten sich Funksignale mit Lichtgeschwindigkeit aus, das sind 300.000 km/s, oder 30cm/ns. Auf Leitungen breiten sich Signale langsamer aus, da das elektromagnetische Feld mit der Umgebung interagiert. Je nach Leitungstyp etwa mit 50..70% der Lichtgeschwindigkeit, sprich mit ca. 15..21 cm/ns.&lt;br /&gt;
&lt;br /&gt;
== Terminierung ==&lt;br /&gt;
&lt;br /&gt;
Wenn eine elektrische Leitung als lang betrachtet werden muß, dann treten Reflexionen auf. Diese sind unerwünscht und können von sporadischen Fehlern bis zum völligen Versagen einer Schaltung alles verursachen. Deshalb müssen solche Leitungen terminiert werden. Die Terminierung absorbiert die einlaufenden Signale und verhindert damit ungewollte Reflexionen. Eine Leitung wird mit einem ohmschen Widerstand terminiert, welcher den gleichen Wert wie der Wellenwiderstand aufweist. Die Terminierungswiderstände müssen möglichst am Ende der Leitung plaziert werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Eine Leitung ist dann als elektrisch lang zu betrachten, wenn die einfache Laufzeit der Leitung grösser als ca. 1/6 der minimalen Anstiegszeit der Signale ist.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ein Beispiel.&lt;br /&gt;
&lt;br /&gt;
Ein [[AVR]] ist ein recht typischer digitaler IC. Die minimale Anstiegszeit beträgt ca. 5ns! Nach obiger Formel darf die Laufzeit nur 1/6 ~ 0,83ns betragen. Bei einer Ausbreitungsgeschwindigkeit von 21cm/ns ergibt das eine maximal zulässige Leitungslänge von 21cm/ns * 0,83ns ~ 17,5cm. Das heißt, bei einer Leitungslänge von bis zu 17,5cm &#039;&#039;&#039;und&#039;&#039;&#039; halbwegs sauberer Leitungsführung treten keine nennenswerten Reflexionen auf, eine Terminierung ist nicht notwendig. Darüber muss man aufpassen, spätestens bei dem doppelten bis dreifachen Wert ist eine Terminierung meist unverzichtbar.&lt;br /&gt;
&lt;br /&gt;
=== Serienterminierung ===&lt;br /&gt;
&lt;br /&gt;
Serienterminierung arbeitet bewußt mit Reflexionen. Von der Quelle wird ein Signal mit einem Innenwiderstand gleich dem Wellenwiderstand eingespeist. Dadurch ergibt sich ein Spannungsteiler von 1:2, d.h. Das Signal hat kurzzeitig nur die halbe Amplitude. Damit läuft es bis zum Ende der Leitung, welches offen ist. Es wird zu 100% reflektiert. Dadurch entsteht der volle Spannungspegel. Wenn die rücklaufende Reflexion die Quelle wieder erreicht wird sie vom Innenwiderstand der Quelle, welcher gleich dem Wellenwiderstand ist, absorbiert, es entsteht keine weitere Reflexion. Idealerweise sollte der externe Serienwiderstand Rs plus der Innenwiderstand des Ausgangs Ri gleich dem Wellenwiderstand sein. CMOS-ICs haben Ausgangswiderstände zwischen 15..50 Ohm.&lt;br /&gt;
&lt;br /&gt;
[[bild:wellenwiderstand_serienterminierung.png]]&lt;br /&gt;
&lt;br /&gt;
Datensignale können meist problemlos mit Serienterminierung betrieben werden. Taktsignale dürfen nur bei Punkt zu Punkt Verbindungen mit Serienterminierung betrieben werden (ein Sender und nur ein Empfänger). Anderenfalls kann es zu Fehlfunktionen kommen, da ein Takteingang, welcher in der Mitte der Leitung sitzt für ein paar Nanosekunden eine Spannung am Eingang anliegen hat die etwas VCC/2 entspricht. Das ist aber genau die Schaltschwelle von CMOS-ICs. Kleinste eingekoppelte Störungen können nun dafür sorgen, daß der Takteingang mehrere Flanken &amp;quot;sieht&amp;quot;, wo eigentlich nur eine sein sollte. &lt;br /&gt;
&lt;br /&gt;
=== Parallelterminierung ===&lt;br /&gt;
&lt;br /&gt;
Parallelterminierung absorbiert die ankommende Welle am Ende einer Leitung. Damit treten zu keinem Zeitpunkt Reflexionen auf.&lt;br /&gt;
&lt;br /&gt;
[[bild:wellenwiderstand_parallelterminierung.png]]&lt;br /&gt;
&lt;br /&gt;
Nachteilig ist der Stromverbrauch bei HIGH Pegel. Den kann man halbieren, indem man mit einem speziellen Spannungsregler eine sog. Terminierungsspannung generiert (z.B. bei SCSI). Dieser Spannungsregler muss sowohl Strom liefern können (source) als auch Strom aufnehmen können (sink). Allerdings ist auch hier der Stromverbrauch noch recht beachtlich. Diese Terminierung ist nicht für 5 oder 3.3V CMOS geeignet. Parallelterminierung wird typisch bei Ethernet sowie beim RS485 Bus verwendet, dort sogar an beiden Enden. Es gibt diverse IO-Standards wie HSTL, SSTL etc., welche für schnelle ICs entwickelt wurden (DDR-RAM, DDR2-RAM), diese arbeiten mit Parallel- sowie Serienterminierung.&lt;br /&gt;
&lt;br /&gt;
[[bild:wellenwiderstand_vt-terminierung.png]]&lt;br /&gt;
&lt;br /&gt;
Ohne Terminierungsspannung kommt man mit der sog. Thevenin-Terminierung aus. Dabei wird der Terminierungswiderstand durch zwei doppelt so große Widerstände ersetzt. Aus Sicht des Kabels sind diese beiden Widerstände &#039;&#039;&#039;parallel&#039;&#039;&#039; geschaltet! Daher auch der Name, Thevenin Equivalent ist im Englischen die Bezeichung für eine Ersatzschaltung mit anderem Aufbau aber im Endeffekt gleichen Eigenschaften. Hier spart man auch die Hälfte des Stroms ein, allerdings fliesst jetzt auch bei LOW ein Strom durch die Terminierung.&lt;br /&gt;
&lt;br /&gt;
[[bild:wellenwiderstand_theveninterminierung.png]]&lt;br /&gt;
&lt;br /&gt;
=== AC-Terminierung ===&lt;br /&gt;
&lt;br /&gt;
Um den Stromverbrauch allgemein zu senken kann AC-Terminierung eingesetzt werden. Dazu wird ein Kondensator in Reihe zum Terminierungswiderstand geschaltet. Damit fliesst nur für eine kurze Zeit ein Strom, wenn der Pegel wechselt. Nachteilig ist die bisweilen kritische Dimensionierung des Kondensators. Er darf nicht zu klein sein, damit die Spannung nicht zu schnell steigt und somit der Terminierungswiderstand nicht voll wirksam ist. Andererseits darf er nicht zu groß sein, damit der Umladevorgang vor dem nächsten Flankenwechsel abgeschlossen ist (Taktfrequenz). Hier muß man ggf. experimentieren und &#039;&#039;&#039;richtig&#039;&#039;&#039; messen. Typische Werte liegen zwischen 100pF und 10nF.&lt;br /&gt;
&lt;br /&gt;
Für Takte  und Signale mit konstantem Mittelwert ([[Manchester]]kodierung, 8B10B Kodierung) kann man den Kondensator sehr groß wählen (100nF Keramik + großen Elko). Dann lädt sich der Kondensator über mehrere hundert Takte auf den Mittelwert der Spannung auf und hält diese. Damit wirkt er wie eine Spannungsquelle für die Terminierungsspannung. Der Vorteil ist der eingesparte Spannungsregler, der Stromverbrauch ist identisch mit der Parallelterminierung. Als grobe Orientierung sollte die Zeitkonstante aus Terminierungswiderstand mal Kondensator ca. 1000 mal größer sein als die Periodendauer des Taktes bzw. die Bitdauer das Datenstroms sein.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;R_T \cdot C_T &amp;gt;= 1000 \cdot T_{CLK}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[bild:wellenwiderstand_ac-terminierung.png]]&lt;br /&gt;
&lt;br /&gt;
== Takt- und Datensignale ==&lt;br /&gt;
&lt;br /&gt;
Bei Datensignalen ist es meist durchaus akzeptabel, wenn ein erhöhtes Maß an Überschwingern und Reflexionen auftreten. Auf synchronen [[Bus]]systemem werden die Daten mittels eines Taktes abgetastet. Nur zu diesem Zeitpunkt müssen die Daten sauber anliegen, ein wenig davor (Setup Time) und ein wenig danach (Hold time). Ganz anders bei Takten, asynchronen Resets und Interruptsignalen. Auf diese reagiert ein digitaler IC &#039;&#039;&#039;sofort&#039;&#039;&#039; und sehr schnell. Durch Reflexionen kann es zu &amp;quot;Zacken&amp;quot; auf Taktflanken kommen, welche ein langsamer IC ignoriert aber ein schneller darauf reagiert und zwei Taktflanken &amp;quot;sieht&amp;quot;, wo eigentlich nur eine ist. Hier muss man aufpassen. Diese Signale sollten&lt;br /&gt;
&lt;br /&gt;
* sehr solide layoutet werden&lt;br /&gt;
* etwas Abstand zu allen anderen Signalen bekommen&lt;br /&gt;
* ggf. sauber terminiert werden&lt;br /&gt;
&lt;br /&gt;
Dann gibt es auch keine Probleme mit instabilen Datenübertragungen etc.&lt;br /&gt;
&lt;br /&gt;
== Leitungsführung und Layout ==&lt;br /&gt;
&lt;br /&gt;
Der Zusatz &amp;quot;und halbwegs saubere Leitungsführung&amp;quot; ist eine entscheidende Komponente bei der Verteilung schneller Signale! Irgendwelche wilde Klingeldrahtorgien oder lieblos auf die Platine geschmissene Leitungen zählen nicht dazu. Im Idealfall sind die Leitungen mit einer Impedanz von 50 oder 75 Ohm layoutet, bei differentiellen Signalen auch 100 Ohm (Ethernet, LVDS etc.). Dazu muß eine bestimmte Geometrie der Leiterbahn eingehalten werden, im wesentlichen bestimmt durch Breite und Abstand zur Referenzfläche (GND oder VCC). Die Stichworte für eine Suche im Internet lauten Microstrip und Stripline. Bei zwei- oder vierlagigen Platinen werden die Leitungen mit 50/75&amp;amp;Omega; ziemlich breit, deshalb kann man sich dort dem Ideal nur sehr grob nähern. Dennoch sollte man vor allem für Takte es versuchen, und möglichst die Leitung über einer Referenzfläche führen. Das grundlegende Prinzip lautet:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Die Fläche der Leiterschleife zwischen Signal und Massefläche muß minimiert werden.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Man muß immer daran denken. Strom fließt immer im Kreis, deshalb heißt es ja auch Stromkreis. Der Stromkreis beginnt am Versorgungspin des ICs, welcher das Signal generiert, läuft über den Ausgang und die Signalleitung zum Eingang des Empfängers bzw. der dort platzierten Terminierung, dort nach Masse und über die Masse zurück zum Sender-IC. Die Rückleitung über Masse ist genauso wichtig wie die Hinleitung des Signals! Eine wild geschlungene Masseleitung macht das beste Layout zunichte. Optimal sind komplette Masseflächen, doch die sind nur meist nur bei Platinen mit vier oder mehr Lagen machbar. Bei hochfrequenten Analogschaltungen gönnt man sich den &amp;quot;Luxus&amp;quot; auch bei zweilagigen, weil man sonst in Teufels Küche kommt. Bei schnellen Digitalschaltungen auf zweilagigen Platinen muß man Kompromisse eingehen. Aber auch hier gilt die alte Weisheit, daß die Masse möglichst sternförmig verteilt werden sollte.&lt;br /&gt;
&lt;br /&gt;
Wenn Kabel als Verbindung zwischen ICs verwendet werden, sollte man auch hier Sorgfalt walten lassen.&lt;br /&gt;
&lt;br /&gt;
* Idealerweise sollte man bei Flachbandkabeln jede 2. Ader auf Masse legen und auf BEIDEN Seiten der Verbindundung am Stecker mit der Masse der Platine verbunden werden.&lt;br /&gt;
* Meist reicht es, jede 4.  bis 10. Ader auf Masse zu legen, wobei man Takte direkt neben die Masse legen sollte.&lt;br /&gt;
* Bei Steuerkabeln (verdrillt oder auch nicht) gilt ähnliches.&lt;br /&gt;
&lt;br /&gt;
== Zusammenfassung ==&lt;br /&gt;
&lt;br /&gt;
* Entscheidend für das Entstehen von Reflexionen ist &#039;&#039;&#039;NICHT&#039;&#039;&#039; die Taktfrequenz sondern die Anstiegszeit der Signale. Eine Schaltung mit schnellen ICs wird auch bei niedrigen Taktfrequenzen sehr schnell schalten, auch wenn das nicht unbedingt notwendig wäre.&lt;br /&gt;
* Mit Reflexionen muß man rechnen, wenn die einfache Laufzeit der Leitung grösser als ca. 1/6 der minimalen Anstiegszeit der Signale ist.&lt;br /&gt;
* Serienterminierung ist für Takte nur bei Punkt zu Punkt Verbindungen sicher nutzbar.&lt;br /&gt;
* Parallelterminierung ist für 5/3,3V CMOS ungeeignet (Stromverbrauch).&lt;br /&gt;
* Auch ohne Terminierung ist bei schnellen Signalen eine halbwegs saubere Leitungsführung notwendig.&lt;br /&gt;
* Man sollte nach Möglichkeit immer die langsamsten Logikbausteine verwenden, um Probleme mit Reflexionen zu minimieren (Wozu braucht man 1ns Anstiegszeit bei 5 MHz Takt?).&lt;br /&gt;
* Ausgänge sollten möglichst identische Ausgangswiderstände für LOW und HIGH haben (wie z.B. die HC Familie), sonst wird eine Serienterminierung schwierig bis unmöglich (wie. z.B. die ABT Familie); siehe [http://www.ti.com/litv/pdf/szza008 &amp;quot;Input and Output Characteristics of Digital Integrated Circuits&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Wellenimpedanz Wellenwiderstand bei Wikipedia]&lt;br /&gt;
* [http://www.signalintegrity.com Die Bibel der hochfrequenten Digitalsignale]&lt;br /&gt;
* [http://www.ti.com/litv/pdf/szza008 &amp;quot;Input and Output Characteristics of Digital Integrated Circuits&amp;quot;]&lt;br /&gt;
* http://www.forelec.ch/www/fichiers/HS-PCB-1.PDF (Sehr gutes Dokument zum Thema)&lt;br /&gt;
* [http://wiki.fed.de/fed-wiki/images/3/3f/Impedanzarten_-_Lagenaufbauten.pdf Striplines/Microstrip schnell berechnet] (PDF)&lt;br /&gt;
* [http://www1.sphere.ne.jp/i-lab/ilab/tool/cpw_e.htm Online Calculator]&lt;br /&gt;
* [http://supachris.homeip.net/cits25setup.exe Offline Calculator]&lt;br /&gt;
* [http://www.hp.woodshot.com/appcad/version302/setup.exe Noch ein Offline Calculator]&lt;br /&gt;
* Linksammlung [http://www.circuitsage.com/tline.html Transmission Line Design and Analysis]&lt;/div&gt;</summary>
		<author><name>Philipp burch</name></author>
	</entry>
</feed>