<?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=Cmf</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=Cmf"/>
	<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/articles/Spezial:Beitr%C3%A4ge/Cmf"/>
	<updated>2026-05-18T00:37:40Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=FAQ&amp;diff=79943</id>
		<title>FAQ</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=FAQ&amp;diff=79943"/>
		<updated>2013-12-11T16:14:14Z</updated>

		<summary type="html">&lt;p&gt;Cmf: Rechtschreibfehler&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ein Verzeichnis von im Forum oft gestellten und immer wieder beantworteten Fragen und den zugehörigen Antworten:&lt;br /&gt;
&lt;br /&gt;
=Wie kann ich Zahlen auf [[LCD]]/[[UART]] ausgeben?=&lt;br /&gt;
&lt;br /&gt;
Aber die Bibliothek, die du benutzt, stellt nur eine Funktion zur Verfügung, mit der man einen String ausgeben kann... Was tun? &lt;br /&gt;
&lt;br /&gt;
In den folgenden Beispielen wird eine selbstgeschriebene Funktion zur Stringausgabe auf LCD - die Funktion lcd_string() - aus dem [[AVR-GCC-Tutorial/LCD-Ansteuerung|LCD-Teil des AVR-GCC-Tutorials]] verwendet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
lcd_string( &amp;quot;Hallo Welt&amp;quot; );  // ggf. auch lcd_out() o.ä. in anderen Libraries&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um also eine Zahl (numerische Konstante oder Variableninhalt) auszugeben, muss von dieser Zahl zunächst ihre String-Repräsentation ermittelt werden. Hier geht es aber nur darum, zu zeigen wie man diese String Repräsenation erzeugen kann. Was man dann mit diesem String weiter macht, ob das dann eine LCD-Ausgabe oder eine UART-Übertragung oder das Abspeichern auf SD-Karte oder ... ist, spielt eine untergeordnete Rolle.&lt;br /&gt;
&lt;br /&gt;
Es gibt mehrere Möglichkeiten, sich die Stringrepräsentation zu erzeugen:&lt;br /&gt;
&lt;br /&gt;
===itoa() (utoa(), ltoa(), ultoa(), ftoa() )===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;itoa()&amp;lt;/b&amp;gt; ist keine C-Standardfunktion (wohl aber ihre Umkehrung &amp;lt;b&amp;gt;atoi()&amp;lt;/b&amp;gt; ). Auf manchen Compilern heisst diese Funktion dann folgerichtig &amp;lt;b&amp;gt;_itoa()&amp;lt;/b&amp;gt;, wobei der führende _ eben anzeigt, dass es sich um eine Erweiterung des C-Standards handelt. Bei [[WinAVR]] ist itoa() Bestandteil der mitgelieferten Library avr-libc, in der Library [http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html&#039;&#039;stdlib.h&#039;&#039;].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
  #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
  char Buffer[20];&lt;br /&gt;
  int i = 25;&lt;br /&gt;
&lt;br /&gt;
  itoa( i, Buffer, 10 );&lt;br /&gt;
  lcd_string( Buffer ); // ggf. auch lcd_out() o.ä. in anderen Libraries&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;itoa( i, Buffer, 10 );&amp;lt;/b&amp;gt; - Die Zahl i wird nach ASCII gewandelt und die String Repräsentierung davon wird in Buffer abgelegt. Die Basis, in der diese Wandlung erfolgt, ist das 10-er System. Wird das dritte Argument von 10 in zb. 2 oder auch 16 abgewandelt, erhält man die binäre oder eben eine hexadezimale Repräsentierung des Wertes. Auch wenn 10, 2 und 16 die häufigsten Angaben an dieser Stelle sind, kann itoa aber grundsätzlich in jedes beliebige Zahlensystem wandlen.&lt;br /&gt;
&lt;br /&gt;
Wichtig ist, darauf zu achten, dass das Array &amp;lt;i&amp;gt;Buffer&amp;lt;/i&amp;gt; groß genug dimensioniert wird, um alle Zeichen der Textrepräsentation der Zahl aufzunehmen - inklusive der 0, die den String abschließt, sowie ein mögliches Vorzeichen.&lt;br /&gt;
&lt;br /&gt;
Anzumerken bleibt weiter, dass es normalerweise für alle Datentypen entsprechende Umwandlungsfunktionen gibt, wenn es sie für einen Datentyp gibt. Die Namensgebung lehnt sich an das Schema an: &#039;&#039;Kürzel_für_den_Datentyp to a&#039;&#039;. Eine Funktion die einen unsigned int wandelt, heißt dann utoa (oder _utoa), Floating Point heißt dann ftoa (oder _ftoa), etc.&lt;br /&gt;
&lt;br /&gt;
===sprintf()===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
  char Buffer[20];&lt;br /&gt;
  int i = 25;&lt;br /&gt;
&lt;br /&gt;
  sprintf( Buffer, &amp;quot;%d&amp;quot;, i );&lt;br /&gt;
  lcd_string( Buffer ); // ggf. auch lcd_out() o.ä. in anderen Libraries&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Methode funktioniert auch bei long oder float Werten. Unbedingt beachtet werden muss allerdings, dass die Typkennzeichnungen im sog. Format-String (hier &amp;quot;%d&amp;quot;) mit den tatsächlichen Typen der auszugebenden Werten übereinstimmt. Und dass der Buffer, der den Text aufnimmt, auch groß genug dimensioniert wird. Dabei sollte die 0, die den String terminiert, nicht vergessen werden.&lt;br /&gt;
&lt;br /&gt;
Mit sprintf() hat man dieselben Möglichkeiten zur Formatierung wie bei &amp;lt;b&amp;gt;printf()&amp;lt;/b&amp;gt; (siehe unten). Insbesondere gibt es natürlich die Möglichkeit die Zahl gleich in einen umgebenden Text einzubetten bzw. Formatierungen anzugeben:&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
  char Buffer[20];&lt;br /&gt;
  int i = 25;&lt;br /&gt;
&lt;br /&gt;
  sprintf( Buffer, &amp;quot;Anzahl: %d Stueck&amp;quot;, i );&lt;br /&gt;
  lcd_out( Buffer );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der &amp;quot;Haken&amp;quot; an der mächtigen Funktion sprintf() ist, daß sie auch bei minimalisierter Konfiguration verhältnismäßig viel Programmspeicher (Flash-ROM) belegt und relativ viel Prozesszeit benötigt. Daher sollte man sprintf() nur verwenden, wenn kein Speicher- und Prozesszeitmangel besteht. Sonst sollte itoa() oder eine eigene, auf die Bedürfnisse optimierte Implementierung auf jeden Fall vorgezogen werden. Der große Vorteil von sprintf liegt darin, dass man über sehr mächtige Formatiermöglichkeiten verfügt, mit der man die Ausgabe einfach steuern und an seine Bedürfnisse anpassen kann. Dinge die man mit einer Funktion wie itoa alle selbst &#039;händisch&#039; erledigen muss.&lt;br /&gt;
&lt;br /&gt;
====Formatierungen mit printf====&lt;br /&gt;
&lt;br /&gt;
Für jedes auszugebende Argument muss es im Formatstring einen entsprechenden Formatbezeichner geben. Der Aufbau eines Formatbezeichners ist immer&lt;br /&gt;
&lt;br /&gt;
  %[Modifizierer][Feldbreite][.Präzision]Typ&lt;br /&gt;
&lt;br /&gt;
(Die in eckigen Klammern [ ] angegebenen Elemente können auch weggelassen werden, wenn man sie nicht benötigt. Im einfachsten Fall benötigt man also nur das % und den Buchstaben zur Typ-Kennung.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Typ&amp;lt;/b&amp;gt; ist dabei eine Kennung, der mit dem Datentyp des jeweiligen auszugebenden Argumentes übereinstimmen muss. Einige oft benutzte Kennungen, ohne Anspruch auf Vollständigkeit, sind:&lt;br /&gt;
  &amp;lt;b&amp;gt;c&amp;lt;/b&amp;gt;    char&lt;br /&gt;
  &amp;lt;b&amp;gt;d&amp;lt;/b&amp;gt;    int&lt;br /&gt;
  &amp;lt;b&amp;gt;f&amp;lt;/b&amp;gt;    float, double&lt;br /&gt;
  &amp;lt;b&amp;gt;ld&amp;lt;/b&amp;gt;   long&lt;br /&gt;
  &amp;lt;b&amp;gt;u&amp;lt;/b&amp;gt;    unsigned int&lt;br /&gt;
  &amp;lt;b&amp;gt;lu&amp;lt;/b&amp;gt;   unsigned long&lt;br /&gt;
  &amp;lt;b&amp;gt;p&amp;lt;/b&amp;gt;    pointer&lt;br /&gt;
  &amp;lt;b&amp;gt;s&amp;lt;/b&amp;gt;    string&lt;br /&gt;
  &amp;lt;b&amp;gt;x&amp;lt;/b&amp;gt;    ein int wird ausgegeben, die Ausgabe erfolgt&lt;br /&gt;
       aber als Hexadezimalzahl&lt;br /&gt;
  &amp;lt;b&amp;gt;X&amp;lt;/b&amp;gt;    ein int wird ausgegeben, die Ausgabe erfolgt&lt;br /&gt;
       aber als Hexadezimalzahl, wobei Grossbuchstaben verwendet werden&lt;br /&gt;
&lt;br /&gt;
Der&#039;&#039;Modifizierer&#039;&#039; bestimmt, wie und womit nicht benutzte Felder des Ausgabefeldes gefüllt werden sollen, wie die Ausrichtung innerhalb des Feldes erfolgen soll und ob ein Vorzeichen auch dann ausgegeben werden soll wenn die auszugebende Zahl positiv ist. Wird kein Modifizierer angegeben, so werden nicht benutzte Felder mit einem Leerzeichen gefüllt, positive Vorzeichen unterdrückt und die Ausgabe im Feld rechts ausgerichtet.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;b&amp;gt;+&amp;lt;/b&amp;gt;    Vorzeichen wird immer ausgegeben&lt;br /&gt;
  &amp;lt;b&amp;gt;-&amp;lt;/b&amp;gt;    Die Ausgabe wird im Ausgabefeld linksbündig ausgerichtet&lt;br /&gt;
  &amp;lt;b&amp;gt;0&amp;lt;/b&amp;gt;    anstelle von Leerzeichen werden führende 0-en ausgegeben&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;Feldbreite&#039;&#039; gibt die Breite des Ausgabefeldes an, in die die Ausgabe durchgeführt werden soll. Reicht die angegebene Feldbreite nicht aus, so vergrößert printf diese Breite eigenmächtig. Die Feldbreite muß nicht angegeben werden. In diesem Fall bestimmt printf selbst die Feldbreite, so dass die Ausgabe darin Platz findet. Mit der Feldbreite hat man eine simple Möglichkeit dafür zu sorgen, dass der erzeugte String immer eine konstante Länge hat, selbst wenn die auszugebende Zahl diese Länge gar nicht benötigen würde (wichtig zb. bei Tabellen, damit die Einerstellen der Tabelleneinträge auch sauber untereinander stehen, auch dann wenn die Zahlen sich in unterschiedlichen Wertebereichen bewegen).&lt;br /&gt;
&lt;br /&gt;
Die &#039;&#039;Präzision&#039;&#039; kommt nur bei float oder double Zahlen zum Einsatz. Sie legt fest, wieviele Positionen der kompletten Feldbreite für die Ausgabe von Nachkommastellen reserviert werden sollen. Auch sie muss wiederrum nicht angegeben werden und printf benutzt in so einem Fall Standardvorgaben.&lt;br /&gt;
&lt;br /&gt;
===== Beispiele =====&lt;br /&gt;
;&amp;lt;tt&amp;gt;&amp;quot;%d&amp;quot;&amp;lt;/tt&amp;gt;: Ausgabe eines Integer&lt;br /&gt;
;&amp;lt;tt&amp;gt;&amp;quot;%5d&amp;quot;&amp;lt;/tt&amp;gt;: Ausgabe eines Integer in einem Feld mit 5 Zeichen Breite&lt;br /&gt;
;&amp;lt;tt&amp;gt;&amp;quot;%05d&amp;quot;&amp;lt;/tt&amp;gt;: Ausgabe eines Integer in einem Feld mit 5 Zeichen Breite, wobei das Feld links mit führenden Nullen auf 5 Zeichen aufgefüllt wird&lt;br /&gt;
;&amp;lt;tt&amp;gt;&amp;quot;%-5d&amp;quot;&amp;lt;/tt&amp;gt;: Ausgabe eines Integer in einem Feld mit 5 Zeichen Breite. Die Zahl wird linksbündig in das Feld gestellt.&lt;br /&gt;
;&amp;lt;tt&amp;gt;&amp;quot;%6.3f&amp;quot;&amp;lt;/tt&amp;gt;: Ausgabe eines float (oder double). Die Ausgabe erfolgt in einem Feld mit 6 Zeichen Breite, wobei 3 Nachkommastellen ausgegeben werden. Achtung: In der Feldbreite ist auch ein eventuelles Vorzeichen sowie der Dezimalpunkt enthalten. Bei einer Feldbreite von 6 Zeichen und 3 Nachkommastellen, bleiben bei einer positiven Zahl daher nur 2 Positionen für den Vorkommaanteil, bei negativen sogar nur 1 Stelle (6 - 3 Nachkommastellen - 1 Dezimalpunkt - 1 Vorzeichen = 1)&lt;br /&gt;
&lt;br /&gt;
===Eigene Umwandlungsfunktionen===&lt;br /&gt;
&lt;br /&gt;
Möchte man &amp;lt;b&amp;gt;itoa()&amp;lt;/b&amp;gt; nicht benutzen oder hat es gar auf seinem System nicht zur Verfügung, dann ist es auch nicht schwer, sich selbst eine Funktion dafür zu schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void ItoA( int z, char* Buffer )&lt;br /&gt;
{&lt;br /&gt;
  int i = 0;&lt;br /&gt;
  int j;&lt;br /&gt;
  char tmp;&lt;br /&gt;
  unsigned u;    // In u bearbeiten wir den Absolutbetrag von z.&lt;br /&gt;
  &lt;br /&gt;
    // ist die Zahl negativ?&lt;br /&gt;
    // gleich mal ein - hinterlassen und die Zahl positiv machen&lt;br /&gt;
    if( z &amp;lt; 0 ) {&lt;br /&gt;
      Buffer[0] = &#039;-&#039;;&lt;br /&gt;
      Buffer++;&lt;br /&gt;
      // -INT_MIN ist idR. größer als INT_MAX und nicht mehr &lt;br /&gt;
      // als int darstellbar! Man muss daher bei der Bildung &lt;br /&gt;
      // des Absolutbetrages aufpassen.&lt;br /&gt;
      u = ( (unsigned)-(z+1) ) + 1; &lt;br /&gt;
    }&lt;br /&gt;
    else { &lt;br /&gt;
      u = (unsigned)z;&lt;br /&gt;
    }&lt;br /&gt;
    // die einzelnen Stellen der Zahl berechnen&lt;br /&gt;
    do {&lt;br /&gt;
      Buffer[i++] = &#039;0&#039; + u % 10;&lt;br /&gt;
      u /= 10;&lt;br /&gt;
    } while( u &amp;gt; 0 );&lt;br /&gt;
&lt;br /&gt;
    // den String in sich spiegeln&lt;br /&gt;
    for( j = 0; j &amp;lt; i / 2; ++j ) {&lt;br /&gt;
      tmp = Buffer[j];&lt;br /&gt;
      Buffer[j] = Buffer[i-j-1];&lt;br /&gt;
      Buffer[i-j-1] = tmp;&lt;br /&gt;
    }&lt;br /&gt;
    Buffer[i] = &#039;\0&#039;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Grundprinzip ist einfach:&amp;lt;br&amp;gt;&lt;br /&gt;
Die Ermittlung der einzelnen Stellen erfolgt in der zentralen Schleife&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    do {&lt;br /&gt;
      Buffer[i++] = &#039;0&#039; + u % 10;&lt;br /&gt;
      u /= 10;&lt;br /&gt;
    } while( u &amp;gt; 0 );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
durch fortgesetzte Division durch 10 und Restbildung.&lt;br /&gt;
&lt;br /&gt;
    8392&lt;br /&gt;
&lt;br /&gt;
    8392 % 10           -&amp;gt; &amp;lt;b&amp;gt;2&amp;lt;/b&amp;gt;&lt;br /&gt;
    8392 / 10  -&amp;gt; 839&lt;br /&gt;
&lt;br /&gt;
     839 % 10           -&amp;gt; &amp;lt;b&amp;gt;9&amp;lt;/b&amp;gt;&lt;br /&gt;
     839 / 10  -&amp;gt; 83&lt;br /&gt;
&lt;br /&gt;
      83 % 10           -&amp;gt; &amp;lt;b&amp;gt;3&amp;lt;/b&amp;gt;&lt;br /&gt;
      83 / 10  -&amp;gt; 8&lt;br /&gt;
&lt;br /&gt;
       8 % 10           -&amp;gt; &amp;lt;b&amp;gt;8&amp;lt;/b&amp;gt;&lt;br /&gt;
       8 / 10  -&amp;gt; 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nur leider erhält man dadurch die einzelnen Ziffern der Zahl in umgekehrter Reihenfolge im String (&#039;2&#039; &#039;9&#039; &#039;3&#039; &#039;8&#039; anstelle von &#039;8&#039; &#039;3&#039; &#039;9&#039; &#039;2&#039;). Dies ist aber kein Problem, die nachfolgende Schleife&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
  for( j = 0; j &amp;lt; i / 2; ++j ) {&lt;br /&gt;
    tmp = Buffer[j];&lt;br /&gt;
    Buffer[j] = Buffer[i-j-1];&lt;br /&gt;
    Buffer[i-j-1] = tmp;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
spiegelt den String in sich, sodass danach der String eine korrekte Repräsentation der ursprünglichen Zahl darstellt. Der Funktionsteil vor der &#039;Zerlegeschleife&#039; behandelt den Sonderfall daß die Zahl negativ ist. Negative Zahlen werden behandelt indem im Endergebnis ein &#039;-&#039; vermerkt wird und danach die Zahl positiv gemacht wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* Forenbeitrag [http://www.mikrocontroller.net/topic/67405#541885 Integer-Zahl in String mit bestimmter Zeichenlänge]&lt;br /&gt;
* Forenbeitrag [http://www.mikrocontroller.net/topic/84005#704736 (Resourcenschonend) Wert einer Variable am LCD ausgeben] von Niels Hüsken &lt;br /&gt;
* Forenbeitrag [http://www.mikrocontroller.net/topic/121526?goto=new#new Formatierte Zahlenausgabe in C] von  Peter Dannegger&lt;br /&gt;
* [[Festkommaarithmetik]]&lt;br /&gt;
&lt;br /&gt;
=Datentypen in Operationen=&lt;br /&gt;
Ein häufiges Problem betrifft die Auswertung von Ausdrücken. Konkret die Frage nach den beteiligten Datentypen.&lt;br /&gt;
zb&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
double i;&lt;br /&gt;
int j, k;&lt;br /&gt;
&lt;br /&gt;
i = j / k;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Die Frage lautet dann: Warum erhalte ich keine Kommastellen, ich weise doch das Ergebnis einem double zu?&lt;br /&gt;
&lt;br /&gt;
Dazu ist zu sagen, dass C nicht so funktioniert. Die Tatsache dass i eine double Variable ist, ist für die Auswahl der Operation, welche die Division durchführt, völlig irrelevant. C orientiert sich ausschliesslich an den &lt;br /&gt;
Datentypen der beteiligten Operanden, um zu entscheiden ob die Division als Integer- oder als Gleitkommadivision durchzuführen ist. Und da sowohl j als auch k ein Integer sind, wird die Division als Integerdivision durchgeführt&lt;br /&gt;
unabhängig davon, was mit dem Ergebnis weiter passiert. Erst nach der Division wird das Ergebnis in einen double überführt, um es an i zuweisen zu können. Zu diesem Zeitpunkt gibt es aber keine Kommastellen mehr, eine Integerdivision erzeugt keine. Und damit tauchen klarerweise auch im Ergebnis keine auf.&lt;br /&gt;
&lt;br /&gt;
Aus genau diesem Grund ist zb das Ergebnis von&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
double i;&lt;br /&gt;
i = 5 / 8;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
eine glatte 0 und nicht 0.625. Die Division 5 / 8 wird als Integer Division gemacht und liefert als solche keine Nachkommastellen. Wird das Ergebnis der Division in einen double umgewandelt, um es an i zuweisen zu können, ist das Kind schon in den Brunnen gefallen: Die Nachkommastellen sind schon längst weg bzw. waren nie vorhanden.&lt;br /&gt;
&lt;br /&gt;
Will man den Compiler dazu zwingen, die Division als Gleitkommadivision durchzuführen, so muss man daher dafür sorgen, dass mindestens einer der beteiligten Operanden ein double Wert ist. Dann bleibt dem Compiler nichts anderes übrig, als auch den zweiten Operanden ebenfalls zu einem double zu machen und die Operation als Gleitkommaoperation durchzuführen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
double i;&lt;br /&gt;
i = 5.0 / 8.0;&lt;br /&gt;
&lt;br /&gt;
i = (double)j / k;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Generell implementiert der Compiler eine Operation immer im &#039;höchsten&#039; Datentyp, der in dieser Operation vorkommenden Operanden. Operanden in einem &#039;niedrigeren&#039; Datentyp werden automatisch immer in diesen &#039;höchsten&#039; Datentyp umgewandelt, zumindest aber int. Die Reihung orientiert sich dabei an der Regel: Ein &#039;höherer&#039; Datentyp kann alle Werte eines &#039;niedrigeren&#039; Datentyps aufnehmen.&lt;br /&gt;
&lt;br /&gt;
    int&lt;br /&gt;
    unsigned int&lt;br /&gt;
    long&lt;br /&gt;
    unsigned long&lt;br /&gt;
    long long&lt;br /&gt;
    unsigned long long&lt;br /&gt;
    double&lt;br /&gt;
    &lt;br /&gt;
float kommt in dieser Tabelle gar nicht vor, da Gleitkommaoperationen grundsätzlich immer als double-Operationen durchgeführt werden. Wohl kann es aber sein, dass double und float dieselbe Anzahl an Bits benutzen. Damit reduziert sich eine double Operation effektiv auf eine float Operation. (Anmerkung: mit dem C99-Standard hat sich dieses geändert. Dort gibt es dann auch echte float Operationen)&lt;br /&gt;
&lt;br /&gt;
Hat man also in einer Operation 2 Operanden der Datentypen int und long, so wird der int implizit zu einem long gemacht und die Operation als long Operation durchgeführt. Das Ergebnis hat dann den Datentyp long.&lt;br /&gt;
&lt;br /&gt;
==Welche Datentypen haben Konstanten==&lt;br /&gt;
&lt;br /&gt;
Auch Zahlenkonstante besitzen einen Datentyp, der selbstverständlich vom Compiler bei der Auswahl der Operation berücksichtigt wird. Hier gilt die Regel: Benutzt wird der Datentyp, der die Zahl gerade noch aufnehmen kann. Eine Zahlenkonstante 5 hat daher den Datentyp int. Die Zahl 32767 passt gerade noch in einen int, und hat daher den Datentyp int. 32768 ist für einen int bereits zu groß und hat daher den Datentyp long. 5.0 ist hingegem immer eine double-Konstante. Der Dezimalpunkt erzwingt dieses.&lt;br /&gt;
&lt;br /&gt;
Eine kleine Feinheit gibt es noch zu beachten. Konstanten in dezimaler Schreibweise haben immer einen signed Datentyp, während Konstanten in hexadezimaler bzw. oktaler Schreibweise je nach Wert einen signed oder einen unsigned Datentyp haben können.&lt;br /&gt;
&lt;br /&gt;
Möchte man einer Konstanten einen bestimmten Datentyp aufzwingen, so gibt es dazu 2 (ein halb) Möglichkeiten:&lt;br /&gt;
* Entweder man castet die Konstante in den gewünschten Datentyp&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
   (long)5&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* oder man benutzt die in C dafür vorgesehene Schreibweise, indem man der Konstanten einen Suffix anhängt, der den gewünschten Datentyp beschreibt&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    5L&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Beides ergibt eine dezimale 5, die vom Datentyp long ist.&lt;br /&gt;
&lt;br /&gt;
* eine Zahl in mit einem Dezimalkomma&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    5.0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
ist immer eine double Zahl. Es sei denn sie hat explizit einen Suffix&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    5.0F&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
dann hat man es mit einer float Zahl zu tun.&lt;br /&gt;
&lt;br /&gt;
Die gültigen Suffixe für Zahlen sind U, L, UL und F:&lt;br /&gt;
&lt;br /&gt;
* U wie unsigned; dabei wird zuerst int angenommen. Es erfolgt eine automatische Ausweitung auf long, wenn die Zahl den Wertebereich eines unsigned int überschreitet. &lt;br /&gt;
* L wie long; die Zahl selbst kann int oder double sein.&lt;br /&gt;
* UL wie unsigned long. Eigentlich eine Zusammensetzung aus U und L&lt;br /&gt;
* F wie float.&lt;br /&gt;
&lt;br /&gt;
Präprozessordefinitionen besitzen keine eigene Datentypen, da sie eine reine Textersetzungen durchführen. Deren Inhalte können aber ggf. zu Werten aufgelöst werden, die datentypbehaftet sind.&lt;br /&gt;
&lt;br /&gt;
=Aktivieren der Floating Point Version von sprintf bei WinAVR bzw AVR-Studio=&lt;br /&gt;
[[Bild:AVR_Studio_float1.gif|thumb|right|300px|Project → Configuration Options  → Libraries → Available Link Objects]]&lt;br /&gt;
[[Bild:AVR_Studio_float2.gif|thumb|right|300px|Custom Options → Custom Compilation Options → Linker Options]]&lt;br /&gt;
Beim WinAVR/AVR-Studio wird standardmässig eine Version der printf-Bibliothek verwendet, die keine Floatingpoint-Verarbeitung unterstützt. Die meisten Programme benötigen keine Floatingpoint-Unterstützung, so dass dadurch wertvoller Programmspeicherplatz gespart werden kann.&lt;br /&gt;
&lt;br /&gt;
Benutzt man allerdings eine printf-Variante für die Ausgabe von Floatingpoint-Zahlen, so erscheint an Stelle der korrekt formatierten Zahl lediglich ein &#039;?&#039;. Dies ist ein Indiz dafür, dass die Floatingpoint-Verarbeitung im Projekt aktiviert werden muss.&lt;br /&gt;
&lt;br /&gt;
Um die Floatingpoint-Verarbeitung zu aktivieren, geht man im &#039;&#039;&#039;AVR Studio 4&#039;&#039;&#039; wie folgt vor: &lt;br /&gt;
* Menüpunkt: &#039;&#039;Project → Configuration Options&#039;&#039;&lt;br /&gt;
* Im sich öffnenden Dialog wird in der linken Navigationsleiste der Eintrag &#039;&#039;Libraries&#039;&#039; ausgewählt.&lt;br /&gt;
* Unter &#039;&#039;Available Link Objects&#039;&#039; werden Bibliotheken angeboten. Für die Aktivierung der Floatingpoint-Unterstützung sind 2 interessant&amp;lt;ref&amp;gt;&amp;lt;tt&amp;gt;libc.a&amp;lt;/tt&amp;gt; sollte nicht zu den Bibliotheken hinzugefügt werden, da sie automatisch eingebunden wird. Etwas Hintergrundinformationen gibt es in [http://www.mikrocontroller.net/topic/173630 diesem Thread.]&lt;br /&gt;
&amp;lt;/ref&amp;gt;:&lt;br /&gt;
** &amp;lt;tt&amp;gt;libprintf_flt.a&amp;lt;/tt&amp;gt;&lt;br /&gt;
** &amp;lt;tt&amp;gt;libm.a&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Beide Bibliotheken werden durch Aktivieren und einen Druck auf &#039;&#039;Add Library → &#039;&#039; in die rechte Spalte übernommen.&lt;br /&gt;
* Danach wählt man in der Navigationsleiste den Eintrag &#039;&#039;Custom Options&#039;&#039;.&lt;br /&gt;
* Unter &#039;&#039;Custom Compilation Options&#039;&#039; wird &#039;&#039;Linker Options&#039;&#039; ausgewählt und in das Textfeld rechts/unten folgender Text eingetragen:&lt;br /&gt;
         -Wl,-u,vfprintf&lt;br /&gt;
* Ein Druck auf &#039;&#039;Add&#039;&#039; befördert die Zeile in das Listenfeld darüber, welches Optionen für den Linker enthält.&lt;br /&gt;
* Mit &#039;&#039;OK&#039;&#039; wird die Konfiguration abgeschlossen.&lt;br /&gt;
&lt;br /&gt;
Bei &#039;&#039;&#039;AVR Studio 5&#039;&#039;&#039; trägt man die Optionen an anderen Stellen ein ([http://www.mikrocontroller.net/topic/221583#2219612 Beitrag von Hal Smith]): &lt;br /&gt;
*&#039;&#039;Project Properties → Toolchain → AVR/GNU C-Linker → Libraries&#039;&#039;&amp;lt;br/&amp;gt;In &#039;&#039;Libraries&#039;&#039; &amp;lt;tt&amp;gt;(-WI, -I), libprintf_flt.a libm.a&amp;lt;/tt&amp;gt; eintragen.&lt;br /&gt;
* &#039;&#039;Project Properties → Toolchain → AVR/GNU C-Linker → Miscellaneous&#039;&#039;&amp;lt;br/&amp;gt;In &#039;&#039;Other Linker Flags&#039;&#039; &amp;lt;tt&amp;gt;-Wl,-u,vfprintf&amp;lt;/tt&amp;gt; eintragen.&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
= Wie funktioniert String-Verarbeitung in C? =&lt;br /&gt;
: → Siehe: &#039;&#039;[[String-Verarbeitung in C]]&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= struct Strukturen =&lt;br /&gt;
&lt;br /&gt;
: → Siehe: &#039;&#039;[[Strukturen in C]]&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
= Funktionszeiger =&lt;br /&gt;
&lt;br /&gt;
: → Siehe: &#039;&#039;[[Funktionszeiger in C]]&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Header File - wie geht das =&lt;br /&gt;
&lt;br /&gt;
Ein Header File ist im Grunde nichts anderes als eine Sammlung aller Informationen, die ein &#039;Aussenstehender&#039; benötigt, um die in einem C-File gesammlten Funktionen benutzen zu können.&lt;br /&gt;
&lt;br /&gt;
Trotzdem gibt es immer wieder Schwierigkeiten, wie sich die Sache mit Header Files und/oder #include verhält und wie man eine derartige Lösung aufbauen kann.&lt;br /&gt;
&lt;br /&gt;
Gegeben sei ein System bestehend aus 3 Funktionen&lt;br /&gt;
* main()&lt;br /&gt;
* functionA()&lt;br /&gt;
* functionB()&lt;br /&gt;
und einigen globalen Variablen. Für dieses System soll eine Aufteilung erfolgen, so dass funtionA samt seinen zugehörigen globalen Variablen in einer eigenen C-Datei residiert (FileA.c), functionB in einem eigenen File residiert (FileB.c) und main() als Hautpfunktion seine eigens C-File (Main.c) darstellt und jeweils die entsprechenden Header Files existieren.&lt;br /&gt;
&lt;br /&gt;
Kochrezeptartig kann man in vielen Fällen einfach so vorgehen:&lt;br /&gt;
Man schreibt erst mal den C-Code der Funktion, die man implementieren möchte. Zb fängt man an mit FileA.c&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// FileA.c&lt;br /&gt;
&lt;br /&gt;
int VarExtA;&lt;br /&gt;
int VarIntA;&lt;br /&gt;
&lt;br /&gt;
#define PortpinX PortA.1&lt;br /&gt;
&lt;br /&gt;
int functionIntA( void )&lt;br /&gt;
{&lt;br /&gt;
  VarIntA = VarExtB;&lt;br /&gt;
  functionB();&lt;br /&gt;
  PortpinX = 1;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jetzt geht man das File, so wie es auch der Compiler macht, von oben nach unten durch schaut den Code durch. Damit functionB aufgerufen werden kann, ist ein Prototyp dafür notwendig. Der kommt aus einem Header File, welches noch nicht existiert, aber im Laufe des Prozesses entstehen und FileB.h heissen wird. FileB.h deshalb, weil die Funktion in FileB.c enthalten ist und man zur Vermeidung von Konfusion die Header Files immer gleich benennt wie die C-Files, nur eben mit einer anderen Dateiendung. FileB.h wird noch geschrieben werden, das hindert uns jetzt aber nicht daran, so zu tun als ob es dieses schon geben würde und ein entsprechender #include ergänzt. (Solange nicht compiliert wird ist das ja auch kein Problem. Irgendwo muss man ja schliesslich mal anfangen die Ergänzungen zu machen.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// FileA.c&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;FileB.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int VarExtA;&lt;br /&gt;
int VarIntA;&lt;br /&gt;
&lt;br /&gt;
#define PortpinX PortA.1&lt;br /&gt;
&lt;br /&gt;
int functionA( void )&lt;br /&gt;
{&lt;br /&gt;
  VarIntA = VarExtB;&lt;br /&gt;
  functionB();&lt;br /&gt;
  PortpinX = 1;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Gut. Die Variable VarExtB wird ebenfalls über den include hereingezogen&lt;br /&gt;
werden. Damit ist FileA.c erst mal vollständig. Da fehlt jetzt erst mal nichts mehr. Alles was in FileA.c vorkommt sind entweder C-Schlüsselwörter, durch FileA.c selbst definiert oder kommt über den #include herein.&lt;br /&gt;
&lt;br /&gt;
Der nächste Schritt ist die Überlegung: Was von dem Zeugs in FileA.C soll von anderer Stelle (von anderen C-Files aus) benutzt und verwendet werden können.&lt;br /&gt;
Welche Dinge muss FileA von sich preis geben.&lt;br /&gt;
&lt;br /&gt;
Da sind zu erst mal die beiden Variablen. Was soll mit denen geschehen?&lt;br /&gt;
VarExtA soll von aussen zugreifbar sein, VarIntA nicht. Und dann&lt;br /&gt;
natürlich die Funktion, die aufrufbar sein soll.&lt;br /&gt;
&lt;br /&gt;
Also beginnt man ein Header File für FileA.c zu schreiben, in das all das&lt;br /&gt;
reinkommt, was FileA.c nach aussen sichtbar machen will.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// FileA.h&lt;br /&gt;
&lt;br /&gt;
extern int VarExtA;&lt;br /&gt;
&lt;br /&gt;
int functionA( void );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Variable kriegt ein extern davor (und wird damit zu einer Deklaration), bei der Funktion wird einfach die Implementierung weggenommen und die somit zu einer Deklaration veränderte Zeile mit einem ; abgeschlossen. Wenn man möchte kann man den so geschaffenen Prototypen auch mit einem extern einleiten. Notwendig ist es aber nicht.&lt;br /&gt;
&lt;br /&gt;
Erneuter Blick aufs Header File. Kommt da irgendwas vor, was nicht&lt;br /&gt;
Standard C Schlüsselwort ist? Nein. Nichts.&lt;br /&gt;
Also ist dieses Header File somit ebenfalls in sich vollständig.&lt;br /&gt;
&lt;br /&gt;
Zur Sicherheit wird in FileA.c noch einen Include auf das&lt;br /&gt;
eigene Header File hinzugefügt, denn dann kann der Compiler überprüfen ob die&lt;br /&gt;
Angaben im Header File mit der tatsächlichen Implementierung&lt;br /&gt;
übereinstimmen. Und da VarIntA von aussen nicht sichtbar sein soll (auch&lt;br /&gt;
nicht durch Tricks), wird sie static gemacht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// FileA.c&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;FileA.h&amp;quot;&lt;br /&gt;
#include &amp;quot;FileB.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int VarExtA;&lt;br /&gt;
static int VarIntA;&lt;br /&gt;
&lt;br /&gt;
#define PortpinX PortA.1&lt;br /&gt;
&lt;br /&gt;
int functionA( void )&lt;br /&gt;
{&lt;br /&gt;
  VarIntA = VarExtB;&lt;br /&gt;
  functionB();&lt;br /&gt;
  PortpinX = 1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dasselbe für FileB.c. Erst mal einfach runterschreiben&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// FileB.c&lt;br /&gt;
&lt;br /&gt;
int VarExtB;&lt;br /&gt;
int VarIntB;&lt;br /&gt;
&lt;br /&gt;
#define SettingB 0x01&lt;br /&gt;
&lt;br /&gt;
int functionB( void )&lt;br /&gt;
{&lt;br /&gt;
  VarExtA = 1;&lt;br /&gt;
  functionA();&lt;br /&gt;
  VarIntB = SettingB;&lt;br /&gt;
&lt;br /&gt;
  MeinePrivateFunktion();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void MeinePrivateFunktion()&lt;br /&gt;
{&lt;br /&gt;
  VarIntB = 8;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
damit functionA aufgerufen werden kann, braucht es wieder einen Prototypen. Den&lt;br /&gt;
kriegt man über von FileA.h, welches daher includiert wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// FileB.c&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;FileA.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int VarExtB;&lt;br /&gt;
int VarIntB;&lt;br /&gt;
&lt;br /&gt;
#define SettingB 0x01&lt;br /&gt;
&lt;br /&gt;
int functionB( void )&lt;br /&gt;
{&lt;br /&gt;
  VarExtA = 1;&lt;br /&gt;
  functionA();&lt;br /&gt;
  VarIntB = SettingB;&lt;br /&gt;
  MeinePrivateFunktion();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void MeinePrivateFunktion()&lt;br /&gt;
{&lt;br /&gt;
  VarIntB = 8;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Was noch? VarExtA. Diese Variable wird aber ebenfalls durch den #include als extern Deklaration ins FileB.c hereingezogen und ist somit bei der Übersetzung von FileB.c bekannt. Kommt sonst noch etwas vor? MeinePrivateFunktion. Diese Funktion soll nur in FileB.c benutzt werden und ist für jemanden ausserhalb FileB.c völlig uninteressant. Nichts destotrotz gilt die Regel: compiliert wird von oben nach unten und verwendet werden kann nur etwas, was auch bekannt ist. D.h. bevor der Aufruf der Funktion in functionB gemacht werden kann, muss es einen Protoypen der Funktion geben. Da diese Funktion aber nicht nach &#039;aussen&#039; exportiert wird, macht man den Protoypen gleich in das C-File mit hinein.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// FileB.c&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;FileA.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int VarExtB;&lt;br /&gt;
int VarIntB;&lt;br /&gt;
&lt;br /&gt;
#define SettingB 0x01&lt;br /&gt;
&lt;br /&gt;
void MeinePrivateFunktion();&lt;br /&gt;
&lt;br /&gt;
int functionB( void )&lt;br /&gt;
{&lt;br /&gt;
  VarExtA = 1;&lt;br /&gt;
  functionA();&lt;br /&gt;
  VarIntB = SettingB;&lt;br /&gt;
  MeinePrivateFunktion();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void MeinePrivateFunktion()&lt;br /&gt;
{&lt;br /&gt;
  VarIntB = 8;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Würde man die Funktion vorziehen, so dass der Funktionskörper vor der ersten Verwendung steht, dann würde man auch keinen Protoypen benötigen. Eine Funktionsdefinition fungiert als ihr eigener Protoyp.&lt;br /&gt;
&lt;br /&gt;
Kommt sonst noch etwas vor? Nix mehr. In FileB.c wird sonst nix mehr verwendet was nicht entweder C Schlüsselwort oder im File selber oder durch einen #include reinkommt.&lt;br /&gt;
&lt;br /&gt;
Dann wieder: das Header File für B schreiben. Dabei einfach nur überlegen: was soll von FileB.c nach aussen getragen werden?&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// FileB.h&lt;br /&gt;
&lt;br /&gt;
extern int VarExtB;&lt;br /&gt;
&lt;br /&gt;
int functionB( void );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
und zur Sicherheit wieder ins eigene C-File includen und alle Variablen&lt;br /&gt;
(oder auch Funktionen), die von aussen nicht sichtbar sein sollen, als&lt;br /&gt;
static markieren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// FileB.c&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;FileB.h&amp;quot;&lt;br /&gt;
#include &amp;quot;FileA.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int VarExtB;&lt;br /&gt;
static int VarIntB;&lt;br /&gt;
&lt;br /&gt;
#define SettingB 0x01&lt;br /&gt;
&lt;br /&gt;
static void MeinePrivateFunktion();&lt;br /&gt;
&lt;br /&gt;
int functionB( void )&lt;br /&gt;
{&lt;br /&gt;
  VarExtA = 1;&lt;br /&gt;
  functionA();&lt;br /&gt;
  VarIntB = SettingB;&lt;br /&gt;
  MeinePrivateFunktion();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void MeinePrivateFunktion()&lt;br /&gt;
{&lt;br /&gt;
  VarIntB = 8;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
damit bleibt nur noch main.c. Auch dieses wird erst mal einfach runtergeschrieben.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int c;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  functionA();&lt;br /&gt;
  functionB();&lt;br /&gt;
  VarExtA = 1;&lt;br /&gt;
  VarExtB = c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit functionA aufgerufen werden kann, braucht es einen Prototypen. Woher kommt er? Aus FileA.h. Also gleich mal includen&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;FileA.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int c;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  functionA();&lt;br /&gt;
  functionB();&lt;br /&gt;
  VarExtA = 1;&lt;br /&gt;
  VarExtB = c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit functionB aufgerufen werden kann, braucht es einen Prototypen. Wo&lt;br /&gt;
kommt der her? Aus FileB.h. Also noch ein #include&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;FileA.h&amp;quot;&lt;br /&gt;
#include &amp;quot;FileB.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int c;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  functionA();&lt;br /&gt;
  functionB();&lt;br /&gt;
  VarExtA = 1;&lt;br /&gt;
  VarExtB = c;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Fehlt noch was? VarExtA ist durch den #include von FileA.h bereits&lt;br /&gt;
abgedeckt und VarExtB ist durch den #include von FileB.h bereits&lt;br /&gt;
abgedeckt. Also fehlt nix mehr. Auch in main.c sind damit alle Sachen&lt;br /&gt;
abgedeckt und es ist in sich vollständig.&lt;br /&gt;
&lt;br /&gt;
Das ist der Standardmechanismus:&lt;br /&gt;
* Implementierung der Funktionen im C File schreiben&lt;br /&gt;
* Überlegen, was von dieser Implementierung von aussen sichtbar sein soll.&lt;br /&gt;
* Dasjenige kommt als Deklaration ins Header File, alles andere am besten static machen.&lt;br /&gt;
* Für alles im C-File, das seinerseits woanders herkommt, gibt es einen #include, der das jeweils notwendige Header File einbindet.&lt;br /&gt;
* Werden im Header File Dinge von woanders benutzt, dann enthält das Header File einen entsprechenden #include&lt;br /&gt;
* Jedes File, sowohl Header-File als auch C-File ist in sich vollständig. Werden dort Dinge benutzt, dann müssen diese vor der Verwendung deklariert worden sein. Wie und wo diese Deklaration herkommt, ist dabei zweitrangig. Es kann sein, dass die Deklaration vor der Verwendung steht, es kann aber auch sein, dass die Deklaration über einen weiteren Include mit aufgenommen wird.&lt;br /&gt;
&lt;br /&gt;
= Ich hab da mehrere *.c und *.h Dateien. Was mache ich damit? =&lt;br /&gt;
&lt;br /&gt;
[[Bild:c-flow.svg|right|thumb|260px|C-Programmierung: Workflow]]&lt;br /&gt;
Zunächst ist es wichtig, sich zu vergegenwärtigen, wie C-Compiler und Linker zusammenarbeiten. Ein komplettes Programmier-Projekt kann und wird im Normalfall aus mehreren Quelldateien bestehen, die alle zusammengenommen das komplette Programm bilden.&lt;br /&gt;
&lt;br /&gt;
Der Prozess des Erstellens des Programmes geschieht in mehrerern Schritten:&lt;br /&gt;
;Compilieren: zunächst werden alle Einzelteile (jede *.c Datei) für sich &#039;&#039;compiliert&#039;&#039;. Dabei ensteht aus jeder c-Datei eine sogenannte Object-Datei, in der bereits der Maschinencode für die im c-File programmierten Funktionen enthalten ist&lt;br /&gt;
;Linken: die einzelnen Object-Dateien werden mit zusätzlichen Bibliotheken und dem Startup-Code zum fertigen Programm &#039;&#039;gelinkt&#039;&#039;.&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
Angenommen, das komplette Projekt besteht aus 2 Dateien:&lt;br /&gt;
&lt;br /&gt;
;main.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int twice (int);&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  twice (5);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
;func.c:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int twice (int number)&lt;br /&gt;
{&lt;br /&gt;
  return 2 * number;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann werden &amp;lt;tt&amp;gt;main.c&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;func.c&amp;lt;/tt&amp;gt; &#039;&#039;unabhängig&#039;&#039; voneinander compiliert. Als Ergebnis erhält man die Dateien &amp;lt;tt&amp;gt;main.o&amp;lt;/tt&amp;gt; und &amp;lt;tt&amp;gt;func.o&amp;lt;/tt&amp;gt;, die den besagten Object-Code enthalten.&lt;br /&gt;
Diese beiden Zwischenergebnisse werden dann zusammen mit Bibliotheken zum fertigen Programm gebunden (gelinkt), das dann ausgeführt werden kann.&lt;br /&gt;
&lt;br /&gt;
Bekommt man also von irgendwo bereits fertige *.c (und zugehörige *.h) Dateien, so genügt es, die *.c Dateien in das Projekt mit aufzunehmen. Dadurch wird das entsprechende C-File compiliert und das Ergebnis davon, das Object-file, wird dann in das fertige Programm mit eingelinkt.&lt;br /&gt;
&lt;br /&gt;
;Achtung: Da jede der C-Dateien unabhängig von allen anderen compiliert wird, bedeutet das auch, dass jede der C-Dateien in sich vollständig sein muss!&lt;br /&gt;
&lt;br /&gt;
Wie eine C-Datei in das Projekt mit aufgenommen wird, hängt im wesentlichen von der benutzten Entwicklungsumgebung ab.&lt;br /&gt;
&lt;br /&gt;
== Makefile ==&lt;br /&gt;
&lt;br /&gt;
Die zusätzliche *.c Datei wird in die SRC Zeile im makefile eingetragen.&lt;br /&gt;
&lt;br /&gt;
== AVR-Studio ==&lt;br /&gt;
&lt;br /&gt;
Hier ist es besonders einfach, eine Datei in das Projekt mit aufzunehmen. Dazu wird im Projektbaum der Knoten &amp;quot;Source Files&amp;quot; aktiviert und mit der rechten Maustaste das Kontextmenü geöffnet. Im Menü wird der Punkt &amp;quot;Add existing Source File(s)&amp;quot; ausgewählt, und anschliessend zeigt man AVR-Studio das zusätzliche C-File. AVR-Studio berücksicht dann diese Datei bei der Projekterzeugung, compiliert es und sorgt dafür, dass es zum fertigen Programm dazugelinkt wird.&lt;br /&gt;
&lt;br /&gt;
=Globale Variablen über mehrere Dateien=&lt;br /&gt;
Ein häufiger Problemkreis in der C Programmierung sind auch globale Variablen, die von mehreren *.c Dateien aus benutzt werden sollen. Was hat es damit auf sich?&lt;br /&gt;
&lt;br /&gt;
Zunächst mal muß man bei der Vereinbarung von Variablen zwischen &#039;&#039;Definition&#039;&#039; und &#039;&#039;Deklaration&#039;&#039; unterscheiden:&lt;br /&gt;
;Definition: Mit einer Definition wird der Compiler angewiesen, eine Variable tatsächlich zu erzeugen. Damit er das kann, muß ihm selbstverständlich der exakte Datentyp und auch der Name der Variablen zur Verfügung stehen. Eine Definition sorgt also dafür, dass im späteren Programm Speicherplatz für diese Variable reserviert wird&lt;br /&gt;
;Deklaration: Mit einer Deklaration teilt man dem Compiler lediglich mit, dass eine Variable existiert. An dieser Stelle soll der Compiler also keinen Speicherplatz reservieren, sondern der Compiler soll einfach nur zur Kenntniss nehmen, daß es eine Variable mit einem bestimmten Namen gibt und von welchem Datentyp sie ist.&lt;br /&gt;
&lt;br /&gt;
Aus obigem folgt sofort, dass eine Definition auch immer eine Deklaration ist. Denn dadurch, daß der Compiler angewiesen wird eine Variable auch tatsächlich zu erzeugen, folgt, dass er dazu auch dieselben Informationen benötigt, die auch in einer Deklaration angegeben werden müssen. Der einzige Unterschied: Bei einer Deklaration trägt der Compiler nur in seinen internen Tabellen ein, dass es diese Variable tatsächlich gibt, während er bei einer Definition zusätzlich auch noch dafür sorgt, dass im fertigen Programm auch Speicher für diese Variable bereitgestellt wird.&lt;br /&gt;
&lt;br /&gt;
Warum ist diese Unterscheidung wichtig?&lt;br /&gt;
&lt;br /&gt;
Weil es in C die sog. &#039;&#039;One Definition Rule&#039;&#039; (ODR). Sie besagt, dass in einem vollständigen Programm, also über alle *.c Dateien gesehen, es für eine Variable nur &amp;lt;b&amp;gt;eine&amp;lt;/b&amp;gt; Definition geben darf. Es darf allerdings beliebig viele Deklarationen geben, solange diese Deklarationen alle im Datentyp übereinstimmen. Kurz gesagt: Man darf den Compiler nur einmal auffordern, eine Variable zu erzeugen (Definition), kann sich aber beliebig oft auf diese eine Variable beziehen (Deklarationen). Aber Vorsicht! Da der Compiler jede einzelne *.c Datei für sich alleine übersetzt und dabei kein Wissen von ausserhalb benutzt, obliegt es der Verantwortung des Programmierers dafür zu sorgen, dass alle Deklarationen im Datentyp übereinstimmen. Der Compiler kann diese Einhaltung prinzipbedingt nicht überwachen!&lt;br /&gt;
&lt;br /&gt;
Woran erkennt man eine Definition bzw. Deklaration?&lt;br /&gt;
&lt;br /&gt;
Eine Definition einer globalen Variable steht immer ausserhalb eines Funktionsblocks. Zb.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int  MyData;         // Globale Variable namens MyData. Sie ist vom Typ int&lt;br /&gt;
char Name[30];       // Globales Array&lt;br /&gt;
long NrElements = 5; // Globale Variable, die auch noch initialisiert wird&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine Deklaration unterscheidet sich von einer Definition in 2 Punkten&lt;br /&gt;
* Es wird das Schlüsselwort &amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt; vorangestellt.&lt;br /&gt;
* Es kann keine Initialisierung geben. Sobald eine Initialisierung vorhanden ist, wird das Schlüsselwort &amp;lt;tt&amp;gt;extern&amp;lt;/tt&amp;gt; ignoriert und aus der Deklaration wird eine Definition.&lt;br /&gt;
&lt;br /&gt;
Beispiele für Deklarationen&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
extern int  MyData;&lt;br /&gt;
extern char Name[30];&lt;br /&gt;
extern long NrElements;&lt;br /&gt;
extern long NrElements = 5;  // Achtung: Dies ist eine Definition!&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Besitzt man also 2 *.c Dateien, main.c und helpers.c, und sollen sich diese beiden Dateien eine globale Variable teilen, so muss in eine Datei eine Definition hinein, während in die andere Datei eine Deklaration derselben Variablen erfolgen muß. Traditionell werden die Definitionen in der *.c-Datei gemacht, die als Hauptdatei des Moduls fungiert, zu der diese Variable konzeptionell gehört. Im Zweifel ist das die *.c Datei, in der main() enthalten ist. Das muss nicht so sein, ist aber eine Konvention, die oft Sinn macht. Alternativ wird auch gerne oft eine eigene *.c Datei (zb. globals.c) gemacht, die einzig und alleine die Defintionen der globalen Variablen enthält.&lt;br /&gt;
&lt;br /&gt;
main.c&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int  AnzahlElemente;        // Dies ist die Definition. Hier wird die globale&lt;br /&gt;
                            // Variable AnzahlElemente tatsächlich erzeugt.&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  AnzahlElemente = 8;&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
helpers.c&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
extern int AnzahlElemente;   // Dies ist die Deklaration die auf die globale&lt;br /&gt;
                             // Variable AnzahlElemente in main.c verweist.&lt;br /&gt;
                             // Wichtig: Der Datentyp muss mit dem in main.c&lt;br /&gt;
                             // angegebenen übereinstimmen&lt;br /&gt;
&lt;br /&gt;
void foo()&lt;br /&gt;
{&lt;br /&gt;
   ...&lt;br /&gt;
  j = AnzahlElemente;&lt;br /&gt;
  AnzahlElemente = 9;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Praktische Durchführung==&lt;br /&gt;
Besteht ein vollständiges Programm aus mehreren *.c Dateien, dann kann man sich vorstellen, daß es mühsam ist, alle Deklarationen immer auf gleich zu halten. Hier bietet sich der Einsatz eines Header Files an, in der die Deklarationen stehen und welches in die jeweiligen *.c Dateien inkludiert wird&lt;br /&gt;
&lt;br /&gt;
Bsp:&lt;br /&gt;
&lt;br /&gt;
Global.h&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
extern int Anzahl;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
main.c&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;Global.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int Anzahl;      // auch wenn Global.h inkludiert wurde, so muss es eine&lt;br /&gt;
                 // Definition der Variablen geben. In Global.h sind ja nur&lt;br /&gt;
                 // Deklarationen.&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
  Anzahl = 5;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
foo.c&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;Global.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void foo()&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
  Anzahl = 8;&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
bar.c&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;Global.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void bar()&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
  j = Anzahl;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auf diese Art kann man erreichen, dass zumindest alle Deklarationen ein und derselben Variablen in einem Programm übereinstimmen. Die Datei Global.h wird auch in main.c inkludiert, obwohl man das eigentlich nicht müsste, denn dort wird die Variable ja definiert. Durch die Inclusion ermöglicht man aber dem Compiler die Überprüfung ob die Deklaration auch tatsächlich mit der Definition übereinstimmt.&lt;br /&gt;
&lt;br /&gt;
Solange kein Initialisierungen der globalen Variablen notwendig sind, gibt es noch einen weiteren Trick, um sich selbst das Leben und die Verwaltung der globalen Variablen zu erleichtern.&lt;br /&gt;
Worin besteht das Problem?&lt;br /&gt;
Das Problem besteht darin, dass man bei Einführung einer neuen globalen Variablen an 2 Stellen erweitern muss: Zum einen in der Header-Datei, die die &#039;extern&#039;-Deklaration der Variablen enthält, zum anderen muss in einer C-Datei die Definition der Variablen erfolgen. Das kann man sich mit etwas Präprozessorarbeit auch einfacher machen:&lt;br /&gt;
&lt;br /&gt;
Global.h&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#ifndef EXTERN&lt;br /&gt;
#define EXTERN extern&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
EXTERN int Anzahl;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
main.c&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define EXTERN&lt;br /&gt;
#include &amp;quot;Global.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
  Anzahl = 5;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
foo.c&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;Global.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void foo()&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
  Anzahl = 8;&lt;br /&gt;
  ...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wie funktioniert das Ganze? Im Grunde muss man nur dafür sorgen, dass der Compiler an &#039;&#039;einer&#039;&#039; Stelle das Schlüsselwort &#039;&#039;&#039;extern&#039;&#039;&#039; ignoriert (hier in main.c) und bei allen anderen Inclusionen beibehält. Dadurch das ein Präprozessor-ifndef benutzt wird, kann dieses erreicht werden. Wird das Header File includiert und ist zu diesem Zeitpunkt das Makro &#039;&#039;&#039;EXTERN&#039;&#039;&#039; noch nicht definiert, so wird innerhalb des Header Files &#039;&#039;&#039;EXTERN&#039;&#039;&#039; zu &#039;&#039;&#039;extern&#039;&#039;&#039; definiert und damit in weiterer Folge im Quelltext &#039;&#039;&#039;EXTERN&#039;&#039;&#039; durch &#039;&#039;&#039;extern&#039;&#039;&#039; ersetzt. Wenn daher foo.c das Header File inkludiert, wird die Zeile&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
EXTERN int Anzahl;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
vom Präprozessor zu&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
extern int Anzahl;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
umgewandelt.&lt;br /&gt;
&lt;br /&gt;
In main.c hingegen sieht die Include-Sequenz so aus&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define EXTERN&lt;br /&gt;
#include &amp;quot;Global.h&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Wenn Global.h bearbeitet wird, existiert bereits ein Makro &#039;&#039;&#039;EXTERN&#039;&#039;&#039;, das auf einen leeren Text expandiert. Dadurch wird verhindert, dass innerhalb von Global.h das Makro &#039;&#039;&#039;EXTERN&#039;&#039;&#039; mit dem Text &#039;&#039;&#039;extern&#039;&#039;&#039; belegt wird und&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
EXTERN int Anzahl;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
wird daher vom Präprozessor zu&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int Anzahl;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
erweitert, genau wie es benötigt wird.&lt;br /&gt;
&lt;br /&gt;
= Was hat es mit volatile auf sich? =&lt;br /&gt;
Immer wieder hört man im Forum die pauschale Aussage &amp;quot;Variablen die in einer ISR verwendet werden, müssen volatile sein&amp;quot;. Nun, das ist so nicht ganz richtig.&lt;br /&gt;
Welches Problem löst denn eigentlich volatile? Was ist denn das eigentliche Problem, das einer Lösung bedarf?&lt;br /&gt;
&lt;br /&gt;
Das Problem findet sich diesmal im Optimierer eines C Compilers. C Compiler übersetzen, wenn sie optimieren dürfen, den C Code nicht direkt so, wie ihn der Programmierer geschrieben hat, sondern sie versuchen Ressourcen einzusparen. Das kann sowohl Programmspeicher als auch Laufzeit, häufig auch beides gemeinsam sein. Zu diesem Zweck untersuchen sie das Programm und versuchen in der funktional gleichwertigen, in Maschinensprache übersetzen Version, Anweisungen einzusparen. Das dürfen sie auch. Der C-Standard erlaubt Optimierungen, solange die &#039;As-If&#039;-Regel eingehalten wird. Das bedeutet: Der Compiler darf das Programm umstellen und verändern, solange die Programmergebnisse dieselben bleiben. Eben &amp;quot;As-if&amp;quot; die Optimierung nie stattgefunden hätte.&lt;br /&gt;
&lt;br /&gt;
Nehmen wir ein Beispiel&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
  i = 2;&lt;br /&gt;
&lt;br /&gt;
  if( i == 5 )&lt;br /&gt;
    j = 8;&lt;br /&gt;
  else&lt;br /&gt;
    j = 6;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
In diesem Programmausschnitt darf der Compiler seine Kenntnisse ausnutzen. Er weiß an dieser Stelle, dass i den Wert 2 hat. Damit ist aber auch klar, dass die Bedingung niemals wahr sein kann, denn 2 kann niemals gleich 5 sein. Wenn die Bedingung aber niemals wahr sein kann, dann kann auch die Zuweisung von 8 an j niemals ausgeführt werden. Der Compiler kann also diesen Programmtext zu diesem hier kürzen&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
  i = 2;&lt;br /&gt;
  j = 6;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
ohne das sich an den Programmergebnissen etwas ändert. Die zweite Version ist aber kürzer und wird, wegen des Wegfalles des Vergleiches, auch schneller ausgeführt.&lt;br /&gt;
&lt;br /&gt;
Eine andere Form der Optimierung betrifft die Verwaltung von µC-Ressourcen und da wieder ganz speziell die Register. Variablen werden ja erst mal im SRAM-Speicher des µC angelegt. Um mit den Werten von Variablen arbeiten zu können, müssen diese Wert aber vom SRAM-Speicher in µC-Register überführt werden (Register kann man sich wie Speicherstellen in der eigentlichen CPU vorstellen). Nur dort können diese Werte mittels Maschinenbefehlen manipuliert werden.&lt;br /&gt;
Jetzt haben aber µC nicht beliebig viele Register. Das bedeutet aber auch, der Compiler muss darüber Buch führen, welche Werte (welche Variablen) gerade in welchen Registern liegen und wenn alle Register belegt sind, muss ein anderes Register freigeräumt werden, in dem der Wert aus dem Register wieder ins SRAM zurück übertragen wird.&lt;br /&gt;
Allerdings kostet das auch Zeit. Der Compiler wird daher versuchen, Variablen, die in einem Programmstück oft benötigt werden, für längere Zeit in den Registern zu halten, um das Registerladen bzw. -zurückschreiben einzusparen. Die Grundannahme lautet dabei immer: In Anweisungen, in denen eine Variable nicht vorkommt, kann diese Variable auch nicht verändert werden. Im Programmstück&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
  while( 1 ) {&lt;br /&gt;
    if( i == 5 )&lt;br /&gt;
      j = 8;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
gibt es für i keine Möglichkeit, verändert zu werden. Der Compiler kann daher entscheiden, dass er diese Variable, *an dieser Stelle*, gar nicht aus dem SRAM laden muss, sondern sich den entsprechenden Wert in einem Register vorhält und dieses Register ausschließlich dafür reserviert. (Er könnte auch entscheiden, dass der Code nie ausgeführt werden kann, aber das ist eine andere Geschichte)&lt;br /&gt;
&lt;br /&gt;
Der springende Punkt ist nun, dass der Compiler hier eine zu kleine Sicht der Dinge hat. Betrachtet man nur dieses Code Stück, dann gibt es tatsächlich für i keine Möglichkeit, seinen Wert zu verändern. Aber die Dinge ändern sich, wenn Interrupts ins Spiel kommen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t i;&lt;br /&gt;
&lt;br /&gt;
ISR( irgendein_Interrupt )&lt;br /&gt;
{&lt;br /&gt;
  i = 5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  while( 1 ) {&lt;br /&gt;
    if( i == 5 )&lt;br /&gt;
      j = 8;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Jetzt gibt es plötzlich eine Möglichkeit, wie i seinen Wert ändern kann: Wenn der entsprechende Interrupt ausgelöst wird, dann wird i auf den Wert 5 gesetzt. i, das ist aber nichts anderes als ein bestimmter Speicherbereich im SRAM. D.h. im SRAM wird die Variable tatsächlich korrekt auf den Wert 5 gesetzt. Nur: Als der Compiler die while-Schleife übersetzt hat, wusste er nichts davon, dass diese Möglichkeit existiert. Er hat entschieden, dass er an dieser Stelle den Wert der Variablen in einem CPU-Register halten wird, um Zugriffe einzusparen. Nur wird diese Kopie des Wertes im Register natürlich nicht verändert, wenn in der ISR das Original von i im SRAM verändert wird.&lt;br /&gt;
Fazit: Obwohl die ISR die Variable tatsächlich verändert, kriegt das der Code im while nicht mit, weil der Compiler es mit der Optimierung an dieser Stelle übertrieben hat. In der while-Schleife wird mit einer Kopie des Wertes von i in einem Register gearbeitet und nicht mit dem originalen Wert von i im SRAM.&lt;br /&gt;
&lt;br /&gt;
Und an dieser Stelle kommt jetzt volatile ins Spiel.&lt;br /&gt;
&lt;br /&gt;
volatile teilt dem Compiler mit, dass ausnahmslos alle Zugriffe auf eine Variable auch tatsächlich auszuführen sind und keine Optimierungen gemacht werden dürfen, weil eine Variable auf Wegen benutzt werden kann, die für den Compiler prinzipiell nicht einsichtig sind. Im obigen Beispiel könnte man argumentieren, dass der Compiler ja wohl die ISR bemerken könne und daher feststellen könnte, dass i tatsächlich verändert wird. Aber das stimmt so in der allgemeinen Form nicht. Niemand sagt, dass der Compiler die ISR überhaupt zu Gesicht bekommen muss, die könnte ja auch in einem ganz anderen C File stecken.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
volatile uint8_t i;&lt;br /&gt;
&lt;br /&gt;
ISR( irgendein_Interrupt )&lt;br /&gt;
{&lt;br /&gt;
  i = 5;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
  while( 1 ) {&lt;br /&gt;
    if( i == 5 )&lt;br /&gt;
      j = 8;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
wird i volatile gemacht, so verbietet man damit dem Compiler explizit, Annahmen über den Datenfluss von i zu treffen. Innerhalb der Schleife muss also tatsächlich jedes Mal wieder erneut i aus dem SRAM geholt werden und mit 5 verglichen werden. Abkürzungen durch Mehrfachverwendung von Registern oder sonstigen Optimierungstricks sind nicht erlaubt. Und damit ist das Problem gelöst. Wird i in der ISR verändert, so bekommt das auch die Abfrage mit, weil ja jetzt auf jeden Fall auf das Original im SRAM zurückgegriffen wird.&lt;br /&gt;
&lt;br /&gt;
Das Gleiche gilt auch ebenso &amp;quot;in die andere Richtung&amp;quot;, wenn also i in der Schleife geändert und in der ISR nur gelesen wird. Auch hier könnte die Optimierung negativ zuschlagen und den Schreibzugriff nur auf eine lokale Kopie der Variable in einem Register durchführen (oder gar ganz wegfallen) lassen, weil der Lesezugriff außerhalb des direkten Programmflusses (in der ISR) für den Compiler nicht ersichtlich ist.&lt;br /&gt;
&lt;br /&gt;
Ein anderes Problem (das ebenfalls mittels volatile gelöst wird) sind Variablen, die tatsächlich im Code überhaupt nie aktiv verändert werden, sondern es sich um Zusatzhardware handelt, die so verschaltet ist, dass sie im Programm in Form einer Variablen auftaucht, z.B. ein Uhren-IC (oder auch ganz banal: Portpins). In diesem Fall wird z.B. die Variable für Sekunden vom Programm gar nicht vom Programm selber verändert, ändert aber trotzdem ihren Inhalt. Die Zusatzhardware selbst macht das. Aus Programmsicht handelt es sich um Speicherzellen, die magisch selbsttätig ihren Wert ändern. Und damit dürfen selbstverständlich auch hier keinerlei Annahmen über den Inhalt der Variablen getroffen werden. Eine derart angebundene externe Hardware nennt man übrigens &amp;quot;memory-mapped&amp;quot;, weil sie ihre Werte ins Memory (=Hauptspeicher) mapped (=einblendet).&lt;br /&gt;
&lt;br /&gt;
Allerdings kann volatile nur bei den Variablen sinnvoll genutzt werden, die &amp;quot;von außen&amp;quot; auch änderbar sind. Bei lokalen Variablen, auch statischen, einer Funktion kann das nur passieren, wenn ihre Adresse einer ISR z.B. durch einen globalen Pointer bekannt gemacht wird.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t *v;&lt;br /&gt;
ISR( irgendein_Interrupt )&lt;br /&gt;
{&lt;br /&gt;
  i = 5;&lt;br /&gt;
  *v = 42;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  uint8_t i; // kann sich nie unerwartet ändern -&amp;gt; volatile nutzlos, behindert nur Optimizer&lt;br /&gt;
&lt;br /&gt;
  volatile uint8_t j; // kann sich unerwartet ändern (über globalen *v)&lt;br /&gt;
  v = &amp;amp;j;&lt;br /&gt;
  ...&lt;br /&gt;
  while( 1 ) {&lt;br /&gt;
    if( i == 5 )&lt;br /&gt;
      j = 8;&lt;br /&gt;
    if( j == 5 )&lt;br /&gt;
      i = 3;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Konstanten an fester Flash-Adresse =&lt;br /&gt;
&lt;br /&gt;
Wie kann man eine Konstante an entsprechender Adresse im Flash ablegen?&lt;br /&gt;
&lt;br /&gt;
Mehmet Kendi hat eine Lösung für [[AVR Studio]] &amp;amp; [[WinAVR]] in &lt;br /&gt;
[http://www.mikrocontroller.net/topic/142704#1453079] angegeben.&lt;br /&gt;
&lt;br /&gt;
= Timer =&lt;br /&gt;
== Was macht ein Timer? ==&lt;br /&gt;
Oft hört man im Forum die Aussage: Timer sind so kompliziert!&lt;br /&gt;
&lt;br /&gt;
Aber eigentlich stimmt das nicht. Ganz im Gegenteil, Timer sind eigentlich eine sehr einfache Sache. Was genau macht eigentlich ein Timer? Die Antwort lautet: er zählt unabhängig vom restlichen Programmfluss vor sich hin. Und? Was macht er noch? Nichts. Das wars schon. Im Kern ist genau das auch schon alles was ein Timer macht.&lt;br /&gt;
[[Bild:Timer_Basis.gif|framed|center|ein 8-Bit Timer bei der Arbeit]]&lt;br /&gt;
&lt;br /&gt;
== Wie schnell macht er es? ==&lt;br /&gt;
Aber so einfach ist die Sache dann doch wieder nicht. Da erhebt sich zunächst mal die Frage: wie schnell zählt denn eigentlich so ein Timer? Normalerweise ist der Timer mit der Taktfrequenz des Prozessors gekoppelt, so dass zb bei einer Taktfrequnz von 1Mhz der Timer auch genau so schnell zählt. In 1 Sekunde zählt ein Timer also von 0 bis 1000000, also 1 Mio Zählschritte. Nun kann aber ein beispielsweise 8-Bit Timer nicht bis 1000000 zählen, dazu ist er nicht groß genug. Mit 8 Bit kann man bis 255 zählen. Zählt man da dann noch 1 dazu, dann läuft der Timer über und beginnt wieder bei 0. Man kann daher ruhigen Gewissens sagen: In 1 Sekunde zählt dieser Timer 3906 mal den Bereich von 0 bis 255 (und weiter auf 0) durch (das sind 256 Zählschritte) und zuätzlich schafft er es danach noch bis 64 zu zählen. Denn 3906 * 256 + 64 = 1000000 und wir haben wieder die 1 Mio Zählschritte, die der Timer in 1 Sekunde erledigt.&lt;br /&gt;
&lt;br /&gt;
Das ist ganz schön schnell. Und weil das oft zu schnell ist, hat jeder Timer noch die Möglichkeit sogenannte Vorteiler (Prescaler) vor den Zähltakt zu schalten. Zb einen Vorteiler von 8. Anstelle von 1Mhz bekommt der Timer dann eine Frequenz von 1Mhz / 8 (= 125kHz) präsentiert. Und dementsprechend würde er in 1 Sekunde dann nur noch von 0 bis 125000 (= 1.000.000 / 8) zählen. Als 8 Bit Timer bedeutet das, dass er in 1 Sekunde jetzt nur noch 488 komplette Zyklen 0 bis 255 schafft und dann noch bis 72 zählen kann. Denn 488 * 256 + 72 = 125000&lt;br /&gt;
&lt;br /&gt;
== Das kann aber nicht alles gewesen sein? ==&lt;br /&gt;
Bis jetzt ist das alles noch unspektakulär und man fragt sich: Was hab ich jetzt davon, wenn der Timer vor sich hinzählt? Nun, die Situation ändert sich, wenn man weiß, dass man bei bestimmten Ereignissen und/oder Zählerständen etwas auslösen lassen kann. So ist zb. dieser Überlauf von 255 auf 0 so ein Ereignis. Mittels eines Interrupts kann man auf dieses Ereignis reagieren lassen und als Folge davon wird eine Funktion vollautomatisch aufgerufen. Und zwar unabhängig davon, was der µC gerade sonst so tut. Und das ist schon recht cool, denn es bedeutet, dass man regelmäßig zu erfolgende Dinge in so eine ISR (Interrupt Service Routine, die Funktion die aufgerufen wird) stecken kann und der Timer sorgt ganz von alleine dafür, dass diese Funktionalität auch tatsächlich regelmäßig ausgeführt wird. Regelmäßig bedeutet in diesem Fall dann auch wirklich regelmäßig. Denn der Timer zählt ja losgelöst von den restlichen Arbeiten, die der µC sonst so erledigt, vor sich hin. Es spielt keine Rolle, ob der µC gerade mitten in einer komplizierten Berechnung steckt oder nicht. Der Timer zählt vor sich hin, und wenn das entsprechende Ereignis eintritt, wird der Interrupt ausgelöst. Und wenn der entsprechende Interrupt mit einer ISR-Funktion gekoppelt ist, dann wird der normale Programmfluss unterbrochen und der µC arbeitet genau diese eine Funktion ab. Und zwar in regelmässigen Zeitabständen, weil ja auch der Interrupt regelmässig auftritt.&lt;br /&gt;
[[Bild:Timer_ISR.gif|framed|center|ein 8-Bit Timer löst durch seinen Overflow regelmäßige ISR Aufrufe aus]]&lt;br /&gt;
Gut, beispielsweise 488 mal in der Sekunde mag für so manchen Zweck zu oft sein, aber es gibt ja auch noch andere Vorteiler (welche steht im Datenblatt) und dann kann man ja auch innerhalb der ISR in einer lokalen Variablen mitzählen und zb nur bei jedem 2.ten Aufruf eine Aktion machen, die dann nur noch 244 mal in der Sekunde ausgeführt wird. Hier gibt es also mehrere Möglichkeiten, wie man die Aufrufhäufigkeit weiter herunterteilen kann, so dass man sich der Zahl annähert, die man benötigt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Für einen Mega16.&lt;br /&gt;
// Andere Prozessoren: siehe Datenblatt wie die Timerkonfiguration einzustellen ist&lt;br /&gt;
&lt;br /&gt;
#define F_CPU 1000000UL&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//&lt;br /&gt;
// der Timer wird mit 1Mhz getaktet. Vorteiler ist 8&lt;br /&gt;
// d.h. der Timer läuft mit 125kHz und würde daher in 1 Sekunde&lt;br /&gt;
// von 0 bis 124999 zaehlen.&lt;br /&gt;
// Aber nach jeweils 256 Zaehlungen erfolgt ein Overflow.&lt;br /&gt;
// Daher werden in 1 Sekunde 125000 / 256 = 488.28125 Overflows erzeugt&lt;br /&gt;
// Oder anders ausgedrückt:  1 / 488.2815 = 0.002048&lt;br /&gt;
// alle 0.002048 Sekunden erfolgt ein Overflow&lt;br /&gt;
//&lt;br /&gt;
ISR( TIMER0_OVF_vect )       // Overflow Interrupt Vector&lt;br /&gt;
{&lt;br /&gt;
  static uint8_t swTeiler = 0;&lt;br /&gt;
&lt;br /&gt;
  swTeiler++;&lt;br /&gt;
  if( swTeiler == 200 ) {    // nur bei jedem 200.ten Aufruf. Effektiv teilt dieses die&lt;br /&gt;
                             // die Aufruffrequenz des nachfolgenden Codes nochmal um&lt;br /&gt;
    swTeiler = 0;            // einen Faktor 200. Der nachfolgende Code wird daher nicht&lt;br /&gt;
                             // alle 0.002 Sekunden sondern alle 0.4096 Sekunden ausgeführt.&lt;br /&gt;
                             // Das reicht, dass man eine LED am Port schon blinken sieht.&lt;br /&gt;
    PORTD = PORTD ^ 0xFF;    // alle Bits am Port umdrehen, einfach damit sich was tut&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  DDRD = 0xFF;          // irgendein Port, damit wir auch was sehen&lt;br /&gt;
&lt;br /&gt;
  TIMSK |= (1&amp;lt;&amp;lt;TOIE0);  // den Overflow Interrupt des Timers freigeben&lt;br /&gt;
  TCCR0 = (1&amp;lt;&amp;lt;CS01);    // Vorteiler 8, jetzt zählt der Timer bereits&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  sei();                // und Interrupts generell freigeben&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  while( 1 )&lt;br /&gt;
  {                     // hier braucht nichts mehr gemacht werden.&lt;br /&gt;
  }                     // der Timer selbst sorgt dafür, dass die ISR Funktion&lt;br /&gt;
}                       // regelmäßig aufgerufen wird&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== CTC Modus ==&lt;br /&gt;
Manchmal reicht das aber nicht. Benötigt man zb nicht 488 sondern möglichst genau 500 ISR Aufrufe in der Sekunde, so wird man weder mit Vorteiler noch durch Softwaremässiges Weiterteilen in der ISR zum Ziel kommen. Man kann natürlich die Taktfrequenz des kompletten Systems soweit umstellen, dass sich das alles ausgeht, aber oft ist das einfach nicht möglich. Was tun?&lt;br /&gt;
&lt;br /&gt;
Die Sache wäre einfacher, wenn man dem Timer vorschreiben könnte, nicht einfach nur von 0 bis 255 zu zählen, sondern wenn man ihm eine Obergrenze vorgeben könnte. Denn dann könnte man sich eine Obergrenze so bestimmen, dass dieser neue Zählbereich in 1 Sekunde ganz genau so oft durchlaufen werden kann, wie man es benötigt. Und hier kommt der sog. &amp;lt;b&amp;gt;CTC&amp;lt;/b&amp;gt; Modus ins Spiel. Denn genau darin besteht sein Wesen: Man gibt dem Timer eine Obergrenze vor. Erreicht seine Zählung diesen Wert, so wird der Timer auf 0 zurückgesetzt und beginnt wieder von vorne. Genau das was wir benötigen. Wollen wir exakt 500 ISR Ausfrufe in der Sekunde haben (bei 1 Mhz Systemtakt), dann wählen wir einen Vorteiler von 8 und setzen die Obergrenze auf 250-1 (nicht vergessen: wir brauchen 250 Zählschritte, das bedeutet der Timer muss von 0 bis 249 zählen, denn auch der Überlauf von 249 zurück auf 0 ist ein Zählschritt). Der Timer taktet dann mit 1Mhz / 8 = 125kHz und da nach jeweils 250 Zählschritten die Obergrenze erreicht ist, wird diese Obergrenze in 1 Sekunde 125000 / 250 = 500 mal erreicht. Genau so wie wir das wollten.&lt;br /&gt;
Wie wird dem Timer nun mitgeteilt, dass er eine spezielle Obergrenze benutzen soll? Nun, jeder Timer hat verschiedene Modi. Welche das bei einem konkreten µC und bei einem konkreten Timer genau sind, findet sich im Datenblatt im Abschnitt über die Timer. Normalerweise ist immer eines der letzteren Abschnitte eines jeden Kapitels im Datenblatt das interessantere: &amp;quot;Register Summary&amp;quot; oder &amp;quot;Register Description&amp;quot; genannt (die Datenblätter sind da nicht ganz einheitlich). So auch hier.&lt;br /&gt;
[[Bild:FAQ_Datenblatt_Timer_Mega16.png|framed|center|Auszug aus dem Atmel Datenblatt für den Mega16 - Suche im Datenblatt]]&lt;br /&gt;
In jedem Atmel Datenblatt findet sich bei jedem Timer immer auch besagter Abschnitt (im Inhaltsverzeichnis beim Kapitel über den jeweiligen Timer suchen. Im Datenblatt-PDF daher immer das Inhaltsverzeichnis anzeigen lassen!), und in diesem Abschnitt gibt es eine Tabelle, aus der hervorgeht, welche Modi es gibt, welche Bits dazu in den Konfigurationsregistern gesetzt werden müssen, wie sich dann die Obergrenze des Timer-Zählbereichs zusammensetzt und noch ein paar Angaben mehr. Beim Mega16 findet sich diese Tabelle für den Timer 0 zb auf Seite 83 und dort ist es die Tabelle 14.2. Diese Tabelle sieht im Datenblatt so aus&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
{| {{Tabelle}} &lt;br /&gt;
|-  style=&amp;quot;background-color:#ffddcc&amp;quot;&lt;br /&gt;
! Mode || WGM01 || WGM00 || Timer/Counter || TOP || Update of || TOV0 Flag&lt;br /&gt;
|-  style=&amp;quot;background-color:#ffddcc&amp;quot;&lt;br /&gt;
!      || (CTC0) || (PWM0) || Mode of Operation || || OCR0 || Set-on&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 0 || 0 || Normal || 0xFF || Immediate || MAX&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 0 || 1 || PWM, Phase Correct || 0xFF || TOP|| BOTTOM&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 1 || 0 || CTC || OCR0 || Immediate || MAX&lt;br /&gt;
|-&lt;br /&gt;
| 3 || 1 || 1 || Fast PWM || 0xFF || BOTTOM || MAX&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dort beginnt man mit der Recherche und sucht sich die Bits für den gewünschten Modus raus. Mit diesen Bits sieht man dann in den Konfigurationsregistern nach, welches Bit zu welchem Register gehört und setzt es ganz einfach. In unserem Fall möchten wir den CTC Modus, also den Modus 2. Dazu muss das Bit WGM01 gesetzt werden und WGM00 muss auf 0 bleiben. Im Datenblatt ein wenig zurückscrollen bringt ans Licht, dass das Bit WGM01 im Konfigurationsregister TCCR0 angesiedelt ist. Weiters entnehmen wir der Tabelle, dass der Timer bis zum Wert in OCR0 zählen wird (die Spalte &amp;lt;b&amp;gt;TOP&amp;lt;/b&amp;gt;). Dort hinein müssen also die 250-1 als Obergrenze geschrieben werden.&lt;br /&gt;
&lt;br /&gt;
Wichtig ist auch noch: Dieser Spezialmodus CTC löst keinen Overflow Interrupt aus, sondern einen sog. Compare Match Interrupt. Dies deshalb, weil die gewünschte Obergrenze ja laut Datenblatt in eines der sog. Compare Match Register geschrieben werden muss (OCR0). Das sind Spezialregister, die nach jedem Zählvorgang mit dem Zählregister verglichen werden. Stimmt ihr Inhalt mit dem des Zählregisters überein, so hat man einen Compare-Match und kann daran wieder eine Aktion (ISR) knüpfen. In diesem speziellen Fall des CTC Modus beinhaltet dieser Compare Match dann auch noch das automatische Rücksetzen des Timers auf 0.&lt;br /&gt;
&lt;br /&gt;
Und natürlich können auch mehrere Techniken kombiniert werden. Z. B. CTC Modus und zusätzliches weiteres softwaremässiges Herunterteilen in der ISR sieht dann so aus:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Für einen Mega16.&lt;br /&gt;
// Andere Prozessoren: siehe Datenblatt wie die Timerkonfiguration einzustellen ist&lt;br /&gt;
 &lt;br /&gt;
#define F_CPU 1000000UL&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
ISR( TIMER0_COMP_vect )    // Compare Match Interrupt Vector&lt;br /&gt;
{&lt;br /&gt;
  static uint8_t swTeiler = 0;&lt;br /&gt;
 &lt;br /&gt;
  swTeiler++;&lt;br /&gt;
  if( swTeiler == 200 ) {&lt;br /&gt;
    swTeiler = 0;&lt;br /&gt;
    PORTD = PORTD ^ 0xFF;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  DDRD = 0xFF;          // irgendein Port, damit wir auch was sehen&lt;br /&gt;
 &lt;br /&gt;
  TIMSK = (1&amp;lt;&amp;lt;OCIE0);               // den Output Compare Interrupt des Timers freigeben&lt;br /&gt;
  OCR0  = 250 - 1;                    // nach 250 Zaehlschritten -&amp;gt; Interrupt und Timer auf 0&lt;br /&gt;
  TCCR0 = (1&amp;lt;&amp;lt;WGM01) | (1&amp;lt;&amp;lt;CS01);    // Vorteiler 8, CTC Modus&lt;br /&gt;
 &lt;br /&gt;
  &lt;br /&gt;
  sei();                // und Interrupts generell freigeben&lt;br /&gt;
 &lt;br /&gt;
  &lt;br /&gt;
  while( 1 )&lt;br /&gt;
  {                     // hier braucht nichts mehr gemacht werden.&lt;br /&gt;
  }                     // der Timer selbst sorgt dafür, dass die ISR Funktion&lt;br /&gt;
}                       // regelmässig aufgerufen wird &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fast PWM ==&lt;br /&gt;
&lt;br /&gt;
Aber der Timer kann noch mehr. Wenn der Timer so vor sich hinzählt, dann kann man bestimmte Output-Pins des µC an diesen Timer koppeln. Der Timer kann dann diesen Pin bei erreichen von bestimmten Zählerständen ganz von alleine wahlweise auf 0 schalten, auf 1 schalten oder umdrehen.&lt;br /&gt;
&lt;br /&gt;
Was passiert da genau? Im folgenden sei von der einfachsten Form der PWM auf einem Mega16 ausgegangen: Wenn der Timer in seiner Zählerei bei 0 ist, dann schaltet er den Pin auf 1, bei einem bestimmten Zählerstand soll er den Pin wieder auf 0 zurücksetzen und ansonsten soll der Timer wie gewohnt laufend von 0 bis 255 durchzählen.&lt;br /&gt;
Es ist die Rede vom Timer-Modus 3, siehe die vorhergehende Tabelle aus dem Datenblatt.&lt;br /&gt;
&lt;br /&gt;
Der Tabelle entnehmen wir wieder: Die Bits WGM01 und WGM00 müssen auf 1 gestellt werden. Der TOP Wert (also der Wert, bis zu dem der Timer zählt) ist 0xFF (also 255) und das OCR0 Register steuert, bei welchem Zählerstand die Timerhardware den Pin wieder auf 0 zurück schaltet. Das Einschalten auf 1 ist vorgegeben (auch das kann man ändern, dazu später mehr).&lt;br /&gt;
&lt;br /&gt;
Stellt man also genau diese Konfiguration her und schreibt in das Register OCR0 beispielsweise den Wert 253, dann beginnt der Timer bei 0 zu zählen, wobei der den Ausgangspin auf 1 schaltet. Wird der Zählerstand 253 erreicht, dann schaltet der Timer den Pin wieder auf 0 zurück und zählt weiter bis 255 um dann wieder erneut bei 0 zu beginnen (und den Ausgansg-Pin wieder auf 1 zu schalten). Der Ausgangspin ist in diesem Fall also die meiste Zeit auf 1 und nur ganz kurz (während der Timer von 253 bis 255 zählt) auf 0.&lt;br /&gt;
&lt;br /&gt;
Schreibt am auf der anderen Seite in das Register OCR0 den Wert 3, dann passiert konzeptionell genau dasselbe nur mit anderen Zahlenwerten. Der Timer beginnt bei 0 zu zählen und schaltet den Ausgansgpin auf 1. Aber diesmal ist es bereits beim Zählerstand 3 so weit: Der Zählerstand stimmt mit dem Wert in OCR0 überein und als Folge davon wird der Ausgangspin wieder auf 0 gestellt. Der Timer zählt natürlich wie immer weiter bis 255 ehe dann das ganze Spiel wieder von vorne beginnt. In diesem Fall war also der Ausgangspin nur ganz kurze Zeit auf 1 (nämich in der Zeit, die der Timer benötigt um von 0 bis 3 zu zählen) und dann die meiste Zeit auf 0. Und genau darum geht es bei PWM: Mit dem Register OCR0 lässt sich daher der zeitliche Anteil steuern, in dem der Pin auf 1 liegt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Für einen Mega16.&lt;br /&gt;
// Andere Prozessoren: siehe Datenblatt wie die Timerkonfiguration einzustellen ist&lt;br /&gt;
 &lt;br /&gt;
#define F_CPU 1000000UL&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;
  &lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  uint8_t i;&lt;br /&gt;
&lt;br /&gt;
  DDRB |= (1&amp;lt;&amp;lt;PB3);       // PB3 auf Ausgang stellen. Dieser Pin&lt;br /&gt;
                          // trägt auch die Bezeichnung OC0 und ist der Pin&lt;br /&gt;
                          // an dem der Timer 0 seine PWM ausgibt&lt;br /&gt;
&lt;br /&gt;
  OCR0  = 250;&lt;br /&gt;
  TCCR0 = (1&amp;lt;&amp;lt;WGM01) | (1&amp;lt;&amp;lt;WGM00) | (1&amp;lt;&amp;lt;CS01);    // Vorteiler 8, Fast PWM 8 Bit&lt;br /&gt;
  TCCR0 = (1&amp;lt;&amp;lt;COM01); &lt;br /&gt;
  &lt;br /&gt;
  while( 1 )&lt;br /&gt;
  {                     // hier braucht nichts mehr gemacht werden.&lt;br /&gt;
                        // der Timer selbst sorgt dafür, dass die PWM läuft&lt;br /&gt;
                        // wir wollen aber ein wenig Action haben.&lt;br /&gt;
                        // Also setzen wir das OCR0 Register auf verschiedene&lt;br /&gt;
                        // Werte, damit eine angeschlossene LED unterschiedliche&lt;br /&gt;
                        // Helligkeiten zeigt&lt;br /&gt;
    OCR0 = 30;&lt;br /&gt;
    _delay_ms( 1000 );&lt;br /&gt;
    OCR0 = 200;&lt;br /&gt;
    _delay_ms( 1000 );&lt;br /&gt;
&lt;br /&gt;
    for( i = 0; i &amp;lt; 255; ++i ) {&lt;br /&gt;
      OCR0 = i;&lt;br /&gt;
      _delay_ms( 10 );&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bleibt noch das gesetzte Bit COM01. Was hat es damit auf sich? Bisher war immer die Rede davon, das der Ausganspin bei einem Zählerstand von 0 auf 1 geschaltet wird usw. Das regelt genau dieses Bit. Im Datenblatt findet sich die Tabelle 14.4 auf der Seite 83, die genau regelt welche Bedeutung die Bits COM01 bzw COM00 haben, wenn der Timer Modus auf Fast-PWM eingestellt ist. Achtung: Je nach Timer-Modus haben diese Bits andere Bedeutungen! Man muss sich also immer die zum jeweiligen Timer-Modus gehörende Tabelle im Datenblatt suchen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:C]]&lt;br /&gt;
[[Kategorie:avr-gcc]]&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=70431</id>
		<title>Benutzer:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=70431"/>
		<updated>2012-12-31T15:12:54Z</updated>

		<summary type="html">&lt;p&gt;Cmf: Artikel wieder gelöscht.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer_Diskussion:Cmf&amp;diff=70364</id>
		<title>Benutzer Diskussion:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer_Diskussion:Cmf&amp;diff=70364"/>
		<updated>2012-12-28T18:17:24Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Kennst du [[Menü]], [[MenuDesigner]] und [[Tinykon]]? --[[Benutzer:Andreas|andreas]] 14:15, 15. Dez. 2012 (UTC)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Danke, ich war anscheinend nicht fähig zu googeln :) Ich schaue mal, was ich mit der Seite machen werde. --[[Benutzer:Cmf|Cmf]] 18:17, 28. Dez. 2012 (UTC)&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer_Diskussion:Cmf&amp;diff=70363</id>
		<title>Benutzer Diskussion:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer_Diskussion:Cmf&amp;diff=70363"/>
		<updated>2012-12-28T18:17:07Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Kennst du [[Menü]], [[MenuDesigner]] und [[Tinykon]]? --[[Benutzer:Andreas|andreas]] 14:15, 15. Dez. 2012 (UTC)&lt;br /&gt;
Danke, ich war anscheinend nicht fähig zu googeln :) Ich schaue mal, was ich mit der Seite machen werde. --[[Benutzer:Cmf|Cmf]] 18:17, 28. Dez. 2012 (UTC)&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR_Net-IO_Bausatz_von_Pollin&amp;diff=70214</id>
		<title>AVR Net-IO Bausatz von Pollin</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR_Net-IO_Bausatz_von_Pollin&amp;diff=70214"/>
		<updated>2012-12-25T13:55:51Z</updated>

		<summary type="html">&lt;p&gt;Cmf: Die Zeilen gibt es in der neusten Software (anscheinend) nicht mehr.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hier steht eine Beschreibung des Pollin Bausatzes [http://www.pollin.de/shop/shop.php?cf=detail.php&amp;amp;pg=NQ==&amp;amp;a=MTQ5OTgxOTk= AVR-NET-IO. Best.Nr. 810 058], oder als aufgebautes Fertigmodul, Best.Nr. 810 073. &lt;br /&gt;
&lt;br /&gt;
Einige Features: Ethernet-Platine mit ATmega32 und Netzwerkcontroller ENC28J60. Die Platine verfügt über 8 digitale Ausgänge, 4 digitale und 4 ADC-Eingänge, welche alle über einen Netzwerkanschluss (TCP/IP) abgerufen bzw. geschaltet werden können.&lt;br /&gt;
&lt;br /&gt;
[[Datei:AVR-NET-IO ADD-ON.JPG|thumb|right|400px|AVR-NET-IO (links) mit zusätzlicher SUB-D Anschlussplatine (rechts, nicht im Lieferumfang)und Add-On-Board (oben, mit aufgelötetem RFM12-433-Modul, beides nicht im Lieferumfang). Ebenso ist zusätzlich ein nicht im Lieferumfang enthaltener kleiner Kühlkörper auf einem der Spannungsregler montiert und die Schraubklemmen zur Stromversorgung wurden durch Buchsen ersetzt.]]&lt;br /&gt;
&lt;br /&gt;
== Technische Daten ==&lt;br /&gt;
&lt;br /&gt;
* Betriebsspannung 9 V AC/DC&lt;br /&gt;
* Stromaufnahme ca. 190 mA&lt;br /&gt;
* 8 digitale Ausgänge (0/5 V) [PC0-PC7 an J3]&lt;br /&gt;
* 4 digitale Eingänge (0/5 V) [PA0-PA3 an J3]&lt;br /&gt;
* 4 ADC-Eingänge (10 Bit) [PA4-PA7 an Schraubklemmen]&lt;br /&gt;
* LCD-Anschluss (HD44780 komp. Controller nötig) [PD2-7,PB0,PB3 an EXT]&lt;br /&gt;
* [[ENC28J60]]&lt;br /&gt;
* [http://www.atmel.com/dyn/Products/Product_card.asp?part_id=2014 ATmega32] Mikrocontroller&lt;br /&gt;
&lt;br /&gt;
Maße (L×B×H): 108×76×22 mm.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
&lt;br /&gt;
Die Schaltung des AVR-NET-IO ist recht einfach:&lt;br /&gt;
* Ein ATmega32 Mikrocontroller enthält die gesamte Software&lt;br /&gt;
* Ein ENC28J60 Ethernet-Controller für das Senden und Empfangen von Ethernet Frames (MAC und PHY Ethernet Layer) ist über [[SPI]] mit dem ATmega32 verbunden&lt;br /&gt;
* Ein Ethernet RJ-45 MagJack TRJ 0011 BA NL von [http://www.trxcom.com/ Trxcom] mit eingebautem Übertrager und Anzeige-LEDs am ENC28J60.&lt;br /&gt;
* Ein MAX232 für die serielle Schnittstelle&lt;br /&gt;
* Zwei Spannungsregler, 5 V und 3,3 V&lt;br /&gt;
* &amp;quot;Hühnerfutter&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Fast alle I/O Pins des ATmega32 sind irgendwo auf Anschlüssen herausgeführt. Entweder auf dem SUB-D Stecker, dem EXT oder ISP Wannensteckern oder den blauen Anschlussklemmen. Eine Schutzbeschaltung gibt es nicht.&lt;br /&gt;
&lt;br /&gt;
Die blauen Anschlussklemmen haben eine Nut und eine Feder mit denen man&lt;br /&gt;
sie zusammenstecken kann, dadurch ist das Anlöten wesentlich leichter&lt;br /&gt;
und sie stehen auch sauber in der Reihe.&lt;br /&gt;
&lt;br /&gt;
=== Erweiterungsplatine ===&lt;br /&gt;
&lt;br /&gt;
Seit Januar 2010 gibt es auch eine Erweiterungsplatine &lt;br /&gt;
&lt;br /&gt;
[http://www.pollin.de/shop/dt/Nzg4OTgxOTk-/Bausaetze/Diverse/Bausatz_Add_on_fuer_AVR_NET_IO.html Add-on für AVR-NET-IO-Board Best.Nr. 810 112]&lt;br /&gt;
&lt;br /&gt;
Diese Platine erweitert das NET-IO um:&lt;br /&gt;
&lt;br /&gt;
* SD-Karten-Slot über SPI&lt;br /&gt;
* Display über PCF 8574&lt;br /&gt;
* Infrarot-Empfang&lt;br /&gt;
* [[RFM12]] Funkmodul (nicht im Lieferumfang enthalten)&lt;br /&gt;
&lt;br /&gt;
Ausserdem soll es die 3.3V Versorgung der Hauptplatine verbessern. Dazu sollte man einen 4,7 kOhm Widerstand parallel zu R2 schalten. Sonst beträgt die Ausgangsspannung nur ca. 2,8V. (Tipp aus dem u.g. Thread im Forum)&lt;br /&gt;
&lt;br /&gt;
Erste Erfahrungsberichte im Forum http://www.mikrocontroller.net/topic/161354&lt;br /&gt;
&lt;br /&gt;
=== Hardware-Umbauten &amp;amp; -Verbesserungen ===&lt;br /&gt;
&lt;br /&gt;
* Kühlkörper auf dem 7805 - (Vorsicht: Der LM317T ist rückseitig spannungsführend. Den Kühlkörper also keinesfalls an beide Spannungsregler anschließen!)&lt;br /&gt;
* MAX232 nach anfänglicher Konfiguration nicht bestücken um Strom zu sparen oder um zwei weitere I/O-Pins zu gewinnen&lt;br /&gt;
* 10µF-Elkos für MAX232N (C14-C17) durch 1µF ersetzen. Eine 10µF-Version für den MAX232 gibt es nicht. Die 10µF-Elkos können auch Ursache einer nicht funktionierenden RS232 sein.&lt;br /&gt;
** Laut Spezifikation sind auch mehr als 1µF erlaubt. Selbst Atmel verwendet beim STK500 10µF. Dies führt keinesfalls dazu, dass die RS232 nicht mehr funktioniert.&lt;br /&gt;
* Die IC-Fassungen aus &amp;quot;Pollins Resterampe&amp;quot; durch Fassungen mit gedrehten Kontakten ersetzen. &lt;br /&gt;
* &#039;&#039;Netz&#039;&#039; LED nicht bestücken oder größere Widerstände einlöten um Strom zu sparen (R3)&lt;br /&gt;
* Vorwiderstände der Ethernet-LEDs größer machen (z.&amp;amp;nbsp;B. verdoppeln) um Strom zu sparen (R6,R7)&lt;br /&gt;
* Linear-Spannungsregler ersetzen&lt;br /&gt;
* Kondensator an AREF-Pin des ATmega32 (ATmega32 Datenblatt) (100nF gegen Masse)&lt;br /&gt;
* Kondensator an den RESET-Pin des ATmega32 ([http://www.atmel.com/dyn/resources/prod_documents/doc2521.pdf Atmel Application Note AVR042: AVR Hardware Design Considerations]) Wenn man diese Quelle genauer liest, ist das aber eher unnötig. - Kondensator bei selbstbau-ISP empfehlenswert.&lt;br /&gt;
* Umbau auf 3,3 V:&lt;br /&gt;
** Ersatz der Spannungsregler durch einen einzigen 3,3 V Regler&lt;br /&gt;
** Anpassen (verkleinern) des LED-Vorwiderstands R3 für 3,3 Volt Betrieb&lt;br /&gt;
** Reduktion der Taktfrequenz (Austausch von Q2) auf den bei 3,3V erlaubten Bereich des ATmega32 ( ATmega32(L)  3.3V /8.0 Mhz Takt )&lt;br /&gt;
** Ersatz des MAX232 durch einen MAX3232&lt;br /&gt;
[[Bild:POWER.JPG|thumb|400px|5V Stromversorgung über USB Kabel, ohne 5 V Spannungsregler und Gleichrichterdioden, Vorsicht: kein Verpolungsschutz!  ]]&lt;br /&gt;
* ATmega32 vom ENC28J60 takten (OSC2)&lt;br /&gt;
* Betrieb mit Gleichspannung:&lt;br /&gt;
** Dioden D2 und D5 durch Drahtbrücken ersetzen, D1 und D4 nicht bestücken (komplette Entfernung des Brückengleichrichters, beinhaltet Verlust des Verpolungsschutzes)&lt;br /&gt;
** Diode D2 bestücken, D5 durch Drahtbrücke ersetzen, D1 und D4 nicht bestücken (Brückengleichrichter durch Verpolungsschutze ersetzen)&lt;br /&gt;
*** ??? Ist dies nicht kontraproduktiv? Bei mir wurde durch D2-Bestückung die Eingangsspannung von ca. 5,2 V am LM317T auf ca. 4,6 V gedrückt, so dass am ENC28J60 nur ca. 2,6 V ankamen (außerhalb der lt. Datenblatt &amp;quot;Operating voltage range of 3.14V to 3.45V&amp;quot;). Man müsste also ein geregeltes Netzteil mit ca. 5,5 V anschließen um 5 und 3,3 V zu erzielen. Dann lieber den Verpolungsschutz durch andere Maßnahmen sicherstellen.&lt;br /&gt;
** Beim Betrieb von USB beachten, dass USB-Spezifikation keinesfalls 5V garantiert, sondern Spannung bis runter 4.4V erlaubt und dann u.U. durch den LM317 nicht mehr genügend Spannung am ENC anliegt. Das äußert sich so, dass zwar der Atmega einwandfrei funktioniert, die Ethernet-Kommunikation aber nicht oder nur sehr sporadisch.&lt;br /&gt;
* Ersatz des ATmega32 durch einen ATmega644 oder ATmega1284p mit mehr FLASH-Speicher.&lt;br /&gt;
** Der ATmega644 und auch der ATMega1284p sind nicht mit der Pollin-Firmware kompatibel&lt;br /&gt;
* 100nF über alle drei IC Störunterdrückung zusätzlich bestücken&lt;br /&gt;
&lt;br /&gt;
== Inbetriebnahme der Originalsoftware ==&lt;br /&gt;
=== Einleitung ===&lt;br /&gt;
&lt;br /&gt;
Die bei Auslieferung (Stand September 2008) in den ATmega32 gebrannte Firmware stellt sich manchmal recht zickig an. Es scheint dann die Netzwerk-Schnittstelle, ggf. auch  die serielle Schnittstelle, nicht zu funktionieren. Falls es Probleme geben sollte, sollte man erst einmal ein Firmwareupdate versuchen. Dies geschieht über die serielle Schnittstelle mittels des Programmes NetServer (aktuelle Version 1.03, Februar 2010), die dem Bausatz beiliegt. &lt;br /&gt;
&lt;br /&gt;
Falls die serielle Schnittstelle ebenfalls nicht zugänglich ist, kann mit den im folgenden beschriebenen Schritten die Inbetriebnahme der Software möglich sein. Dazu benötigt man:&lt;br /&gt;
&lt;br /&gt;
* Einen Windows-PC mit Ethernet-Schnittstelle und RS232-Schnittstelle (ein Prolific RS232-USB Konverter funktioniert)&lt;br /&gt;
* Entweder&lt;br /&gt;
**zwei normale (&#039;&#039;straight through&#039;&#039;) Ethernet-Kabel und einen Ethernet Switch/Hub, oder&lt;br /&gt;
**ein gekreuztes(&#039;&#039;cross over&#039;&#039;) Ethernet-Kabel&lt;br /&gt;
* Einen AVR Programmer (Hardware und Software). Zum Beispiel einen [[AVR Dragon]] oder [[STK500]] mit [[AVR Studio]] oder das [[Pollin ATMEL Evaluations-Board]] und [[avrdude]].&lt;br /&gt;
* Die [http://www.pollin.de/shop/ds/MTQ5OTgxOTk-.html Pollin NetServer Software], Version 1.03 (oder neuer)&lt;br /&gt;
&lt;br /&gt;
=== Gelieferten ATmega32 richtig einstellen ===&lt;br /&gt;
[[image:fuse_bits_avr_studio.jpg|thumb|right|250px|Einstellungen der Fuse-Bits mittels AVR Studio 4]]&lt;br /&gt;
Die Fuses der gelieferten ATmega32s scheinen nicht immer mit den im Handbuch auf Seite 12 als erforderlich angegebenen Fuse-Einstellungen übereinzustimmen.&lt;br /&gt;
&lt;br /&gt;
Dies kann man mittels eines Programmers ändern. LFuse = 0xBF, HFuse = 0xD2. Das genaue Vorgehen hängt dabei vom verwendeten Programmer ab. Bei der Gelegenheit kann man ebenfalls eine Sicherheitskopie des ursprünglichen Flash-Inhalts und des EEPROMs anfertigen. Das EEPROM scheint die MAC-Adresse des Ethernet-Ports zu enthalten.&lt;br /&gt;
&lt;br /&gt;
Entgegen der Spezifikation im Handbuch von Pollin sollten die &#039;&#039;&#039;HFuses auf 0xC2&#039;&#039;&#039; gesetzt werden, d. h. CKOPT-Fuse programmiert (dies ist in der Software Version 1.03 bereits vollzogen). Das sorgt für einen stabilen Betrieb des AVR-Oszillators im &amp;quot;full rail-to-rail swing&amp;quot;-Mode bei 16 MHz. Atmel garantiert ansonsten nur stabilen Betrieb bis 8 MHz. Siehe ATmega32-Datenblatt, Kapitel 8.4, Crystal Oscillator.&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
==== Funktionsfähige Konfiguration - AVR-Prog ====&lt;br /&gt;
&lt;br /&gt;
[[Bild:Avrprog.png|thumb|right|250px]]&lt;br /&gt;
Benutzer von AVR-Prog können die nachfolgenden Einstellungen für die Lock- und Fuse-Bits verwenden. Hierbei handelt es sich um die ausgelesenen Einstellungen eines funktionsfähigen Controllers. Allerdings sollte, laut Handbuch des AVR-NET-IO-Boards, das Fuse-Bit EESAVE eigentlich gesetzt sein. &lt;br /&gt;
&lt;br /&gt;
Alternativ kann auch per avrdude die Einstellung getroffen werden:&lt;br /&gt;
 avrdude -c stk500v2 -pm32 -U lfuse:w:0xBF:m&lt;br /&gt;
und &lt;br /&gt;
 avrdude -c stk500v2 -pm32 -U hfuse:w:0xC2:m&lt;br /&gt;
&lt;br /&gt;
Anschließend muß noch der Bootloader und die Firmware aktualisiert werden (siehe Handbuch AVR-NET-IO-Board Seite 12 Punkt 3).&lt;br /&gt;
&lt;br /&gt;
=== PC Konfiguration ===&lt;br /&gt;
&lt;br /&gt;
==== PC normalerweise nicht im 192.168.0.0/24 Subnetz ====&lt;br /&gt;
&lt;br /&gt;
Betreibt man den PC nicht im 192.168.0.0/24 Subnetz, muss er wie folgt umkonfiguriert werden, oder die IP Adresse des Boards wird entsprechend angepasst. ( Siehe Handbuch Seite 14ff. Das ist meist sinnvoller und auch einfacher. ) &lt;br /&gt;
&lt;br /&gt;
Den PC vom normalen Netzwerk abstecken[1]. Zur Umkonfiguration dazu bei Windows XP in der Systemsteuerung &#039;&#039;Netzwerkverbindungen&#039;&#039; aufrufen und die lokale &#039;&#039;LAN-Verbindung&#039;&#039; markieren. Dann in der rechten Leiste &#039;&#039;Einstellungen dieser Verbindung ändern&#039;&#039; aufrufen. &lt;br /&gt;
&lt;br /&gt;
Es erscheint der Dialog &#039;&#039;Eigenschaften von &amp;lt;Verbindungsname&amp;gt;&#039;&#039;. In der Liste im Dialog zu &#039;&#039;Internetprotokoll (TCP/IP)&#039;&#039; gehen. Ein Doppelklick auf den Eintrag öffnet den &#039;&#039;Eigenschaften von Internetprotokoll (TCP/IP)&#039;&#039; Dialog.&lt;br /&gt;
&lt;br /&gt;
In diesem Dialog &#039;&#039;Folgende IP-Adresse verwenden:&#039;&#039; auswählen und zum Beispiel&lt;br /&gt;
&lt;br /&gt;
IP-Adresse: &#039;&#039;&#039;192.168.0.100&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Subnetzmaske: &#039;&#039;&#039;255.255.255.0&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Standardgateway: &#039;&#039;&#039;192.168.0.1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
eingeben. &lt;br /&gt;
&lt;br /&gt;
Anmerkung von bitman:&lt;br /&gt;
[1] Dies ist spätestens ab Windows XP nicht mehr notwendig, wenn das Netz 192.168.0.0/24 noch frei ist. Dann kann man einfach den Client &#039;&#039;zusätzlich&#039;&#039; in diesem Netzwerk zusätzlich einbinden über Einstellungen/Netzwerkverbindungen/Lanverbindung/Eigenschaften/TCP-IP/Eigenschaften/Erweitert/IP-Adresse hinzufügen. Es werden dann eben mehrere IP-Adressen an den NIC gebunden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Alle geöffneten Dialoge nacheinander mit OK schließen.&lt;br /&gt;
&lt;br /&gt;
Alternativ bietet sich das Umprogrammieren des Boards über die serielle Schnittstelle an. Die Werte für IP-Adresse, Netzmaske und Standard-Gateway werden mit den dokumentierten SETxx-Befehlen geändert, das Board neu gestartet und ans vorhandene Netzwerk gesteckt.&lt;br /&gt;
&lt;br /&gt;
Im EEPROM sind folgende Werte vorprogrammiert:&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
3EE - 3F3 MAC-ADRESSE&amp;lt;br&amp;gt;&lt;br /&gt;
3F4 - 3F7 GATEWAY&amp;lt;br&amp;gt;&lt;br /&gt;
3F8 - 3FB NETMASK&amp;lt;br&amp;gt;&lt;br /&gt;
3FC - 3FF IP-ADRESSE&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== PC bereits im 192.168.0.0/24 Subnetz ====&lt;br /&gt;
&lt;br /&gt;
In diesem Fall muss man prüfen, ob die IP-Adresse 192.168.0.90 bereits im Subnetz verwendet wird. Ist dies der Fall, muss das verwendete Gerät mit dieser IP vorübergehend aus dem Subnetz entfernt werden. Es sei denn, dabei handelt es sich um den PC. In diesem Fall muss er wie zuvor umkonfiguriert werden. Ansonsten kann der unverändert im Netz verbleiben.&lt;br /&gt;
&lt;br /&gt;
Dem AVR-NET-IO gibt man eine neue, zuvor unbenutzte Adresse (siehe unten). Dann kann das abgekoppelte Gerät wieder angeschlossen werden, beziehungsweise der PC zurückkonfiguriert werden.&lt;br /&gt;
&lt;br /&gt;
=== AVR-NET-IO anschließen ===&lt;br /&gt;
&lt;br /&gt;
Musste man den PC umkonfigurieren, so werden jetzt nur der PC und der AVR-NET-IO über Ethernet miteinander verbunden. Je nach Ethernet-Kabel benötigt man dazu einen Switch/Hub oder nicht.&lt;br /&gt;
&lt;br /&gt;
Musste man den PC nicht umkonfigurieren, so kann man den AVR-NET-IO wie einen normalen Rechner an das vorhandenen Netz anschließen.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich schließt man die serielle Schnittstelle des AVR-NET-IO an den PC an.&lt;br /&gt;
&lt;br /&gt;
=== Firmware 1.03 einspielen ===&lt;br /&gt;
&lt;br /&gt;
Laut Handbuch sollte der AVR-NET-IO jetzt über Ethernet funktionieren. Ebenso sollte er über die serielle Schnittstelle und ein Terminalprogramm konfigurierbar sein. Beides ist offensichtlich im Auslieferungszustand selten der Fall.&lt;br /&gt;
&lt;br /&gt;
Auch wenn sich Pollins NetServer Software nicht mit dem AVR-NET-IO verbinden lässt, so ist sie jedoch in der Lage eine neue Firmware 1.03 einzuspielen. Das Vorgehen ist im Handbuch auf Seite 12 beschrieben. NetServer präsentiert dabei ein paar einfache Anweisungen denen man folgen sollte.&lt;br /&gt;
&lt;br /&gt;
Wenn sich nach dem scheinbar erfolgreichem Einspielen der Firmware, später nichts tut, so sollte die Firmware mit gesetztem &amp;quot;FailSafe&amp;quot; in der mitgelieferten NetServer-Software nochmals Eingespielt werden.&lt;br /&gt;
&lt;br /&gt;
=== Abschluss ===&lt;br /&gt;
&lt;br /&gt;
Jetzt sollte sich die NetServer Software mit dem AVR-NET-IO über Ethernet verbinden lassen. Dies macht es wiederum möglich, den AVR-NET-IO mit einer anderen IP-Adresse zu versehen. Will man den AVR-NET-IO in einem anderen Subnetz betreiben kann man dies jetzt einstellen.&lt;br /&gt;
&lt;br /&gt;
Nachdem man die IP-Adresse neu eingestellt hat, muss man den PC zurückkonfigurieren und kann dann sowohl den AVR-NET-IO und den PC zusammen betreiben.&lt;br /&gt;
&lt;br /&gt;
== Bekannte Fehler ==&lt;br /&gt;
=== AVR Net IO ===&lt;br /&gt;
&lt;br /&gt;
Siehe auch [[#Hardware-Umbauten_.26_-Verbesserungen|Hardware-Umbauten und Verbesserungen]]&amp;lt;br&amp;gt;&lt;br /&gt;
Käufer berichten von fehlenden Bauteilen im Bausatz (Wannenstecker, Widerstände, Kondensatoren, Induktivitäten). Für Reklamationen: [https://www.pollin.de/shop/kontakt_service/reklamation.html]&lt;br /&gt;
&lt;br /&gt;
* Die Stückliste auf Seite 4 in den Anleitung mit den Versionsangaben&lt;br /&gt;
** &#039;&#039;Stand 20.08.2008, kloiber, #1100, wpe&#039;&#039; (gedruckt im Bausatz)&lt;br /&gt;
** &#039;&#039;Stand 20.08.2008, cd, #all, wpe&#039;&#039; (auf der CD)&lt;br /&gt;
:ist falsch. Pollin legt dem Bausatz irgendwann ab September 2008 einen gedruckten Korrekturzettel bei. Die Online-Version der Anleitung ist korrigiert.&lt;br /&gt;
* Im Schaltplan auf Seite 7 in den Anleitungen mit den Versionen&lt;br /&gt;
** &#039;&#039;Stand 20.08.2008, kloiber, #1100, wpe&#039;&#039; (gedruckt im Bausatz)&lt;br /&gt;
** &#039;&#039;Stand 20.08.2008, cd, #all, wpe&#039;&#039; (auf der CD)&lt;br /&gt;
** &#039;&#039;Stand 03.09.2008, online, #all, wpe&#039;&#039; (Online)&lt;br /&gt;
:ist eine 25-polige SUB-D Buchse gezeichnet. Geliefert wird und in der Stückliste verzeichnet ist ein Stecker.&lt;br /&gt;
&lt;br /&gt;
* Die September 2008 ausgelieferte Firmware im ATmega32  funktioniert bei vielen nicht und muss erst upgedatet werden (siehe [[#Inbetriebnahme der Originalsoftware|Inbetriebnahme der Originalsoftware]])&lt;br /&gt;
&lt;br /&gt;
* Im Flash der gelieferten AVR ist anders als beschrieben nur der Bootloader enthalten, die eigentliche Firmware muss erst mit Hilfe der Updatefunktion geladen werden. Wenn zusätzlich auch die Fuses falsch gebrannt sind, dann funktioniert das Update nicht, auch wenn das PC Programm was anderes behauptet.&lt;br /&gt;
&lt;br /&gt;
* Die Fuse-Einstellungen des ausgelieferten ATmega32 entspricht nicht der Anleitung (siehe [[#Inbetriebnahme der Originalsoftware|Inbetriebnahme der Originalsoftware]])&lt;br /&gt;
&lt;br /&gt;
* Bausatz, gekauft am 27.10.08, Anleitungsversion 19.09.08, ohne Probleme oder erkennbare Fehler zusammengebaut und in Betrieb genommen.&lt;br /&gt;
&lt;br /&gt;
* Bausatz gekauft 29.09.2008, Pinbelegung des 25 poligen D-Sub &amp;quot;Anschlusses&amp;quot; stimmt nicht mit der Anleitung überein. Der Aufdruck auf der Platine ist falsch. Pin1 &amp;lt;-&amp;gt; Pin13, Pin2 &amp;lt;-&amp;gt; Pin12 usw. Setzt man den D-Sub Stecker ein, so sind dessen Pinnummern korrekt. Bei einem Bausatz gekauft 10/2010 ist dies ebenfalls noch der Fall.&lt;br /&gt;
&lt;br /&gt;
* 3 Bausätze Anf. Oktober 2008 gekauft, bei einem waren 2 LM317 dabei, dafür fehlte der 7805 - aus der Bastelkiste ersetzt. Alle haben jedoch auf Anhieb funktioniert&lt;br /&gt;
&lt;br /&gt;
* Bausatz gekauft Ende Januar 2009. Die Lock-Bits (u.a. für PonyProg2000) werden falsch beschrieben. Die in Klammern aufgeführten Werte stimmen bei einem Bit nicht. Die Texte &amp;quot;Programmiert/Unprogrammiert&amp;quot; hingegen schon. Bei den Bauteilen gab es 4 Kondensatoren mit der Aufschrift &amp;quot;220&amp;quot;, ich habe diese durch welche mit 22p ersetzt, da ich nicht sicher war ob wirklich 22p geliefert wurden. Dafür wurden statt einem zwei 7805 und statt einem mindestens vier LM317 mitgeliefert.&lt;br /&gt;
&lt;br /&gt;
* Bausatz geliefert 22.4.2009. Alles vollständig, zusammengebaut, läuft. Software-Version 1.03. Für den oben schon genannten Steckverbinder wurde eine Buchse geliefert. Allerdings stimmen die PIN-Nummern im Schaltplan nicht mit den PIN-Nummern auf der Buchse überein (sie sind gespiegelt), daher liefen die Test-LEDs zunächst nicht.&lt;br /&gt;
&lt;br /&gt;
* Bausatz geliefert 11.7.2009. Spannungsregler LM317T fehlt, grüne statt roter LED. Ein Kondensator 22pF zu viel. LM317T wurde auf Anfrage kostenlos nachgeliefert (27.7.). Inbetriebnahme problemlos.&lt;br /&gt;
&lt;br /&gt;
* Bausatz geliefert 24.7.2009. Ein Quarz 16MHz zu viel, ebenfalls grüne statt rote LED.&lt;br /&gt;
&lt;br /&gt;
* Bausatz geliefert 20.08.2009. Ein Kondensator 22pF zuviel und grüne statt rote LED.&lt;br /&gt;
&lt;br /&gt;
* Bausatz Juli &#039;09 gekauft, grüne statt rote LED&lt;br /&gt;
&lt;br /&gt;
* Bausatz 25.09.09 geliefert, grüne Betriebs-LED, ein ELKO zuviel, Fehler 1µF am MAX232 statt 100nF behoben, richtiger C wird mitgeliefert, Aufbau komplett nach Pollin Anleitung durchgeführt, auf Anhieb fehlerfrei!&lt;br /&gt;
&lt;br /&gt;
* Bausatz 17.10.09 geliefert, grüne Betriebs-LED, zwei 100nF Kondensatoren zu wenig. Aufbau und Inbetriebnahme problemlos.&lt;br /&gt;
&lt;br /&gt;
* Bausatz 21.10.09 gekauft, grüne Betriebs-LED. Aufbau problemlos, RS232 läuft nicht. LAN läuft&lt;br /&gt;
&lt;br /&gt;
* Bausatz Nov. 09 gekauft, grüne LED, alles o.k.&lt;br /&gt;
&lt;br /&gt;
* Bausatz Nov. 09 gekauft, grüne LED, ENC28J60, MAX232 und ATmega32 fehlen, Nachlieferung nach einer Woche&lt;br /&gt;
&lt;br /&gt;
*Bausatz Nov. 09 gekauft,Bauteile komplett.Verbindungsaufbau Seriell klappt erst nach mehreren Versuchen.Problem gelöst:Spannung an MAX und Mega zu niedrig&lt;br /&gt;
&lt;br /&gt;
* Bausatz Dez. 09 gekauft, grüne LED, 100µF Kondensator fehlt, alles o.k.&lt;br /&gt;
&lt;br /&gt;
* Bausatz August 09 gekauft, alle teile da nach Einstellen der fusebits lief alles perfekt&lt;br /&gt;
&lt;br /&gt;
* Bausatz Okt. 09 gekauft, ein 100nF Kondensator und 25MHz Quarz fehlten ... hab beim lokalen Elektronikhändler keinen 25Mhz Grundton Quarz sondern nur im 3. Oberton bekommen aber mit R2.2k parallel zum Quarz schwingt er in der Schaltung schön bei 25Mhz. Mit 1µF am MAX232 funktioniert jetzt auch die RS232.&lt;br /&gt;
&lt;br /&gt;
* 2x Bausatz Feb. 10 gekauft, bei beiden fehlten 7805, L1+L2 je 100µH sowie 4x falscher Wert Kondensator an Max232 vorhanden. Fehlende Bauteile nachgelötet und Funktion getestet. Hat alles einwandfrei funktioniert!!!&lt;br /&gt;
&lt;br /&gt;
* Bausatz März. 10 gekauft, RS232 Printbuchse fehlt, dafür 1x 10pol Wannenstecker zuviel. Grüne LED statt Rot. Funktioniert ansonsten einwandfrei.&lt;br /&gt;
&lt;br /&gt;
* Bausatz Jan. 10 gekauft, gelbe LED statt rot, C14...C17: 10µF, weder seriell noch via Ethernet Konnektivität. Nach Austausch von C14-C17 gegen 1µF, wenigstens serielle Kontaktaufnahme möglich, kein Ethernet auch nach Flash von 1.03 mit NetServer.&lt;br /&gt;
&lt;br /&gt;
* Bausatz Feb. 10 gekauft, Spannungsregler LM317T fehlte&lt;br /&gt;
&lt;br /&gt;
* Bausatz März 10 gekauft, gelbe statt rote LED geliefert, aber Aufbau und inbetriebnahme lt. Handbuch ohne Probleme&lt;br /&gt;
&lt;br /&gt;
* Bausatz März 10 gekauft und gelbe statt rote LED geliefert, funzt wunderbar gemäß Anleitung&lt;br /&gt;
&lt;br /&gt;
* Fertig gelötete Platine gekauft. µC war falsch im Sockel.&lt;br /&gt;
&lt;br /&gt;
* Bausatz April 10 gekauft und gelbe statt rote LED geliefert, ADM232LJN statt MAX232 - Funktion erst nach Ersetzung des ADM durch nen MAX&lt;br /&gt;
&lt;br /&gt;
* Bausatz April 10 gekauft und gelbe statt rote LED geliefert, ADM232LJN statt MAX232 - funktionierte sofort auch mit dem ADM232LJN.&lt;br /&gt;
&lt;br /&gt;
* Bausatz April 10 gekauft wurde mit grüner statt roter LED Ausgeliefert&lt;br /&gt;
&lt;br /&gt;
* Bausatz Juni 10 gekauft: wurde mit grüner statt roter Netz-LED ausgeliefert, 2x 22pF Kerko zuviel&lt;br /&gt;
&lt;br /&gt;
* Bausatz August 10 gekauft: komplett und sofort funktioniert&lt;br /&gt;
* Bausatz Juli 10 gekauft: 2 Quarze mit 16 MHz geliefert, statt 1x 16MHz und   1x25MHz.&lt;br /&gt;
* Bausatz September 10 gekauft: hat sofort funktioniert. 1x 3,3k und 1x 10k Widerstand zuviel. Statt 100nF Kondensatoren wurden 1µF geliefert -&amp;gt; Platzprobleme auf der Platine durch grössere Bauform. LED grün.&lt;br /&gt;
* Bausatz Oktober  6 gekauft: alles funktioniert. LED grün statt rot.&lt;br /&gt;
&lt;br /&gt;
* Fertigmodul Oktober 10 gekauft: Auf Anhieb alles funktioniert!&lt;br /&gt;
* Bausatz Oktober 10 gekauft: komplett und sofort funktioniert&lt;br /&gt;
&lt;br /&gt;
* Bausatz November 10 gekauft: komplett und sofort funktioniert (sogar mit der neusten Pollin Firmware 1.03 schon drauf) LED grün statt rot.&lt;br /&gt;
&lt;br /&gt;
* Bausatz November 10 gekauft. Nach Bezug neuer Feinst-Lötspitzen konnte ich ihn dann auch zusammenlöten. Es hat sofort alles funktioniert, obwohl ich nur 12V bzw. 9V Gleichspannung zur Verfügung hatte, und nicht sicher war, wieviel die Komponenten wirklich benötigen. Der Regler wird auch bei 9V Gleichspannungsversorgung noch sehr warm. Da muss auf jeden Fall ein Kühlkörper dran! Ich habe auch eine grüne LED bekommen, ist mir aber wurscht :-)&lt;br /&gt;
&lt;br /&gt;
* Bausatz Dezember 10 gekauft: komplett und funktionierte sofort. Firmware 1.03, grüne LED (Ein Quarz und ein IC-Sockel zu viel)&lt;br /&gt;
&lt;br /&gt;
*Bausatz Januar 2011 gekauft: nur genau die richtige Anzahl Teile dabei, Firmware 1.03, grüne LED, ging auf Anhieb&lt;br /&gt;
&lt;br /&gt;
* 2x Bausatz Januar 2011 gekauft: beide grüne LED, und 1x doppelter Satz Jumper/Stiftleiste, 22PF und Anschlussklemmen. Rest vollständig und beide haben sofort nach zusammenbau funktioniert.&lt;br /&gt;
&lt;br /&gt;
* Februar 2011: AVR-NET-IO: die Diode D5 fehlt, 10 µF gegen 1 µF für MAX232 getauscht, Flash im ATmega32 war programmiert, passende IP-Adr über serielle Schnittstelle eingestellt; ADD-ON: für R1 war 22Ω statt 0,2Ω beigelegt, durch richtigen ersetzt, Beschreibung der LED Bestückung mangelhaft / oe1smc&lt;br /&gt;
&lt;br /&gt;
* Februar 2011: AVR-NET-IO: 1 Diode zuviel, 2 Spulen fehlen, LED grün. Die fehlenden Spulen wurden durch welche aus der Bastelkiste ersetzt - funktioniert. Der 7805 bekam einen kleinen Kühlkörper spendiert.&lt;br /&gt;
&lt;br /&gt;
* Februar 2011: AVR-NET-IO: 2x 10k Widerstände fehlen. Dafür eine Diode zu viel.&lt;br /&gt;
&lt;br /&gt;
* Ende Februar 2011: Zwei Bausaetze an jeweils zwei Adressen, alles in Ordnung.&lt;br /&gt;
&lt;br /&gt;
* Ende März 2011: 2x 25 Mhz Quarz statt 1x16 u. 1x25 Mhz. LED fehlt. Bausatz funktioniert nach Tausch des Quarz den mir mein Freund oe9rsv aus seinem Fundus spendiert hat. Danke auch für die Hilfe beim Fehler suchen.&lt;br /&gt;
&lt;br /&gt;
* Mitte 2010 gekauft: 1x 100nF fehlt&lt;br /&gt;
&lt;br /&gt;
* Mitte Juni 2011: Beide Quarze fehlen und beide Spannungsregler fehlen, Pollin wollte, dass ich das ganze Paket zurückschicke für einen Austausch. Ein 51Ω zu viel. 16Mhz im Handel und 25Mhz vom alten Mobo ausgelötet. Läuft wunderbar.&lt;br /&gt;
&lt;br /&gt;
* Anfang Juni 2011: Beide Quarze fehlen und beide Spannungsregler fehlen, nach kurzer Mail an Pollin (leider ohne Antwort) wurden diese nach ca. 1 Woche in einem Brief nachgeliefert.&lt;br /&gt;
&lt;br /&gt;
* August 2011: alles 1a...&lt;br /&gt;
* August 2011: Platine fehlte -&amp;gt; in Nachlieferung&lt;br /&gt;
* 30 August 2011: alles 1a...&lt;br /&gt;
* 06 Sep. 2011: alles 1a...&lt;br /&gt;
* August 2011: 6 Stück bestellt, bei einem haben die 100nF Kondensatoren gefehlt, bei einem zwei LM317 statt 7805 und LM317. Angerufen, 3 Tage später Nachlieferung erhalten.&lt;br /&gt;
* Nov. 2011: &#039;&#039;&#039;Net_IO&#039;&#039;&#039; vollständig. Einspielen der Firmware 1.03 war erforderlich. Bei &#039;&#039;&#039;Add-On&#039;&#039;&#039; immer noch falscher Q1 BC548 (NPN) in Stückliste und Lieferung. BC327-40 oder BC328-40 (PNP) nachgefordert. R11 und R24 mitgeliefert entsprechend Beschreibung V1.1 von Pollin&#039;s Download. Beiliegende Beschreibung war älter, ohne diese Widerstände.&lt;br /&gt;
&lt;br /&gt;
* Ende Nov.2011, alle Teile dabei, Firmware war drauf, sofort funktioniert.&lt;br /&gt;
&lt;br /&gt;
* Anfang Dez.2011, komplett bestückte Platine gekauft. Auf 7805 Kühlkörper gebaut da er nach 1Minute schon ausgestiegen ist (LED hat das Pumpen angefangen). Firmware 1.03 musste noch aufgespielt werden danach funktioniert alles einwandfrei. In betrieb mit 10V DC&lt;br /&gt;
* Ende Dez.2011 2xNET-IO und 2xADD bestellt 4 verschieden volle Kisten bekommen... WSL16 ist mit verriegelung geht nicht aufs board jumper fehlen spannungsregler doppelt potti löcher zu klein lsb3 fehlt sd-slot hab ich jetzt 3 100nF hab ich jetzt 4 übrig ... also immnoch lustig  HW stand immernoch 1.0 ( gab es überhaupt eine 1.1?)&lt;br /&gt;
&lt;br /&gt;
* Mitte Jan. 2012, 10pol. beide Wannenstecker nicht dabei, Firmware war drauf, sofort funktioniert. 1 LED zuviel. Unproblematische Nachlieferung bei Reklamation (wegen der beiden Wannenstecker kam ein PAKET!).&lt;br /&gt;
&lt;br /&gt;
* Ende Feb. 2012, Um die PHP-Scripte über öffentlichen Webserver zu betreiben muss mit SETGW die Gateway-Adresse des lokalen Routers eingetragen werden. Bei der NAT im Router sollte z.B. Port 8080 auf den internen Port 50290 umgeleitet werden, da manche Provider diesen Port für die Socket-Kommunikation nicht zulassen.&lt;br /&gt;
&lt;br /&gt;
*Juli 2012, Bausatz vollständig, Nach Aufbau sofort den 7805 mit einem kleinen Kühlkörper versehen, da er sonst thermisch überlastet wird! hat weder auf LAN noch RS232 reagiert, musste erst Update einspielen (Download Pollin), danach funktionierte alles einwandfrei!&lt;br /&gt;
&lt;br /&gt;
=== Erweiterungsplatine ===&lt;br /&gt;
&lt;br /&gt;
Um bei einem Neuaufbau parallele Widerstände zu vermeiden, sollten folgende Änderungen auf dem Addon-Board gemacht werden:&lt;br /&gt;
*R2 1,5kΩ ersetzen mit 2kΩ&lt;br /&gt;
*R3 1,8K ersetzen mit 3,3kΩ&lt;br /&gt;
*R19 470kΩ ersetzen zu 470Ω&lt;br /&gt;
*Q1 BC548 ersetzen durch BC327 oder BC328 (Hauptsache PNP! und mehr als 100mA)&lt;br /&gt;
&lt;br /&gt;
*Stand Feb. 2011: R2 wird mit 2,2kΩ und R3 wird mit 3,6kΩ ausgeliefert. Somit werden die 3,3 V richtig erzeugt. R19 hat 470Ω.&lt;br /&gt;
Der ISP-Anschluß ist nicht vollständig durchgeschleift, es besteht keine Verbindung der RESET-Leitung zwischen ISP und ISP1 (Abhilfe: Drahtbrücke einlöten, [http://www.mikrocontroller.net/topic/161354#1600385 Quelle]). &lt;br /&gt;
&lt;br /&gt;
*Stand Nov. 2011: bei mir ist die RESET-Leitung korrekt zw. ISP und ISP1 verbunden. Es gibt jetzt auch einen R24 (470Ohm) und R11 (1KOhm), der in der bei mir mitgelieferten Bauanleitung fehlt, in der zum Download (V1.1) angebotenen  aber drin steht.&lt;br /&gt;
Es wird immer noch der falsche Q1 BC548C (NPN) mitgeliefert. Das Schaltsymbol für einen PNP ist richtig im Schaltplan gezeichnet.&lt;br /&gt;
&lt;br /&gt;
*Stand Dez. 2011: &#039;&#039;&#039;R24&#039;&#039;&#039; (470Ohm) sollte mit 0 Ohm ersetzt&lt;br /&gt;
und &#039;&#039;&#039;R11&#039;&#039;&#039; (1KOhm) völlig weggelassen werden! &amp;lt;br&amp;gt;&lt;br /&gt;
Diese Widerstände bilden einen überflüssigen Spannungsteiler in der MISO Leitung. &amp;lt;br&amp;gt;                                                              &lt;br /&gt;
[http://son.ffdf-clan.de/include.php?path=forumsthread&amp;amp;threadid=1167&amp;amp;postid=9203 Fehler im Add-On V1.1]&lt;br /&gt;
&lt;br /&gt;
*Sept&#039;12: Bausatz mit Stecker anstelle einer Buchse ausgeliefert, 5mm anstelle von 3mm LED&#039;s dafür aber 3 Poti zuviel.&lt;br /&gt;
&lt;br /&gt;
*Sept&#039;12: Ebenfalls Bausatz mit Sub-D-Stecker statt Buchse ausgeliefert, 5mm anstelle von 3mm LED&#039;s und 3 Potis zuviel.&lt;br /&gt;
&lt;br /&gt;
== Andere Software für den Client-PC ==&lt;br /&gt;
=== NetIOLib ===&lt;br /&gt;
&lt;br /&gt;
In C# geschriebene Bibliothek zur Ansteuerung der Platine im Orginalzustand. Inkl. Beispielsoftware und Quellcode (GNU GPL) &lt;br /&gt;
&lt;br /&gt;
Links gehen nicht:&lt;br /&gt;
DLL: [http://www.tware.org/downloads/NetIOLib_dll.zip Download-Link]&lt;br /&gt;
Source: [http://www.tware.org/downloads/NetIOLib_src.zip Download-Link]&lt;br /&gt;
&lt;br /&gt;
=== E2000-NET-IO-Multi-Control ===&lt;br /&gt;
Mti dem E2000-NET-IO-Multi-Control ist es möglich, die vom dem E2000-NET-IO-Designer erstellten Projekte zu öffnen und die AVR-NET-IO&#039;s zu steuern. &lt;br /&gt;
&lt;br /&gt;
Die Anwendung liegt dem [http://www.mikrocontroller.net/articles/AVR_Net-IO_Bausatz_von_Pollin#E2000-NET-IO-Designer_.28Windows.5BXP.2F7.5D_.2F_Android.29 E2000-NET-IO-Designer] bei.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ControlIO ===&lt;br /&gt;
Einfache Bibliothek zur Ansteuerung mit Originalfirmware.&lt;br /&gt;
http://www.mikrocontroller.net/topic/149695&lt;br /&gt;
&lt;br /&gt;
=== JAVA Lib ===&lt;br /&gt;
Einfache Java-Bibliothek zur Ansteuerung mit Originalfirmware.&lt;br /&gt;
http://son.ffdf-clan.de/?path=forumsthread&amp;amp;threadid=611&lt;br /&gt;
&lt;br /&gt;
=== PHP ===&lt;br /&gt;
PHP Klasse zur Ansteuerung mit der Originalfirmware. (Opensource Lizenz)&lt;br /&gt;
http://blog.coldtobi.de/1_coldtobis_blog/archive/298_pollin_net-io_php_library.html&lt;br /&gt;
&lt;br /&gt;
PHP Funktionen zum Ansteuern der Originalfirmware. (Free for All Lizenz)&lt;br /&gt;
http://defcon-cc.dyndns.org/projects/mikrocontroller/netio.php&lt;br /&gt;
&lt;br /&gt;
== Clients für Smartphones ==&lt;br /&gt;
&lt;br /&gt;
=== App NetIO (Windows Mobile 6.5) ===&lt;br /&gt;
Frei verfügbare App für Windows Mobile zur Ansteuerung mit der Orginalsoftware. Das HTC HD2 wird damit zur Fernsteuerung für das AVR Net-IO Board.&lt;br /&gt;
http://www.heesch.net/netio.aspx&lt;br /&gt;
&lt;br /&gt;
=== NET-IO Control (Android) ===&lt;br /&gt;
Eine Application für das Android Betriebssystem zur Steuerung des AVR Net-IO Boards. Es ist möglich, alle Ausgänge zu steuern und alle Eingänge anzuzeigen. Die Analogen Eingänge können mit einem Berechnungsfaktor versehen werden. &#039;&#039;Geplant ist noch ein Offsetwert.&#039;&#039; Außerdem kann jedem analogen Wert eine Einheit zugeordnet werden. Die Ausgänge können in der neusten Version in einen Tastermodus gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
[[Datei:NET-IO-Control.png|200px]] [[Datei:NET-IO-Control2.png|200px]] [[Datei:NET-IO-Control3.png|200px]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Trial-Version: [https://play.google.com/store/apps/details?id=de.android.AVR.NETIOControlTRAIL Google-Play]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
(In dieser Probe Version können nur 1 Output und 2 Inputs gesteuert werden)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vollversion: [https://play.google.com/store/apps/details?id=de.android.AVR.NETIOControl Google-Play]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
(Kostet im Google-Play 3,00 €)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Weitere Informationen sind auf der Entwickler-Seite zu finden:  [http://elektronik2000.de/ Elektronik2000.de]&lt;br /&gt;
&lt;br /&gt;
=== E2000-NET-IO-Designer (Windows[XP/7] / Android) ===&lt;br /&gt;
[[Datei:E2000-NET-IO-Designer.png|400px|right]]&lt;br /&gt;
Mit dem E2000-NET-IO-Designer ist es möglich, eine grafische Oberfläche für die NET-IOs von Pollin zu erstellen. Dafür werden Knöpfe, Texte und Anzeigebilder zur Verfügung gestellt. Jedes dieser Element kann &amp;quot;Aufgaben&amp;quot; übernehmen um die NET-IOs zu steuern oder einen Status des NET-IO anzuzeigen. Weitere Icons können von dem Benutzer selbst in den entsprechenden Ordner gelegt werden und in die Oberfläche eingebunden werden. Es können mehrere Seiten designt werden die durch einen selbst positionierten Knopf erreichbar sind. Die Android Application arbeitet somit im Fullscreen-Modus. Des weiteren ist es möglich, mehrere NET-IO&#039;s in einem Projekt zu benutzen. Nach dem erstellen der grafischen Oberfläche mit dem E2000-NET-IO-Designer, kann mit der Android APP das Projekt einfach gedownloaded werden. Dafür baut die APP eine Verbindung zum E2000-NET-IO-Designer auf und läd alle benötigten Dateien herunter (Achtung: Firewall-Einstellungen beachten). Die designten Oberflächen können außerdem noch mit der E2000-NET-IO-Multi-Control.exe auf dem Computer ausgeführt werden. Dadurch ist es Möglich, seine NET-IOs vom PC aus zu steuern über eine selbst designte Oberfläche. &lt;br /&gt;
&lt;br /&gt;
Die Software ist zur Zeit in einer Testphase in der jeder die Software ausprobieren kann. Zum Ausführen des E2000-NET-IO-Designer muss .NET Framework 4.0 installiert sein und es muss eine Internetverbindung exisitieren.&lt;br /&gt;
&lt;br /&gt;
[http://www.elektronik2000.de/downloads.php?id=44 Download E2000-NET-IO-Designer]&lt;br /&gt;
&lt;br /&gt;
[http://elektronik2000.de/hilfe/uebersicht.html Online Hilfe]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Weitere Informationen sind auf der Entwickler-Seite zu finden:  [http://elektronik2000.de/ Elektronik2000.de]&lt;br /&gt;
&lt;br /&gt;
=== NetIO ( iPhone &amp;amp; Android ) ===&lt;br /&gt;
&amp;lt;div style=&#039;float: right&#039;&amp;gt;&lt;br /&gt;
[[Datei:NetIO_Screenshot1.png|190px]]&lt;br /&gt;
[[Datei:Netio_app1.png|190px]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Schöne (aber leider teure) universelle Fernbedienung für das Board (iOS / Android) . Konfigurierbar über einen Online Editor. &amp;lt;br&amp;gt;&lt;br /&gt;
AppStore Link: http://itunes.apple.com/app/netio/id464924297?mt=8 &amp;lt;br/&amp;gt;&lt;br /&gt;
Google Play Link: https://play.google.com/store/apps/details?id=com.luvago.netio &amp;lt;br/&amp;gt;&lt;br /&gt;
Die gleiche Konfiguration kann auch mit einem [https://github.com/davideickhoff/NetIO-OSX-Dashboard-Widget OSX Widget] benutzt werden. &amp;lt;br/&amp;gt;&lt;br /&gt;
Die inzwischen übersichtliche Webseite dazu findet man unter http://netio.davideickhoff.de &lt;br /&gt;
&lt;br /&gt;
Hinweis: &amp;lt;br&amp;gt; Man findet es unter &amp;quot;NetIO&amp;quot; im Store, im Icon selbst und in iTunes wird es als &amp;quot;Controller&amp;quot; angezeigt. &amp;lt;br&amp;gt;&lt;br /&gt;
Den JSON (JavaScriptObjectNotation) Code kann man im [http://jsonlint.com/ JSONLint Validator] prüfen. &amp;lt;br&amp;gt;&lt;br /&gt;
Die eigene Konfiguration kann man mit dem [http://netio.davideickhoff.de/editor2 Online Editor] vorher am PC erstellen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;div style=&#039;clear: both&#039;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== AVR Net IO (iPhone) ===&lt;br /&gt;
[[Datei:AVRNetIO-Screenshot1.png|160px|rechts]]&lt;br /&gt;
Update 15.12.2011: Die Neue Version 1.3 ist seit gestern im AppStore. Fehlerkorrekturen und ein robusteres Handling machen die App nun zur universellen AVR-Net-IO-Steuerung.&lt;br /&gt;
&lt;br /&gt;
Mit der [http://itunes.apple.com/de/app/avr-net-io/id460991760?mt=8 iPhone App AVR-Net-IO] kann das Board ferngesteuert werden. Die Fernsteuerung umfasst in der Version 1.1 folgende Funktionen:&amp;lt;br&amp;gt;&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;ADC-Werte zyklisch auslesen und darstellen&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Digital-Inputs zyklisch darstellen&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Digital-Outputs können über Buttons geschaltet werden. Die Werte der Digital-Outputs werden zuerst ausgelesen und zeigen den zuletzt gesetzten Wert an.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Terminal-Modus: Hier können beliebige AVR-Net-IO-Befehle eingegeben werden. Das Ergebnis wird 1:1 angezeigt, wie es vom Board kommt. Hilfreich für Tests bei Eigenentwicklungen und Konfigurationen.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Mehr Infos gibt&#039;s dazu direkt von den Entwicklern auf [http://www.facebook.com/pages/AVR-Net-IO/187799687958255?ref=nf AVR-net-IO Facebook-Page] oder direkt auf deren Homepage [http://www.ondics.de/apps/1001/ Homepage].&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Hinweis: MIt der aktuellen Version 1.1 gibt es noch bei manchen Boards Probleme beim auslesen und anzeigen der ADC- und Digital-Werte. Das Terminal funzt problemlos. Die Entwickler kümmern sich gerade drum und haben einen baldigen Update versprochen.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Andere Software statt der Originalsoftware von Pollin ==&lt;br /&gt;
&lt;br /&gt;
Die Umrüstung auf einen Webserver durch Austausch der Software (und ev. des ATmega32) bietet sich an. Kleiner Hinweis dabei: wenn zum Flashen ein ISP-Adapter verwendet wird, diesen unbedingt vor dem Start der neuen Software abziehen! Der ISP arbeitet nämlich über dieselbe SPI-Schnittstelle über die auch der ENC28J60 angesteuert wird. Ein eventuell noch angeschlossener, wenn auch passiver ISP-Adapter stört diese Kommunikation, d.h. das Programm an sich scheint zu laufen, aber die Ethernet-Schnittstelle funktioniert nicht.&lt;br /&gt;
&lt;br /&gt;
=== E2000 - Logik ===&lt;br /&gt;
&lt;br /&gt;
[[Datei:E2000-Logik-Bedienoberflaeche.jpg|500px|rechts]]&lt;br /&gt;
&lt;br /&gt;
Anwenderfreundliche Logik-Software von Elektronik2000.de zur Steuerung des AVR-NET-IO. Der ATMEGA32 wird durch einen ATMEGA644 ersetzt und mit der E2000-Firmware beschrieben. Nun ist es möglich in der E2000-Logik Software eine Logikschaltung zu erstellen und diese auf das NET-IO-Board zu übertragen. Dort wird diese Schaltung simuliert. Dies funktioniert komplett ohne einen Computer.&lt;br /&gt;
&lt;br /&gt;
Durch ein Erweiterungsboard von Elektronik2000.de ist es auch möglich, das Board ohne Internet laufen zu lassen eine RTC (RealTimeClock) übernimmt dabei die Uhrzeitgesteuerten Funktionen. Auf dieser Erweiterung ist auch ein EEPROM integriert, um Firmware-Updates über Netzwerk einzuspielen (in Zukunft). Diese Erweiterung bietet außerdem die Anbindung an das E2000-Bus-System, durch das es Mäglich ist das AVR-NET-IO-Board durch weitere Ein- und Ausgänge zu erweitern.&lt;br /&gt;
&lt;br /&gt;
Das Designen von Schaltaufgaben wird in diesem Programm grafisch dargestellt, durch das ein einfaches Anpassen seiner Logikschaltungen möglich ist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Eine Steuerung des E2000-NET-IO ist möglich durch den Intregrieten Webserver, die PC-Software (E2000-NET-IO Control) oder der Androidsoftware. All diese Können gleichzeitig auf das E2000-NET-IO zugreifen und Funktionen ausführen. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Weitere Informationen gibt es auf der Entwicklerseite: [http://www.elektronik2000.de Elektronik2000.de]&lt;br /&gt;
&lt;br /&gt;
=== Bascom Version von Hütti ===&lt;br /&gt;
&lt;br /&gt;
(Quelle: http://bascom-forum.de/index.php/topic,1781.45.html )&lt;br /&gt;
dort am Ende der Seite.&lt;br /&gt;
&lt;br /&gt;
=== Ben&#039;s Bascom Quellcode ===&lt;br /&gt;
&lt;br /&gt;
(Quelle: http://members.home.nl/bzijlstra/software/examples/enc28j60.htm )&lt;br /&gt;
&lt;br /&gt;
Muss aber für Bascom 1.11.9.3 angepasst werden, siehe Code von Hütti !&lt;br /&gt;
&lt;br /&gt;
=== U. Radigs Webserver ===&lt;br /&gt;
&lt;br /&gt;
Angepasster Sourcecode von U.Radig: http://www.mikrocontroller.net/attachment/40027/Webserver_MEGA32.hex&lt;br /&gt;
oder selbst anpassen: &lt;br /&gt;
Ändere in der Datei ENC28J60.H:&lt;br /&gt;
 #define ENC28J60_PIN_CS    4&lt;br /&gt;
(Quelle: http://www.mikrocontroller.net/topic/109988#988386)&lt;br /&gt;
&lt;br /&gt;
Temporären Dateien (*.d, *,lst,*.o) vorher im Verzeichnis löschen &#039;&#039;make clean&#039;&#039;, damit neu compiliert wird.&lt;br /&gt;
&lt;br /&gt;
IP: 192.168.0.99&amp;lt;br&amp;gt;&lt;br /&gt;
User: admin&amp;lt;br&amp;gt;&lt;br /&gt;
Pass: uli1&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den orginal SourceCode gibt&#039;s übrigens hier:http://www.ulrichradig.de/home/index.php/avr/eth_m32_ex&lt;br /&gt;
&lt;br /&gt;
Bei den Fuses BOOTRST ausschalten, da die Software keinen Bootloader enthält.&lt;br /&gt;
&lt;br /&gt;
IP: 192.168.1.90&amp;lt;br&amp;gt;&lt;br /&gt;
User: admin&amp;lt;br&amp;gt;&lt;br /&gt;
Pass: tim&amp;lt;br&amp;gt;&lt;br /&gt;
Test: http://beitz-online.dyndns.org&amp;lt;br&amp;gt;&lt;br /&gt;
Test: http://pieper-online.dyndns.org&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weiterentwicklung des Radig-Codes von RoBue: &amp;lt;br&amp;gt;&lt;br /&gt;
- 1-Wire-Unterstützung (Anschlus an PORTA7) &amp;lt;br&amp;gt;&lt;br /&gt;
- PORTA0-3 digitaler Eingang (ein/aus) &amp;lt;br&amp;gt;&lt;br /&gt;
- PORTA4-6 analoger Eingang (0 - 1023) &amp;lt;br&amp;gt;&lt;br /&gt;
- LCD an PORTC &amp;lt;br&amp;gt;&lt;br /&gt;
- Schalten in Abhängigkeit von Temperatur und analogem Wert &amp;lt;br&amp;gt;&lt;br /&gt;
- (Teilweise) Administration über Weboberfläche &amp;lt;br&amp;gt;&lt;br /&gt;
- Erweiterung des cmd-Befehlsatzes für telnet/rs232 &amp;lt;br&amp;gt;&lt;br /&gt;
Gedacht ist der Einsatz des AVR-NET-IO-Bausatzes für Heizungs- oder Haussteuerung) &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test: http://avrboard.eluhost.de/&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Quelle:&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.mikrocontroller.net/attachment/43307/AVR-NET-IO_RoBue_V1.3.zip&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.mikrocontroller.net/attachment/44569/AVR-NET-IO_RoBue_V1.4.zip&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.mikrocontroller.net/attachment/46720/AVR-NET-IO_RoBue_1.5-final_hoffentlich_.zip)&lt;br /&gt;
&lt;br /&gt;
Bei der Ver 1.5 sind die Ports PD2+3 fürs 4bit LCD (Ext.) vertauscht ! Gruß B.P&lt;br /&gt;
&lt;br /&gt;
=== Simon Ks Webserver (uip-Stack) ===&lt;br /&gt;
Angepasster Sourcecode von Simon K: http://www.mikrocontroller.net/attachment/39939/uWebSrv.zip&lt;br /&gt;
IP: 192.168.0.93:8080&amp;lt;br&amp;gt;&lt;br /&gt;
Um diesen Code mit einem Atmega1284P verwenden zu können, muss in der main.c in Zeile 38, &amp;quot;TIMSK&amp;quot; durch &amp;quot;TIMSK1&amp;quot; ersetzt werden.&lt;br /&gt;
Die Fusebits für den Atmega1284p ohne Bootloader sind:&lt;br /&gt;
lfuse=0xFF, hfuse=0xD9, efuse=0xFF&lt;br /&gt;
&lt;br /&gt;
=== Ethersex Server ===&lt;br /&gt;
&lt;br /&gt;
http://www.ethersex.de - Einfach für atmega32 compilieren und funktioniert.&lt;br /&gt;
&lt;br /&gt;
=== Etherrape Server ===&lt;br /&gt;
&lt;br /&gt;
http://www.lochraster.org/etherrape/ &lt;br /&gt;
&lt;br /&gt;
ist in jedem Fall hier auch zu erwähnen zumal es sich beim etherrape um das Ursprungsprojekt von ethersex handelt.&lt;br /&gt;
Es scheint aber bei der Weiterentwicklung wenig zu passieren.&lt;br /&gt;
Ausführliche Dokumentation findet sich unter http://wiki.lochraster.org/wiki/Etherrape&lt;br /&gt;
&lt;br /&gt;
=== Mini SRCP Server (kommerziell, Closed-Source)===&lt;br /&gt;
&lt;br /&gt;
Damit wird die Platine zu einer Modellbahnsteuerung, die&lt;br /&gt;
über das Netzwerkprotokoll SRCP mit verschiedenen Programmen&lt;br /&gt;
gesteuert werden kann.&lt;br /&gt;
&lt;br /&gt;
[http://www.7soft.de/de/mini_srcp_server/index.html Infoseite] zur Hardware&lt;br /&gt;
und das zugrundeliegende [http://www.der-moba.de/index.php/Digitalprojekt Digitalprojekt].&lt;br /&gt;
&lt;br /&gt;
=== AvrArtNode ===&lt;br /&gt;
&lt;br /&gt;
Hiermit kann die Platine zu einem Art-Net Node werden, mit dem sich ein DMX-Universe über Ethernet übertragen lässt. Basiert auf den Quellen von Ulrich Radig.&lt;br /&gt;
&lt;br /&gt;
Dokumentation: [http://www.dmxcontrol.de/wiki/Art-Net-Node_f%C3%BCr_25_Euro Art-Net-Node für 25 Euro]&lt;br /&gt;
&lt;br /&gt;
=== Webserver von G. Menke ===&lt;br /&gt;
&lt;br /&gt;
Ein Webserver (basierend auf den Sourcen von U. Radig), der so angepasst ist, dass alle Ein- und Ausgänge wie bei der originalen Pollin-Software genutzt werden können (8xDIGOUT, 4xDIGIN, 4xADIN). Der Webserver kann daher direkt auf das Net-IO geladen werden. Im ZIP-File sind ein ReadMe und alle C-Sourcen enthalten. Download:&lt;br /&gt;
[http://gm.stream-center.de/webserver/ Webserver mit passender IO]&lt;br /&gt;
&lt;br /&gt;
=== OpenMCP ===&lt;br /&gt;
&lt;br /&gt;
Tolles Projekt, welches viele Features bietet und stabil läuft. Hervorzuheben ist die Übersichtlichkeit der Programmteile/Module und die vielleicht nicht ganz komplette Dokumentation. Man merkt, dass viel Arbeit und Liebe in diesem Projekt steckt. Herausgekommen ist dabei eine einfach zu handhabende Entwicklungsumgebung. Anfänger können, dank des gut durchdachten CGI-Systems, welches sich um alle wichtigen Sachen kümmert, leicht eigene CGI implementieren. Alle Ausgaben erfolgen nur mit printf über die Standardausgabe und werden automatisch richtig per Netzwerk übertragen, dadurch ist es auch für den Anfänger recht gut geeignet, da man sich nicht mit der Netzwerkprogrammierung auseinander setzen muss.&lt;br /&gt;
&lt;br /&gt;
Die Software belegt im Moment (Stand Juli 2010) ca. 55 Kb im Flash, so dass man das Board mit einem grösseren µC (z.B. ATMega644) aufrüsten muss.&lt;br /&gt;
&lt;br /&gt;
[http://wiki.neo-guerillaz.de Projekt und Doku]&lt;br /&gt;
&lt;br /&gt;
Der Autor stellt zwei über das Internet erreichbare Testboards bereit unter http://www.neo-guerillaz.de:81 und http://www.neo-guerillaz.de:82 die beide unter OpenMCP laufen, je auf einen AVR-NETIO mit einem ATmega644 und dem eigentlichen Board mit einem ATmega2561. Zusätzlich ist gerade eine Version für das myAVR in Arbeit die schon ordentlich Fortschritte macht.&lt;br /&gt;
&lt;br /&gt;
=== OpenMLP ===&lt;br /&gt;
Auf openMCP basierender Port nach [http://avr.myluna.de LunaAVR] (GPL). Umfangreiche Funktionalität und direkte Anpassung an die Sprache. Abgespeckte Version auch auf Atmega32 lauffähig. Die Original-Dokumentation kann zum Großteil hergenommen werden. Einige Zusatzfeatures. Leichte Konfiguration und guter Einstieg für Anfänger und zum Verständnis der Serverfunktionalität.&lt;br /&gt;
&lt;br /&gt;
[http://avr.myluna.de/doku.php?id=de:openmlp Artikelseite]&lt;br /&gt;
[http://forum.myluna.de/viewtopic.php?f=8&amp;amp;t=13 Forum]&lt;br /&gt;
&lt;br /&gt;
=== ENC28J60 I/O-Webserver von Thomas Heldt ===&lt;br /&gt;
&lt;br /&gt;
Ein Modul-Webserver (Softwarekompatibel zum Pollin Webserver), der durch div. Module erweitert werden kann, Software in Bascom basierend auf dem Code von Ben Zijlsta wurde erweitert und angepasst:&lt;br /&gt;
&lt;br /&gt;
[http://mikrocontroller.heldt.eu/index.php?page=enc28j60-io-webserver Projekt und Software]&lt;br /&gt;
&lt;br /&gt;
=== AVR-Netino ===&lt;br /&gt;
[http://code.google.com/p/avr-netino/ Projekt und Software]&lt;br /&gt;
&lt;br /&gt;
Arduino fürs Net-IO&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* Diskussion zu diesem Projekt: http://www.mikrocontroller.net/topic/109988&lt;br /&gt;
* [http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en022889 ENC28J60 Produktseite]&lt;br /&gt;
* [http://ww1.microchip.com/downloads/en/DeviceDoc/39662c.pdf ENC28J60 Datenblatt(pdf)]&lt;br /&gt;
* [http://son.ffdf-clan.de Forum für AVR-Net-IO]&lt;br /&gt;
* [http://avr.myluna.de/doku.php?id=de:openmlp LunaAVR openMLP ]&lt;br /&gt;
* [http://bascom-forum.de/index.php/topic,1781.0.html Bascom Forum ]&lt;br /&gt;
* [http://hobbyelektronik.org/w/index.php/AVR-NET-IO-Shield Shield für den NET-IO]&lt;br /&gt;
&lt;br /&gt;
[[Category:AVR-Boards]]&lt;br /&gt;
[[Category:Ethernet|P]]&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR_In_System_Programmer&amp;diff=70060</id>
		<title>AVR In System Programmer</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR_In_System_Programmer&amp;diff=70060"/>
		<updated>2012-12-21T15:47:45Z</updated>

		<summary type="html">&lt;p&gt;Cmf: Broken Link entfernt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einführung ==&lt;br /&gt;
&lt;br /&gt;
In-System-Programming (ISP) bedeutet, einen Mikrocontroller oder anderen programmierbaren Baustein im eingebauten Zustand zu programmieren. Dazu muss der Mikrocontroller entsprechend beschaltet sein. Das bedeutet, die benötigten Anschlüsse am Mikrocontroller müssen zugänglich und nicht ohne weitere Vorkehrungen anderweitig benutzt sein - siehe [http://www.atmel.com/dyn/resources/prod_documents/doc2521.pdf Atmel Application Note AVR042].&lt;br /&gt;
&lt;br /&gt;
Atmel verwendet für ihre 8-Bit RISC Mikrocontroller zum Teil unterschiedliche ISP-Protokolle. Das bekannteste davon wird einfach als ISP bezeichnet. Insgesamt findet man:&lt;br /&gt;
&lt;br /&gt;
;ISP:Der Normalfall. Bei vielen, aber nicht allen AVRs teilen sich [[SPI]]- und ISP-Schnittstelle die Pins. Je nach AVR gibt es leichte Unterschiede im Protokoll. Das Protokoll für einen Typ ist im Datenblatt unter &#039;&#039;Memory Programming -&amp;gt; Serial Downloading&#039;&#039; beschrieben.&lt;br /&gt;
;TPI:Tiny Programming Interface. Einige AVRs der Tiny-Serie, besonders die 6-Pin Tinys.&lt;br /&gt;
;PDI:Programming and Debugging Interface. Die XMEGAs.&lt;br /&gt;
;JTAG:AVRs mit [[JTAG]] Debugging-Schnittstelle lassen sich auch über JTAG in-system-programmieren.&lt;br /&gt;
;Bootloader:Einige wenige AVRs kommen bereits mit einem einprogrammierten [[Bootloader]]. Bei diesen kann man ein zum Bootloader passendes Programm nutzen um den AVR über eine im Bootloader definierte Schnittstelle programmieren. Auf Bootloadern basierende Systeme haben ansonsten ein Henne-Ei Problem. Irgendwie muss der Bootloader einmal konventionell in den AVR programmiert werden, zum Beispiel mit ISP.&lt;br /&gt;
&lt;br /&gt;
Atmels [[debugWire]] ist keine Programmierschnittstelle, sondern eine reines Debugging-Interface. Zum Programmieren verwendet man bei AVRs mit debugWire daher normalerweise ISP.&lt;br /&gt;
&lt;br /&gt;
Atmel hat für die AVR 8-Bit RISC Mikrocontroller mehrere Application Notes herausgegeben, auf deren Basis eine Vielzahl von Programmiergeräten (&#039;&#039;programmer&#039;&#039;) entwickelt wurden. &lt;br /&gt;
&lt;br /&gt;
Natürlich liefert Atmel auch eigene, fertige Programmiergeräte (AVRISP (mk I), AVRISP mk II, [[AVR-Dragon]], ...), Programmiersoftware (AVRProg, AVR Studio) und Entwicklungsboards mit integriertem Programmiergerät (z.&amp;amp;nbsp;B. [[STK500]]).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p style=&amp;quot;color:darkred;&amp;quot;&amp;gt;&amp;lt;big&amp;gt;FAQ/Tipp: &#039;&#039;&#039;&amp;quot;Welchen ISP-Adapter sollte man sich zulegen oder bauen?&amp;quot;&#039;&#039;&#039;&amp;lt;/big&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Man sollte sich einen fertigen, original Atmel (keinen Clone) ISP-Adapter kaufen. Zum Beispiel für ISP (und PDI) Programmierung &#039;&#039;&#039;Atmels original [[AVR_In_System_Programmer#Atmel_AVRISP_MKII|AVRISP mkII]] für rund 36,- Euro&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Das ist eine Investition, die viel Zeit und Ärger spart, denn es geht nichts über zuverlässiges Werkzeug. Beim Umgang mit µCs ist es sehr frustrierend an drei Fronten gleichzeitig zu kämpfen:&lt;br /&gt;
# Bugs in der Software, &lt;br /&gt;
# Bugs in der Schaltung und &lt;br /&gt;
# Bugs/Probleme beim ISP-Adapter-/PC-Gespann.&lt;br /&gt;
&lt;br /&gt;
Wenigstens Probleme mit dem ISP-Adapter lassen sich durch den Kauf eines zuverlässigen ISP-Adapters eliminieren. Siehe auch diverse Forenbeiträge u.a. [http://www.mikrocontroller.net/topic/91042#778908] und [http://www.mikrocontroller.net/topic/153841#1447882].&lt;br /&gt;
&lt;br /&gt;
Sehr unzuverlässig sind häufig billige oder selbstgebaute Programmierkabel mit nichts außer ein paar Widerständen. Unzuverlässig sind häufig auch billige oder selbstgebaute Programmierkabel mit einem einfachen Bustreiber. Nur weil sie bei manchen funktionieren heißt das nicht, dass sie überall problemlos funktionieren.&lt;br /&gt;
&lt;br /&gt;
Parallelport- (Druckerport-) ISP-Adapter funktionieren gar nicht, wenn man sie mit einem USB &amp;lt;-&amp;gt; Druckerport Adapter an einen USB-Port am PC anschließt. Einfach (unintelligente) ISP-Adapter für die serielle Schnittstelle funktionieren gar nicht oder extrem langsam, wenn man sie mit einem USB &amp;lt;-&amp;gt; Seriell Adapter am PC anschließt. Gute intelligente serielle Programmieradapter, wie der in Atmels STK500 eingebaute, funktionieren normalerweise mit einem USB-Adapter.&lt;br /&gt;
&lt;br /&gt;
Bei allen Programmieradaptern mit eigener Firmware, einschließlich der Original-Adapter von Atmel, ist man darauf angewiesen, dass der Hersteller wenn nötig Firmware-Updates bereitstellt. Bei Clones ist die Versorgung mit Firmware manchmal fraglich. &lt;br /&gt;
&lt;br /&gt;
Oftmals funktionieren auch die Treiber der Clones unter 64-Bit Betriebssystem nicht richtig oder nur mit Tricks, die leider wichtige Sicherheitsfunktionen des Betriebssystem abschalten. Der [[AVR_In_System_Programmer#Atmel_AVRISP_MKII|AVRISP mkII]] funktioniert dagegen auch unter Windows 7 (64-Bit).&lt;br /&gt;
&lt;br /&gt;
== Application Notes ==&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/DOC0943.PDF AVR910] (PDF) &amp;quot;&#039;&#039;Low-cost&#039;&#039;&amp;quot; &#039;&#039;In-system programming&#039;&#039; (&#039;&#039;&#039;AVRISP&#039;&#039;&#039;) beschreibt einen einfachen, kostengünstigen Programmieradapter zur Übertragung von Programmen in den Mikrocontroller. Auf dem Programmer befindet sich ein Mikrocontroller (natürlich von Atmel ;-), der serielle Steuerkommandos und Daten vom PC in Programmiersignale für den Mikrocontroller umsetzt.&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2568.pdf AVR911] (PDF) &#039;&#039;Open source serial programmer&#039;&#039; (&#039;&#039;&#039;AVROSP&#039;&#039;&#039;) beschreibt eine &#039;&#039;open source&#039;&#039; Programmiersoftware zur Übertragung von Programmen in den Mikrocontroller. &lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc1644.pdf AVR109] (PDF) &#039;&#039;Self-Programming&#039;&#039; mit Hilfe eines [[Bootloader|Bootloaders]]. Hier wird im Mikrocontroller zunächst ein mikrocontroller-spezifisches Bootloader-Programm abgelegt. Dieses Programm empfängt das eigentliche Benutzerprogramm oder Daten z.&amp;amp;nbsp;B. über einen seriellen Anschluss ([[UART]]), legt es ggf. im Speicher (Flash-ROM, EEPROM) ab und führt ggf. anschliessend das Benutzerprogramm aus.&lt;br /&gt;
&lt;br /&gt;
== Pinbelegung ==&lt;br /&gt;
===ISP===&lt;br /&gt;
Die Standard-Pinbelegung des ISP-Steckers zum Anschluss des Mikrocontrollers sieht nach obigen Application Notes und der [http://www.atmel.com/dyn/resources/prod_documents/doc2521.pdf AVR042] (PDF) folgendermaßen aus (Anschluss auf der Platine, Ansicht von oben). Atmel bevorzugt dabei bereits seit Jahren den 6-poligen Anschluss.&lt;br /&gt;
&lt;br /&gt;
[[Bild:avr-isp-pinout.png|right]]&lt;br /&gt;
  &lt;br /&gt;
  10-poliger       6-poliger&lt;br /&gt;
  Anschluss        Anschluss&lt;br /&gt;
  &lt;br /&gt;
  1 MOSI           1 MISO&lt;br /&gt;
  2 VCC            2 VCC&lt;br /&gt;
  3 - (*)          3 SCK&lt;br /&gt;
  4,6,8,10 GND     4 MOSI&lt;br /&gt;
  5 RESET          5 RESET&lt;br /&gt;
  7 SCK            6 GND&lt;br /&gt;
  9 MISO&lt;br /&gt;
&lt;br /&gt;
Pin 1 ist am Pfostenstecker mit einem kleinen Pfeil gekennzeichnet.&lt;br /&gt;
&lt;br /&gt;
Um Verwechslungen zu vermeiden, empfiehlt es sich, für die einzelnen Leitungen unterschiedliche Farben zu verwenden. Atmel hat dafür keine Festlegung getroffen, so dass es keinen festen Standard gibt. Üblich ist jedoch eine Farbzuordnung wie beim [https://guloshop.de/shop/Mikrocontroller-Programmierung/guloboard-G6::5.html guloboard]:&lt;br /&gt;
&lt;br /&gt;
  1 MISO  weiß&lt;br /&gt;
  2 VCC   rot&lt;br /&gt;
  3 SCK   blau&lt;br /&gt;
  4 MOSI  grün&lt;br /&gt;
  5 RESET gelb&lt;br /&gt;
  6 GND   schwarz&lt;br /&gt;
&lt;br /&gt;
(*) Einige Programmieradapter (Ponyprog-Adapter nach Lancos-Schaltplan) unterstützen an Pin 3 des 10-poligen Steckers eine LED (Kathode an Pin), die &amp;quot;Programmierzugriff&amp;quot; signalisieren soll. Dies ist aber kaum nützlich, daher wird der Pin auch von Atmel als N/C (not connected) definiert und beim original Atmel AVRISP mit GND verbunden.&lt;br /&gt;
&lt;br /&gt;
Der 10-polige Anschluss wurde von der Firma Kanda beim STK200 verwendet und ist deshalb auch als &amp;quot;Kanda-Standard&amp;quot; bekannt und war zur Zeit der STK200 Programmieradapter relativ weit verbreitet. Die Anschlussbelegung über einen 6-poligen Stecker stammt von Atmel selbst und ist platzsparender auf der Platine.&lt;br /&gt;
&lt;br /&gt;
Am besten kauft oder fertigt man sich einen Adapter 6 &amp;lt;-&amp;gt; 10 (siehe [http://www.shop.robotikhardware.de/shop/catalog/product_info.php?products_id=190], [http://www.watterott.com/de/AVR-Programmier-Kabel], [https://guloshop.de/shop/Adapterkabel/Programmieradapterkabel-6-polig-10-polig-lang::9.html]), dann lassen sich praktisch alle Boards mit jedem Programmer programmieren.&lt;br /&gt;
&lt;br /&gt;
[[Datei:Kabeloben.jpg]]&lt;br /&gt;
[[Datei:Kabelunten.jpg]]&lt;br /&gt;
[[Datei:isp_kab.jpg]]&lt;br /&gt;
&lt;br /&gt;
Zehnpolige Messerleisten (Wannenstecker) zur Montage auf einer µC Platine zum verpolungssicheren Anschluss des Programmieradapters sind fast &amp;quot;überall&amp;quot; verfügbar, nach den sechspoligen muss man häufig etwas suchen. Mittlerweile sind sie endlich bei Reichelt erhältlich (WSL 6G).&amp;lt;br/&amp;gt;&lt;br /&gt;
Alternativ bleibt nur der Griff zu den nicht verpolungssicheren 2xN Stiftleisten (z.&amp;amp;nbsp;B. 2x40), wobei man eine Stiftleiste auf 2x3 Pole kürzt.&lt;br /&gt;
&lt;br /&gt;
Sechspolige Federleisten (Pfostenbuchsen) zum Anquetschen an ein Programmierkabel sind dagegen zumindest bei den großen Versendern und Distributoren erhältlich (z.&amp;amp;nbsp;B. von Bürklin  Art.53F3500; Conrad Art.701980-62; Farnell Art.1097021; Reichelt PFL 6). Kleine lokale Elektronikläden führen diese jedoch häufig nicht. Zu den sechpoligen Pfostenbuchsen gibt es keine Alternative, wenn man ein sechpoliges Programmierkabel bauen möchte. Zehnpolige Pfostenbuchsen lassen sich nicht auf sechs Pole kürzen. Korrektur: Man kann die äußeren pins  ( 2 rechts, 2 links) einfach rausdrücken, dann passt der 6pol in die Buchse. Verpolungsschutz besteht weiterhin.&lt;br /&gt;
&lt;br /&gt;
Je nach Programmieradapter hat der VCC-Anschluss unterschiedliche Funktionen:&lt;br /&gt;
&lt;br /&gt;
1. Versorgung des Programmieradapters mit Strom aus der Schaltung, wie es bei vielen Parallelport-Adaptern der Fall ist.&lt;br /&gt;
&lt;br /&gt;
2. Versorgung der Schaltung mit Strom aus dem Programmieradapter. Dies ist insbesondere beim STK500 möglich und dank dessen programmierbarer Versorgungsspannung manchmal ganz praktisch. &lt;br /&gt;
&lt;br /&gt;
3. Messung der Betriebsspannung der Schaltung, so dass der Programmieradapter sich auf diese Spannung einstellen kann und so ein 3,3 V Board mit 3,3 V und ein 5 V Board mit 5 V programmiert. So wie zum Beispiel beim AVRISP mkII. Daher wird VCC auf neueren Schaltbildern auch als Vtg oder VTref bezeichnet (Atmel kann sich da nicht auf eine Bezeichnung einigen).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Je nach verwendetem Programmer muss man daher sorgfältig auf die Beschaltung von VCC/Vtg/VTref und auf die Stromversorgung von Board und Programmer achten.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===TPI===&lt;br /&gt;
&lt;br /&gt;
Die TPI-Programmierung setzt sich aus mehreren Schichten zusammen: Hardware (Ansteuerung der IO-Pins), Speicher-Management (stellt Funktionen zum Flashen bereit) und der Speicher selbst.&lt;br /&gt;
&lt;br /&gt;
  Data  1 2 VCC&lt;br /&gt;
  Clock 3 4 N.C.&lt;br /&gt;
  Reset 5 6 GND&lt;br /&gt;
&lt;br /&gt;
Standard TPI connector used on e.g. STK600 and AVRISP mkII.&lt;br /&gt;
&lt;br /&gt;
===PDI===&lt;br /&gt;
====Atmel Board-Schnittstelle &amp;amp; AVRISP MkII ====&lt;br /&gt;
Für Mikrocontroller-Boards schlägt Atmel einen 6-Pin Header, 2,54 mm Raster, mit folgender Pinbelegung vor (Ansicht von Oben):&lt;br /&gt;
&lt;br /&gt;
 DATA  1 2  VCC&lt;br /&gt;
 N.C.  3 4  N.C.&lt;br /&gt;
  CLK  5 6  GND&lt;br /&gt;
&lt;br /&gt;
(N.C.: Not Connected, nicht verbunden). Diese Belegung wird auch von Atmels AVRISP MkII im PDI-Modus verwendet.&lt;br /&gt;
&lt;br /&gt;
Bei Atmels eigenem XPlain Eval-Kit und anderen Programmieradaptern geht es zur Zeit jedoch noch fröhlich durcheinander. Folgenden Pinbelegungen lassen sich finden.&lt;br /&gt;
&lt;br /&gt;
====Atmel XPlain Eval-Board====&lt;br /&gt;
&lt;br /&gt;
Hier hat Atmel die Xmega PDI- und JTAG-Schnittstelle gemeinsam auf den Header J100 gelegt. Die PDI-Belegung ist wie folgt:&lt;br /&gt;
&lt;br /&gt;
       1  2  GND&lt;br /&gt;
       3  4  VCC&lt;br /&gt;
       5  6  CLK&lt;br /&gt;
  VCC  7  &#039;&#039;&#039;8  DATA&#039;&#039;&#039;&lt;br /&gt;
       9 10  GND&lt;br /&gt;
&lt;br /&gt;
Nur jeweils ein VCC- und ein GND-Anschluss muss verwendet werden. Es bieten sich die Pins 2 und 4 an.&lt;br /&gt;
&lt;br /&gt;
Man beachte die Position von DATA auf Pin 8 bei dieser Belegung von PDI auf dem XPlain JTAG-Header.&lt;br /&gt;
&lt;br /&gt;
====Atmel JTAGICE MkII====&lt;br /&gt;
&lt;br /&gt;
Einige sehr alte JTAGICE MkII unterstützen kein PDI. Alle neueren, in den letzten Jahren hergestellte tun es. Eventuell ist ein Firmware-Upgrade über AVR-Studio nötig.&lt;br /&gt;
&lt;br /&gt;
Laut [http://support.atmel.no/knowledgebase/avrstudiohelp/mergedProjects/JTAGICEmkII/mkII/Html/Connecting_to_target_through_the_PDI_interface.htm] und der eingebauten Hilfe von [[AVR Studio]] 4.18 SP 1 verwendet ein JTAGICE MkII im PDI-Modus folgende Pinbelegung:&lt;br /&gt;
&lt;br /&gt;
       1  2  GND&lt;br /&gt;
       3  4  VTref&lt;br /&gt;
       5  6  CLK&lt;br /&gt;
       7  8&lt;br /&gt;
 &#039;&#039;&#039;DATA  9&#039;&#039;&#039; 10  GND&lt;br /&gt;
&lt;br /&gt;
Man beachte, dass DATA hier angeblich auf Pin 9 liegt. (VTref dürfte VCC entsprechen). In der Hilfe zu AVR Studio 4.18 SP 1 ist der Pin CLK mit PDI_CLK, und der Pin DATA mit PDI_DATA bezeichnet.&lt;br /&gt;
&lt;br /&gt;
====Atmel AVR Dragon====&lt;br /&gt;
&lt;br /&gt;
Erst mit der Dragon-Firmware im SP 1 für AVR Studio 4.18 soll der PDI-Support des [[AVR Dragon]] funktionieren. Angekündigt war PDI-Support bereits für AVR Studio 4.18. &lt;br /&gt;
&lt;br /&gt;
Leider hat Atmel es versäumt in der Dragon-Dokumentation die Pinbelegung für PDI auf der Seite des Dragon anzugeben. In der Studio-Dokumentation ist von einem ominösen Dragon PDI Adapter die Rede, der Teil des &amp;quot;Dragon Kit&amp;quot; sein soll. Allerdings wird der Dragon &#039;nackt&#039; ausgeliefert und bisher gibt es keine Berichte darüber, dass jemand diesen ominösen Adapter gesehen hat. Von neueren Versionen des JTAGICE mkII ist hingegen bekannt, dass sie mit einem &#039;&#039;XMEGA PDI adapter kit&#039;&#039; geliefert werden.&lt;br /&gt;
&lt;br /&gt;
Angeblich ist es nötig, beim Dragon jeweils einen 330Ω Widerstand in die CLK und DATA Leitung zu legen, um Probleme mit dem Überschwingen der Signale zu vermeiden.&lt;br /&gt;
&lt;br /&gt;
== Programmer-Varianten ==&lt;br /&gt;
&lt;br /&gt;
Mittlerweile existiert eine fast unüberschaubare Zahl von Programmer-Varianten und Untervarianten. Hier sollen nur die wichtigsten Varianten mit Bauanleitungen aufgelistet werden, geordnet nach der Art des Anschlusses an den PC.&lt;br /&gt;
&lt;br /&gt;
Zur Zeit (März 2012) gibt es vermehrt Probleme, mit den neuen Varianten 5.x des AVR Studios, kompatible Programmer, die nicht von Atmel selbst hergestellt wurden, anzusteuern. Es sollte beim Erwerb/Nachbau auf die Zusicherung der Komptibilität zum gewünschen AVR Studio geachtet werden.&lt;br /&gt;
&lt;br /&gt;
=== Parallelport ===&lt;br /&gt;
&lt;br /&gt;
==== STK200-kompatibel ====&lt;br /&gt;
&lt;br /&gt;
Fast alle erhältlichen Parallelport-Programmieradapter, u.a. auch der hier im [http://shop.mikrocontroller.net/ Shop] angebotene, sind kompatibel zum Programmer des [[STK200]] / STK300.&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/STK200 Schaltbilder für STK200 und kompatible]&lt;br /&gt;
* Bauanleitung für einen [http://rumil.de/hardware/avrisp.html STK200-kompatiblen Programmieradapter] von Rolf Milde&lt;br /&gt;
* Universelles Programmiergerät mit 74HC244 und Schutzwiderständen http://www.aplomb.nl/TechStuff/PPPD/PPPD%20English.html&lt;br /&gt;
&lt;br /&gt;
==== Paralleles Interface für AVR und PonyProg ====&lt;br /&gt;
&lt;br /&gt;
Schaltplan und Erläuterungen bei [http://s-huehn.de/elektronik/avr-prog/avr-prog-alt.htm Scott-Falk Hühn]&lt;br /&gt;
&lt;br /&gt;
==== SP12 Programmer ====&lt;br /&gt;
&lt;br /&gt;
Schaltplan, Erläuterungen und Software für mehrere Plattformen, darunter auch MSDOS, gibt es bei [http://www.xs4all.nl/~sbolt/e-spider_prog.html#programmer Steven Bolt]. [http://www.xs4all.nl/~sbolt/e-spider_prog.html#programmer Ken&#039;s Dongle] ist ein spezieller Kabeladapter für SP12 zur Verbesserung der Signalqualität. Anpassung an neue Typen erfolgt durch leicht selbst erstellbare Beschreibungsdateien.&lt;br /&gt;
&lt;br /&gt;
=== Serieller Port ([[RS-232]]) ===&lt;br /&gt;
&lt;br /&gt;
==== Atmel AVRISP, STK500, AVR910 ====&lt;br /&gt;
&lt;br /&gt;
Der original AVRISP von Atmel, das [[STK500]] und der Programmer aus der Application Note AVR910 enthalten einen Mikrocontroller, der die Umsetzung der seriellen Daten auf das ISP- und TPI-Programmierinterface vornimmt. Sie lassen sich direkt mit dem AVR-Studio programmieren und sind auch problemlos mit einem USB-seriell-Adapter verwendbar.&lt;br /&gt;
&lt;br /&gt;
Ein Layout mit Schaltplan und erweitertem Sourcecode findet sich in diesem Thread in der Codesammlung [http://www.mikrocontroller.net/topic/88295#749553 AVR910 Programmer, Schaltplan, Layout, Firmware].&lt;br /&gt;
&lt;br /&gt;
Das AVR910 Design ist u.a. auf der Seite von [http://www.serasidis.gr/circuits/avr_isp/avr_isp.htm Serasidis Vasilis] im Detail beschrieben.&lt;br /&gt;
&lt;br /&gt;
Eine weitere, auführliche Anleitung zum AVR910 gibt es in deutsch auf der Seite von [http://www.klaus-leidinger.de/mp/Mikrocontroller/AVR-Prog/AVR-Programmer.html Klaus Leidinger].&lt;br /&gt;
* [https://www.ssl-id.de/b-redemann.de AVR910-USB-Prog: Bausatz incl. USB-seriell Wandler]&lt;br /&gt;
* [http://www.avr-projekte.de/isp.htm AVR910-USB: Bauanleitung incl. USB-seriell Wandler]&lt;br /&gt;
&lt;br /&gt;
Einen AVR-ISP STK500 Protokoll Programmmer und JTAGICE kompatiblen Programmer/Debugger können Sie auf folgender Homepage bestellen: [http://www.myevertool.de myevertool]&lt;br /&gt;
&lt;br /&gt;
==== SI-Prog ====&lt;br /&gt;
&lt;br /&gt;
Daneben gibt es noch weitere Programmieradapter für den seriellen Port, die auf den eigenen Mikrocontroller im Programmieradapter verzichten und das ISP-Programmierprotokoll über die Steuerleitungen des RS-232-Port nachbilden. Das Programmierprogramm auf dem PC sendet jetzt keine Steuerkommandos und Daten mehr, sondern gibt direkt die Programmiersignale an der seriellen Schnittstelle aus (&amp;quot;Pinwackeln an den Statuspins&amp;quot;). Der Nachteil dieser Adapter ist, dass sie meistens relativ langsam sind und nur unter wenigen Betriebssystemen funktionieren. Ein Beispiel dafür ist SI-Prog.&lt;br /&gt;
&lt;br /&gt;
* [http://www.lancos.com/siprogsch.html SI-Prog Originalversion]&lt;br /&gt;
* [http://s-huehn.de/elektronik/avr-prog/avr-prog.htm Schaltplan und Erläuterungen]&lt;br /&gt;
&lt;br /&gt;
==== Sercon2 ====&lt;br /&gt;
&lt;br /&gt;
Mit einer etwas anderen Steckerbelegung als der SI-Prog arbeitet die Sercon Familie an Adaptern. Nähere Unterlagen dazu finden sich &lt;br /&gt;
[http://www.speedy-bl.com/adapter.htm hier]&lt;br /&gt;
&lt;br /&gt;
==== Selbstbau-Programmer, basierend auf dem FTDI chip (via avrdude) ====&lt;br /&gt;
http://irq5.wordpress.com/2010/07/15/programming-the-attiny10/&lt;br /&gt;
&lt;br /&gt;
=== USB ===&lt;br /&gt;
&lt;br /&gt;
Die meisten USB-Programmieradapter verwenden einen USB-seriell-Wandler und ein STK500/AVRPROG-kompatibles Protokoll und können damit direkt aus dem AVR-Studio programmiert werden.&lt;br /&gt;
&lt;br /&gt;
Eine Quick-and-Dirty Programmierlösung bietet der [[#USB-Hub-ISP]], der außer einem USB-Hub nur Standard-Bauteile voraussetzt.&lt;br /&gt;
&lt;br /&gt;
==== Atmel AVRISP MKII ====&lt;br /&gt;
&lt;br /&gt;
Nachfolger des Atmel AVRISP &amp;quot;MKI&amp;quot;. Mit USB-Schnittstelle, leistungsfähigerem Programmiercontroller und erweitertem Hardwareschutz. Programmiersoftware: [[AVR-Studio]] und [[AVRDUDE]]. Herstellerinformation bei [http://www.atmel.com/dyn/products/tools_card.asp?family_id=607&amp;amp;family_name=AVR+8%2DBit+RISC+&amp;amp;tool_id=3808 atmel.com]&lt;br /&gt;
&lt;br /&gt;
Dave Jones hat im EEVblog #158 ein [http://www.eevblog.com/2011/03/25/eevblog-158-avr-isp-mk2-lm317-regulator-tutorial/ Videotutorial] erstellt, wie man beim Atmel AVRISP &amp;quot;MKI&amp;quot; mit dem LM317 Spannungsregler 3.3V oder 5V Versorgungsspannungen für das Targetboard nachrüstet. Im Video schlägt Dave als bessere Lösung die Verwendung eines Low-Drop-Spannungsreglers vor. Dafür eignet sich z.B. der [http://www.mikrocontroller.net/part/LM1117 LM1117]&lt;br /&gt;
&lt;br /&gt;
Weiter unten auf dieser Seite wird auch ein einfacher, kompatibler Nachbau namens [http://www.mikrocontroller.net/articles/AVR_In_System_Programmer#usbprog usbprog] vorgestellt.&lt;br /&gt;
&lt;br /&gt;
==== Atmel AT90USBKEY ====&lt;br /&gt;
Mit hilfe des [http://www.fourwalledcubicle.com/AVRISP.php AVRISP-MKII Clone] Projekts aus dem [http://www.fourwalledcubicle.com/LUFA.php LUFA] Paket wird aus dem [http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3879 AT90USBKEY] recht einfach ein Programmer, der mit [[AVR-Studio]] und [[AVRDUDE]] genutzt werden kann.&lt;br /&gt;
&lt;br /&gt;
==== AVRISP mkII Klon mit dem dem Teensy-Board und der Lufa-Bibliothek ====&lt;br /&gt;
Mit der [http://www.fourwalledcubicle.com/LUFA.php LUFA-Bibliothek] und dem [http://www.pjrc.com/teensy TEENSY 2.0 Board] kann schnell ein AVRISP mk2 Klon gebaut werden, der auch mit [[AVR-Studio]] in Windows einwandfrei  zusammenarbeitet. Weitere Infos auf [http://www.weigu.lu/b/avrispmk2 weigu.lu].&lt;br /&gt;
&lt;br /&gt;
==== AVRISP mkII Klon mit dem Atmega32U2-Breakout-Board und der Lufa-Bibliothek ====&lt;br /&gt;
Mit der [http://www.fourwalledcubicle.com/LUFA.php LUFA-Bibliothek] ([http://dokuwiki.ehajo.de/artikel:atmega_u-howto:avrisp-mkii Eine Anleitung gibt es hier]) und dem [http://www.ehajo.de/Bausaetze/Atmega32u2-Breakout-Board Atmega32U2-Breakout-Board] kann problemlos ein AVRISP mkII-Klon programmiert werden. Um praktisch auf die Programmierpins zugreifen zu können gibt es [http://www.ehajo.de/Bausaetze/ISP-Addon-Atmega*U2-Breakout dieses Addon-Board] für das Breakout-Board. Der Programmer läuft problemlos mit [[AVR-Studio]] unter Windows.&lt;br /&gt;
&lt;br /&gt;
==== Bascom USB ISP ====&lt;br /&gt;
Beliebter USB programmer der speziell für den Bascom Compiler entwickelt wurde. &lt;br /&gt;
Unterstützt Bascom einen neuen AVR-Controller, so kann dies automatisch auch dieser USB Programmer, eine neue Firmware ist nicht erforderlich. Ein weiterer Vorteil ist, dass er speziell für Bascom entwickelt wurde und in der IDE unterstützt wird. Er unterstützt alle Features von Bascom, auch die automatische Fusebit-Einstellung per Direktive im Quellcode.&lt;br /&gt;
&lt;br /&gt;
Angenehm ist auch, dass er keine 5V benötigt. Im Gegenteil, er kann sogar Boards über das übliche ISP-Programmierkabel mit 5V versorgen, so dass viele Boards auch ohne weitere Spannungsquelle programmiert werden können. &lt;br /&gt;
Ein wirklich empfehlenswerter Qualitätsprogrammer für alle Programmierer, die ausschließlich mit Bascom arbeiten wollen&lt;br /&gt;
* [http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=73&amp;amp;products_id=161 Vertrieb in Deutschland bei robotikhardware.de]&lt;br /&gt;
&lt;br /&gt;
Im Online- / Auktionshandel werden auch Alternativen angeboten, teils recht schick im Plexiglasgehäuse für ca. 20 Euro. Angeboten z.&amp;amp;nbsp;B. als &amp;quot;USB 2.0 Full Speed low cost Programmer für ATMEGA Chips&amp;quot; oder &amp;quot;AVR USB ISP Programmer ATMEL ATMEGA STK500&amp;quot;. Die Adapter funktionieren auch mit BasCom (aber auch mit AVR Studio), z.&amp;amp;nbsp;B. mit der Einstellung &amp;quot;STK500 native driver&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Man kann die Targetspannungsversorgung per USB zwischen 3,3 und 5V umschalten oder ganz abschalten (per DIP-Schalter). Sie sind per USB an den PC angeschlossen und arbeiten über einen virtuellen COM-Port. Achtung: In BasCom funktioniert das nur bis COM9. Wenn sich das Gerät z.&amp;amp;nbsp;B. auf COM15 installiert, wird es im BasCom evtl. nicht gefunden. Dann in der Systemsteuerung entsprechend umstellen.&lt;br /&gt;
&lt;br /&gt;
==== Atmel AVR Dragon ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Hauptartikel [[AVR-Dragon]]&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Der [http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3891 AVR Dragon] ist ein preiswerter ISP (und ICE) von Atmel, der aufgrund Preis/Leistungs-Verhältnisses schnell populär wurde. Atmel wurde von dieser Popularität überrascht, da der Dragon wohl ursprünglich nur als ein &amp;quot;Gimmick&amp;quot; zur Verbreitung von AVRs in Asien gedacht war.&lt;br /&gt;
&lt;br /&gt;
Die großen Vorteile des Dragons sind, dass er alle Programmiermodi beherrscht, inklusive High-Voltage Parallel Programming (&amp;quot;verfuste&amp;quot; AVRs retten), dass er ein natives USB-Interface hat, von AVR-Studio unterstützt wird, und sogar [[JTAG]] und [[debugWIRE]] ICE / Debugging unterstützt (bei den AVRs die dies können). &lt;br /&gt;
&lt;br /&gt;
Zu den größten bekannten Nachteilen gehören, dass der Dragon völlig &amp;quot;nackt&amp;quot; kommt. Kein USB-Kabel, kein Gehäuse, nicht einmal Abstandsbolzen unter der Platine, keine Patchkabel und nicht einmal die Fassungen zum Einstecken von AVRs sind bestückt. Eine gedruckte Anleitung gibt es auch nicht. Daneben wird aufgrund des Stromverbrauchs des Dragon ein USB-Hub mit Netzteil benötigt.&lt;br /&gt;
&lt;br /&gt;
Weiter ist der Dragon dafür bekannt, empfindlich auf statische Aufladungen zu reagieren. Ein Spannungsregler und ein Ausgangstreiber gehen dabei besonders gerne kaputt. Ein gerne von Anfängern gemachter Fehler ist es, den Dragon im Betrieb auf dem mitgelieferten &amp;quot;Schaumstoff&amp;quot; aus der Verpackung liegen zu lassen. Das ist jedoch kein Schaumstoff, sondern leitendes Moosgummi.&lt;br /&gt;
&lt;br /&gt;
Weitere Schutzmaßnahmen für gefährdete AVR Dragons findet man auf der Dragonlair-Seite von [http://www.aplomb.nl/TechStuff/Dragon/Dragon.html Nard Awater].&lt;br /&gt;
&lt;br /&gt;
Der Dragon wird unter Linux z.&amp;amp;nbsp;B. von der avrdude-Programmiersoftware unterstützt. Unerklärlicherweise stellt Atmel die Dokumentation und Beschreibung des Dragon nur als Teil der Online-Hilfe der AVR-Studio Software unter Windows zur Verfügung. Weiterhin lassen sich Firmware-Updates auch nur mittels eine proprietären Atmel-Software unter Windows einspielen. Daher ist der Dragon für Linux-Benutzer nur dann zu empfehlen, wenn man zusätzlich noch Zugriff auf eine Windows-Installation hat.&lt;br /&gt;
&lt;br /&gt;
==== USBisp ====&lt;br /&gt;
&lt;br /&gt;
AVR Programmierdongle mit USB Anschluss und kompatibel zum STK500-Protokoll. Unter anderem programmierbar mit [[AVR-Studio]], [[AVRDUDE]] und [[uisp]]. Schaltplan (PDF), Layout (PDF), Erläuterungen und Firmware gibt es vom Entwickler [http://www.matwei.de Matthias Weißer].&lt;br /&gt;
&lt;br /&gt;
==== USB avrisp ====&lt;br /&gt;
&lt;br /&gt;
USB AVR Programmer auf Basis des AVR 910 Designs. Den Schaltplan, Layout und Erläuterungen (englisch) gibt es von [http://www.e.kth.se/~joakimar/hardware.html Joakim Arfvidsson].&lt;br /&gt;
&lt;br /&gt;
==== Evertool ====&lt;br /&gt;
&lt;br /&gt;
Mit USB-seriell-Wandler. Getestet mit Adapterkabeln/ICs von FTDI, SiLabs und Prolific (Adapterkabel z.&amp;amp;nbsp;B. für ca. 10EUR bei Reichelt).&lt;br /&gt;
&lt;br /&gt;
* [http://www.siwawi.arubi.uni-kl.de/avr_projects/evertool/ Evertool-&amp;quot;Homepage&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
==== USBasp ====&lt;br /&gt;
&lt;br /&gt;
Thomas Fischls [http://www.fischl.de/usbasp/ USBasp] ist ein&lt;br /&gt;
Openhardware/Openfirmware USB-ISP-Adapter.  Er basiert auf einem&lt;br /&gt;
ATmega8 (oder ATmega88), der mittels einer rein auf Firmware&lt;br /&gt;
basierenden USB-Implementierung von&lt;br /&gt;
[http://www.obdev.at/products/avrusb/index.html Objective Development]&lt;br /&gt;
arbeitet. &lt;br /&gt;
&lt;br /&gt;
Bezugsquellen:&lt;br /&gt;
* Ein [http://www.FundF.net/usbasp/ offizieller USBasp Bausatz] ist erhältlich.&lt;br /&gt;
* Einen preiswerten Bausatz incl. Dokumentation gibt es bei [http://www.b-redemann.de/produkte-programmer.shtml www.b-redemann.de] und bei [http://shop.ulrichradig.de/Bausaetze/USB-ASP-Bausatz.html shop.ulrichradig.de].&lt;br /&gt;
* Eine MacOS X Anpassung stammt von [http://www.macsven.de/usbasp.html Sven Schwiecker]. Man kann aber auch das Komplettpaket Crosspack-AVR, in dem AVRDUDE für Mac OS X bereits enthalten ist, von [http://www.obdev.at/products/crosspack/index-de.html obdev.at] benutzen&lt;br /&gt;
&lt;br /&gt;
Zum Ansteuern des USBasp wird [[AVRDUDE]] in einem speziellen Modus benötigt, der ab Version 5.2 standardmäßig vorhanden ist (vorher waren&lt;br /&gt;
Patches nötig).&lt;br /&gt;
&lt;br /&gt;
Zum Programmieren von neuen ATtinys muss der Jumper Slow SCK gesetzt werden.&lt;br /&gt;
Alternativ ist es möglich mit der zusätzlichen Option von avrdude &amp;quot;-B100&amp;quot; die Periodendauer von SCK auf etwa 100 µs oder noch länger zu vergrößern (funktioniert nur, wenn die Firmware des USBasp vom Mai 2011 oder neuer ist).&lt;br /&gt;
&lt;br /&gt;
Der originale USBasp hat den Nachteil, dass er nicht die Targetspannung zum Programmieren benutzt, sondern immer seine 5V. Deshalb kann es Probleme geben, wenn das Target mit einer niedrigen Spannung versorgt wird, da der USBasp die Target-Highpegel eventuell nicht mehr als High erkennt. Abhilfe kann ein kleiner Hack schaffen, mit dem der µC wahlweise mit 5V oder mit ~3.6V betrieben wird:&lt;br /&gt;
http://www.mikrocontroller.net/topic/109648?goto=2031524#2031524&lt;br /&gt;
&lt;br /&gt;
Der [http://diy.elektroda.eu/usbasp-z-optoizolacja-do-25kv-18v-6v/?lang=en Optoisolated USBASP 1.8V to 6V] ist eine Hardwareänderung ebenfalls mit breitem Targetspannungsbereich und zusätzlich galvanischer Isolation über die [[Optokoppler]] 6N317 (schnelle Datenleitungen) und PC817 (langsame Resetleitung).&lt;br /&gt;
&lt;br /&gt;
Neuere USBasp sind in der Regel umschaltbar zwischen 5 V und 3,3 V. Falls man später darüber eine Schaltung mit 3,3 Volt betreiben will – etwa zum direkten Ansprechen einer SD-Karte – lohnt gezieltes Nachfragen vor dem Kauf.&lt;br /&gt;
&lt;br /&gt;
==== AvrUsb500 ====&lt;br /&gt;
&lt;br /&gt;
* [http://www.tuxgraphics.org/electronics/200510/article05101.shtml AvrUsb500] - an open source Atmel AVR Programmer, stk500 V2 compatible, with USB interface&lt;br /&gt;
* [http://www.mechaos.de/avr_progusb.php meCHAOS] - Nachbau mit neuem Platinenlayout und weiteren Funktionen.&lt;br /&gt;
&lt;br /&gt;
==== usbprog ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Hinweis:&#039;&#039;&#039; Damit der Programmer mit AS5.x zusammen arbeitet, muss die Firmware aktualisiert werden: http://www.usbprog.org/index.php/Firmwares (siehe Update Hinweis)&lt;br /&gt;
&lt;br /&gt;
[http://www.embedded-projects.net/usbprog usbprog] von Benedikt Sauter ist ein USB Programmieradapter, der fast alle Atmel Mikrocontroller unterstützt (ATiny, ATMega, AT89, AT90,&amp;amp;nbsp;...) und daneben auch für ARM7/9 und MSP universell einsetzbar ist. Unterstützung für Xmega gibt es nicht.&lt;br /&gt;
&lt;br /&gt;
Der Programmer wurde so entwickelt, dass man die Firmware auf dem Adapter über die USB-Verbindung austauschen kann. Dadurch sollte der Adapter lange attraktiv bleiben, da alles rund um das Projekt als open Source veröffentlicht ist und daher neue Controller einfach in die usbprog-Firmware integriert werden können.&lt;br /&gt;
Es ensteht gerade eine Firmware für einen einfachen JTAG Adapter. Damit kann man dann ganz einfach debuggen (voraussichtlich auch aus dem AVR Studio aus).&lt;br /&gt;
&lt;br /&gt;
Man kann den Adapter auch als 1:1 AVRISP mkII kompatibles Gerät betreiben. Dafür muss man eine andere Firmware einspielen, die ebenfalls Teil des Projektes ist. Der Vorteil ist der, dass man so auf jede bestehende Programmiersoftware zurückgreifen kann, die das originale AVRISP mkII unterstützt. Getestet wurde usbprog bis jetzt mit avrdude (Linux und Windows) und dem AVR Studio 4 (Windows).&lt;br /&gt;
&lt;br /&gt;
Derzeit kann man bei Benedikt Sauter Platinen und Bauteile im Set für 22 EUR (neue v3 für 34 EUR) bestellen. Näheres auf der [http://www.embedded-projects.net/usbprog Projektseite].&lt;br /&gt;
&lt;br /&gt;
==== AVR-Doper ====&lt;br /&gt;
&lt;br /&gt;
[http://www.obdev.at/products/avrusb/avrdoper.html AVR-Doper] kann neben ISP auch im High-Voltage Serial Mode als [[AVR HV-Programmer]] programmieren. Rein auf Firmware basierende USB-Implementierung. BUS-Powered. Einseitige Platine und damit auch für Selbstbauer geeignet. Verwendet einen Mega8 zur Steuerung des Programmers. Ist kompatibel zu AVR-Studio durch STK500-Protokoll.&lt;br /&gt;
&lt;br /&gt;
==== USB AVR-Lab ====&lt;br /&gt;
&lt;br /&gt;
[http://www.ullihome.de/index.php/Hauptseite#USB_AVR-Lab USB AVR-Lab] besteht aus einer sehr einfachen Hardware, usb wird in Software gemacht. Mit einem Bootloader nebst Applikation kann die Funktion des Lab´s zwischen &lt;br /&gt;
&lt;br /&gt;
*AVRISPmkII kompatiblem Programmer (AVR Studio, Linux, MacOS)&lt;br /&gt;
*JTAGICEmkII kompatibler AVR Programmer (AVR Studio, Linux, MacOS) (keine AVR32, kein Xmega)&lt;br /&gt;
*OpenOCD Interface (sehr viel ARM Controller, PLD´s, FPGA´s)&lt;br /&gt;
*STK500v2 kompatiblem Programmer (AVR Studio)&lt;br /&gt;
*USBasp kompatiblem Programmer (Linux, MacOS)&lt;br /&gt;
*JTAG Boundary Scan Interface + Software&lt;br /&gt;
*RS232/RS485 Wandler&lt;br /&gt;
*I2C Logger&lt;br /&gt;
*I2C Interface (zur benutzung aus eigenen Programmen)&lt;br /&gt;
*Oszi&lt;br /&gt;
*6-Kanal Logik Analyzer (in Entwicklung)&lt;br /&gt;
*Labornetzteil (in Entwicklung)&lt;br /&gt;
&lt;br /&gt;
getauscht werden. Mit der STK500v2 kompatiblen Firmware kann der Programmer direkt aus dem AVR Studio heraus voll kompatibel zum AVR-ISP mkII arbeiten.&lt;br /&gt;
Zusätzlich bietet der Programmer den virtuellen Com Port als Debug Port an solange nicht geflasht wird. Man kann also direkt mit dem Terminalprogramm auf seinen AVR zugreifen über den ISP Adapter.&lt;br /&gt;
Dieser Modus wird von jeder ISP Firmware unterstützt.&lt;br /&gt;
Statusanzeige des Targets (angeschlossen, falsch angeschlossen, nicht angeschlossen), max. 3 Mhz ISP Freq. Das Ganze ist sehr günstig in der Beschaffung (10 Eur Bauteile bei Reichelt + 3,5 Eur Platine von ullihome.de, oder 15 Eur bestückt von ullihome.de)&lt;br /&gt;
&lt;br /&gt;
==== USBtinyISP ====&lt;br /&gt;
&lt;br /&gt;
[http://www.ladyada.net/make/usbtinyisp/ USBtinyISP] ist ein preiswerter (ca. 16$ für die Bauteile) AVR ISP Programmer und SPI Interface auf open-source Basis. Als Software kann z.B. AVRDUDE oder AVRStudio verwendet werden. Der Programmer wurde auf Windows, MacOS X und Ubuntu (ab 9.04) getestet. Bei Adafruit sind auch Selbstbaukits erhältlich.&lt;br /&gt;
Eine miniaturisierte Version findet sich hier [http://www.mikrocontroller.net/articles/AVR-ISP-Stick www.mikrocontroller.net/articles/AVR-ISP-Stick]. Diese ist ab 6,90€ als Bausatz bei [http://www.ehajo.de/Bausaetze/AVR-ISP-Stick eHaJo.de] erhältlich.&lt;br /&gt;
&lt;br /&gt;
==== UCOM-IR ====&lt;br /&gt;
Der [http://www.nibo-roboter.de/wiki/UCOM-IR UCOM-IR] Programmieradapter ist ein kommerzieller Bausatz (ca. 25 €), der auf einem AT90USB162 basiert. Durch die Verwendung des STK500v2 Protokolls kann zur Programmierung sowohl das [[AVR-Studio]] wie auch [[AVRDUDE]] verwendet werden. Zusätzlich hat der Adapter einen IR-Empfänger und zwei Sendedioden, die zur Kommunikation und zur Fernsteuerung verwendet werden können.&lt;br /&gt;
&lt;br /&gt;
==== Selbstbau-Programmer, basierend auf dem vUSB stack ====&lt;br /&gt;
http://www.avrfreaks.net/index.php?name=PNphpBB2&amp;amp;file=viewtopic&amp;amp;t=90498&lt;br /&gt;
&lt;br /&gt;
==== USB-Hub-ISP ====&lt;br /&gt;
HUB ISP - Solving the USB-Only &amp;quot;Chicken or Egg&amp;quot; Problem:&amp;lt;br&amp;gt;&lt;br /&gt;
HUB ISP can write an AVR chip using only a USB hub, one cheap/common logic chip, and a few resistors.&amp;lt;br&amp;gt;&lt;br /&gt;
http://www.pjrc.com/hub_isp/&lt;br /&gt;
&lt;br /&gt;
==== Launchprog ====&lt;br /&gt;
Der [[Launchprog]] ist ein AVR-ISP-Programmer nach der Atmel AVR910-Appnote, der auf einem [http://processors.wiki.ti.com/index.php?title=MSP430_LaunchPad_%28MSP-EXP430G2%29 TI Launchpad 1.4] mit dem beiliegenden [http://www.ti.com/product/msp430g2211 MSP430G2211] und dem beiliegenden Uhrenquarz läuft. Nach außen hin ist der [[Launchprog]] wie ein AVR910 zu verwenden. Allerdings muss die Geschwindigkeit der seriellen Schnittstelle auf 9600 Baud eingestelllt werden.&amp;lt;br&amp;gt;&lt;br /&gt;
Beispiel der avrdude-Kommandozeile: &amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;avrdude -c avr910 -b 9600 -P &amp;lt;PORT&amp;gt; -p &amp;lt;PART&amp;gt; -U &amp;lt;KOMMANDO&amp;gt;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== mySmartUSB ====&lt;br /&gt;
Der mySmartUSB Programmer von myAVR ist ein kompakter ISP Programmer mit USB Anschluss (der Preis liegt bei 28€). Lt. Hersteller kann er auch für die Kommunikation via UART, TWI, SPI verwendet werden (hab ich noch nicht probiert).&lt;br /&gt;
&lt;br /&gt;
ich aber: Beim Schreiben der Fuse Bits musste ich das Tool myAVR_ProgTool.exe verwenden - siehe http://www.opencharge.de/wiki/Mysmartusb&lt;br /&gt;
&lt;br /&gt;
Mit avrdude ist das Schreiben der Fuse-Bits mit dem AVR910-Modus möglich.&lt;br /&gt;
 &lt;br /&gt;
avrdude-Kommandozeile :&lt;br /&gt;
&#039;&#039;avrdude -c avr910 -P PORT -p PART -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Achtung:&#039;&#039;&#039; Die neuere Version (mySmartUSB MK3) scheint mit der aktuellen Firmwareversion noch große Probleme mit ISP zu haben (siehe Postings im Supportforum: http://myavr.info/myForum/viewforum.php?f=8). Solange diese Probleme nicht ausgemerzt sind, sollte man auf die ältere Version (mySmartUSB MK2) oder ein anderes Produkt ausweichen.&lt;br /&gt;
&lt;br /&gt;
==== mySmartUSB light ====&lt;br /&gt;
&lt;br /&gt;
Preiswerter (ca. 15 €) Programmer im USB-Stick Design von myAVR. Der mySmartUSB light verfügt über eine Auto-Speed Funktion die die Frequenz des Programmers automatisch an die Taktfrequenz des Controllers anpasst.&lt;br /&gt;
Der Programmer kann 5V und 3.3V Systeme programmieren, Treiber gibt es für Windows, Linux und MacOS X und unterstützt wird je nach Firmware-Version das STK500v2 oder AVR910/911 Protokoll.&lt;br /&gt;
&lt;br /&gt;
==== Amadeus-USB ====&lt;br /&gt;
&lt;br /&gt;
[http://home.arcor.de/bernhard.michelis Amadeus-USB] ist ein ISP-Programmer zum Selberbauen. Er unterstützt eine Vielzahl von AVRs und verfügt über ein eigenes User-Interface. Der Programmer enthält einen einfach zu bedienenden Fuse-Editor. Sollte man einmal die falschen Clock-Einstellungen vorgenommen haben, ist das kein Problem, da der Programmer über eine Takterzeugung verfügt, mit der man den AVR wiederbeleben kann.&lt;br /&gt;
Auch wer mit niedrigen Taktraten arbeitet (z.&amp;amp;nbsp;B. 32kHz), kann einen ATmega64 in ca. 4,8 Sekunden programmieren und vergleichen. Darüber hinaus kann mit geeigneten Makros die Programmausführung getracet werden. Die maximale Programmierdauer beträgt bei einem ATmega64 mit 16MHz Quarz 3,1 Sekunden, wenn der gesamte Speicher geschrieben und verglichen werden muss. Ist das Programm kleiner, geht es natürlich schneller ;-) Für einen ATTiny2313 oder ATTiny24 braucht er weniger als eine Sekunde.&lt;br /&gt;
&lt;br /&gt;
==== AVR-ISP-Stick ====&lt;br /&gt;
&lt;br /&gt;
Der [http://www.ehajo.de/Bausaetze/AVR-ISP-Stick AVR-ISP-Stick] ist ein OpenSource/CC-Projekt und eine sehr günstige (6,90€!) Alternative zu den restlichen Programmieradaptern auf dem Markt. Er ist als Bausatz erhältlich und bereits über 100 mal im produktiven Einsatz.&lt;br /&gt;
&lt;br /&gt;
==== µISP-Stick ====&lt;br /&gt;
&lt;br /&gt;
Der [http://www.ehajo.de/Bausaetze/µISP-Stick µISP-Stick] ist die Weiterentwicklung des AVR-ISP-Sticks. Für 9,90€ bekommt man hier einen vorbestückten Bausatz an dem nur noch die bedrahteten Stecker angelötet werden müssen.&lt;br /&gt;
&lt;br /&gt;
==== Arduino ISP Shield ====&lt;br /&gt;
&lt;br /&gt;
Ein Arduino-Board kann mit dem entsprechenden Sketch und einfachen Jumperwires oder einem komfortablen Shield benutzt werden, um AVRs ohne [[Bootloader]] zu flashen. Eine Anleitung dazu wird bei [http://www.open-electronics.org/arduino-isp-in-system-programming-and-stand-alone-circuits/ www.open-electronics.org] und [http://hlt.media.mit.edu/?p=1229 hlt.media.mit.edu] (via [http://www.mikrocontroller.net/topic/252620#2598960]) gegeben.&lt;br /&gt;
&lt;br /&gt;
=== Standalone ===&lt;br /&gt;
&lt;br /&gt;
Die folgenden Geräte verfügen über interne Speicher, auf denen der zu programmierende Maschinencode abgelegt werden kann. Zum &amp;quot;flashen&amp;quot; selbst ist keine Verbindung zwischen Arbeitsplatzrechner bzw. Notebook und Programmiergerät erforderlich. &lt;br /&gt;
&lt;br /&gt;
==== roloFlash (kommerziell) ====&lt;br /&gt;
[http://www.halec.de/roloFlash/?ref=wiki_isp.mikrocontroller.net roloFlash] wird mit einer microSD-Karte bestückt, die die zu flashenden Daten enthält. Dadurch können unabhängig von einem PC an jedem beliebigen Ort AVR-Controller geflasht werden.&lt;br /&gt;
&lt;br /&gt;
In einem ersten Schritt wird die microSD-Karte vorbereitet. Durch die auf dem roloFlash eingebaute Scriptsprache roloBasic lässt sich der gewünschte Ablauf sehr flexibel festlegen.&lt;br /&gt;
&lt;br /&gt;
Nun kann roloFlash irgendwo anders ohne PC AVR-Controller flashen. Dabei geben 5 zweifarbigen LEDs Auskunft über den Fortschritt bzw. das Ergebnis des Flash-Prozesses. Fehlbedienungen sind unmöglich, da es keine Bedienelemente gibt.&lt;br /&gt;
&lt;br /&gt;
Einsatzgebiete:&lt;br /&gt;
* Produktion&lt;br /&gt;
* Fehlbedienungssichere Updates beim Kunden&lt;br /&gt;
&lt;br /&gt;
==== TheCableAVR-SD (kommerziell) ====&lt;br /&gt;
[http://www.priio.com/productcart/pc/viewPrd.asp?idcategory=6&amp;amp;idproduct=88 TheCableAVR-SD]  works by saving the &amp;quot;ISP&amp;quot;, &amp;quot;HEX&amp;quot; and &amp;quot;EEP&amp;quot; files required for part programming from the PC application onto an SD-Card and inserting it into TheCableAVR-SD. This programmer is stand alone, making it very handy for field software updates and production programming. &lt;br /&gt;
&lt;br /&gt;
Wird 4/2012 scheinbar nicht mehr verkauft ([http://www.mikrocontroller.net/topic/257278#2657606 Forumsbeitrag Priio AVR Programmer?]).&lt;br /&gt;
&lt;br /&gt;
==== ButtLoad ====&lt;br /&gt;
[http://www.fourwalledcubicle.com/ButtLoad.php ButtLoad] is based on the Atmel [[AVR Butterfly]] development board. ButtLoad is specially written firmware which converts a low-cost official Atmel Butterfly evaluation board into a smart ISP programmer for other members of the Atmel AVR family. It supports the entire AVR range, and allows for a complete program (including EEP, HEX, Fuse and Lock Bytes) to be stored and later programmed into a device from the Butterfly&#039;s on board non-volatile memory.&lt;br /&gt;
&lt;br /&gt;
[http://www.fourwalledcubicle.com/ButtLoad.php ButtLoad] basiert auf dem Atmel-[[AVR Butterfly]]-development board und ist eine spezielle Firmware, die ein (billiges) Atmel-Butterfly-Board in einen vollwertigen ISP-Programmierer für andere Controller der Atmel-AVR-Familie verwandelt. Es unterstützt den gesamten AVR-Bereich und erlaubt, ein Programm komplett mit EEP, HEX, Sicherungs- und Lock-Bytes im nichtflüchtigen on-board-Speicher des Butterflys abzulegen und dann von dort heraus die Controller zu programmieren.&lt;br /&gt;
&lt;br /&gt;
==== PalmAVR ====&lt;br /&gt;
* siehe [http://www.mikrocontroller.net/topic/77870#648376 Forenbeitrag]&lt;br /&gt;
&lt;br /&gt;
==== AVR-ISP500, AVR-ISP500 tiny ====&lt;br /&gt;
von Olimex, siehe&lt;br /&gt;
* [http://www.olimex.com/dev/avr-isp500-iso.html Herstellerseite zum ISP500] &lt;br /&gt;
* [http://www.olimex.com/dev/avr-isp500-tiny.html Herstellerseite zum ISP500-TINY]&lt;br /&gt;
&lt;br /&gt;
=== Geschwindigkeitsvergleich ===&lt;br /&gt;
&lt;br /&gt;
Im Rahmen einer Forendiskussion entstand die folgende Messung, die&lt;br /&gt;
einige der möglichen Programmer in ihrer Geschwindigkeit vergleicht.&lt;br /&gt;
Mit einbezogen in den Vergleich wurde neben originalen&lt;br /&gt;
Atmel-ISP-Werkzeugen noch Werkzeuge für [[JTAG#AVR_JTAG|JTAG]].&lt;br /&gt;
&lt;br /&gt;
Die Testdatei war 29704 Bytes groß.  Target ist ein ATmega6490, der&lt;br /&gt;
mit 8 MHz vom RC-Oszillator getaktet wird.  Das alles wurde mit einem&lt;br /&gt;
AVRDUDE 5.5 getestet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Programmer     Parameter         Zeit fürs&lt;br /&gt;
                              Schreiben  Lesen&lt;br /&gt;
-----------------------------------------------&lt;br /&gt;
JTAG ICE mkII  default        2,58 s     3,27 s&lt;br /&gt;
JTAG           (4 MHz)&lt;br /&gt;
-----------------------------------------------&lt;br /&gt;
JTAG ICE mkII  1 MHz          8,34 s     8,51 s   (**)&lt;br /&gt;
ISP&lt;br /&gt;
-----------------------------------------------&lt;br /&gt;
AVRISP mkII    250 kHz        5,37 s     5,46 s&lt;br /&gt;
               1 MHz          2,45 s     2,45 s&lt;br /&gt;
               2 MHz          1,89 s     1,99 s&lt;br /&gt;
-----------------------------------------------&lt;br /&gt;
STK500         900 kHz        5,84 s     3,49 s&lt;br /&gt;
               (schnellstes)&lt;br /&gt;
-----------------------------------------------&lt;br /&gt;
AVR Dragon     default        2,81 s     3,49 s&lt;br /&gt;
JTAG           (4 MHz)&lt;br /&gt;
-----------------------------------------------&lt;br /&gt;
AVR Dragon     1 MHz          8,34 s     8,64 s&lt;br /&gt;
ISP            2 MHz          -          -        (*)&lt;br /&gt;
-----------------------------------------------&lt;br /&gt;
Parallelport-  keine Delay   13,20 s    12,45 s   (**)&lt;br /&gt;
Dongle &amp;quot;alf&amp;quot;   CPU 900 MHz&lt;br /&gt;
-----------------------------------------------&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(*) Benutzung unmöglich, weder Fuses noch Signature zuverlässig&lt;br /&gt;
lesbar.&lt;br /&gt;
&lt;br /&gt;
(**) Fuses und Signature OK, aber das programmierte Ergebnis ist&lt;br /&gt;
fehlerhaft (verify errors)&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.myplace.nu/avr/yaap/ yaap] (Windows, diverse Parallelport-Programmer, GUI)&lt;br /&gt;
* [[Pony-Prog Tutorial|PonyProg]] (Linux, Windows, diverse Programmer für den parallelen und seriellen Port, GUI, am seriellen Port nur &amp;quot;Statuspinwackler&amp;quot; nach dem Schaltplan auf der lancos-Seite)&lt;br /&gt;
* [http://www.soft-land.de/index.php?page=avrburner AVRBurner] Ponyprog ähnliche Oberfläche für AVRDUDE.&lt;br /&gt;
* [http://www.nongnu.org/avrdude AVRDUDE] (Unix, Linux, Windows, praktisch alle Programmer, leicht erweiterbar auf andere Parallelportadapter-Anschlussbelegungen, Kommandozeile, auch für AVR Butterfly über dessen vorinstallierten Bootloader/Firmware-Uploader) siehe im Wiki [[AVRDUDE]]&lt;br /&gt;
* [http://savannah.nongnu.org/projects/uisp uisp] (Unix, Linux, Windows, praktisch alle Programmer, Kommandozeile, nicht mehr gepflegt).&lt;br /&gt;
* AVR-Studio (nur Programmieradapter mit integriertem Controller für den seriellen Port, z.&amp;amp;nbsp;B. AVR910, ATMEL AVRISP und STK500)&lt;br /&gt;
* [http://www.mcselec.com Eingebauter Programmer im Bascom-Basic Compiler]&lt;br /&gt;
* [http://esnips.com/web/AtmelAVR AvrOspII] - GUI Open Source programmer based on Atmels Application note AVR911.&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/60817 Forumsbeitrag] - Wie man Ponyprog aus dem AVR-Studio heraus nutzt&lt;br /&gt;
* [http://www.cadmaniac.org/projectMain.php?projectName=kontrollerlab Kontrollerlab] - (Linux), Grafische Oberfläche zu avr-gcc, uisp, avrdude und kate mit built-in debugger und serial terminal. Einfach verständlich und aufgeräumt (im KDE-Stil)&lt;br /&gt;
* [http://shop.myavr.de/index.php?sp=download.sp.php&amp;amp;suchwort=dl112 myAVRProgTool] - Freies Programmiertool und zusätzlich auch als DUDE-GUI geeignet, einfach zu bedienen&lt;br /&gt;
* [http://dybkowski.net/isp ISP Programmer] von Adam Dybkowski (Opensource, Windows 95, 98, Me, NT 4.0, 2000, XP, 2003, Vista and Windows 7 (32-bit and 64-bit versions))&lt;br /&gt;
&lt;br /&gt;
== ISP-Pins am AVR auch für andere Zwecke nutzen ==&lt;br /&gt;
&lt;br /&gt;
Bei einem Programmer mit eingebautem [[Ausgangsstufen_Logik-ICs#Tristate|Tristate]]-Treiber (z.&amp;amp;nbsp;B. 74HC(T)244) werden die Leitungen MISO, MOSI und SCK hochohmig geschaltet wenn die Programmierung beendet ist, d.h. sie beeinflussen die Schaltung nicht. Man kann die betreffenden Pins am AVR also relativ problemlos als Ausgänge verwenden, wenn man darauf achtet, dass die daran angeschlossene Peripherie durch die Programmierimpulse keinen Schaden nehmen kann. Als Eingänge sollte man die Pins allerdings nicht verwenden, da ein angeschlossener Taster zum Beispiel die Programmierimpulse kurzschließen würde, wenn er gedrückt ist.&lt;br /&gt;
&lt;br /&gt;
Atmel empfiehlt in der Application Note [http://www.atmel.com/dyn/resources/prod_documents/doc2521.pdf AVR042: AVR Hardware Design Considerations (PDF)] Peripherie an der SPI-Schnittstelle, bei gleichzeitiger Verwendung der Schnittstelle als In-System-Programmieranschluss, über Widerstände anzuschliessen.&lt;br /&gt;
&lt;br /&gt;
Ein Widerstand in SCK ist in diesem Zusammenhang aber nur dann sinnvoll, wenn am AVR ein externer SPI-Master hängt, denn nur dann kann ein Konflikt zwischen diesem SCK treibenden Master und dem ebenfalls SCK treibenden ISP auftreten. Ist der AVR hingegen wie üblich selbst der Master, dann ist ein Konflikt ausgeschlossen. Das gleiche gilt für MOSI.&lt;br /&gt;
&lt;br /&gt;
Bei MISO kann ein Konflikt nur auftreten, wenn diese Leitung vom Slave in der ISP-Phase aktiv treibend sein kann. Das ist beispielsweise bei Porterweiterungen (Inputs) mit Schieberegistern der Fall, wenn der&lt;br /&gt;
Datenausgang des Schieberegisters nicht passivierbar ist (tristate, Z-state). Dann ist ein Serienwiderstand in MISO sinnvoll.&lt;br /&gt;
&lt;br /&gt;
Normale SPI-Slaves mit CS-Leitung, wie ADCs, passivieren jedoch ihren Datenausgang wenn CS inaktiv ist. In diesem Fall ist ein Serienwiderstand in MISO unnötig, es muss nur über schwache Pullup-Widerstände an allen relevanten CS Leitungen sichergestellt sein, dass sie während Reset hochgezogen werden. Manche SPI-Slaves haben die bereits an Bord. Die internen Pullups im AVR sind keine Hilfe, da sie während Reset abgeschaltet sind.&lt;br /&gt;
&lt;br /&gt;
siehe auch [http://www.mikrocontroller.net/articles/AVR_HV-Programmer AVR HV-Programmer]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR-Programmer und -Bootloader| ]]&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69884</id>
		<title>Benutzer:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69884"/>
		<updated>2012-12-15T11:31:56Z</updated>

		<summary type="html">&lt;p&gt;Cmf: /* Einfachstes Menü */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Warnung|Seite im Aufbau, wird später zur richtigen Wiki-Seite verschoben!}}&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
&lt;br /&gt;
Oft benötigt man eine kleine Menüführung für sein Mikrocontroller Projekt. Dabei soll (Häufig auf einem LCD-Display) ein mehr oder weniger komplexes Menü angezeigt werden. Programmiert man das aber &amp;quot;einfach so drauf los&amp;quot;, wird es schnell unübersichtlich und speicherintensiv. Im folgenden wird versucht, ein Menü mit steigendem Schwierigkeitsgrad mit einem Mikrocontroller auf dem Display darzustellen.&lt;br /&gt;
&lt;br /&gt;
== Bedienung ==&lt;br /&gt;
Grundsätzlich hängt die Bedienmethode eines Menüs immer vom jeweiligen Projekt ab. Es folgt eine Auflistung der am häufigsten benutzten Bedienmethoden:&lt;br /&gt;
* Ein-Tasten Bedienung&lt;br /&gt;
* Zwei-Tasten Bedienung&lt;br /&gt;
* Drei-Tasten Bedienung&lt;br /&gt;
=== Fünf-Tasten / Steuerkreuz ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
=== [[Drehimpulsgeber]] ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Aktion || Menüführung || Werteingabe&lt;br /&gt;
|-&lt;br /&gt;
| Drehen || Blättern durch die Menüpunkte auf gleicher Ebene || Verändern eines Wertes&lt;br /&gt;
|-&lt;br /&gt;
| Tastendruck || Hinabsteigen in eine tiefere Menüebene  || Speichern des Wertes&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Umsetzung in GCC ==&lt;br /&gt;
&lt;br /&gt;
Wichtig für das Verständnis des folgenden Codes sind diese Artikel:&lt;br /&gt;
* [[Funktionszeiger_in_C]]&lt;br /&gt;
* [[String-Verarbeitung_in_C]]&lt;br /&gt;
&lt;br /&gt;
Dabei ist zu unterscheiden zwischen Interrupt-gesteuerten Menüs (das Programm kann also auch etwas anderes machen, solange der Benutzer nichts eingibt) und nicht Interrupt-gesteuerten Menüs. In den ersten Beispielen wird das Menü der Einfachheit halber ohne die Benutzung von Interrupts erstellt und angezeigt.&lt;br /&gt;
&lt;br /&gt;
=== Einfachstes Menü ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define MAX_TEXT_LAENGE 16&lt;br /&gt;
&lt;br /&gt;
//Typedef für einen Funktionspointer&lt;br /&gt;
typedef void (*MenueFnct) (int);&lt;br /&gt;
&lt;br /&gt;
//Struktur für einen Menüpunkt&lt;br /&gt;
struct MenueEintrag{&lt;br /&gt;
    char      text[MAX_TEXT_LAENGE];&lt;br /&gt;
    MenueFnct function; //Wird einmalig beim Aufruf ausgeführt&lt;br /&gt;
    int       argument;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void test(int a)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct MenueEintrag HauptMenu[] =&lt;br /&gt;
{&lt;br /&gt;
    { &amp;quot;Punkt 1&amp;quot;, NULL, 0},&lt;br /&gt;
    { &amp;quot;Punkt 2&amp;quot;, test, 5},&lt;br /&gt;
    { &amp;quot;Punkt 3&amp;quot;, NULL, 10}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int menuepunkt = 0;&lt;br /&gt;
&lt;br /&gt;
void ausgabe(char *text)&lt;br /&gt;
{&lt;br /&gt;
    printf(&amp;quot;%s\n&amp;quot;, text);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void eingabe(int *i)&lt;br /&gt;
{&lt;br /&gt;
    scanf(&amp;quot;%d&amp;quot;,     i); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void menue_starten(void)&lt;br /&gt;
{&lt;br /&gt;
    while(1)&lt;br /&gt;
    {&lt;br /&gt;
        //Menütext ausgeben&lt;br /&gt;
        ausgabe(HauptMenu[menuepunkt].text);&lt;br /&gt;
        //Funktion des Menüpunkts aufrufen&lt;br /&gt;
        if(HauptMenu[menuepunkt].function != NULL)&lt;br /&gt;
            HauptMenu[menuepunkt].function(HauptMenu[menuepunkt].argument);&lt;br /&gt;
        &lt;br /&gt;
        eingabe(&amp;amp;menuepunkt);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    menue_starten();&lt;br /&gt;
    &lt;br /&gt;
    //Wird nie erreicht&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Menü mit Werteingabe ===&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [[Funktionszeiger_in_C]]&lt;br /&gt;
* [[String-Verarbeitung_in_C]]&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* b&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69883</id>
		<title>Benutzer:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69883"/>
		<updated>2012-12-15T11:02:21Z</updated>

		<summary type="html">&lt;p&gt;Cmf: /* Siehe auch */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Warnung|Seite im Aufbau, wird später zur richtigen Wiki-Seite verschoben!}}&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
&lt;br /&gt;
Oft benötigt man eine kleine Menüführung für sein Mikrocontroller Projekt. Dabei soll (Häufig auf einem LCD-Display) ein mehr oder weniger komplexes Menü angezeigt werden. Programmiert man das aber &amp;quot;einfach so drauf los&amp;quot;, wird es schnell unübersichtlich und speicherintensiv. Im folgenden wird versucht, ein Menü mit steigendem Schwierigkeitsgrad mit einem Mikrocontroller auf dem Display darzustellen.&lt;br /&gt;
&lt;br /&gt;
== Bedienung ==&lt;br /&gt;
Grundsätzlich hängt die Bedienmethode eines Menüs immer vom jeweiligen Projekt ab. Es folgt eine Auflistung der am häufigsten benutzten Bedienmethoden:&lt;br /&gt;
* Ein-Tasten Bedienung&lt;br /&gt;
* Zwei-Tasten Bedienung&lt;br /&gt;
* Drei-Tasten Bedienung&lt;br /&gt;
=== Fünf-Tasten / Steuerkreuz ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
=== [[Drehimpulsgeber]] ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Aktion || Menüführung || Werteingabe&lt;br /&gt;
|-&lt;br /&gt;
| Drehen || Blättern durch die Menüpunkte auf gleicher Ebene || Verändern eines Wertes&lt;br /&gt;
|-&lt;br /&gt;
| Tastendruck || Hinabsteigen in eine tiefere Menüebene  || Speichern des Wertes&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Umsetzung in GCC ==&lt;br /&gt;
&lt;br /&gt;
Wichtig für das Verständnis des folgenden Codes sind diese Artikel:&lt;br /&gt;
* [[Funktionszeiger_in_C]]&lt;br /&gt;
* [[String-Verarbeitung_in_C]]&lt;br /&gt;
&lt;br /&gt;
Dabei ist zu unterscheiden zwischen Interrupt-gesteuerten Menüs (das Programm kann also auch etwas anderes machen, solange der Benutzer nichts eingibt) und nicht Interrupt-gesteuerten Menüs. In den ersten Beispielen wird das Menü der Einfachheit halber ohne die Benutzung von Interrupts erstellt und angezeigt.&lt;br /&gt;
&lt;br /&gt;
=== Einfachstes Menü ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void()&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    menue_starten();&lt;br /&gt;
&lt;br /&gt;
    while(1)&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;
&lt;br /&gt;
=== Menü mit Werteingabe ===&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [[Funktionszeiger_in_C]]&lt;br /&gt;
* [[String-Verarbeitung_in_C]]&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* b&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69882</id>
		<title>Benutzer:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69882"/>
		<updated>2012-12-15T10:59:15Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Warnung|Seite im Aufbau, wird später zur richtigen Wiki-Seite verschoben!}}&lt;br /&gt;
&lt;br /&gt;
== Problem ==&lt;br /&gt;
&lt;br /&gt;
Oft benötigt man eine kleine Menüführung für sein Mikrocontroller Projekt. Dabei soll (Häufig auf einem LCD-Display) ein mehr oder weniger komplexes Menü angezeigt werden. Programmiert man das aber &amp;quot;einfach so drauf los&amp;quot;, wird es schnell unübersichtlich und speicherintensiv. Im folgenden wird versucht, ein Menü mit steigendem Schwierigkeitsgrad mit einem Mikrocontroller auf dem Display darzustellen.&lt;br /&gt;
&lt;br /&gt;
== Bedienung ==&lt;br /&gt;
Grundsätzlich hängt die Bedienmethode eines Menüs immer vom jeweiligen Projekt ab. Es folgt eine Auflistung der am häufigsten benutzten Bedienmethoden:&lt;br /&gt;
* Ein-Tasten Bedienung&lt;br /&gt;
* Zwei-Tasten Bedienung&lt;br /&gt;
* Drei-Tasten Bedienung&lt;br /&gt;
=== Fünf-Tasten / Steuerkreuz ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
=== [[Drehimpulsgeber]] ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Aktion || Menüführung || Werteingabe&lt;br /&gt;
|-&lt;br /&gt;
| Drehen || Blättern durch die Menüpunkte auf gleicher Ebene || Verändern eines Wertes&lt;br /&gt;
|-&lt;br /&gt;
| Tastendruck || Hinabsteigen in eine tiefere Menüebene  || Speichern des Wertes&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Umsetzung in GCC ==&lt;br /&gt;
&lt;br /&gt;
Wichtig für das Verständnis des folgenden Codes sind diese Artikel:&lt;br /&gt;
* [[Funktionszeiger_in_C]]&lt;br /&gt;
* [[String-Verarbeitung_in_C]]&lt;br /&gt;
&lt;br /&gt;
Dabei ist zu unterscheiden zwischen Interrupt-gesteuerten Menüs (das Programm kann also auch etwas anderes machen, solange der Benutzer nichts eingibt) und nicht Interrupt-gesteuerten Menüs. In den ersten Beispielen wird das Menü der Einfachheit halber ohne die Benutzung von Interrupts erstellt und angezeigt.&lt;br /&gt;
&lt;br /&gt;
=== Einfachstes Menü ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void()&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    menue_starten();&lt;br /&gt;
&lt;br /&gt;
    while(1)&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;
&lt;br /&gt;
=== Menü mit Werteingabe ===&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* a&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* b&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69881</id>
		<title>Benutzer:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69881"/>
		<updated>2012-12-15T10:57:00Z</updated>

		<summary type="html">&lt;p&gt;Cmf: /* Fünf-Tasten / Steuerkreuz */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Problem ==&lt;br /&gt;
&lt;br /&gt;
Oft benötigt man eine kleine Menüführung für sein Mikrocontroller Projekt. Dabei soll (Häufig auf einem LCD-Display) ein mehr oder weniger komplexes Menü angezeigt werden. Programmiert man das aber &amp;quot;einfach so drauf los&amp;quot;, wird es schnell unübersichtlich und speicherintensiv. Im folgenden wird versucht, ein Menü mit steigendem Schwierigkeitsgrad mit einem Mikrocontroller auf dem Display darzustellen.&lt;br /&gt;
&lt;br /&gt;
== Bedienung ==&lt;br /&gt;
Grundsätzlich hängt die Bedienmethode eines Menüs immer vom jeweiligen Projekt ab. Es folgt eine Auflistung der am häufigsten benutzten Bedienmethoden:&lt;br /&gt;
* Ein-Tasten Bedienung&lt;br /&gt;
* Zwei-Tasten Bedienung&lt;br /&gt;
* Drei-Tasten Bedienung&lt;br /&gt;
=== Fünf-Tasten / Steuerkreuz ===&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
=== [[Drehimpulsgeber]] ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Aktion || Menüführung || Werteingabe&lt;br /&gt;
|-&lt;br /&gt;
| Drehen || Blättern durch die Menüpunkte auf gleicher Ebene || Verändern eines Wertes&lt;br /&gt;
|-&lt;br /&gt;
| Tastendruck || Hinabsteigen in eine tiefere Menüebene  || Speichern des Wertes&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Umsetzung in GCC ==&lt;br /&gt;
&lt;br /&gt;
Wichtig für das Verständnis des folgenden Codes sind diese Artikel:&lt;br /&gt;
* [[Funktionszeiger_in_C]]&lt;br /&gt;
* [[String-Verarbeitung_in_C]]&lt;br /&gt;
&lt;br /&gt;
Dabei ist zu unterscheiden zwischen Interrupt-gesteuerten Menüs (das Programm kann also auch etwas anderes machen, solange der Benutzer nichts eingibt) und nicht Interrupt-gesteuerten Menüs. In den ersten Beispielen wird das Menü der Einfachheit halber ohne die Benutzung von Interrupts erstellt und angezeigt.&lt;br /&gt;
&lt;br /&gt;
=== Einfachstes Menü ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void()&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    menue_starten();&lt;br /&gt;
&lt;br /&gt;
    while(1)&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;
&lt;br /&gt;
=== Menü mit Werteingabe ===&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* a&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* b&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69880</id>
		<title>Benutzer:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69880"/>
		<updated>2012-12-15T10:55:29Z</updated>

		<summary type="html">&lt;p&gt;Cmf: /* Umsetzung in GCC */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Problem ==&lt;br /&gt;
&lt;br /&gt;
Oft benötigt man eine kleine Menüführung für sein Mikrocontroller Projekt. Dabei soll (Häufig auf einem LCD-Display) ein mehr oder weniger komplexes Menü angezeigt werden. Programmiert man das aber &amp;quot;einfach so drauf los&amp;quot;, wird es schnell unübersichtlich und speicherintensiv. Im folgenden wird versucht, ein Menü mit steigendem Schwierigkeitsgrad mit einem Mikrocontroller auf dem Display darzustellen.&lt;br /&gt;
&lt;br /&gt;
== Bedienung ==&lt;br /&gt;
Grundsätzlich hängt die Bedienmethode eines Menüs immer vom jeweiligen Projekt ab. Es folgt eine Auflistung der am häufigsten benutzten Bedienmethoden:&lt;br /&gt;
* Ein-Tasten Bedienung&lt;br /&gt;
* Zwei-Tasten Bedienung&lt;br /&gt;
* Drei-Tasten Bedienung&lt;br /&gt;
=== Fünf-Tasten / Steuerkreuz ===&lt;br /&gt;
&lt;br /&gt;
=== [[Drehimpulsgeber]] ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Aktion || Menüführung || Werteingabe&lt;br /&gt;
|-&lt;br /&gt;
| Drehen || Blättern durch die Menüpunkte auf gleicher Ebene || Verändern eines Wertes&lt;br /&gt;
|-&lt;br /&gt;
| Tastendruck || Hinabsteigen in eine tiefere Menüebene  || Speichern des Wertes&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Umsetzung in GCC ==&lt;br /&gt;
&lt;br /&gt;
Wichtig für das Verständnis des folgenden Codes sind diese Artikel:&lt;br /&gt;
* [[Funktionszeiger_in_C]]&lt;br /&gt;
* [[String-Verarbeitung_in_C]]&lt;br /&gt;
&lt;br /&gt;
Dabei ist zu unterscheiden zwischen Interrupt-gesteuerten Menüs (das Programm kann also auch etwas anderes machen, solange der Benutzer nichts eingibt) und nicht Interrupt-gesteuerten Menüs. In den ersten Beispielen wird das Menü der Einfachheit halber ohne die Benutzung von Interrupts erstellt und angezeigt.&lt;br /&gt;
&lt;br /&gt;
=== Einfachstes Menü ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void()&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    menue_starten();&lt;br /&gt;
&lt;br /&gt;
    while(1)&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;
&lt;br /&gt;
=== Menü mit Werteingabe ===&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* a&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* b&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69879</id>
		<title>Benutzer:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69879"/>
		<updated>2012-12-15T10:50:16Z</updated>

		<summary type="html">&lt;p&gt;Cmf: /* Lösung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Problem ==&lt;br /&gt;
&lt;br /&gt;
Oft benötigt man eine kleine Menüführung für sein Mikrocontroller Projekt. Dabei soll (Häufig auf einem LCD-Display) ein mehr oder weniger komplexes Menü angezeigt werden. Programmiert man das aber &amp;quot;einfach so drauf los&amp;quot;, wird es schnell unübersichtlich und speicherintensiv. Im folgenden wird versucht, ein Menü mit steigendem Schwierigkeitsgrad mit einem Mikrocontroller auf dem Display darzustellen.&lt;br /&gt;
&lt;br /&gt;
== Bedienung ==&lt;br /&gt;
Grundsätzlich hängt die Bedienmethode eines Menüs immer vom jeweiligen Projekt ab. Es folgt eine Auflistung der am häufigsten benutzten Bedienmethoden:&lt;br /&gt;
* Ein-Tasten Bedienung&lt;br /&gt;
* Zwei-Tasten Bedienung&lt;br /&gt;
* Drei-Tasten Bedienung&lt;br /&gt;
=== Fünf-Tasten / Steuerkreuz ===&lt;br /&gt;
&lt;br /&gt;
=== [[Drehimpulsgeber]] ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Aktion || Menüführung || Werteingabe&lt;br /&gt;
|-&lt;br /&gt;
| Drehen || Blättern durch die Menüpunkte auf gleicher Ebene || Verändern eines Wertes&lt;br /&gt;
|-&lt;br /&gt;
| Tastendruck || Hinabsteigen in eine tiefere Menüebene  || Speichern des Wertes&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Umsetzung in GCC ==&lt;br /&gt;
&lt;br /&gt;
Wichtig für das Verständnis des folgenden Codes:&lt;br /&gt;
* [[Funktionszeiger_in_C]]&lt;br /&gt;
* [[String-Verarbeitung_in_C]]&lt;br /&gt;
&lt;br /&gt;
=== Das einfachste Menü ===&lt;br /&gt;
&lt;br /&gt;
=== Ein Menü mit Zahleneingabe ===&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* a&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* b&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69878</id>
		<title>Benutzer:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69878"/>
		<updated>2012-12-15T10:49:40Z</updated>

		<summary type="html">&lt;p&gt;Cmf: /* Drehimpulsgeber */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Problem ==&lt;br /&gt;
&lt;br /&gt;
Oft benötigt man eine kleine Menüführung für sein Mikrocontroller Projekt. Dabei soll (Häufig auf einem LCD-Display) ein mehr oder weniger komplexes Menü angezeigt werden. Programmiert man das aber &amp;quot;einfach so drauf los&amp;quot;, wird es schnell unübersichtlich und speicherintensiv. Im folgenden wird versucht, ein Menü mit steigendem Schwierigkeitsgrad mit einem Mikrocontroller auf dem Display darzustellen.&lt;br /&gt;
&lt;br /&gt;
== Bedienung ==&lt;br /&gt;
Grundsätzlich hängt die Bedienmethode eines Menüs immer vom jeweiligen Projekt ab. Es folgt eine Auflistung der am häufigsten benutzten Bedienmethoden:&lt;br /&gt;
* Ein-Tasten Bedienung&lt;br /&gt;
* Zwei-Tasten Bedienung&lt;br /&gt;
* Drei-Tasten Bedienung&lt;br /&gt;
=== Fünf-Tasten / Steuerkreuz ===&lt;br /&gt;
&lt;br /&gt;
=== [[Drehimpulsgeber]] ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Aktion || Menüführung || Werteingabe&lt;br /&gt;
|-&lt;br /&gt;
| Drehen || Blättern durch die Menüpunkte auf gleicher Ebene || Verändern eines Wertes&lt;br /&gt;
|-&lt;br /&gt;
| Tastendruck || Hinabsteigen in eine tiefere Menüebene  || Speichern des Wertes&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Lösung ==&lt;br /&gt;
&lt;br /&gt;
Wichtig für das Verständnis des folgenden Codes:&lt;br /&gt;
* [[Funktionszeiger_in_C]]&lt;br /&gt;
* [[String-Verarbeitung_in_C]]&lt;br /&gt;
&lt;br /&gt;
=== Das einfachste Menü ===&lt;br /&gt;
&lt;br /&gt;
=== Ein Menü mit Zahleneingabe ===&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* a&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* b&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69877</id>
		<title>Benutzer:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69877"/>
		<updated>2012-12-15T10:48:49Z</updated>

		<summary type="html">&lt;p&gt;Cmf: /* Drehimpulsgeber */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Problem ==&lt;br /&gt;
&lt;br /&gt;
Oft benötigt man eine kleine Menüführung für sein Mikrocontroller Projekt. Dabei soll (Häufig auf einem LCD-Display) ein mehr oder weniger komplexes Menü angezeigt werden. Programmiert man das aber &amp;quot;einfach so drauf los&amp;quot;, wird es schnell unübersichtlich und speicherintensiv. Im folgenden wird versucht, ein Menü mit steigendem Schwierigkeitsgrad mit einem Mikrocontroller auf dem Display darzustellen.&lt;br /&gt;
&lt;br /&gt;
== Bedienung ==&lt;br /&gt;
Grundsätzlich hängt die Bedienmethode eines Menüs immer vom jeweiligen Projekt ab. Es folgt eine Auflistung der am häufigsten benutzten Bedienmethoden:&lt;br /&gt;
* Ein-Tasten Bedienung&lt;br /&gt;
* Zwei-Tasten Bedienung&lt;br /&gt;
* Drei-Tasten Bedienung&lt;br /&gt;
=== Fünf-Tasten / Steuerkreuz ===&lt;br /&gt;
&lt;br /&gt;
=== [[Drehimpulsgeber]] ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Bedienung&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
! Aktion || Menüführung || Werteingabe&lt;br /&gt;
|-&lt;br /&gt;
| Drehen || Blättern durch die Menüpunkte auf gleicher Ebene || Verändern eines Wertes&lt;br /&gt;
|-&lt;br /&gt;
| Tastendruck || Hinabsteigen in eine tiefere Menüebene  || Speichern des Wertes&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Lösung ==&lt;br /&gt;
&lt;br /&gt;
Wichtig für das Verständnis des folgenden Codes:&lt;br /&gt;
* [[Funktionszeiger_in_C]]&lt;br /&gt;
* [[String-Verarbeitung_in_C]]&lt;br /&gt;
&lt;br /&gt;
=== Das einfachste Menü ===&lt;br /&gt;
&lt;br /&gt;
=== Ein Menü mit Zahleneingabe ===&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* a&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* b&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69876</id>
		<title>Benutzer:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69876"/>
		<updated>2012-12-15T10:45:22Z</updated>

		<summary type="html">&lt;p&gt;Cmf: /* Bedienung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Problem ==&lt;br /&gt;
&lt;br /&gt;
Oft benötigt man eine kleine Menüführung für sein Mikrocontroller Projekt. Dabei soll (Häufig auf einem LCD-Display) ein mehr oder weniger komplexes Menü angezeigt werden. Programmiert man das aber &amp;quot;einfach so drauf los&amp;quot;, wird es schnell unübersichtlich und speicherintensiv. Im folgenden wird versucht, ein Menü mit steigendem Schwierigkeitsgrad mit einem Mikrocontroller auf dem Display darzustellen.&lt;br /&gt;
&lt;br /&gt;
== Bedienung ==&lt;br /&gt;
Grundsätzlich hängt die Bedienmethode eines Menüs immer vom jeweiligen Projekt ab. Es folgt eine Auflistung der am häufigsten benutzten Bedienmethoden:&lt;br /&gt;
* Ein-Tasten Bedienung&lt;br /&gt;
* Zwei-Tasten Bedienung&lt;br /&gt;
* Drei-Tasten Bedienung&lt;br /&gt;
=== Fünf-Tasten / Steuerkreuz ===&lt;br /&gt;
&lt;br /&gt;
=== [[Drehimpulsgeber]] ===&lt;br /&gt;
&lt;br /&gt;
Hierbei bewirkt ein Tastendruck das hinabsteigen in einen tieferen Menüpunkt oder die Speicherung eines eben eingegebenen Wertes. Drehen nach links und rechts bewirkt ein Blättern durch die Menüpunkte auf gleicher Ebene oder das Einstellen eines Wertes.&lt;br /&gt;
&lt;br /&gt;
== Lösung ==&lt;br /&gt;
&lt;br /&gt;
Wichtig für das Verständnis des folgenden Codes:&lt;br /&gt;
* [[Funktionszeiger_in_C]]&lt;br /&gt;
* [[String-Verarbeitung_in_C]]&lt;br /&gt;
&lt;br /&gt;
=== Das einfachste Menü ===&lt;br /&gt;
&lt;br /&gt;
=== Ein Menü mit Zahleneingabe ===&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* a&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* b&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69875</id>
		<title>Benutzer:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69875"/>
		<updated>2012-12-15T10:42:13Z</updated>

		<summary type="html">&lt;p&gt;Cmf: /* Die Lösung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Problem ==&lt;br /&gt;
&lt;br /&gt;
Oft benötigt man eine kleine Menüführung für sein Mikrocontroller Projekt. Dabei soll (Häufig auf einem LCD-Display) ein mehr oder weniger komplexes Menü angezeigt werden. Programmiert man das aber &amp;quot;einfach so drauf los&amp;quot;, wird es schnell unübersichtlich und speicherintensiv. Im folgenden wird versucht, ein Menü mit steigendem Schwierigkeitsgrad mit einem Mikrocontroller auf dem Display darzustellen.&lt;br /&gt;
&lt;br /&gt;
== Bedienung ==&lt;br /&gt;
Grundsätzlich hängt die Bedienmethode eines Menüs immer vom jeweiligen Projekt ab. Es folgt eine Auflistung der am häufigsten benutzten Bedienmethoden:&lt;br /&gt;
* Ein-Tasten Bedienung&lt;br /&gt;
* Zwei-Tasten Bedienung&lt;br /&gt;
* Drei-Tasten Bedienung&lt;br /&gt;
* Fünf-Tasten Bedienung&lt;br /&gt;
* [[Drehimpulsgeber]]&lt;br /&gt;
&lt;br /&gt;
== Lösung ==&lt;br /&gt;
&lt;br /&gt;
Wichtig für das Verständnis des folgenden Codes:&lt;br /&gt;
* [[Funktionszeiger_in_C]]&lt;br /&gt;
* [[String-Verarbeitung_in_C]]&lt;br /&gt;
&lt;br /&gt;
=== Das einfachste Menü ===&lt;br /&gt;
&lt;br /&gt;
=== Ein Menü mit Zahleneingabe ===&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* a&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* b&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69874</id>
		<title>Benutzer:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69874"/>
		<updated>2012-12-15T10:42:04Z</updated>

		<summary type="html">&lt;p&gt;Cmf: /* Das Problem */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Problem ==&lt;br /&gt;
&lt;br /&gt;
Oft benötigt man eine kleine Menüführung für sein Mikrocontroller Projekt. Dabei soll (Häufig auf einem LCD-Display) ein mehr oder weniger komplexes Menü angezeigt werden. Programmiert man das aber &amp;quot;einfach so drauf los&amp;quot;, wird es schnell unübersichtlich und speicherintensiv. Im folgenden wird versucht, ein Menü mit steigendem Schwierigkeitsgrad mit einem Mikrocontroller auf dem Display darzustellen.&lt;br /&gt;
&lt;br /&gt;
== Bedienung ==&lt;br /&gt;
Grundsätzlich hängt die Bedienmethode eines Menüs immer vom jeweiligen Projekt ab. Es folgt eine Auflistung der am häufigsten benutzten Bedienmethoden:&lt;br /&gt;
* Ein-Tasten Bedienung&lt;br /&gt;
* Zwei-Tasten Bedienung&lt;br /&gt;
* Drei-Tasten Bedienung&lt;br /&gt;
* Fünf-Tasten Bedienung&lt;br /&gt;
* [[Drehimpulsgeber]]&lt;br /&gt;
&lt;br /&gt;
== Die Lösung ==&lt;br /&gt;
&lt;br /&gt;
Wichtig für das Verständnis des folgenden Codes:&lt;br /&gt;
* [[Funktionszeiger_in_C]]&lt;br /&gt;
* [[String-Verarbeitung_in_C]]&lt;br /&gt;
&lt;br /&gt;
=== Das einfachste Menü ===&lt;br /&gt;
&lt;br /&gt;
=== Ein Menü mit Zahleneingabe ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* a&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* b&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69873</id>
		<title>Benutzer:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69873"/>
		<updated>2012-12-15T10:41:39Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Das Problem ==&lt;br /&gt;
&lt;br /&gt;
Oft benötigt man eine kleine Menüführung für sein Mikrocontroller Projekt. Dabei soll (Häufig auf einem LCD-Display) ein mehr oder weniger komplexes Menü angezeigt werden. Programmiert man das aber &amp;quot;einfach so drauf los&amp;quot;, wird es schnell unübersichtlich und speicherintensiv. Im folgenden wird versucht, ein Menü mit steigendem Schwierigkeitsgrad mit einem Mikrocontroller auf dem Display darzustellen.&lt;br /&gt;
&lt;br /&gt;
== Bedienung ==&lt;br /&gt;
Grundsätzlich hängt die Bedienmethode eines Menüs immer vom jeweiligen Projekt ab. Es folgt eine Auflistung der am häufigsten benutzten Bedienmethoden:&lt;br /&gt;
* Ein-Tasten Bedienung&lt;br /&gt;
* Zwei-Tasten Bedienung&lt;br /&gt;
* Drei-Tasten Bedienung&lt;br /&gt;
* Fünf-Tasten Bedienung&lt;br /&gt;
* [[Drehimpulsgeber]]&lt;br /&gt;
&lt;br /&gt;
== Die Lösung ==&lt;br /&gt;
&lt;br /&gt;
Wichtig für das Verständnis des folgenden Codes:&lt;br /&gt;
* [[Funktionszeiger_in_C]]&lt;br /&gt;
* [[String-Verarbeitung_in_C]]&lt;br /&gt;
&lt;br /&gt;
=== Das einfachste Menü ===&lt;br /&gt;
&lt;br /&gt;
=== Ein Menü mit Zahleneingabe ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* a&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* b&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69872</id>
		<title>Benutzer:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69872"/>
		<updated>2012-12-15T10:31:12Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Das Problem ==&lt;br /&gt;
&lt;br /&gt;
Oft benötigt man eine kleine Menüführung für sein Mikrocontroller Projekt. Dabei soll (Häufig auf einem LCD-Display) ein mehr oder weniger komplexes Menü angezeigt werden. Programmiert man das aber &amp;quot;einfach so drauf los&amp;quot;, wird es schnell unübersichtlich und speicherintensiv. Im folgenden wird versucht, ein Menü mit steigendem Schwierigkeitsgrad mit einem Mikrocontroller auf dem Display darzustellen.&lt;br /&gt;
&lt;br /&gt;
== Die Lösung ==&lt;br /&gt;
&lt;br /&gt;
Wichtig für das Verständnis:&lt;br /&gt;
* [[Funktionszeiger_in_C]]&lt;br /&gt;
* [[String-Verarbeitung_in_C]]&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* a&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* b&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69871</id>
		<title>Benutzer:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69871"/>
		<updated>2012-12-15T10:29:41Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Das Problem ==&lt;br /&gt;
&lt;br /&gt;
Oft benötigt man eine kleine Menüführung für sein Mikrocontroller Projekt. Dabei soll (Häufig auf einem LCD-Display) ein mehr oder weniger komplexes Menü angezeigt werden. Programmiert man das aber &amp;quot;einfach so drauf los&amp;quot;, wird es schnell unübersichtlich und speicherintensiv. Im folgenden wird versucht, ein Menü mit steigendem Schwierigkeitsgrad mit einem Mikrocontroller auf dem Display darzustellen.&lt;br /&gt;
&lt;br /&gt;
== Die Lösung ==&lt;br /&gt;
&lt;br /&gt;
Wichtig für das Verständnis:&lt;br /&gt;
* [[Funktionszeiger_in_C]]&lt;br /&gt;
* [[String-Verarbeitung_in_C]]&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69870</id>
		<title>Benutzer:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Cmf&amp;diff=69870"/>
		<updated>2012-12-15T10:26:18Z</updated>

		<summary type="html">&lt;p&gt;Cmf: Die Seite wurde neu angelegt: „Oft benötigt man eine kleine Menüführung für sein Mikrocontroller Projekt.  == Das Problem ==  == Die Lösung ==  Wichtig für das Verständnis: * [[Funktions…“&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Oft benötigt man eine kleine Menüführung für sein Mikrocontroller Projekt.&lt;br /&gt;
&lt;br /&gt;
== Das Problem ==&lt;br /&gt;
&lt;br /&gt;
== Die Lösung ==&lt;br /&gt;
&lt;br /&gt;
Wichtig für das Verständnis:&lt;br /&gt;
* [[Funktionszeiger_in_C]]&lt;br /&gt;
* [[String-Verarbeitung_in_C]]&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR-GCC-Tutorial/Der_UART&amp;diff=67324</id>
		<title>AVR-GCC-Tutorial/Der UART</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR-GCC-Tutorial/Der_UART&amp;diff=67324"/>
		<updated>2012-07-14T07:42:52Z</updated>

		<summary type="html">&lt;p&gt;Cmf: /* Senden einzelner Zeichen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Über den [[UART]] kann ein [[AVR]] leicht mit einer [[RS-232]]-Schnittstelle eines PC oder sonstiger Geräte mit &amp;quot;[[seriell]]er Schnittstelle&amp;quot; verbunden werden. &lt;br /&gt;
&lt;br /&gt;
== Allgemeines zum UART ==&lt;br /&gt;
&lt;br /&gt;
Mögliche Anwendungen des UART:&lt;br /&gt;
&lt;br /&gt;
;Debug-Schnittstelle: z.&amp;amp;nbsp;B. zur Anzeige von Zwischenergebnissen (&amp;quot;printf-debugging&amp;quot; - hier besser &amp;quot;Logging&amp;quot; oder &amp;quot;UART-debugging&amp;quot;) über [[RS-232]] auf einem PC. Auf dem Rechner reicht dazu ein [[RS-232#Terminalprogramme|Terminalprogramm]] (MS-Windows: Hyperterm oder besser [https://sites.google.com/site/terminalbpp/], [http://www.der-hammer.info/terminal/ HTerm]; Unix/Linux z.&amp;amp;nbsp;B. minicom). Ein direkter Anschluss ist aufgrund unterschiedlicher Pegel nicht möglich, jedoch sind entsprechende Schnittstellen-ICs wie z.&amp;amp;nbsp;B. ein MAX232 günstig und leicht zu integrieren. Rechner ohne serielle Schnittstelle können über fertige USB-seriell-Adapter angeschlossen werden. &lt;br /&gt;
;Mensch-Maschine Schnittstelle: z.&amp;amp;nbsp;B. Konfiguration und Statusabfrage über eine &amp;quot;Kommandozeile&amp;quot; oder Menüs (siehe z.&amp;amp;nbsp;B. Forumsbeitrag [http://www.mikrocontroller.net/topic/52985 Auswertung RS232-Befehle] und Artikel [[Tinykon]]) &lt;br /&gt;
;Übertragen von gespeicherten Werten: z.&amp;amp;nbsp;B. bei einem Datenlogger&lt;br /&gt;
;Anschluss von Geräten: mit serieller Schnittstelle (z.&amp;amp;nbsp;B. (Funk-)Modems, Mobiltelefone, Drucker, Sensoren, &amp;quot;intelligente&amp;quot; LC-Displays, GPS-Empfänger). &lt;br /&gt;
;&amp;quot;Feldbusse&amp;quot;: auf RS485/RS422-Basis mittels entsprechenden Bustreiberbausteinen (z.&amp;amp;nbsp;B. MAX485)&lt;br /&gt;
;DMX, Midi: etc.&lt;br /&gt;
;LIN-Bus: &#039;&#039;&#039;L&#039;&#039;&#039;ocal &#039;&#039;&#039;I&#039;&#039;&#039;nterconnect &#039;&#039;&#039;N&#039;&#039;&#039;etwork: Preiswerte Sensoren/Aktoren in der Automobiltechnik und darüber hinaus&lt;br /&gt;
&lt;br /&gt;
Einige AVR-Controller haben ein bis zwei vollduplexfähige UART (&#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) schon eingebaut (&amp;quot;Hardware-UART&amp;quot;). &lt;br /&gt;
Übrigens: Vollduplex heißt nichts anderes, als dass der Baustein gleichzeitig senden und empfangen kann.&lt;br /&gt;
&lt;br /&gt;
Neuere AVRs (ATmega, ATtiny) verfügen über einen bis vier U&#039;&#039;&#039;S&#039;&#039;&#039;ART(s), dieser unterscheidet sich vom UART hauptsächlich durch interne FIFO-Puffer für Ein- und Ausgabe und erweiterte Konfigurationsmöglichkeiten. Die Puffergröße ist allerdings nur 1 Byte.&lt;br /&gt;
&lt;br /&gt;
== Die Hardware ==&lt;br /&gt;
&lt;br /&gt;
Der UART basiert auf normalem TTL-Pegel mit 0V (logisch 0) und 5V (logisch 1). Die Schnittstellenspezifikation für RS-232 definiert jedoch -3V ... -12V (logisch 1) und&lt;br /&gt;
+3 ... +12V (logisch 0). Daher muss der Signalaustausch zwischen AVR und Partnergerät invertiert werden. Für die Anpassung der Pegel und das Invertieren der Signale gibt es fertige Schnittstellenbausteine. Der bekannteste davon ist wohl der MAX232. &lt;br /&gt;
&amp;lt;!-- &amp;quot;Hackerloesung&amp;quot; auskommentiert - nicht so gut in einem &amp;quot;Einsteiger-Tutorial&amp;quot; - mthomas&lt;br /&gt;
Allerdings kostet der auch wieder Geld und benötigt&lt;br /&gt;
zusätzlich immerhin 4 externe Elkos.&lt;br /&gt;
&lt;br /&gt;
Die in den PC eingebauten Schnittstellen vertragen ohne Klagen auch den TTL-Pegel vom AVR. Allerdings müssen wir immer noch die Signale invertieren. Im einfachtesn Fall verwenden wir dazu jeweils einen einfachen NPN-Transistor und 2 Widerstände. Näheres dazu erfahrt ihr in den folgenden Übungen.--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Streikt die Kommunikation per UART, so ist oft eine fehlerhafte Einstellung der Baudrate die Ursache. Die Konfiguration auf eine bestimmte Baudrate ist abhängig von der Taktfrequenz des Controllers. Gerade bei neu aufgebauten Schaltungen (bzw. neu gekauften Controllern) sollte man sich daher noch einmal vergewissern, dass der Controller auch tatsächlich mit der vermuteten Taktrate arbeitet und nicht z.&amp;amp;nbsp;B. den bei einigen Modellen werksseitig eingestellten internen [[Oszillator]] statt eines externen Quarzes nutzt. Die Werte der verschiedenen fuse-bits im Fehlerfall also beispielsweise mit &#039;&#039;[[AVRDUDE]]&#039;&#039; kontrollieren und falls nötig anpassen. Grundsätzlich empfiehlt sich auch immer ein Blick in die [[AVR_Checkliste]].&lt;br /&gt;
&lt;br /&gt;
== Die UART-Register ==&lt;br /&gt;
&lt;br /&gt;
Der UART wird über vier separate Register angesprochen. Die USARTs der ATMEGAs verfügen über mehrere zusätzliche Konfigurationsregister. Das Datenblatt gibt darüber Auskunft. Die folgende Tabelle gibt nur die Register für die UARTs der ATmega8/16/32 u.ä. wieder.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;UCSRA&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;U&#039;&#039;&#039;ART &#039;&#039;&#039;C&#039;&#039;&#039;ontrol and &#039;&#039;&#039;S&#039;&#039;&#039;tatus &#039;&#039;&#039;R&#039;&#039;&#039;egister &#039;&#039;&#039;A&#039;&#039;&#039;.&amp;lt;br /&amp;gt;&lt;br /&gt;
Hier teilt uns der UART mit, was er gerade so macht.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;RXC&#039;&#039;&#039;|| &#039;&#039;&#039;TXC&#039;&#039;&#039;|| &#039;&#039;&#039;UDRE&#039;&#039;&#039;|| &#039;&#039;&#039;FE&#039;&#039;&#039;|| &#039;&#039;&#039;DOR&#039;&#039;&#039;|| &#039;&#039;&#039;PE&#039;&#039;&#039;|| &#039;&#039;&#039;U2X&#039;&#039;&#039;|| &#039;&#039;&#039;MPCM&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R|| R/W|| R|| R|| R|| R|| R/W|| R/W&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0|| 0|| 1|| 0|| 0|| 0|| 0|| 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RXC&#039;&#039;&#039; (UART Receive Complete)&lt;br /&gt;
:Dieses Bit wird vom AVR gesetzt, wenn ein empfangenes Zeichen vom Empfangs-Schieberegister in das Empfangs-Datenregister transferiert wurde.&lt;br /&gt;
:Das Zeichen muss nun schnellstmöglich aus dem Datenregister ausgelesen werden. Falls dies nicht erfolgt, bevor ein weiteres Zeichen komplett empfangen wurde, wird eine Überlauf-Fehlersituation eintreten. Mit dem Auslesen des Datenregisters wird das Bit automatisch gelöscht.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TXC&#039;&#039;&#039; (UART Transmit Complete)&lt;br /&gt;
:Dieses Bit wird vom AVR gesetzt, wenn das im Sende-Schieberegister befindliche Zeichen vollständig ausgegeben wurde und kein weiteres Zeichen im Sendedatenregister ansteht. Dies bedeutet also, dass die Kommunikation vollumfänglich abgeschlossen ist.&lt;br /&gt;
:Dieses Bit ist wichtig bei Halbduplex-Verbindungen, wenn das Programm nach dem Senden von Daten auf Empfang schalten muss. Im Vollduplexbetrieb brauchen wir dieses Bit nicht zu beachten.&lt;br /&gt;
:Das Bit wird nur dann automatisch gelöscht, wenn der entsprechende Interrupthandler aufgerufen wird, ansonsten müssen wir das Bit selber löschen.&lt;br /&gt;
:Um das Bit zu löschen muss eine 1 an die entsprechende Position geschrieben werden!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;UDRE&#039;&#039;&#039; (&#039;&#039;&#039;U&#039;&#039;&#039;ART &#039;&#039;&#039;D&#039;&#039;&#039;ata &#039;&#039;&#039;R&#039;&#039;&#039;egister &#039;&#039;&#039;E&#039;&#039;&#039;mpty)&lt;br /&gt;
:Dieses Bit zeigt an, ob der Sendepuffer bereit ist, um ein zu sendendes Zeichen aufzunehmen. Das Bit wird vom AVR gesetzt (1), wenn der Sendepuffer leer ist. Es wird gelöscht (0), wenn ein Zeichen im Sendedatenregister vorhanden ist und noch nicht in das Sende-Schieberegister übernommen wurde. Atmel empfiehlt aus Kompatibilitätsgründen mit kommenden µC, UDRE auf 0 zu setzen, wenn das UCSRA Register beschrieben wird.&lt;br /&gt;
:Das Bit wird automatisch gelöscht, wenn ein Zeichen in das Sendedatenregister geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FE&#039;&#039;&#039; (&#039;&#039;&#039;F&#039;&#039;&#039;raming &#039;&#039;&#039;E&#039;&#039;&#039;rror)&lt;br /&gt;
:Dieses Bit wird vom AVR gesetzt, wenn der UART einen Zeichenrahmenfehler detektiert, d.h. wenn das Stopbit eines empfangenen Zeichens 0 ist.&lt;br /&gt;
:Das Bit wird automatisch gelöscht, wenn das Stopbit des empfangenen Zeichens 1 ist.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DOR&#039;&#039;&#039; (&#039;&#039;&#039;D&#039;&#039;&#039;ata &#039;&#039;&#039;O&#039;&#039;&#039;ver &#039;&#039;&#039;R&#039;&#039;&#039;un)&lt;br /&gt;
:Dieses Bit wird vom AVR gesetzt, wenn unser Programm das im Empfangsdatenregister bereit liegende Zeichen nicht abholt bevor das nachfolgende Zeichen komplett empfangen wurde.&lt;br /&gt;
:Das nachfolgende Zeichen wird verworfen.&lt;br /&gt;
:Das Bit wird automatisch gelöscht, wenn das empfangene Zeichen in das Empfangsdatenregister transferiert werden konnte.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;PE&#039;&#039;&#039; (&#039;&#039;&#039;P&#039;&#039;&#039;arity &#039;&#039;&#039;E&#039;&#039;&#039;rror&#039;&#039;&#039;)&lt;br /&gt;
:Dieses Bit wird vom AVR gesetzt, wenn das im Empfangsdatenregister bereit liegende Zeichen eine Paritätsfehler aufweist.&lt;br /&gt;
:Das Bit wird automatisch gelöscht, wenn das empfangene Zeichen in das Empfangsdatenregister transferiert werden konnte.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;U2X&#039;&#039;&#039; (Double the transmission speed)&lt;br /&gt;
:Dieses Bit wird lediglich im asynchronen Modus genutzt. Im synchronen Modus ist es 0 zu setzen. Wird das Bit gesetzt, so wird der Baudraten Divisor von 16 auf 8 reduziert, was einer Verdopplung der Transferrate gleich kommt.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MPCM&#039;&#039;&#039; (&#039;&#039;&#039;M&#039;&#039;&#039;ulti &#039;&#039;&#039;P&#039;&#039;&#039;rozessor &#039;&#039;&#039;C&#039;&#039;&#039;ommunication &#039;&#039;&#039;M&#039;&#039;&#039;ode)&lt;br /&gt;
:Dieses Bit aktiviert die Multi-Prozessor-Kommunikation. Jeder eintreffende Frame der keine Adressinformation enthält wird dadurch ignoriert.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;UCSRB &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;U&#039;&#039;&#039;ART &#039;&#039;&#039;C&#039;&#039;&#039;ontrol and &#039;&#039;&#039;S&#039;&#039;&#039;tatus &#039;&#039;&#039;R&#039;&#039;&#039;egister &#039;&#039;&#039;B&#039;&#039;&#039;.&amp;lt;br /&amp;gt;&lt;br /&gt;
In diesem Register stellen wir ein, wie wir den UART verwenden möchten.&amp;lt;br /&amp;gt;&lt;br /&gt;
Das Register ist wie folgt aufgebaut:&lt;br /&gt;
&lt;br /&gt;
{|  class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;RXCIE&#039;&#039;&#039;|| &#039;&#039;&#039;TXCIE&#039;&#039;&#039;|| &#039;&#039;&#039;UDRIE&#039;&#039;&#039;|| &#039;&#039;&#039;RXEN&#039;&#039;&#039;|| &#039;&#039;&#039;TXEN&#039;&#039;&#039;|| &#039;&#039;&#039;UCSZ2&#039;&#039;&#039;|| &#039;&#039;&#039;RXB8&#039;&#039;&#039;|| &#039;&#039;&#039;TXB8&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W|| R/W|| R/W|| R/W|| R/W|| R/W|| R|| R/W&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0|| 0|| 0|| 0|| 0|| 0|| 0|| 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RXCIE&#039;&#039;&#039; (&#039;&#039;&#039;RX&#039;&#039;&#039; &#039;&#039;&#039;C&#039;&#039;&#039;omplete &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;E&#039;&#039;&#039;nable)&lt;br /&gt;
:Wenn dieses Bit gesetzt ist, wird ein UART RX Complete Interrupt ausgelöst, wenn ein Zeichen vom UART empfangen wurde. Das Global Enable Interrupt Flag muss selbstverständlich auch gesetzt sein.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TXCIE&#039;&#039;&#039; (&#039;&#039;&#039;TX&#039;&#039;&#039; &#039;&#039;&#039;C&#039;&#039;&#039;omplete &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;E&#039;&#039;&#039;nable)&lt;br /&gt;
:Wenn dieses Bit gesetzt ist, wird ein UART TX Complete Interrupt ausgelöst, wenn ein Zeichen vom UART gesendet wurde. Das Global Enable Interrupt Flag muss selbstverständlich auch gesetzt sein.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;UDRIE&#039;&#039;&#039; (&#039;&#039;&#039;U&#039;&#039;&#039;ART &#039;&#039;&#039;D&#039;&#039;&#039;ata &#039;&#039;&#039;R&#039;&#039;&#039;egister &#039;&#039;&#039;E&#039;&#039;&#039;mpty &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;E&#039;&#039;&#039;nable)&lt;br /&gt;
:Wenn dieses Bit gesetzt ist, wird ein UART Datenregister Leer Interrupt ausgelöst, wenn der UART wieder bereit ist um ein neues zu sendendes Zeichen zu übernehmen. Das Global Enable Interrupt Flag muss selbstverständlich auch gesetzt sein.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RXEN&#039;&#039;&#039; (&#039;&#039;&#039;R&#039;&#039;&#039;eceiver &#039;&#039;&#039;E&#039;&#039;&#039;nable)&lt;br /&gt;
:Nur wenn dieses Bit gesetzt ist, arbeitet der Empfänger des UART überhaupt. Wenn das Bit nicht gesetzt ist, kann der entsprechende Pin des AVR als normaler I/O-Pin verwendet werden. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TXEN&#039;&#039;&#039; (&#039;&#039;&#039;T&#039;&#039;&#039;ransmitter &#039;&#039;&#039;E&#039;&#039;&#039;nable)&lt;br /&gt;
:Nur wenn dieses Bit gesetzt ist, arbeitet der Sender des UART überhaupt. Wenn das Bit nicht gesetzt ist, kann der entsprechende Pin des AVR als normaler I/O-Pin verwendet werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;UCSZ2&#039;&#039;&#039; (Characters Size)&lt;br /&gt;
:Dieses Bit setzt in Verbindung mit dem UCSZ1:0 Bits im UCSRC Register die Anzahl von Datenbits eines Frames beim Empfang oder Senden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RXB8&#039;&#039;&#039; (Receive Data Bit 8)&lt;br /&gt;
:Wenn das vorher erwähnte CHR9-Bit gesetzt ist, dann enthält dieses Bit das 9. Datenbit eines empfangenen Zeichens.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TXB8&#039;&#039;&#039; (Transmit Data Bit 8)&lt;br /&gt;
:Wenn das vorher erwähnte CHR9-Bit gesetzt ist, dann muss in dieses Bit das 9. Bit des zu sendenden Zeichens eingeschrieben werden bevor das eigentliche Datenbyte in das Datenregister geschrieben wird.&lt;br /&gt;
|-&lt;br /&gt;
| &#039;&#039;&#039;UCSRC &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;U&#039;&#039;&#039;ART &#039;&#039;&#039;C&#039;&#039;&#039;ontrol and &#039;&#039;&#039;S&#039;&#039;&#039;tatus &#039;&#039;&#039;R&#039;&#039;&#039;egister &#039;&#039;&#039;C&#039;&#039;&#039;.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{|  class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;URSEL&#039;&#039;&#039;|| &#039;&#039;&#039;UMSEL&#039;&#039;&#039;|| &#039;&#039;&#039;UPM1&#039;&#039;&#039;|| &#039;&#039;&#039;UPM0&#039;&#039;&#039;|| &#039;&#039;&#039;USBS&#039;&#039;&#039;|| &#039;&#039;&#039;UCSZ1&#039;&#039;&#039;|| &#039;&#039;&#039;UCSZ0&#039;&#039;&#039;|| &#039;&#039;&#039;UCPOL&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W|| R/W|| R/W|| R/W|| R/W|| R/W|| R/W|| R/W&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 1|| 0|| 0|| 0|| 0|| 1|| 1|| 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;URSEL&#039;&#039;&#039; (Register Select)&lt;br /&gt;
:Dieses Bit selektiert die Auswahl des UCSRC- bzw. des UBRRH Registers. Beim Lesen von UCSRC wird es als 1 gelesen. Beim Schreiben auf UCSRC muss es auf 1 gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
:Achtung: Manche Prozessoren verfügen über dieses Bit, andere wiederrum nicht. Was hat es damit auf sich?&amp;lt;br&amp;gt;Um Zugriffsadressen einzusparen, wurde von Atmel ein etwas seltsamer Weg gewählt. Das UCSRC Register und das High-Byte des Baudratenregisters teilen sich dieselbe Registeradresse! Um der Hardware mitzuteilen, welche Bedeutung ein zugewiesener Wert haben soll, entweder neue Belegung des Baudratenregisters oder eben Konfiguration des UCSRC Registers, dient dieses Bit. Ist es nicht gesetzt, dann wird eine Zuweisung immer als Zuweisung an das High-Byte des Baudratenregisters angesehen, selbst wenn das so nicht beabsichtigt war. Nur dann wenn dieses Bit gesetzt ist, dann wird eine Zuweisung auch tatsächlich als eine Zuweisung an das UCSRC Register gewertet und die Konfiguration verändert. Lässt man das Bit irrtümlich weg, dann verursacht eine Zuweisung an UCSRC eine Veränderung der Baudrateneinstellung!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;UMSEL&#039;&#039;&#039; (USART Mode Select)&lt;br /&gt;
:Durch dieses Bit kann eine asynchrone oder synchrone Übertragung eingestellt werden. Durch Setzen des Bits wird eine synchrone Übertragung eingestellt.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;UPM1:0&#039;&#039;&#039; (Parity Mode)&lt;br /&gt;
{|  class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;UPM1&#039;&#039;&#039;|| &#039;&#039;&#039;UPM0&#039;&#039;&#039;|| &#039;&#039;&#039;Parity Mode&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
| 0|| 0|| Disabled&lt;br /&gt;
|- &lt;br /&gt;
| 0|| 1|| Reserved&lt;br /&gt;
|- &lt;br /&gt;
| 1|| 0|| Enabled, Even Priority&lt;br /&gt;
|- &lt;br /&gt;
| 1|| 1|| Enabled, OddPriority&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;USBS&#039;&#039;&#039; (&#039;&#039;&#039;U&#039;&#039;&#039;SART &#039;&#039;&#039;S&#039;&#039;&#039;top &#039;&#039;&#039;B&#039;&#039;&#039;it &#039;&#039;&#039;S&#039;&#039;&#039;elect)&lt;br /&gt;
:Diese Bits setzen die Anzahl der zu sendenden Stopbits eines Frames. Beim Setzen werden 2 Stopbits übertragen, andernfalls nur 1 Stopbit.&lt;br /&gt;
{|  class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;USBS&#039;&#039;&#039;|| &#039;&#039;&#039;Anzahl der Stop Bits&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
|  0|| 1&lt;br /&gt;
|- &lt;br /&gt;
|  1|| 2&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;UCSZ1:0&#039;&#039;&#039; (Character Size)&lt;br /&gt;
:Diese Bits setzen in Verbindung mit UCSZ2 aus dem UCSRB Register die Anzahl der Datenbits eines Frames.&lt;br /&gt;
:Diese Bits setzen den entsprechenden Paritätsmodus.&lt;br /&gt;
{|  class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;UCSZ2&#039;&#039;&#039;|| &#039;&#039;&#039;UCSZ1&#039;&#039;&#039;|| &#039;&#039;&#039;UCSZ0&#039;&#039;&#039;|| &#039;&#039;&#039;Character Size&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
| 0|| 0|| 0|| 5-Bit&lt;br /&gt;
|- &lt;br /&gt;
| 0|| 0|| 1|| 6-Bit&lt;br /&gt;
|- &lt;br /&gt;
| 0|| 1|| 0|| 7-Bit&lt;br /&gt;
|- &lt;br /&gt;
| 0|| 1|| 1|| 8-Bit&lt;br /&gt;
|- &lt;br /&gt;
| 1|| 0|| 0|| Reserved&lt;br /&gt;
|- &lt;br /&gt;
| 1|| 0|| 1|| Reserved&lt;br /&gt;
|- &lt;br /&gt;
| 1|| 1|| 0|| Reserved&lt;br /&gt;
|- &lt;br /&gt;
| 1|| 1|| 1|| 9-Bit&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;UCPOL&#039;&#039;&#039; (Clock Polarity)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;UDR&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;U&#039;&#039;&#039;ART &#039;&#039;&#039;D&#039;&#039;&#039;ata &#039;&#039;&#039;R&#039;&#039;&#039;egister.&amp;lt;br /&amp;gt;&lt;br /&gt;
Hier werden Daten zwischen UART und CPU übertragen. Da der UART im&lt;br /&gt;
Vollduplexbetrieb gleichzeitig empfangen und senden kann, handelt es sich&lt;br /&gt;
hier physikalisch um 2 Register, die aber über die gleiche I/O-Adresse&lt;br /&gt;
angesprochen werden. Je nachdem, ob ein Lese- oder ein Schreibzugriff auf&lt;br /&gt;
den UART erfolgt wird automatisch das richtige UDR angesprochen.&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;UBRR&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;U&#039;&#039;&#039;ART &#039;&#039;&#039;B&#039;&#039;&#039;aud &#039;&#039;&#039;R&#039;&#039;&#039;ate &#039;&#039;&#039;R&#039;&#039;&#039;egister.&amp;lt;br /&amp;gt;&lt;br /&gt;
In diesem Register müssen wir dem UART mitteilen, wie schnell wir gerne kommunizieren möchten. Der Wert, der in dieses Register geschrieben werden muss, errechnet sich nach folgender Formel (wenn U2X Bit 0 gesetzt ist):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\mathrm{UBRR} = \frac{\mathrm{Taktfrequenz}}{\mathrm{Baudrate} \cdot 16} - 1&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es sind Baudraten bis über 115200 Baud möglich, je nach Controller und CPU-Frequenz. Siehe Datenblatt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== UART initialisieren ==&lt;br /&gt;
&lt;br /&gt;
Wir wollen nun Daten mit dem UART auf die serielle Schnittstelle ausgeben. Dazu müssen wir den UART zuerst mal initialisieren. Dazu setzen wir je nach gewünschter Funktionsweise die benötigten Bits im &#039;&#039;&#039;U&#039;&#039;&#039;ART &#039;&#039;&#039;C&#039;&#039;&#039;ontrol &#039;&#039;&#039;R&#039;&#039;&#039;egister.&lt;br /&gt;
&lt;br /&gt;
Da wir vorerst nur senden möchten und noch keine Interrupts auswerten wollen, gestaltet sich die Initialisierung wirklich sehr einfach, da wir lediglich das &#039;&#039;&#039;Transmitter Enable&#039;&#039;&#039; Bit setzen müssen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  UCSRB |= (1&amp;lt;&amp;lt;TXEN);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Neuere AVRs mit USART haben mehrere Konfigurationsregister und erfordern eine etwas andere Konfiguration. Für einen ATmega16 z.&amp;amp;nbsp;B.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  UCSRB |= (1&amp;lt;&amp;lt;TXEN);                           // UART TX einschalten&lt;br /&gt;
  UCSRC = (1&amp;lt;&amp;lt;URSEL)|(1 &amp;lt;&amp;lt; UCSZ1)|(1 &amp;lt;&amp;lt; UCSZ0); // Asynchron 8N1&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun ist noch das Baudratenregister &#039;&#039;&#039;UBRR&#039;&#039;&#039; der verwendeten UARTs einzustellen, bzw. bei neueren AVRs die beiden Register &#039;&#039;&#039;UBRRL&#039;&#039;&#039; und &#039;&#039;&#039;UBRRH&#039;&#039;&#039;. &amp;lt;!--Der Wert dafür ergibt sich aus der unten angegebenen Formel durch Einsetzen der Taktfrequenz und der gewünschten Übertragungsrate. Das Berechnen der Formel wird dem [[C-Präprozessor|Präprozessor]] überlassen. Dabei ist zu beachten, dass der Präprozessor keine Floating Point Ergebnisse liefert, sondern Integer Ergebnisse. Das bedeutet, dass wenn durch Division auf einen Integer Wert 1.99 zugewiesen wird, 0.99 abgeschnitten werden und das Ergebnis 1.0 ist - obwohl 2.0 viel näher wäre.--&amp;gt;. Die Berechnung wird während des Compilerlaufs ausgeführt, beansprucht also in der gezeigten Form weder Speicher noch Rechenzeit des Controllers. Das Ergebniss wird jedoch als ganzzahliger Wert eingesetzt, d.h. Nachkommastellen werden einfach abgeschnitten und es erfolgt keine Rundung. Aus diesem Grund kann man sich eines kleinen Tricks bedienen, indem vor der eigentlichen Division bei der Zuweisung die Hälfte des Wertes dazu addiert wird. Allgemein formuliert bedeutet das: &amp;lt;code&amp;gt;int i = ( a + b/2 ) / b;&amp;lt;/code&amp;gt;. Dies wird in der unten angegebenen Berechnung von UBRR_VAL ausgenutzt um den Fehler zu minimieren. (Eine ausführliche Erklärung zum &#039;&#039;cleveren Runden&#039;&#039; findet sich in einer [http://www.mikrocontroller.net/topic/170617#1631916 Forumsdiskussion].) &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/* &lt;br /&gt;
  UART-Init: &lt;br /&gt;
Berechnung des Wertes für das Baudratenregister &lt;br /&gt;
aus Taktrate und gewünschter Baudrate&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
/* In neueren Version der WinAVR/Mfile Makefile-Vorlage kann&lt;br /&gt;
   F_CPU im Makefile definiert werden, eine nochmalige Definition&lt;br /&gt;
   hier wuerde zu einer Compilerwarnung fuehren. Daher &amp;quot;Schutz&amp;quot; durch&lt;br /&gt;
   #ifndef/#endif &lt;br /&gt;
&lt;br /&gt;
   Dieser &amp;quot;Schutz&amp;quot; kann zu Debugsessions führen, wenn AVRStudio &lt;br /&gt;
   verwendet wird und dort eine andere, nicht zur Hardware passende &lt;br /&gt;
   Taktrate eingestellt ist: Dann wird die folgende Definition &lt;br /&gt;
   nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?) &lt;br /&gt;
   von AVRStudio - daher Ausgabe einer Warnung falls F_CPU&lt;br /&gt;
   noch nicht definiert: */&lt;br /&gt;
#warning &amp;quot;F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000&amp;quot;&lt;br /&gt;
#define F_CPU 4000000UL  // Systemtakt in Hz - Definition als unsigned long beachten &lt;br /&gt;
                         // Ohne ergeben sich unten Fehler in der Berechnung&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#define BAUD 9600UL      // Baudrate&lt;br /&gt;
&lt;br /&gt;
// Berechnungen&lt;br /&gt;
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden&lt;br /&gt;
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate&lt;br /&gt;
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.&lt;br /&gt;
&lt;br /&gt;
#if ((BAUD_ERROR&amp;lt;990) || (BAUD_ERROR&amp;gt;1010))&lt;br /&gt;
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! &lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Makros sind sehr praktisch, da damit sowohl automatisch der Wert für UBRR, als auch die Abweichung in der generierten (möglichen) von der gewünschten Baudrate berechnet wird. Im Falle einer zu hohen Abweichung (+/-1%) wird eine Fehlermeldung ausgegeben und der Compilerablauf abgebrochen. Damit können viele Probleme mit &amp;quot;UART sendet komische Zeichen&amp;quot; vermieden werden. Ausserdem kann man mühelos die Einstellung an eine neue Taktfrequenz bzw. Baudrate anpassen, ohne selber rechnen oder in Tabellen nachschlagen zu müssen.&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Initialisierung der UART Register kann im Hauptprogramm main() vorgenommen werden. Öfters wird jedoch eine Funktion z.&amp;amp;nbsp;B. uart_init() dafür geschrieben, die in der eigenen Codesammlung in mehreren Projekten verwendet werden kann.&lt;br /&gt;
&lt;br /&gt;
Für einige AVR (z.&amp;amp;nbsp;B. ATmega169, ATmega48/88/168, AT90CAN jedoch nicht für z.&amp;amp;nbsp;B. ATmega16/32, ATmega128, ATtiny2313) wird durch die Registerdefinitionen der avr-libc (io*.h) auch für Controller mit zwei UBRR-Registern (UBRRL/UBRRH) ein UBRR bzw. UBRR0 als &amp;quot;16-bit-Register&amp;quot; definiert und man kann den Wert direkt per UBRR = UBRR_VAL zuweisen. Intern werden dann zwei Zuweisungen für UBRRH und UBRRL generiert. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/* UART-Init Bsp. ATmega48 */&lt;br /&gt;
&lt;br /&gt;
void uart_init(void)&lt;br /&gt;
{&lt;br /&gt;
  UBRR0 = UBRR_VAL;&lt;br /&gt;
  UCSR0B |= (1&amp;lt;&amp;lt;TXEN0);&lt;br /&gt;
  // Frame Format: Asynchron 8N1&lt;br /&gt;
  UCSR0C = (1&amp;lt;&amp;lt;UCSZ01)|(1&amp;lt;&amp;lt;UCSZ00);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die einzelne Anweisung ist nicht bei allen Controllern möglich, da die beiden Register nicht bei allen aufeinanderfolgende Addressen aufweisen. Die getrennte Zuweisung an UBRRH und UBRRL wie im nächsten Beispiel gezeigt, ist universeller und portabler und daher vorzuziehen. Wichtig ist, dass UBRRH &#039;&#039;&#039;vor&#039;&#039;&#039; UBRRL geschrieben wird:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/* UART-Init Bsp. ATmega16 */&lt;br /&gt;
&lt;br /&gt;
void uart_init(void)&lt;br /&gt;
{&lt;br /&gt;
  UBRRH = UBRR_VAL &amp;gt;&amp;gt; 8;&lt;br /&gt;
  UBRRL = UBRR_VAL &amp;amp; 0xFF;&lt;br /&gt;
&lt;br /&gt;
  UCSRB |= (1&amp;lt;&amp;lt;TXEN);  // UART TX einschalten&lt;br /&gt;
  UCSRC = (1&amp;lt;&amp;lt;URSEL)|(1&amp;lt;&amp;lt;UCSZ1)|(1&amp;lt;&amp;lt;UCSZ0);  // Asynchron 8N1 &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inzwischen gibt es in der avr-libc Makros für obige Berechnung der UBRR Registerwerte aus Taktrate F_CPU und Baudrate BAUD. Dazu wird die Includedatei  [http://www.nongnu.org/avr-libc/user-manual/group__util__setbaud.html &amp;lt;util/setbaud.h&amp;gt;] eingebunden, nachdem F_CPU und die gewünschte Baudrate definiert wurden. Einige Beispiele zur Anwendung finden sich in der Dokumentation der avr-libc. Im Quellcode kann dann analog zur oben gezeigten Vorgehensweise einfach das Makro UBRR_VALUE (bzw. UBRRH_VALUE und UBRRL_VALUE) an der entsprechenden Stelle eingesetzt werden. Es wird auch automatisch ermittelt, ob der U2X-Modus (vgl. Datenblatt) zu geringeren Abweichungen führt und dann dem Makro USE_U2X ein Wert ungleich null zugewiesen. Ein Beispiel (angelehnt an die avr-libc-Dokumentation):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt; &lt;br /&gt;
#define F_CPU 1000000 /* evtl. bereits via Compilerparameter definiert */&lt;br /&gt;
#define BAUD 9600&lt;br /&gt;
#include &amp;lt;util/setbaud.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void uart_init(void)   &lt;br /&gt;
{&lt;br /&gt;
   UBRRH = UBRRH_VALUE;&lt;br /&gt;
   UBRRL = UBRRL_VALUE;&lt;br /&gt;
   /* evtl. verkuerzt falls Register aufeinanderfolgen (vgl. Datenblatt)&lt;br /&gt;
      UBRR = UBRR_VALUE;&lt;br /&gt;
   */&lt;br /&gt;
#if USE_2X&lt;br /&gt;
   /* U2X-Modus erforderlich */&lt;br /&gt;
   UCSRA |= (1 &amp;lt;&amp;lt; U2X);&lt;br /&gt;
#else&lt;br /&gt;
   /* U2X-Modus nicht erforderlich */&lt;br /&gt;
   UCSRA &amp;amp;= ~(1 &amp;lt;&amp;lt; U2X);&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
   // hier weitere Initialisierungen (TX und/oder RX aktivieren, Modus setzen &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/group__util__setbaud.html Dokumentation der avr-libc zu &amp;lt;util/setbaud.h&amp;gt;]&lt;br /&gt;
* [http://www.wormfood.net/avrbaudcalc.php WormFood&#039;s AVR Baud Rate Calculator] online.&lt;br /&gt;
* [http://www.gjlay.de/helferlein/avr-uart-rechner.html AVR Baudraten-Rechner] in JavaScript&lt;br /&gt;
&lt;br /&gt;
== Senden mit dem UART ==&lt;br /&gt;
&lt;br /&gt;
=== Senden einzelner Zeichen ===&lt;br /&gt;
&lt;br /&gt;
Um nun ein Zeichen auf die Schnittstelle auszugeben, müssen wir dasselbe&lt;br /&gt;
lediglich in das &#039;&#039;&#039;U&#039;&#039;&#039;ART &#039;&#039;&#039;D&#039;&#039;&#039;ata &#039;&#039;&#039;R&#039;&#039;&#039;egister schreiben. Vorher ist zu prüfen, ob das UART-Modul bereit ist, das zu sendende Zeichen entgegenzunehmen. Die Bezeichnungen des/der Statusregisters mit dem Bit UDRE ist abhängig vom Controllertypen (vgl. Datenblatt).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// bei neueren AVRs steht der Status in UCSRA/UCSR0A/UCSR1A, hier z.B. fuer ATmega16:&lt;br /&gt;
    while (!(UCSRA &amp;amp; (1&amp;lt;&amp;lt;UDRE)))  /* warten bis Senden moeglich                   */&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    UDR = &#039;x&#039;;                    /* schreibt das Zeichen x auf die Schnittstelle */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Schreiben einer Zeichenkette (String) ===&lt;br /&gt;
&lt;br /&gt;
Die Aufgabe &amp;quot;String senden&amp;quot; wird durch zwei Funktionen abgearbeitet. Die universelle/controllerunabhängige Funktion uart_puts übergibt jeweils ein Zeichen der Zeichenkette an eine Funktion uart_putc, die abhängig von der vorhandenen Hardware implementiert werden muss. In der Funktion zum Senden eines Zeichens ist darauf zu achten, dass vor dem Senden geprüft wird, ob der UART bereit ist den &amp;quot;Sendeauftrag&amp;quot; entgegenzunehmen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/* ATmega16 */&lt;br /&gt;
int uart_putc(unsigned char c)&lt;br /&gt;
{&lt;br /&gt;
    while (!(UCSRA &amp;amp; (1&amp;lt;&amp;lt;UDRE)))  /* warten bis Senden moeglich */&lt;br /&gt;
    {&lt;br /&gt;
    }                             &lt;br /&gt;
&lt;br /&gt;
    UDR = c;                      /* sende Zeichen */&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* puts ist unabhaengig vom Controllertyp */&lt;br /&gt;
void uart_puts (char *s)&lt;br /&gt;
{&lt;br /&gt;
    while (*s)&lt;br /&gt;
    {   /* so lange *s != &#039;\0&#039; also ungleich dem &amp;quot;String-Endezeichen(Terminator)&amp;quot; */&lt;br /&gt;
        uart_putc(*s);&lt;br /&gt;
        s++;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die in uart_putc verwendeten Schleifen, in denen gewartet wird bis die UART-Hardware zum senden bereit ist, sind insofern etwas kritisch, da während des Sendens eines Strings nicht mehr auf andere Ereignisse reagiert werden kann. Universeller ist die Nutzung von FIFO(first-in first-out)-Puffern, in denen die zu sendenden bzw. empfangenen Zeichen/Bytes zwischengespeichert und in Interruptroutinen an die U(S)ART-Hardware weitergegeben bzw. von ihr ausgelesen werden. Dazu existieren fertige Komponenten (Bibliotheken, Libraries), die man recht einfach in eigene Entwicklungen integrieren kann. Es empfiehlt sich, diese Komponenten zu nutzen und das Rad nicht neu zu erfinden.&lt;br /&gt;
&lt;br /&gt;
=== Schreiben von Variableninhalten ===&lt;br /&gt;
&lt;br /&gt;
Sollen Inhalte von Variablen (Ganzzahlen, Gleitkomma) in &amp;quot;menschenlesbarer&amp;quot; Form gesendet werden, ist vor dem Transfer eine Umwandlung in Zeichen (&amp;quot;ASCII&amp;quot;) erforderlich. Bei nur einer Ziffer ist diese Umwandlung relativ einfach: man addiert den ASCII-Wert von Null zur Ziffer und kann diesen Wert direkt senden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
// hier uart_putc (s.o.)&lt;br /&gt;
&lt;br /&gt;
int main (void) &lt;br /&gt;
{&lt;br /&gt;
   // Ausgabe von 0123456789&lt;br /&gt;
   char c;&lt;br /&gt;
&lt;br /&gt;
   uart_init();&lt;br /&gt;
&lt;br /&gt;
   for (uint8_t i=0; i&amp;lt;=9; ++i) {&lt;br /&gt;
      c = i + &#039;0&#039;;&lt;br /&gt;
      uart_putc( c );&lt;br /&gt;
      // verkuerzt: uart_putc( i + &#039;0&#039; );&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   while (1) {&lt;br /&gt;
      ;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   return 0; // never reached &lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Soll mehr als eine Ziffer ausgegeben werden, bedient man sich zweckmäßigerweise vorhandener Funktionen zur Umwandlung von Zahlen in Zeichenketten/Strings. Die Funktion der avr-libc zur Umwandlung von vorzeichenbehafteten 16bit-Ganzzahlen (int16_t) in Zeichenketten heißt &#039;&#039;itoa&#039;&#039; (Integer to ASCII). Man muss der Funktion einen Speicherbereich zur Verarbeitung (buffer) mit Platz für alle Ziffern, das String-Endezeichen (&#039;\0&#039;) und evtl. das Vorzeichen bereitstellen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
// hier uart_init, uart_putc, uart_puts (s.o.)&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
   char s[7];&lt;br /&gt;
   int16_t i = -12345;&lt;br /&gt;
   &lt;br /&gt;
   uart_init();&lt;br /&gt;
&lt;br /&gt;
   itoa( i, s, 10 ); // 10 fuer radix -&amp;gt; Dezimalsystem&lt;br /&gt;
   uart_puts( s );&lt;br /&gt;
&lt;br /&gt;
   // da itoa einen Zeiger auf den Beginn von s zurueckgibt verkuerzt auch:&lt;br /&gt;
   uart_puts( itoa( i, s, 10 ) );&lt;br /&gt;
&lt;br /&gt;
   while (1) {&lt;br /&gt;
      ;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return 0; // never reached &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für vorzeichenlose 16bit-Ganzzahlen (uint16_t) exisitert &#039;&#039;utoa&#039;&#039;. Die Funktionen für 32bit-Ganzzahlen (int32_t und uint32_t) heißen &#039;&#039;ltoa&#039;&#039; bzw. &#039;&#039;ultoa&#039;&#039;. Da 32bit-Ganzzahlen mehr Stellen aufweisen können, ist ein entsprechend größerer Pufferspeicher vorzusehen.&lt;br /&gt;
&lt;br /&gt;
Auch Gleitkommazahlen (float/double) können mit bereits vorhandenen Funktionen in Zeichenfolgen umgewandelt werden, dazu existieren die Funktionen &#039;&#039;dtostre&#039;&#039; und &#039;&#039;dtostrf&#039;&#039;. dtostre nutzt Exponentialschreibweise (&amp;quot;engineering&amp;quot;-Format). (Hinweis: z.Zt. existiert im avr-gcc kein &amp;quot;echtes&amp;quot; double, intern wird immer mit &amp;quot;einfacher Genauigkeit&amp;quot;, entsprechend float, gerechnet.) &lt;br /&gt;
&lt;br /&gt;
dtostrf und dtostre benötigen die libm.a der avr-libc. Bei Nutzung von Makefiles ist der Parameter -lm in in LDFLAGS anzugeben (Standard in den WinAVR/mfile-Makefilevorlagen). Nutzt man AVRStudio als IDE für den GNU-Compiler (gcc-Plugin) ist die libm.a unter Libaries auszuwählen: Project -&amp;gt; Configurations Options -&amp;gt; Libaries -&amp;gt; libm.a mit dem Pfeil nach rechts einbinden. Siehe auch die [[FAQ#Aktivieren_der_Floating_Point_Version_von_sprintf_beim_WinAVR_mit_AVR-Studio|FAQ]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
// hier uart_init, uart_putc, uart_puts (s.o.)&lt;br /&gt;
&lt;br /&gt;
/* lt. avr-libc Dokumentation:&lt;br /&gt;
char* dtostrf(&lt;br /&gt;
  double __val,&lt;br /&gt;
  char   __width,&lt;br /&gt;
  char   __prec,&lt;br /&gt;
  char * __s&lt;br /&gt;
)  &lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
   // Pufferspeicher ausreichend groß&lt;br /&gt;
   // evtl. Vorzeichen + width + Endezeichen:&lt;br /&gt;
   char s[8]; &lt;br /&gt;
   float f = -12.345;&lt;br /&gt;
   &lt;br /&gt;
   uart_init();&lt;br /&gt;
&lt;br /&gt;
   dtostrf( f, 6, 3, s ); &lt;br /&gt;
   uart_puts( s );&lt;br /&gt;
   // verkürzt: uart_puts( dtostrf( f, 7, 3, s ) );&lt;br /&gt;
&lt;br /&gt;
   while (1) {&lt;br /&gt;
      ;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return 0; // never reached &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Empfangen ==&lt;br /&gt;
=== Einzelne Zeichen empfangen ===&lt;br /&gt;
&lt;br /&gt;
Zum Empfang von Zeichen muss der Empfangsteil des UART bei der Initialisierung aktiviert werden, indem das RXEN-Bit im jeweiligen Konfigurationsregister (UCSRB bzw UCSR0B/UCSR1B) gesetzt wird. Im einfachsten Fall wird solange gewartet, bis ein Zeichen empfangen wurde, dieses steht dann im UART-Datenregister (UDR bzw. UDR0 und UDR1 bei AVRs mit 2 UARTS) zur Verfügung (sogen. &amp;quot;Polling-Betrieb&amp;quot;). Ein Beispiel für den ATmega16:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;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;
&lt;br /&gt;
/* Siehe auch obere Baudrateneinstellung */&lt;br /&gt;
/* USART-Init beim ATmega16 */&lt;br /&gt;
&lt;br /&gt;
void uart_init(void)&lt;br /&gt;
{&lt;br /&gt;
    UBRRH = UBRR_VAL &amp;gt;&amp;gt; 8;&lt;br /&gt;
    UBRRL = UBRR_VAL &amp;amp; 0xFF;&lt;br /&gt;
&lt;br /&gt;
    UCSRC = (1&amp;lt;&amp;lt;URSEL)|(1&amp;lt;&amp;lt;UCSZ1)|(1&amp;lt;&amp;lt;UCSZ0);  // Asynchron 8N1 &lt;br /&gt;
    UCSRB |= (1&amp;lt;&amp;lt;RXEN);                        // UART RX einschalten&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Zeichen empfangen */&lt;br /&gt;
uint8_t uart_getc(void)&lt;br /&gt;
{&lt;br /&gt;
    while (!(UCSRA &amp;amp; (1&amp;lt;&amp;lt;RXC)))   // warten bis Zeichen verfuegbar&lt;br /&gt;
        ;&lt;br /&gt;
    return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Und die Anwendung in einem Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// hier Makro für die Baudratenberechnung &lt;br /&gt;
&lt;br /&gt;
// hier uart_init, uart_getc (s.o.)&lt;br /&gt;
 &lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  uart_init();&lt;br /&gt;
  while (1) &lt;br /&gt;
  {&lt;br /&gt;
    uint8_t c;&lt;br /&gt;
    c = uart_getc();&lt;br /&gt;
&lt;br /&gt;
    // hier etwas mit c machen z.B. auf PORT ausgeben&lt;br /&gt;
    DDRC = 0xFF; // PORTC Ausgang&lt;br /&gt;
    PORTC = c;&lt;br /&gt;
  }&lt;br /&gt;
  return 0; // never reached &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Funktion uart_getc() blockiert allerdings den Programmablauf, denn es wird gewartet, bis ein Zeichen empfangen wird! Möchte man das Warten vermeiden, kann das RXC-Bit in einer Programmschleife abgefragt werden und dann nur bei gesetztem RXC-Bit UDR ausgelesen werden. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// hier Makro für die Baudratenberechnung &lt;br /&gt;
&lt;br /&gt;
// hier uart_init, uart_getc (s.o.)&lt;br /&gt;
 &lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  uart_init();&lt;br /&gt;
  while (1) &lt;br /&gt;
  {&lt;br /&gt;
    if ( (UCSRA &amp;amp; (1&amp;lt;&amp;lt;RXC)) )&lt;br /&gt;
    {&lt;br /&gt;
      // Zeichen wurde empfangen, jetzt abholen&lt;br /&gt;
      uint8_t c;&lt;br /&gt;
      c = uart_getc();&lt;br /&gt;
      // hier etwas mit c machen z.B. auf PORT ausgeben&lt;br /&gt;
      DDRC = 0xFF; // PORTC Ausgang&lt;br /&gt;
      PORTC = c;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
      // Kein Zeichen empfangen, Restprogramm ausführen...&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  return 0; // never reached &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eleganter und in den meisten Anwendungsfällen &amp;quot;stabiler&amp;quot; ist die Vorgehensweise, die empfangenen Zeichen in einer Interrupt-Routine einzulesen und zur späteren Verarbeitung in einem Eingangsbuffer (FIFO-Buffer) zwischenzuspeichern. Dazu existieren fertige und gut getestete [[Libraries|Bibliotheken]] &amp;lt;!-- &amp;quot;echte Libraries&amp;quot; (.a) wie im Verweis beschrieben sind hier eigentlich nicht gemeint, verwirrt hier etwas, da AVR-&amp;quot;Libraries&amp;quot; meist per #defines anpassbare Source-Codes sind, vielleicht so: --&amp;gt; und Quellcodekomponenten (z.&amp;amp;nbsp;B. UART-Library von P. Fleury, procyon-avrlib und einige in der &amp;quot;Academy&amp;quot; von avrfreaks.net).&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html Dokumenation der avr-libc/stdlib.h]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Die_Nutzung_von_sprintf_und_printf Die Nutzung von sprintf und printf]&lt;br /&gt;
* [http://homepage.hispeed.ch/peterfleury/ Peter Fleurys] UART-Bibiliothek fuer avr-gcc/avr-libc&lt;br /&gt;
&amp;lt;!-- nimmermehr: * siehe auch: Weiterführende Informationen inkl. Beispielen für die Nutzung von stdio-Funktionen (printf etc.) im [[AVR-Tutorial:_UART]]. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TODO: 9bit&lt;br /&gt;
&lt;br /&gt;
=== Empfang von Zeichenketten (Strings) ===&lt;br /&gt;
&lt;br /&gt;
Beim Empfang von Zeichenketten, muß man sich zunächst darüber im klaren sein, daß es ein Kriterium geben muß, an dem der µC erkennen kann, wann ein Text zu Ende ist. Sehr oft wird dazu das Zeichen &#039;Return&#039; benutzt, um das Ende eines Textes zu markieren. Dies ist vom Benutzer einfach eingebbar und er ist auch daran gewöhnt, daß er eine Eingabezeile mit einem Druck auf die Return Taste abgeschlossen wird.&lt;br /&gt;
&lt;br /&gt;
Prinzipiell gibt es jedoch keine Einschränkung bezüglich dieses speziellen Zeichens. Es muß nur sichergestellt werden, daß dieses spezielle &#039;Ende eines Strings&#039; - Zeichen nicht mit einem im Text vorkommenden Zeichen verwechselt werden kann. Wenn also im zu übertragenden Text beispielsweise kein &#039;;&#039; vorkommt, dann spricht nichts dagegen, den Benutzer die Eingabe eines Textes mit einem &#039;;&#039; abschließen zu lassen.&lt;br /&gt;
&lt;br /&gt;
Im Folgenden wird die durchaus übliche Annahme getroffen, daß eine Stringübertragung identisch ist mit der Übertragung einer Textzeile und daher mit einem Return (&#039;\n&#039;) abgeschlossen wird.&lt;br /&gt;
&lt;br /&gt;
Das Problem der Übertragung eines Strings reduziert sich damit auf die Aufgabenstellung: Empfange und sammle Zeichen in einem char Array, bis entweder das Array voll ist oder das Text Ende Zeichen&#039; empfangen wurde. Danach wird der empfangene Text noch mit einem &#039;\0&#039; Zeichen abgeschlossen um einen Standard C-String daraus zu machen, mit dem dann weiter gearbeitet werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
/* Zeichen empfangen */&lt;br /&gt;
uint8_t uart_getc(void)&lt;br /&gt;
{&lt;br /&gt;
    while (!(UCSRA &amp;amp; (1&amp;lt;&amp;lt;RXC)))   // warten bis Zeichen verfuegbar&lt;br /&gt;
        ;&lt;br /&gt;
    return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void uart_gets( char* Buffer, uint8_t MaxLen )&lt;br /&gt;
{&lt;br /&gt;
  uint8_t NextChar;&lt;br /&gt;
  uint8_t StringLen = 0;&lt;br /&gt;
&lt;br /&gt;
  NextChar = uart_getc();         // Warte auf und empfange das nächste Zeichen&lt;br /&gt;
&lt;br /&gt;
                                  // Sammle solange Zeichen, bis:&lt;br /&gt;
                                  // * entweder das String Ende Zeichen kam&lt;br /&gt;
                                  // * oder das aufnehmende Array voll ist&lt;br /&gt;
  while( NextChar != &#039;\n&#039; &amp;amp;&amp;amp; StringLen &amp;lt; MaxLen - 1 ) {&lt;br /&gt;
    *Buffer++ = NextChar;&lt;br /&gt;
    StringLen++;&lt;br /&gt;
    NextChar = uart_getc();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
                                  // Noch ein &#039;\0&#039; anhängen um einen Standard&lt;br /&gt;
                                  // C-String daraus zu machen&lt;br /&gt;
  *Buffer = &#039;\0&#039;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beim Aufruf ist darauf zu achten, dass das empfangende Array auch mit einer&lt;br /&gt;
vernünftigen Größe definiert wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  char Line[40];      // String mit maximal 39 zeichen&lt;br /&gt;
&lt;br /&gt;
  uart_gets( Line, sizeof( Line ) );&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei der Benutzung von sizeof() ist allerdings zu beachten, dass sizeof() nicht die Anzahl der Elemente des Arrays liefert, sondern die Länge in Byte. Da ein char nur ein Byte lang ist, passt der Aufruf &#039;uart_gets(Line, sizeof( Line ) );&#039; in diesem Fall. Falls man - aus welchen Gründen auch immer - andere Datentypen benutzen möchte, sollte man zur korrekten Angabe der Array-Länge folgende Vorgehensweise bevorzugen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
  int Line[40];      // Array vom Typ int&lt;br /&gt;
&lt;br /&gt;
  uart_gets( Line, sizeof( Line ) / sizeof( Line[0] ) );&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Interruptbetrieb==&lt;br /&gt;
&lt;br /&gt;
Hier wird das Grundwissen des Artikels [[Interrupt]] und des Abschnitts [[AVR-GCC-Tutorial#Programmieren_mit_Interrupts|AVR-GCC-Tutorial: Programmieren_mit_Interrupts]] vorausgesetzt.&lt;br /&gt;
&lt;br /&gt;
=== Empfangen (RX) ===&lt;br /&gt;
&lt;br /&gt;
Beim ATmega8 muss das &#039;&#039;&#039;RXCIE&#039;&#039;&#039; Bit im Register UCSRB gesetzt werden, damit ein Interrupt beim Empfang eines Zeichens ausgelöst werden kann.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/* siehe auch obere Baudrateneinstellung */&lt;br /&gt;
/* USART-Init beim ATmega16 */&lt;br /&gt;
void uart_init(void)&lt;br /&gt;
{&lt;br /&gt;
  UBRRH = UBRR_VAL &amp;gt;&amp;gt; 8;&lt;br /&gt;
  UBRRL = UBRR_VAL &amp;amp; 0xFF;&lt;br /&gt;
  UCSRC = (1&amp;lt;&amp;lt;URSEL)|(1&amp;lt;&amp;lt;UCSZ1)|(1&amp;lt;&amp;lt;UCSZ0); // Asynchron 8N1 &lt;br /&gt;
  UCSRB |= (1&amp;lt;&amp;lt;RXEN)|(1&amp;lt;&amp;lt;TXEN)|(1&amp;lt;&amp;lt;RXCIE);  // UART RX, TX und RX Interrupt einschalten&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Natürlich muss &amp;quot;Global Interrupt Enable&amp;quot; mittels des Befehls sei() aktiviert sein. Interrupt-spezifische Definitionen werden über die Includedatei eingebunden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Interrupt wird immer ausgelöst, wenn ein Zeichen erfolgreich empfangen wurde. Zusätzlich braucht man die Interruptserviceroutine (ISR). &lt;br /&gt;
&lt;br /&gt;
In diesem Beispiel enthält die ISR einen FIFO-Puffer (First in, First out). Dafür werden ein paar globale Variablen und Makros benötigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#define UART_MAXSTRLEN 10&lt;br /&gt;
&lt;br /&gt;
volatile uint8_t uart_str_complete = 0;     // 1 .. String komplett empfangen&lt;br /&gt;
volatile uint8_t uart_str_count = 0;&lt;br /&gt;
volatile char uart_string[UART_MAXSTRLEN + 1] = &amp;quot;&amp;quot;;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
ISR(USART_RXC_vect)&lt;br /&gt;
{&lt;br /&gt;
  unsigned char nextChar;&lt;br /&gt;
&lt;br /&gt;
  // Daten aus dem Puffer lesen&lt;br /&gt;
  nextChar = UDR;&lt;br /&gt;
  if( uart_str_complete == 0 ) {	// wenn uart_string gerade in Verwendung, neues Zeichen verwerfen&lt;br /&gt;
&lt;br /&gt;
    // Daten werden erst in uart_string geschrieben, wenn nicht String-Ende/max Zeichenlänge erreicht ist/string gerade verarbeitet wird&lt;br /&gt;
    if( nextChar != &#039;\n&#039; &amp;amp;&amp;amp;&lt;br /&gt;
        nextChar != &#039;\r&#039; &amp;amp;&amp;amp;&lt;br /&gt;
        uart_str_count &amp;lt; UART_MAXSTRLEN ) {&lt;br /&gt;
      uart_string[uart_str_count] = nextChar;&lt;br /&gt;
      uart_str_count++;&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
      uart_string[uart_str_count] = &#039;\0&#039;;&lt;br /&gt;
      uart_str_count = 0;&lt;br /&gt;
      uart_str_complete = 1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zur Funktion: Wurde eine komplette Zeichenkette empfangen, also das Ende (\n oder \r) erkannt oder die maximale Länge &#039;&#039;UART_MAXSTRLEN&#039;&#039; erreicht, wird die globale Variable &#039;&#039;uart_str_complete&#039;&#039; auf &#039;1&#039; gesetzt. Damit wird dem Hauptprogramm, welches auf diese Variable pollt, mitgeteilt, dass die Zeichenkette &#039;&#039;uart_string&#039;&#039; zur Verarbeitung bereit steht. Nach der Verarbeitung der Zeichenkette in der entsprechenden main-Routine, muss die Variable &#039;&#039;uart_str_complete&#039;&#039; wieder auf &#039;0&#039; zurück gesetzt werden. Dadurch werden alle neu empfangenen Zeichen wieder in den globalen Puffer geschrieben.&lt;br /&gt;
&lt;br /&gt;
=== (Baustelle) ===&lt;br /&gt;
&lt;br /&gt;
* Empfangen (Receive) (Anm.: z.T. erledigt)&lt;br /&gt;
** ggf. Fallstricke ([http://www.mikrocontroller.net/topic/84256#707214 UDR in der ISR lesen!])&lt;br /&gt;
** Komplettes, einfaches Beispiel ([http://www.mikrocontroller.net/topic/84228#707052 Echo] (noch buggy beim Datenzugriff, siehe Lit. 2+3!)), ggf. LED zur ISR-Empfangsanzeige oder Overflow-Anzeige&lt;br /&gt;
&lt;br /&gt;
* Senden (Transmit)&lt;br /&gt;
** Variante &amp;quot;UART Data Register Empty&amp;quot; (UDRE) [http://www.mikrocontroller.net/topic/101472#882716]&lt;br /&gt;
** Variante &amp;quot;UART Transmit Complete&amp;quot; (TXC) &lt;br /&gt;
&lt;br /&gt;
* FIFO-Puffer [http://www.mikrocontroller.net/topic/101472#882716], Ringpuffer (Byte Buffering (circular))&lt;br /&gt;
&lt;br /&gt;
* UART-Bibliotheken &lt;br /&gt;
** [http://homepage.hispeed.ch/peterfleury/avr-software.html UART-Library] von Peter Fleury (UART (interrupt driven), Byte Buffering (circular))&lt;br /&gt;
** [http://beaststwo.org/avr-uart/index.shtml Updated AVR UART Library]  (modernisierte und erweiterte Version der Bibliothek von Peter Fleury)&lt;br /&gt;
** [http://www.procyonengineering.com/embedded/avr/avrlib/ Procyon AVRlib] von Pascal Stang (UART (interrupt driven), Byte Buffering (circular), VT100 Terminal Output)&lt;br /&gt;
&lt;br /&gt;
* Literatur &lt;br /&gt;
** [http://www.avrfreaks.net/index.php?name=PNphpBB2&amp;amp;file=viewtopic&amp;amp;t=48188 avrfreaks.net Tutorial] inkl. Diskussion (engl.)&lt;br /&gt;
** avr-libc FAQ: [http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_16bitio Why do some 16-bit timer registers sometimes get trashed?]&lt;br /&gt;
&lt;br /&gt;
==Software-UART==&lt;br /&gt;
&lt;br /&gt;
Falls die Zahl der vorhandenen Hardware-UARTs nicht ausreicht, können weitere Schnittstellen über sogennante Software-UARTs ergänzt werden. Es gibt dazu (mindestens) zwei Ansätze: &lt;br /&gt;
* Der bei AVRs üblichste Ansatz basiert auf dem Prinzip, dass ein externer Interrupt-Pin für den Empfang (&amp;quot;RX&amp;quot;) genutzt wird. Das Startbit löst den Interrupt aus, in der Interrupt-Routine (ISR) wird der externe Interrupt deaktiviert und ein Timer aktiviert. In der Interrupt-Routine des Timers wird der Zustand des Empfangs-Pins entsprechend der Baudrate abgetastet. Nach Empfang des Stop-Bits wird der externe Interrupt wieder aktiviert. Senden kann über einen beliebigen Pin (&amp;quot;TX&amp;quot;) erfolgen, der entsprechend der Baudrate und dem zu sendenden Zeichen auf 0 oder 1 gesetzt wird. Die Implementierung ist nicht ganz einfach, es existieren dazu aber fertige Bibliotheken (z.&amp;amp;nbsp;B. bei [http://www.avrfreaks.net/ avrfreaks] oder in der [http://www.procyonengineering.com/embedded/avr/avrlib/ Procyon avrlib]).&lt;br /&gt;
* Ein weiterer Ansatz erfordert keinen Pin mit &amp;quot;Interrupt-Funktion&amp;quot; aber benötigt mehr Rechenzeit. Jeder Input-Pin kann als Empfangspin (RX) dienen. Über einen Timer wird der Zustand des RX-Pins mit einem vielfachen der Baudrate abgetastet (dreifach scheint üblich) und High- bzw. Lowbits anhand einer Mindestanzahl identifiziert. (Beispiel: &amp;quot;Generic Software Uart&amp;quot; Application-Note von IAR)&lt;br /&gt;
&lt;br /&gt;
Neuere AVRs (z.&amp;amp;nbsp;B. ATtiny26 oder ATmega48,88,168,169) verfügen über ein Universal Serial Interface (USI), das teilweise UART-Funktion übernehmen kann. Atmel stellt eine Application-Note bereit, in der die Nutzung des USI als UART erläutert wird (im Prinzip &amp;quot;Hardware-unterstützter Software-UART&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
==Handshaking==&lt;br /&gt;
Wenn der Sender ständig sendet, wird irgendwann der Fall eintreten, daß der Empfänger nicht bereit ist, neue Zeichen zu empfangen. In diesem Fall muß durch ein &#039;&#039;&#039;Handshake-Verfahren&#039;&#039;&#039; die Situation bereinigt werden. Handshake bedeutet nichts anderes, als daß der Empfänger dem Sender mitteilt, daß er zur Zeit keine Daten annehmen kann und der Sender die Übertragung der nächsten Zeichen solange einstellen soll, bis der Empfänger signalisiert, daß er wieder Zeichen aufnehmen kann.&lt;br /&gt;
===Hardwarehandshake (RTS/CTS)===&lt;br /&gt;
Beim Hardwarehandshake werden zusätzlich zu den beiden Daten-Übertragungsleitungen noch 2 weitere Leitungen benötigt: &#039;&#039;&#039;RTS&#039;&#039;&#039; (&#039;&#039;&#039;R&#039;&#039;&#039;equest &#039;&#039;&#039;T&#039;&#039;&#039;o &#039;&#039;&#039;S&#039;&#039;&#039;end) und &#039;&#039;&#039;CTS&#039;&#039;&#039; (&#039;&#039;&#039;C&#039;&#039;&#039;lear &#039;&#039;&#039;T&#039;&#039;&#039;o &#039;&#039;&#039;S&#039;&#039;&#039;end). Jeder der beiden Kommunikationspartner ist verpflichtet, bevor ein Zeichen gesendet wird, den Zustand der &#039;&#039;&#039;RTS&#039;&#039;&#039; Leitung zu überprüfen. Nur wenn die Gegenstelle darauf Empfangsbereitschaft signalisiert, darf das Zeichen gesendet werden. Um der Gegenstelle zu signalisieren, daß sie zur Zeit keine Zeichen schicken soll, wird die Leitung &#039;&#039;&#039;CTS&#039;&#039;&#039; benutzt.&lt;br /&gt;
&lt;br /&gt;
===Softwarehandshake (XON/XOFF)===&lt;br /&gt;
Beim Softwarehandshake sind keine speziellen Leitungen notwendig. Stattdessen werden besondere ASCII-Zeichen benutzt, die der Gegenstelle signalisieren, das Senden einzustellen bzw. wieder aufzunehmen.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;XOFF&#039;&#039;&#039; Aufforderung das Senden einzustellen&lt;br /&gt;
* &#039;&#039;&#039;XON&#039;&#039;&#039;  Gegenstelle darf wieder senden&lt;br /&gt;
&lt;br /&gt;
Nachteilig bei einem Softwarehandshake ist, dass dadurch keine direkte binäre Datenübertragung mehr möglich ist, denn von den möglichen 256 Bytewerten werden ja nun zwei (nämlich für &#039;&#039;&#039;XON&#039;&#039;&#039; und für &#039;&#039;&#039;XOFF&#039;&#039;&#039;) für besondere Zwecke benutzt und fallen daher aus. In einem quasi-zufälligen Bytestrom, den eine Binärdatei darstellt, kämen diese beiden reservierten früher oder später vor und würden dann den Strom ungewollt stoppen und starten.&lt;br /&gt;
&lt;br /&gt;
==Galvanische Trennung==&lt;br /&gt;
Für eine geringe Überspannungsfestigkeit empfielt es sich, die Datenkanäle über Optokoppler zu führen. Es bietet sich z.b. der 6N138 an, ein &amp;quot;normaler&amp;quot; CNY-17 ist für hohe Baudraten nicht brauchbar.&lt;br /&gt;
&lt;br /&gt;
==Fehlersuche==&lt;br /&gt;
Erstaunlich oft wird im Forum der Hilferuf laut: &amp;quot;Meine UART funktioniert nicht, was mache ich falsch&amp;quot;. In der überwiegenden Mehrzahl der Fälle stellt sich dann heraus, daß es sich um ein Hardwareproblem handelt, wobei da wiederrum der Löwenanteil auf das Konto einer nicht korrekt eingestellten Taktrate geht: Der µC benutzt nicht einen angeschlossenen Quarz, so wie er auch im Programm eingetragen ist, sondern läuft immer noch mit dem internen RC-Takt. Daraus resultiert aber auch, daß der Baudraten Konfigurationswert falsch berechnet wird.&lt;br /&gt;
&lt;br /&gt;
Hilfreich zum Aufspüren solcher Fehler ist auch die [[AVR_Checkliste#UART/USART|AVR-Checkliste]].&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
Tipps zur Verarbeitung von Strings sind in den [[FAQ]].&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:avr-gcc Tutorial]]&lt;br /&gt;
[[Kategorie:UART und RS232]]&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Transistor-%C3%9Cbersicht&amp;diff=66740</id>
		<title>Transistor-Übersicht</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Transistor-%C3%9Cbersicht&amp;diff=66740"/>
		<updated>2012-06-08T15:13:10Z</updated>

		<summary type="html">&lt;p&gt;Cmf: /* NPN */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Im Forum wird immer wieder gefragt, welcher [[Transistor]] für eine bestimmte Anwendung passend ist, dafür wurde dieser Wikieintrag angelegt. Wie in der [[Mosfet-Übersicht]] und der [[Dioden-Übersicht]] soll hier eine Liste entstehen mit gängigen Bipolar-Transistoren, die leicht erhältlich sind. Für die Typbezeichnung siehe [[Kennzeichnung von Halbleitern]]. Eine allgemeine Übersicht über verschiedene Bauteile gibt es hier: [[Standardbauelemente]].&lt;br /&gt;
&lt;br /&gt;
== NPN ==&lt;br /&gt;
&#039;&#039;&#039;Bemerkungen:&#039;&#039;&#039;&lt;br /&gt;
*U&amp;lt;sub&amp;gt;CE&amp;lt;/sub&amp;gt; = Maximale Kollektor-Emitter-Spannung bei I&amp;lt;sub&amp;gt;C&amp;lt;/sub&amp;gt; = 0&lt;br /&gt;
*I&amp;lt;sub&amp;gt;C&amp;lt;/sub&amp;gt; = Maximaler Kollektorstrom&lt;br /&gt;
*SOT-32 = TO-126&lt;br /&gt;
&lt;br /&gt;
(Tabelle mit Klick auf Überschrift sortierbar)&lt;br /&gt;
{| {{Tabelle}} class=&amp;quot;sortable&amp;quot; id=&amp;quot;npn&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#eeeeee&amp;quot;&lt;br /&gt;
! Bezeichnung || Package || U&amp;lt;sub&amp;gt;CE&amp;lt;/sub&amp;gt;/V || I&amp;lt;sub&amp;gt;C&amp;lt;/sub&amp;gt;/A || &amp;amp;beta; (Beta)|| &amp;amp;beta;@IC|| V&amp;lt;sub&amp;gt;CEsat&amp;lt;/sub&amp;gt; || P&amp;lt;sub&amp;gt;tot&amp;lt;/sub&amp;gt;/W|| f&amp;lt;sub&amp;gt;G&amp;lt;/sub&amp;gt;/MHz|| Bemerkung|| Lieferant|| Datenblatt|| ca. Preis/&amp;amp;euro;&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/PN2222 PN2222]&lt;br /&gt;
|TO-92&lt;br /&gt;
|30&lt;br /&gt;
|0,8&lt;br /&gt;
|100-300&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|0.6&lt;br /&gt;
|300&lt;br /&gt;
|Allrounder&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://www.reichelt.de/?ACTION=7;LA=3;INDEX=0;FILENAME=A100%252FPN2222A_NXP.pdf National]&lt;br /&gt;
|0.06&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/2N3904 2N3904]&lt;br /&gt;
|TO-92&lt;br /&gt;
|40&lt;br /&gt;
|0.2&lt;br /&gt;
|100-300&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|0.5&lt;br /&gt;
|300&lt;br /&gt;
|Schalttransistor&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://www.fairchildsemi.com/ds/2N/2N3904.pdf Fairchild]&lt;br /&gt;
|0.04&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/2N3055 2N3055]&lt;br /&gt;
|TO-3&lt;br /&gt;
|60&lt;br /&gt;
|15&lt;br /&gt;
|20-70&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|115&lt;br /&gt;
|2.5&lt;br /&gt;
|Leistungstransistor&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://pdf1.alldatasheet.com/datasheet-pdf/view/2466/MOSPEC/2N3055.html alldatasheet.com]&lt;br /&gt;
|0.40&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/BC107 BC107]B&lt;br /&gt;
|TO-18&lt;br /&gt;
|45&lt;br /&gt;
|0.1&lt;br /&gt;
|200-450&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|0.3&lt;br /&gt;
|300&lt;br /&gt;
|&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://pdf1.alldatasheet.com/datasheet-pdf/view/45348/SIEMENS/BC107B.html alldatasheet.com]&lt;br /&gt;
|0.23&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/BC547 BC547]B&lt;br /&gt;
|TO-92&lt;br /&gt;
|45&lt;br /&gt;
|0.1&lt;br /&gt;
|125-500&lt;br /&gt;
|&lt;br /&gt;
|0.9&lt;br /&gt;
|0.625&lt;br /&gt;
|300&lt;br /&gt;
|Schalttransistor&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://www.fairchildsemi.com/ds/BC/BC547.pdf Fairchild]&lt;br /&gt;
|0.04&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/BD679 BD679]A&lt;br /&gt;
|TO-126&lt;br /&gt;
|80&lt;br /&gt;
|4&lt;br /&gt;
|750&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|40&lt;br /&gt;
|&lt;br /&gt;
|Darlington&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://pdf1.alldatasheet.com/datasheet-pdf/view/11588/ONSEMI/BD679A.html alldatasheet.com]&lt;br /&gt;
|0.21&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/MPSA42 MPSA42]&lt;br /&gt;
|TO-92&lt;br /&gt;
|300&lt;br /&gt;
|0.5&lt;br /&gt;
|40&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|0.625&lt;br /&gt;
|50&lt;br /&gt;
|hohe Spannung&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://www.fairchildsemi.com/ds/MP/MPSA42.pdf Fairchild]&lt;br /&gt;
|0.05&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/BC337 BC337]&lt;br /&gt;
|TO-92&lt;br /&gt;
|45&lt;br /&gt;
|0.8&lt;br /&gt;
|100-630&lt;br /&gt;
|100&lt;br /&gt;
|0.7&lt;br /&gt;
|0.625&lt;br /&gt;
|210&lt;br /&gt;
|&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://www.fairchildsemi.com/ds/BC%2FBC337.pdf Fairchild]&lt;br /&gt;
|0.05&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/BC368 BC368]&lt;br /&gt;
|TO-92&lt;br /&gt;
|20&lt;br /&gt;
|1.5&lt;br /&gt;
|100-450&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|0.625&lt;br /&gt;
|40&lt;br /&gt;
|&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://www.fairchildsemi.com/ds/BC/BC368.pdf Fairchild]&lt;br /&gt;
|0.08&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/FMMT617 FMMT617]&lt;br /&gt;
|SOT-23&lt;br /&gt;
|15&lt;br /&gt;
|3&lt;br /&gt;
|60-300&lt;br /&gt;
|300&lt;br /&gt;
|0.15&lt;br /&gt;
|0.625&lt;br /&gt;
|&lt;br /&gt;
|Schalttransistor&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://www.zetex.com/3.0/pdf/FMMT617.pdf Zetex]&lt;br /&gt;
|0.27&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/FMMT619 FMMT619]&lt;br /&gt;
|SOT-23&lt;br /&gt;
|50&lt;br /&gt;
|2&lt;br /&gt;
|40-400&lt;br /&gt;
|200&lt;br /&gt;
|0.2&lt;br /&gt;
|0.625&lt;br /&gt;
|&lt;br /&gt;
|Schalttransistor&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://www.zetex.com/3.0/pdf/FMMT619.pdf Zetex]&lt;br /&gt;
|0.32&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/FMMT625 FMMT625]&lt;br /&gt;
|SOT-23&lt;br /&gt;
|150&lt;br /&gt;
|1&lt;br /&gt;
|15-400&lt;br /&gt;
|45&lt;br /&gt;
|0.2&lt;br /&gt;
|0.625&lt;br /&gt;
|&lt;br /&gt;
|Schalttransistor&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://www.zetex.com/3.0/pdf/FMMT625.pdf Zetex]&lt;br /&gt;
|0.32&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/MJ15003 MJ15003]&lt;br /&gt;
| TO-3&lt;br /&gt;
| 140&lt;br /&gt;
| 20&lt;br /&gt;
| 25-150&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
| 250&lt;br /&gt;
| 2&lt;br /&gt;
| Leistungstransistor&lt;br /&gt;
| Rei Far&lt;br /&gt;
| [http://www.alldatasheet.com/datasheet-pdf/pdf/4799/MOTOROLA/MJ15004.html alldatasheet.com]&lt;br /&gt;
| 1.55&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BD131 BD131]&lt;br /&gt;
| TO-126&lt;br /&gt;
| 45&lt;br /&gt;
| 3&lt;br /&gt;
| 30-70&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
| 15&lt;br /&gt;
| 60&lt;br /&gt;
| Mittlere Leistung, guter Allrounder&lt;br /&gt;
| Rei&lt;br /&gt;
| [http://www.datasheetcatalog.org/datasheet/philips/BD131.pdf Fairchild]&lt;br /&gt;
| 0.21&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/BC517 BC517]&lt;br /&gt;
|TO-92&lt;br /&gt;
|30&lt;br /&gt;
|0.5&lt;br /&gt;
|30000&lt;br /&gt;
|&lt;br /&gt;
|1&lt;br /&gt;
|0.6&lt;br /&gt;
|200&lt;br /&gt;
|Darlington&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://www.nxp.com/documents/data_sheet/BC517.pdf NXP]&lt;br /&gt;
|0.08&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/BCW66 BCW66]&lt;br /&gt;
|SOT-23&lt;br /&gt;
|45&lt;br /&gt;
|0.8&lt;br /&gt;
|100-630&lt;br /&gt;
|&lt;br /&gt;
|0.9&lt;br /&gt;
|0.36&lt;br /&gt;
|170&lt;br /&gt;
|&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://www.diodes.com/datasheets/BCW66.pdf Zetex]&lt;br /&gt;
|0.041&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/BFR92 BFR92]&lt;br /&gt;
|SOT-23&lt;br /&gt;
|15&lt;br /&gt;
|0.3&lt;br /&gt;
|50&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|0.2&lt;br /&gt;
|5000&lt;br /&gt;
| Hochfrequenz&lt;br /&gt;
|Rei ...&lt;br /&gt;
|&lt;br /&gt;
|0.16&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/BUX85 BUX85]&lt;br /&gt;
|TO-220&lt;br /&gt;
|450&lt;br /&gt;
|2&lt;br /&gt;
|&amp;gt;35&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|40&lt;br /&gt;
|12&lt;br /&gt;
|&lt;br /&gt;
|Rei Con&lt;br /&gt;
|[http://www.bourns.com/pdfs/bux85.pdf bourns.com]&lt;br /&gt;
|0.48&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/TIP41C TIP41C]&lt;br /&gt;
|TO-220&lt;br /&gt;
|100&lt;br /&gt;
|6&lt;br /&gt;
|15&lt;br /&gt;
|3000&lt;br /&gt;
|1.5&lt;br /&gt;
|65&lt;br /&gt;
|3&lt;br /&gt;
|&lt;br /&gt;
|csd Rei Con&lt;br /&gt;
|&lt;br /&gt;
|0.24&lt;br /&gt;
|-&lt;br /&gt;
|BSR14&lt;br /&gt;
|SOT23&lt;br /&gt;
|40&lt;br /&gt;
|0.8&lt;br /&gt;
|100&lt;br /&gt;
|0.15&lt;br /&gt;
|1&lt;br /&gt;
|0.35&lt;br /&gt;
|300&lt;br /&gt;
|&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://www.nxp.com/documents/data_sheet/BSR13_BSR14.pdf NXP]&lt;br /&gt;
|0.08&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/BF199 BF199]&lt;br /&gt;
|TO-92&lt;br /&gt;
|25&lt;br /&gt;
|0.05&lt;br /&gt;
|&lt;br /&gt;
|38&lt;br /&gt;
|0.2&lt;br /&gt;
|0.35&lt;br /&gt;
|700&lt;br /&gt;
| alter HF-Transistor&lt;br /&gt;
|Rei Con Far ...&lt;br /&gt;
|[http://www.nxp.com/documents/data_sheet/BF199.pdf NXP]&lt;br /&gt;
|0.35&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== PNP ==&lt;br /&gt;
(Tabelle mit Klick auf Überschrift sortierbar)&lt;br /&gt;
{| {{Tabelle}} class=&amp;quot;sortable&amp;quot; id=&amp;quot;pkanalmosfets&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#eeeeee&amp;quot;&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Package&lt;br /&gt;
! U&amp;lt;sub&amp;gt;CE&amp;lt;/sub&amp;gt;/V&lt;br /&gt;
! I&amp;lt;sub&amp;gt;C&amp;lt;/sub&amp;gt;/A&lt;br /&gt;
! &amp;amp;beta; (Beta)&lt;br /&gt;
! P&amp;lt;sub&amp;gt;tot&amp;lt;/sub&amp;gt;/W&lt;br /&gt;
! f&amp;lt;sub&amp;gt;G&amp;lt;/sub&amp;gt;/MHz&lt;br /&gt;
! Bemerkung&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
! ca. Preis/€&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/2N3906 2N3906]&lt;br /&gt;
|TO-92&lt;br /&gt;
|40&lt;br /&gt;
|0.2&lt;br /&gt;
|100-300&lt;br /&gt;
|0.5&lt;br /&gt;
|250&lt;br /&gt;
|&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://pdf1.alldatasheet.com/datasheet-pdf/view/15078/PHILIPS/2N3906.html alldatasheet.com]&lt;br /&gt;
|0.05&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/BC560 BC560]&lt;br /&gt;
|TO-92&lt;br /&gt;
|45&lt;br /&gt;
|0,1&lt;br /&gt;
|110-800&lt;br /&gt;
|0.5&lt;br /&gt;
|150&lt;br /&gt;
|&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://alldatasheet.com/view.jsp?Searchword=BC560 alldatasheet.com]&lt;br /&gt;
|0.04&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/BC327 BC327]&lt;br /&gt;
|TO-92&lt;br /&gt;
|45&lt;br /&gt;
|0.8&lt;br /&gt;
|100-630&lt;br /&gt;
|0.625&lt;br /&gt;
|&lt;br /&gt;
|Komplement zu BC337&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://alldatasheet.com/view.jsp?Searchword=BC327 alldatasheet.com]&lt;br /&gt;
|0.04&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/BC369 BC369]&lt;br /&gt;
|TO-92&lt;br /&gt;
|20&lt;br /&gt;
|1.5&lt;br /&gt;
|100-400&lt;br /&gt;
|0.625&lt;br /&gt;
|&lt;br /&gt;
|Komplement zu BC368&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://alldatasheet.com/view.jsp?Searchword=BC369 alldatasheet.com]&lt;br /&gt;
|0.08&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/FMMT717 FMMT717]&lt;br /&gt;
|SOT-23&lt;br /&gt;
|12&lt;br /&gt;
|2.5&lt;br /&gt;
|50-300&lt;br /&gt;
|0.625&lt;br /&gt;
|&lt;br /&gt;
|Komplement zu [http://www.mikrocontroller.net/part/FMMT617 FMMT617]&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://www.zetex.com/3.0/pdf/FMMT717.pdf Zetex]&lt;br /&gt;
|0.19&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/BD438 BD438]&lt;br /&gt;
|TO-126&lt;br /&gt;
|45&lt;br /&gt;
|4&lt;br /&gt;
|30-140&lt;br /&gt;
|36&lt;br /&gt;
|3&lt;br /&gt;
|&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://alldatasheet.com/view.jsp?Searchword=BD438 alldatasheet.com]&lt;br /&gt;
|0.17&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/MJ2955 MJ2955]&lt;br /&gt;
|TO-3&lt;br /&gt;
|60&lt;br /&gt;
|15&lt;br /&gt;
|20-70&lt;br /&gt;
|115&lt;br /&gt;
|2.5&lt;br /&gt;
|2N3055 Komplement&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://alldatasheet.com/view.jsp?Searchword=MJ2955 alldatasheet.com]&lt;br /&gt;
|0.40&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BD132 BD132]&lt;br /&gt;
| TO-126&lt;br /&gt;
| 45&lt;br /&gt;
| 3&lt;br /&gt;
| 30-120&lt;br /&gt;
| 15&lt;br /&gt;
| 60&lt;br /&gt;
| Komplement zu BD131&lt;br /&gt;
| Rei,?&lt;br /&gt;
| [http://www.alldatasheet.com/datasheet-pdf/pdf/16168/PHILIPS/BD132.html alldatasheet.com]&lt;br /&gt;
| 0.20&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/BC516 BC516]&lt;br /&gt;
|TO-92&lt;br /&gt;
|30&lt;br /&gt;
|0.5&lt;br /&gt;
|30000&lt;br /&gt;
|0.5&lt;br /&gt;
|220&lt;br /&gt;
|Komplement zum BC517&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://pdf1.alldatasheet.com/datasheet-pdf/view/15078/PHILIPS/2N3906.html alldatasheet.com]&lt;br /&gt;
|0.12&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/BCP53 BCP53]&lt;br /&gt;
|SOT223&lt;br /&gt;
|80&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|1.3&lt;br /&gt;
|115&lt;br /&gt;
| &lt;br /&gt;
|Rei&lt;br /&gt;
|[http://www.datasheetcatalog.net/de/datasheets_pdf/B/C/P/5/BCP52-16.shtml datasheetcatalog.com]&lt;br /&gt;
|0.17&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/BDP950 BDP950]&lt;br /&gt;
|SOT223&lt;br /&gt;
|60&lt;br /&gt;
|3&lt;br /&gt;
|&lt;br /&gt;
|3&lt;br /&gt;
|100&lt;br /&gt;
|&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://www.datasheetcatalog.com/datasheets_pdf/B/D/P/9/BDP950.shtml datasheetcatalog.com]&lt;br /&gt;
|0.29&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/BCW67 BCW67]&lt;br /&gt;
|SOT-23&lt;br /&gt;
|42&lt;br /&gt;
|0.8&lt;br /&gt;
|100-630&lt;br /&gt;
|0.32&lt;br /&gt;
|200&lt;br /&gt;
|&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://pdf1.alldatasheet.com/datasheet-pdf/view/79166/INFINEON/BCW67.html alldatasheet.com]&lt;br /&gt;
|0.041&lt;br /&gt;
|-&lt;br /&gt;
|[http://www.mikrocontroller.net/part/MJ2955 MJ2955]&lt;br /&gt;
|T0-3&lt;br /&gt;
|60&lt;br /&gt;
|15&lt;br /&gt;
|20-70&lt;br /&gt;
|115&lt;br /&gt;
|&lt;br /&gt;
|Komplement zu 2N3055, Leistungstransistor&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://www.datasheetcatalog.net/de/datasheets_pdf/M/J/2/9/MJ2955.shtml datasheetcatalog]&lt;br /&gt;
|0.70&lt;br /&gt;
|-&lt;br /&gt;
|BSR15&lt;br /&gt;
|SOT23&lt;br /&gt;
|40&lt;br /&gt;
|0.8&lt;br /&gt;
|100&lt;br /&gt;
|0.25&lt;br /&gt;
|200&lt;br /&gt;
|Schalttransistor&lt;br /&gt;
|Rei&lt;br /&gt;
|[http://www.nxp.com/documents/data_sheet/BSR15_BSR16.pdf NXP]&lt;br /&gt;
|0.09&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Transistor-Array ==&lt;br /&gt;
(Tabelle mit Klick auf Überschrift sortierbar)&lt;br /&gt;
{| {{Tabelle}} class=&amp;quot;sortable&amp;quot; id=&amp;quot;pkanalmosfets&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#eeeeee&amp;quot;&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Package&lt;br /&gt;
! U&amp;lt;sub&amp;gt;CE&amp;lt;/sub&amp;gt;/V&lt;br /&gt;
! I&amp;lt;sub&amp;gt;C&amp;lt;/sub&amp;gt;/A&lt;br /&gt;
! &amp;amp;beta; (Beta)&lt;br /&gt;
! P&amp;lt;sub&amp;gt;tot&amp;lt;/sub&amp;gt;/W&lt;br /&gt;
! f&amp;lt;sub&amp;gt;T&amp;lt;/sub&amp;gt;/MHz&lt;br /&gt;
! Bemerkung&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
! ca. Preis/€&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/NTE912 NTE912]&lt;br /&gt;
| DIL-14&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| 5 NPN-Transistoren&lt;br /&gt;
| Far&lt;br /&gt;
| [http://www.nteinc.com/specs/900to999/pdf/nte912.pdf NTE]&lt;br /&gt;
| 3.50&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/CA3086 CA3086]&lt;br /&gt;
| DIL-14&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| 5 NPN-Transistoren, abgekündigt&lt;br /&gt;
| eBay&lt;br /&gt;
| [http://www.intersil.com/data/fn/fn483.pdf Intersil]&lt;br /&gt;
| 0.50&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BCV61 BCV61]&lt;br /&gt;
| SOT143&lt;br /&gt;
| 30&lt;br /&gt;
| 0.1&lt;br /&gt;
| 100-800&lt;br /&gt;
| 0.25&lt;br /&gt;
| 100&lt;br /&gt;
| 2 NPN-Transistoren für Stromspiegel&lt;br /&gt;
| Rei, Far&lt;br /&gt;
| [http://www.alldatasheet.com/view.jsp?Searchword=BCV61 alldatasheet.com] &lt;br /&gt;
| 0.14&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BCV62 BCV62]&lt;br /&gt;
| SOT143&lt;br /&gt;
| 30&lt;br /&gt;
| 0.1&lt;br /&gt;
| 100-800&lt;br /&gt;
| 0.25&lt;br /&gt;
| 100&lt;br /&gt;
| 2 PNP-Transistoren für Stromspiegel&lt;br /&gt;
| Rei, Far&lt;br /&gt;
| [http://www.alldatasheet.com/view.jsp?Searchword=BCV62 alldatasheet.com] &lt;br /&gt;
| 0.19&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/ULN2801 ULN2801] [http://www.mikrocontroller.net/part/ULN2802 ULN2802] [http://www.mikrocontroller.net/part/ULN2803 ULN2803] [http://www.mikrocontroller.net/part/ULN2804 ULN2804] &lt;br /&gt;
| DIL18 SO18&lt;br /&gt;
| 50&lt;br /&gt;
| 0.35&lt;br /&gt;
| &lt;br /&gt;
| 1&lt;br /&gt;
| kHz&lt;br /&gt;
| 8x Low-Side NPN-Darlington, Freilaufdiode, max 500mA insgesamt&lt;br /&gt;
| Rei, Far, alle&lt;br /&gt;
| [http://www.alldatasheet.com/view.jsp?Searchword=BCV62 alldatasheet.com] &lt;br /&gt;
| 0.35 - 0,50&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/UDN2981 UDN2981]&lt;br /&gt;
| DIL18 SO18&lt;br /&gt;
| 50&lt;br /&gt;
| 0.35&lt;br /&gt;
| &lt;br /&gt;
| 1&lt;br /&gt;
| kHz&lt;br /&gt;
| 8x High-Side NPN-Darlington, Freilaufdiode, max 500mA insgesamt, obsolete, Ersatz: Micrel MIC2981&lt;br /&gt;
| Rei, Far&lt;br /&gt;
| [http://www.allegromicro.com/en/Products/Part_Numbers/2981/2981.pdf Allegro] &lt;br /&gt;
| 1.75&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Vollbrücke, Halbbrücke ==&lt;br /&gt;
(Tabelle mit Klick auf Überschrift sortierbar)&lt;br /&gt;
{| {{Tabelle}} class=&amp;quot;sortable&amp;quot; id=&amp;quot;pkanalmosfets&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#eeeeee&amp;quot;&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Package&lt;br /&gt;
! U&amp;lt;sub&amp;gt;CE&amp;lt;/sub&amp;gt;/V&lt;br /&gt;
! I&amp;lt;sub&amp;gt;C&amp;lt;/sub&amp;gt;/A&lt;br /&gt;
! &amp;amp;beta; (Beta)&lt;br /&gt;
! P&amp;lt;sub&amp;gt;tot&amp;lt;/sub&amp;gt;/W&lt;br /&gt;
! f&amp;lt;sub&amp;gt;T&amp;lt;/sub&amp;gt;/MHz&lt;br /&gt;
! Bemerkung&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Datenblatt&lt;br /&gt;
! ca. Preis/€&lt;br /&gt;
|-&lt;br /&gt;
| ZDT 6790 TA&lt;br /&gt;
| SM-8&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| Halbbrücke 1x NPN, 1x PNP&lt;br /&gt;
| Rei&lt;br /&gt;
| [http://www.datasheetarchive.com/pdf-datasheets/Datasheets-311/133888.html Datasheetarchive.com]&lt;br /&gt;
| 0,74 €&lt;br /&gt;
|-&lt;br /&gt;
| ZHB6792&lt;br /&gt;
| SM-8&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| H-Brücke 2x NPN, 2x PNP&lt;br /&gt;
| Rei&lt;br /&gt;
| [http://www.diodes.com/zetex/_pdfs/3.0/pdf/ZHB6792.pdf Diodes.com]&lt;br /&gt;
| 1,70 €&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Lieferantenübersicht ==&lt;br /&gt;
* [Rei] [[Elektronikversender#Reichelt|Reichelt]]: http://www.reichelt.de&lt;br /&gt;
* [Con] [[Elektronikversender#Conrad|Conrad-Elektronik]]: http://www.conrad.de&lt;br /&gt;
* [csd] [[Elektronikversender#csd-electronics|CSD-Electronics]]: http://www.csd-electronics.de/&lt;br /&gt;
* [Kes] [[Elektronikversender#Kessler|Kessler]]: http://www.kessler-elektronik.de&lt;br /&gt;
* [Far] [[Elektronikversender#Farnell|Farnell]]: http://www.farnell.de &lt;br /&gt;
&lt;br /&gt;
== Parametrische Suche beim Hersteller ==&lt;br /&gt;
* [http://www.infineon.com/cms/de/product/channel.html?channel=db3a304319c6f18c011a14e8a6de25fc Infineon]&lt;br /&gt;
* [http://www.diodes.com/zetex/?ztx=3.0/transistor_search Diodes (vormals Zetex)]&lt;br /&gt;
* [http://www.nxp.com/#/homepage/cb=%5Bt%3Dp%2Cp%3D%2F71078%2F47196%5D%7Cpp%3D%5Bt%3Dpfp%2Ci%3D47196%5D NXP Small-Signal]&lt;br /&gt;
* [http://www.nxp.com/#/homepage/cb=%5Bt%3Dp%2Cp%3D%2F71078%2F41781%5D%7Cpp%3D%5Bt%3Dpfp%2Ci%3D41781%5D NXP low VCEsat]&lt;br /&gt;
* [http://www.onsemi.com/PowerSolutions/taxonomy.do?id=797&amp;amp;lctn=home ONsemi]&lt;br /&gt;
&lt;br /&gt;
[[Category:Bauteile]]&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer_Diskussion:Cmf&amp;diff=66710</id>
		<title>Benutzer Diskussion:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer_Diskussion:Cmf&amp;diff=66710"/>
		<updated>2012-06-07T14:37:48Z</updated>

		<summary type="html">&lt;p&gt;Cmf: /* Vorlage:Warnung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Quarze_und_AVR&amp;diff=66447</id>
		<title>Quarze und AVR</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Quarze_und_AVR&amp;diff=66447"/>
		<updated>2012-05-20T17:44:52Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Diese Seite behandelt [[Schwingquarz]]e im Zusammenhang mit [[AVR]]s.&lt;br /&gt;
&lt;br /&gt;
Die Genauigkeit von Quarzen liegt bei 10–100ppm	(1ppm = 0,0001 %) und wird somit nur noch von [[Quarzoszillator]]en überboten. Außerdem sind Quarze im Gegensatz zum internen RC-Oszillator weniger temperaturabhängig.&lt;br /&gt;
&lt;br /&gt;
== Verwendung ==&lt;br /&gt;
&lt;br /&gt;
Quarze sind in folgenden Situationen sinnvoll / notwendig:&lt;br /&gt;
&lt;br /&gt;
* Interner Oszillator des [[µC]] zu langsam&lt;br /&gt;
* Interner Oszillator des µC zu ungenau&lt;br /&gt;
** Bei Verwendung des [[UART]]&lt;br /&gt;
** Bei zeitgenauen Anwendungen wie Uhren&lt;br /&gt;
&lt;br /&gt;
== Wahl der richtigen Frequenz ==&lt;br /&gt;
&lt;br /&gt;
Vor allem als Anfänger denkt man sich, &#039;&#039;ich kaufe einfach mal 10MHz, das ist eine so schön gerade Zahl&#039;&#039;. Allerdings sind diese Quarze nur in den seltensten Fällen sinnvoll. Viel sinnvoller sind [[Baudratenquarz]]e. &amp;quot;Baudraten&amp;quot;-Frequenzen sind ganzzahlige Vielfache der bei [[RS232]] üblichen Baudraten. Mit Baudrate-Frequenz kann  man exakte Baudraten erreichen. Mit &amp;quot;runden&amp;quot; Frequenzen entstehen hingegen Fehler, weshalb damit oft nur sehr niedrige Baudraten möglich sind.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Runde&amp;quot; Frequenzen (4MHz, 8MHz, 10MHz....) sind meist leichter erhältlich und haben den Vorteil, dass man Verzögerungsschleifen und Rechendauern relativ leicht errechnen kann.&lt;br /&gt;
&lt;br /&gt;
== Anschluss ==&lt;br /&gt;
&lt;br /&gt;
Die Kapazitäten von C1 und C2 entsprechen &#039;&#039;nicht&#039;&#039; der Lastkapazität des Quarzes! Sie errechnen sich folgendermaßen:&lt;br /&gt;
[[Bild:Quarz_Anschluss_AVR.png|right|thumb|Anschluss eines Quarzes an einen AVR]]&lt;br /&gt;
&lt;br /&gt;
C = 2·CL – (CP+CI)&lt;br /&gt;
&lt;br /&gt;
*CP: Leiterbahnen bedingte Kapazität&lt;br /&gt;
*CI: Portbedingte Kapazität&lt;br /&gt;
*CL: Datenblatt des Quarzes&lt;br /&gt;
*CP+CI ca. 5pF&lt;br /&gt;
&lt;br /&gt;
Am Beispiel von CL = 32pF:&lt;br /&gt;
&lt;br /&gt;
C = 2·32pF – 5pF = 59pF&lt;br /&gt;
&lt;br /&gt;
C1 und C2 sind die vom Hersteller des Kontrollers empfohlenen Werte. Mit ihnen wird die Schwingsicherheit der Oszillatorschaltung gewährleistet. C1 und C2 sollten in etwa eingehalten werden, also nicht mehr als ±20% von den Angaben abweichen.&lt;br /&gt;
&lt;br /&gt;
CL, der im Datenblatt angegebene Wert, wird beim Abgleich des Quarzes während der Herstellung benutzt. &lt;br /&gt;
&lt;br /&gt;
Wenn CL nicht eingehalten wird, hat das — solange der Faktor 2 nicht überschritten wird — keinen Einfluss auf das Schwingen des Oszillators, sondern nur auf die Frequenz, aber das in einem Maße (max. 0,01% der Frequenz. Dies ist für die meisten Mikrocontroller-Anwendungen bedeutungslos.&lt;br /&gt;
{{Warnung |&lt;br /&gt;
;Hinweis: Soll ein Uhrenquarz eine Real-Time-Clock versorgen, so sind die Kapazitäten von großer Wichtigkeit. Die Uhr läuft bei falsch dimensionierten Kapazitäten gleich im 3-stelligen ppm-Bereich falsch. Das bedeutet praktisch gleich mehrere Minuten pro Tag!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Einstellung der Fuses ==&lt;br /&gt;
{{Warnung |&lt;br /&gt;
;Warnung: Hier ist besondere Vorsicht geboten. Fast immer liegt das Problem, wenn ein AVR nicht mehr läuft, an falsch eingestellten [[AVR Fuses]]!&lt;br /&gt;
&lt;br /&gt;
:Ein Quarz ist &#039;&#039;keine&#039;&#039; &amp;quot;External Clock&amp;quot;, sondern ein &amp;quot;External Crystal/Ceramic Resonator&amp;quot;. &lt;br /&gt;
}}&lt;br /&gt;
Bei vielen AVRs muss nicht nur &amp;quot;External Crystal&amp;quot; eingestellt werden, sondern auch der Frequenzbereich des Quarzes. Dabei gibt es die folgenden Bereiche:&lt;br /&gt;
*Low Freq.: 0,9 - 3 MHz&lt;br /&gt;
*Medium Freq.: 3 - 8 MHz&lt;br /&gt;
*High Freq.: &amp;gt;= 1 MHz&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wenn man wirklich auf Nummer sicher gehen will, sollte man:&lt;br /&gt;
* Immer das Datenblatt und den Abschnitt &amp;quot;Clock Source&amp;quot; aufmerksam lesen.&lt;br /&gt;
* Per Fuse Calculator die Fuses berechnen lassen. Siehe dazu die Weblinks unten.&lt;br /&gt;
* Nochmals genau überprüfen&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[AVR_Fuses#Taktquellen Fuse Einstellung|AVR Fuses: Taktquellen Fuse Einstellung]]&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
* AppNotes von Atmel zum Thema Quarze:&lt;br /&gt;
** [http://www.atmel.com/Images/doc2521.pdf AVR042: &#039;&#039;AVR Hardware Design Considerations&#039;&#039;]&lt;br /&gt;
** [http://www.atmel.com/Images/doc8128.pdf AVR186: &#039;&#039;Best Practices for the PCB layout of Oscillators&#039;&#039;]&lt;br /&gt;
* Fuse Calculator: [http://www.engbedded.com/fusecalc]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR]]&lt;br /&gt;
[[Kategorie:Timer und Uhren]]&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Quarze_und_AVR&amp;diff=66397</id>
		<title>Quarze und AVR</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Quarze_und_AVR&amp;diff=66397"/>
		<updated>2012-05-17T21:55:30Z</updated>

		<summary type="html">&lt;p&gt;Cmf: Hinweise zum Frequenzbereich&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Diese Seite behandelt [[Schwingquarz]]e im Zusammenhang mit [[AVR]]s.&lt;br /&gt;
&lt;br /&gt;
Die Genauigkeit von Quarzen liegt bei 10–100ppm	(1ppm = 0,0001 %) und wird somit nur noch von [[Quarzoszillator]]en überboten. Außerdem sind Quarze im Gegensatz zum internen RC-Oszillator weniger temperaturabhängig.&lt;br /&gt;
&lt;br /&gt;
== Verwendung ==&lt;br /&gt;
&lt;br /&gt;
Quarze sind in folgenden Situationen sinnvoll / notwendig:&lt;br /&gt;
&lt;br /&gt;
* Interner Oszillator des [[µC]] zu langsam&lt;br /&gt;
* Interner Oszillator des µC zu ungenau&lt;br /&gt;
** Bei Verwendung des [[UART]]&lt;br /&gt;
** Bei zeitkritischen Anwendungen wie Uhren&lt;br /&gt;
&lt;br /&gt;
== Wahl der richtigen Frequenz ==&lt;br /&gt;
&lt;br /&gt;
Vor allem als Anfänger denkt man sich, &#039;&#039;ich kaufe einfach mal 10MHz, das ist eine so schön gerade Zahl&#039;&#039;. Allerdings sind diese Quarze nur in den seltensten Fällen sinnvoll. Viel sinnvoller sind [[Baudratenquarz]]e. &amp;quot;Baudraten&amp;quot;-Frequenzen sind ganzzahlige Vielfache der bei [[RS232]] üblichen Baudraten. Mit Baudrate-Frequenz kann  man exakte Baudraten erreichen. Mit &amp;quot;runden&amp;quot; Frequenzen entstehen hingegen Fehler, weshalb damit oft nur sehr niedrige Baudraten möglich sind.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Runde&amp;quot; Frequenzen (4MHz, 8MHz, 10MHz....) sind meist leichter erhältlich und haben den Vorteil, dass man Verzögerungsschleifen und Rechendauern relativ leicht errechnen kann.&lt;br /&gt;
&lt;br /&gt;
== Anschluss ==&lt;br /&gt;
&lt;br /&gt;
Die Kapazitäten von C1 und C2 entsprechen &#039;&#039;nicht&#039;&#039; der Lastkapazität des Quarzes! Sie errechnen sich folgendermaßen:&lt;br /&gt;
[[Bild:Quarz_Anschluss_AVR.png|right|thumb|Anschluss eines Quarzes an einen AVR]]&lt;br /&gt;
&lt;br /&gt;
C = 2·CL – (CP+CI)&lt;br /&gt;
&lt;br /&gt;
*CP: Leiterbahnen bedingte Kapazität&lt;br /&gt;
*CI: Portbedingte Kapazität&lt;br /&gt;
*CL: Datenblatt des Quarzes&lt;br /&gt;
*CP+CI ca. 5pF&lt;br /&gt;
&lt;br /&gt;
Am Beispiel von CL = 32pF:&lt;br /&gt;
&lt;br /&gt;
C = 2·32pF – 5pF = 59pF&lt;br /&gt;
&lt;br /&gt;
C1 und C2 sind die vom Hersteller des Kontrollers empfohlenen Werte. Mit ihnen wird die Schwingsicherheit der Oszillatorschaltung gewährleistet. C1 und C2 sollten in etwa eingehalten werden, also nicht mehr als ±20% von den ANgaben abweichen.&lt;br /&gt;
&lt;br /&gt;
CL, der im Datenblatt angegebene Wert, wird beim Abgleich des Quarzes während der Herstellung benutzt. &lt;br /&gt;
&lt;br /&gt;
Wenn CL nicht eingehalten wird, hat das — solange der Faktor 2 nicht überschritten wird — keinen Einfluss auf das Schwingen des Oszillators, sondern nur auf die Frequenz, aber das in einem Maße (max. 0,01% der Frequenz. Dies ist für die meisten Mikrokontrolleranwendungen bedeutungslos.&lt;br /&gt;
{{Warnung |&lt;br /&gt;
;Hinweis: Soll ein Uhrenquarz eine Real-Time-Clock versorgen, so sind die Kapazitäten von großer Wichtigkeit. Die Uhr läuft bei falsch dimensionierten Kapazitäten gleich im 3-Stelligen ppm-Bereich falsch. Das bedeutet praktisch gleich mehrere Minuten pro Tag!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Einstellung der Fuses ==&lt;br /&gt;
{{Warnung |&lt;br /&gt;
;Warnung: Hier ist besondere Vorsicht geboten. Fast immer liegt das Problem, wenn ein AVR nicht mehr läuft, an falsch eingestellten [[AVR Fuses]]!&lt;br /&gt;
&lt;br /&gt;
:Ein Quarz ist &#039;&#039;keine&#039;&#039; &amp;quot;External Clock&amp;quot;, sondern ein &amp;quot;External Crystal/Ceramic Resonator&amp;quot;. &lt;br /&gt;
}}&lt;br /&gt;
Bei vielen AVRs muss nicht nur &amp;quot;External Crystal&amp;quot; eingestellt werden, sondern auch der Frequenzbereich des Quarzes. Dabei gibt es die folgenden Bereiche:&lt;br /&gt;
*Low Freq.: 0,9 - 3 mHz&lt;br /&gt;
*Medium Freq.: 3 - 8 mHz&lt;br /&gt;
*High Freq.: &amp;gt;= 1 mHz&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Wenn man wirklich auf Nummer sicher gehen will, sollte man:&lt;br /&gt;
* Immer das Datenblatt und den Abschnitt &amp;quot;Clock Source&amp;quot; aufmerksam lesen&lt;br /&gt;
* Per Fuse Calculator die Fuses berechnen lassen. Siehe dazu die Weblinks unten.&lt;br /&gt;
* Nochmals genau überprüfen&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[AVR_Fuses#Taktquellen Fuse Einstellung|AVR Fuses: Taktquellen Fuse Einstellung]]&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
* AppNotes von Atmel zum Thema Quarze:&lt;br /&gt;
** [http://www.atmel.com/Images/doc2521.pdf AVR042: &#039;&#039;AVR Hardware Design Considerations&#039;&#039;]&lt;br /&gt;
** [http://www.atmel.com/Images/doc8128.pdf AVR186: &#039;&#039;Best Practices for the PCB layout of Oscillators&#039;&#039;]&lt;br /&gt;
* Fuse Calculator: [http://www.engbedded.com/fusecalc]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR]]&lt;br /&gt;
[[Kategorie:Timer und Uhren]]&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Quarze_und_AVR&amp;diff=66396</id>
		<title>Quarze und AVR</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Quarze_und_AVR&amp;diff=66396"/>
		<updated>2012-05-17T17:30:06Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Diese Seite behandelt [[Schwingquarz]]e im Zusammenhang mit [[AVR]]s.&lt;br /&gt;
&lt;br /&gt;
Die Genauigkeit von Quarzen liegt bei 10–100ppm	(1ppm = 0,0001 %) und wird somit nur noch von [[Quarzoszillator]]en überboten. Außerdem sind Quarze im Gegensatz zum internen RC-Oszillator weniger temperaturabhängig.&lt;br /&gt;
&lt;br /&gt;
== Verwendung ==&lt;br /&gt;
&lt;br /&gt;
Quarze sind in folgenden Situationen sinnvoll / notwendig:&lt;br /&gt;
&lt;br /&gt;
* Interner Oszillator des [[µC]] zu langsam&lt;br /&gt;
* Interner Oszillator des µC zu ungenau&lt;br /&gt;
** Bei Verwendung des [[UART]]&lt;br /&gt;
** Bei zeitkritischen Anwendungen wie Uhren&lt;br /&gt;
&lt;br /&gt;
== Wahl der richtigen Frequenz ==&lt;br /&gt;
&lt;br /&gt;
Vor allem als Anfänger denkt man sich, &#039;&#039;ich kaufe einfach mal 10MHz, das ist eine so schön gerade Zahl&#039;&#039;. Allerdings sind diese Quarze nur in den seltensten Fällen sinnvoll. Viel sinnvoller sind [[Baudratenquarz]]e. &amp;quot;Baudraten&amp;quot;-Frequenzen sind ganzzahlige Vielfache der bei [[RS232]] üblichen Baudraten. Mit Baudrate-Frequenz kann  man exakte Baudraten erreichen. Mit &amp;quot;runden&amp;quot; Frequenzen entstehen hingegen Fehler, weshalb damit oft nur sehr niedrige Baudraten möglich sind.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Runde&amp;quot; Frequenzen (4MHz, 8MHz, 10MHz....) sind meist leichter erhältlich und haben den Vorteil, dass man Verzögerungsschleifen und Rechendauern relativ leicht errechnen kann.&lt;br /&gt;
&lt;br /&gt;
== Anschluss ==&lt;br /&gt;
&lt;br /&gt;
Die Kapazitäten von C1 und C2 entsprechen &#039;&#039;nicht&#039;&#039; der Lastkapazität des Quarzes! Sie errechnen sich folgendermaßen:&lt;br /&gt;
[[Bild:Quarz_Anschluss_AVR.png|right|thumb|Anschluss eines Quarzes an einen AVR]]&lt;br /&gt;
&lt;br /&gt;
C = 2·CL – (CP+CI)&lt;br /&gt;
&lt;br /&gt;
*CP: Leiterbahnen bedingte Kapazität&lt;br /&gt;
*CI: Portbedingte Kapazität&lt;br /&gt;
*CL: Datenblatt des Quarzes&lt;br /&gt;
*CP+CI ca. 5pF&lt;br /&gt;
&lt;br /&gt;
Am Beispiel von CL = 32pF:&lt;br /&gt;
&lt;br /&gt;
C = 2·32pF – 5pF = 59pF&lt;br /&gt;
&lt;br /&gt;
C1 und C2 sind die vom Hersteller des Kontrollers empfohlenen Werte. Mit ihnen wird die Schwingsicherheit der Oszillatorschaltung gewährleistet. C1 und C2 sollten in etwa eingehalten werden, also nicht mehr als ±20% von den ANgaben abweichen.&lt;br /&gt;
&lt;br /&gt;
CL, der im Datenblatt angegebene Wert, wird beim Abgleich des Quarzes während der Herstellung benutzt. &lt;br /&gt;
&lt;br /&gt;
Wenn CL nicht eingehalten wird, hat das — solange der Faktor 2 nicht überschritten wird — keinen Einfluss auf das Schwingen des Oszillators, sondern nur auf die Frequenz, aber das in einem Maße (max. 0,01% der Frequenz. Dies ist für die meisten Mikrokontrolleranwendungen bedeutungslos.&lt;br /&gt;
{{Warnung |&lt;br /&gt;
;Hinweis: Soll ein Uhrenquarz eine Real-Time-Clock versorgen, so sind die Kapazitäten von großer Wichtigkeit. Die Uhr läuft bei falsch dimensionierten Kapazitäten gleich im 3-Stelligen ppm-Bereich falsch. Das bedeutet praktisch gleich mehrere Minuten pro Tag!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Einstellung der Fuses ==&lt;br /&gt;
{{Warnung |&lt;br /&gt;
;Warnung: Hier ist besondere Vorsicht geboten. Fast immer liegt das Problem, wenn ein AVR nicht mehr läuft, an falsch eingestellten [[AVR Fuses]]!&lt;br /&gt;
&lt;br /&gt;
:Ein Quarz ist &#039;&#039;keine&#039;&#039; &amp;quot;External Clock&amp;quot;, sondern ein &amp;quot;External Crystal/Ceramic Resonator&amp;quot;. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Wenn man wirklich auf Nummer sicher gehen will, sollte man:&lt;br /&gt;
* Immer das Datenblatt und den Abschnitt &amp;quot;Clock Source&amp;quot; aufmerksam lesen&lt;br /&gt;
* Per Fuse Calculator die Fuses berechnen lassen. Siehe dazu die Weblinks unten.&lt;br /&gt;
* Nochmals genau überprüfen&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
* [[AVR_Fuses#Taktquellen Fuse Einstellung|AVR Fuses: Taktquellen Fuse Einstellung]]&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
&lt;br /&gt;
* AppNotes von Atmel zum Thema Quarze:&lt;br /&gt;
** [http://www.atmel.com/Images/doc2521.pdf AVR042: &#039;&#039;AVR Hardware Design Considerations&#039;&#039;]&lt;br /&gt;
** [http://www.atmel.com/Images/doc8128.pdf AVR186: &#039;&#039;Best Practices for the PCB layout of Oscillators&#039;&#039;]&lt;br /&gt;
* Fuse Calculator: [http://www.engbedded.com/fusecalc]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:AVR]]&lt;br /&gt;
[[Kategorie:Timer und Uhren]]&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Quarze_und_AVR&amp;diff=66379</id>
		<title>Quarze und AVR</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Quarze_und_AVR&amp;diff=66379"/>
		<updated>2012-05-16T20:43:00Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Diese Seite behandelt Quarze im Zusammenhang mit AVRs. Für allgemeine Informationen zum Thema siehe [[Quarz]].&lt;br /&gt;
&lt;br /&gt;
Die Genauigkeit von Quarzen liegt bei 10-100ppm	(1ppm = 0,0001 %) und wird somit nur noch vom [[Oszillator#Quarzoszillator|Quarzoszillator]] überboten. Außerdem sind Quarze im Gegensatz zum internen RC-Oszillator weniger temperaturunabhängig.&lt;br /&gt;
&lt;br /&gt;
= Verwendung =&lt;br /&gt;
Quarze sind in folgenden Situationen sinnvoll / notwendig:&lt;br /&gt;
&lt;br /&gt;
* Interner Oszillator des µC zu langsam&lt;br /&gt;
* Interner Oszillator des µC zu ungenau&lt;br /&gt;
**Bei Verwendung des [[UART]]&lt;br /&gt;
**Bei zeitkritischen Anwendungen wie z.B. einer Uhr&lt;br /&gt;
&lt;br /&gt;
= Wahl der richtigen Frequenz =&lt;br /&gt;
Vor allem als Anfänger denkt man sich, &#039;&#039;ich kaufe einfach mal 10MHz, das ist eine so schön gerade Zahl&#039;&#039;. Allerdings sind diese Quarze nur in den seltensten Fällen sinnvoll. Viel sinnvoller sind [[Baudratenquarz]]e. &amp;quot;Baudraten&amp;quot;-Frequenzen sind ganzzahlige Vielfache der bei RS232 üblichen Baudraten. Mit Baudrate-Frequenz kann  man exakte Baudraten erreichen, mit &amp;quot;runden&amp;quot; Frequenzen entstehen Fehler, weshalb oft nur sehr niedrige Baudraten möglich sind.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Runde&amp;quot; Frequenzen (4MHz, 8MHz, 10MHz....) sind meist leichter erhältlich und haben den Vorteil, dass man Verzögerungsschleifen und Rechendauern relativ leicht errechnen kann.&lt;br /&gt;
&lt;br /&gt;
= Anschluss =&lt;br /&gt;
[[Bild:Quarz_Anschluss_AVR.png|right|framed|Anschluss eines Quarzes an einen AVR]]&lt;br /&gt;
Die Kapazitäten von C1 und C2 entsprechen &#039;&#039;&#039;nicht&#039;&#039;&#039; der Lastkapazität des Quarzes!&lt;br /&gt;
Sie errechnen sich folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
C=2xCL-(CP+CI)&lt;br /&gt;
&lt;br /&gt;
*CP: Leiterbahnen bedingte Kapazität&lt;br /&gt;
*CI: Portbedingte Kapazität&lt;br /&gt;
*CL: Datenblatt des Quarzes&lt;br /&gt;
*CP+CI ca. 5pF&lt;br /&gt;
&lt;br /&gt;
Am Beispiel von CL = 32pF:&lt;br /&gt;
&lt;br /&gt;
C = 2x32pF-5pF = 59pF&lt;br /&gt;
&lt;br /&gt;
C1 und C2 sind die vom Hersteller des Kontrollers empfohlenen Werte, mit ihnen wird die Schwingsicherheit der Oszillatorschaltung gewährleistet. C1 und C2 sollten in etwa eingehalten werden (so + - 20% machen aber nichts aus).&lt;br /&gt;
&lt;br /&gt;
CL, der im Datenblatt angegebene Wert, wird beim Abgleich des Quarzes während der Herstellung benutzt. &lt;br /&gt;
&lt;br /&gt;
Wenn CL nicht eingehalten wird, hat das keinen Einfluss auf das Schwingen des Oszillators (solange der Faktor2 nicht überschritten wird) sondern nur auf die Frequenz, aber das in einem Maße (max. 0,01%der Frequenz), das für die meisten Mikrokontrolleranwendungen bedeutungslos ist.&lt;br /&gt;
{{Warnung |&lt;br /&gt;
;Soll ein Uhrenquarz eine Real-Time-Clock versorgen, so sind die Kapazitäten von großer Wichtigkeit. Die Uhr läuft bei falsch dimensionierten Kapazitäten gleich im 3-Stelligen PPM-Bereich falsch. Das bedeutet praktisch gleich mehrere Minuten pro Tag!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Einstellung der Fuses =&lt;br /&gt;
{{Warnung |&lt;br /&gt;
;Hier ist besondere Vorsicht geboten. Fast immer liegt hier das Problem, wenn ein Mikrocontroller nicht mehr läuft!&lt;br /&gt;
}}&lt;br /&gt;
Ein Quarz ist &#039;&#039;&#039;keine&#039;&#039;&#039; &amp;quot;External Clock&amp;quot;, sondern ein &amp;quot;External Crystal/Ceramic Resonator&amp;quot;. &lt;br /&gt;
Wenn man wirklich auf Nummer sicher gehen will, sollte man:&lt;br /&gt;
*Das Datenblatt &#039;&#039;&#039;genau&#039;&#039;&#039; lesen (Abschnitt &amp;quot;Clock Source&amp;quot;)&lt;br /&gt;
*Beim Fuse Calculator [http://www.engbedded.com/fusecalc] die Fuses berechnen lassen&lt;br /&gt;
*Nochmals genau überprüfen&lt;br /&gt;
Siehe auch: [[AVR_Fuses#Taktquellen_Fuse_Einstellung]]&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
&lt;br /&gt;
= Weblinks =&lt;br /&gt;
*AppNotes von Atmel zum Thema Quarze: [http://www.atmel.com/Images/doc2521.pdf][http://www.atmel.com/Images/doc8128.pdf]&lt;br /&gt;
*Fuse Calculator: [http://www.engbedded.com/fusecalc]&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Quarze_und_AVR&amp;diff=66378</id>
		<title>Quarze und AVR</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Quarze_und_AVR&amp;diff=66378"/>
		<updated>2012-05-16T20:41:45Z</updated>

		<summary type="html">&lt;p&gt;Cmf: /* Anschluss */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Diese Seite behandelt Quarze im Zusammenhang mit AVRs. Für allgemeine Informationen zum Thema siehe [[Quarz]].&lt;br /&gt;
&lt;br /&gt;
Die Genauigkeit von Quarzen liegt bei 10-100ppm	(1ppm = 0,0001 %) und wird somit nur noch vom [[Oszillator#Quarzoszillator|Quarzoszillator]] überboten. Außerdem sind Quarze im Gegensatz zum internen RC-Oszillator weniger temperaturunabhängig.&lt;br /&gt;
&lt;br /&gt;
= Verwendung =&lt;br /&gt;
Quarze sind in folgenden Situationen sinnvoll / notwendig:&lt;br /&gt;
&lt;br /&gt;
* Interner Oszillator des µC zu langsam&lt;br /&gt;
* Interner Oszillator des µC zu ungenau&lt;br /&gt;
**Bei Verwendung des [[UART]]&lt;br /&gt;
**Bei zeitkritischen Anwendungen wie z.B. einer Uhr&lt;br /&gt;
&lt;br /&gt;
= Wahl der richtigen Frequenz =&lt;br /&gt;
Vor allem als Anfänger denkt man sich, &#039;&#039;ich kaufe einfach mal 10MHz, das ist eine so schön gerade Zahl&#039;&#039;. Allerdings sind diese Quarze nur in den seltensten Fällen sinnvoll. Viel sinnvoller sind [[Baudratenquarz]]e. &amp;quot;Baudraten&amp;quot;-Frequenzen sind ganzzahlige Vielfache der bei RS232 üblichen Baudraten. Mit Baudrate-Frequenz kann  man exakte Baudraten erreichen, mit &amp;quot;runden&amp;quot; Frequenzen entstehen Fehler, weshalb oft nur sehr niedrige Baudraten möglich sind.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Runde&amp;quot; Frequenzen (4MHz, 8MHz, 10MHz....) sind meist leichter erhältlich und haben den Vorteil, dass man Verzögerungsschleifen und Rechendauern relativ leicht errechnen kann.&lt;br /&gt;
&lt;br /&gt;
= Anschluss =&lt;br /&gt;
[[Bild:Quarz_Anschluss_AVR.png|right|framed|Anschluss eines Quarzes an einen AVR]]&lt;br /&gt;
Die Kapazitäten von C1 und C2 entsprechen &#039;&#039;&#039;nicht&#039;&#039;&#039; der Lastkapazität des Quarzes!&lt;br /&gt;
Sie errechnen sich folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
C=2xCL-(CP+CI)&lt;br /&gt;
&lt;br /&gt;
*CP: Leiterbahnen bedingte Kapazität&lt;br /&gt;
*CI: Portbedingte Kapazität&lt;br /&gt;
*CL: Datenblatt des Quarzes&lt;br /&gt;
*CP+CI ca. 5pF&lt;br /&gt;
&lt;br /&gt;
Am Beispiel von CL = 32pF:&lt;br /&gt;
&lt;br /&gt;
C = 2x32pF-5pF = 59pF&lt;br /&gt;
&lt;br /&gt;
C1 und C2 sind die vom Hersteller des Kontrollers empfohlenen Werte, mit ihnen wird die Schwingsicherheit der Oszillatorschaltung gewährleistet. C1 und C2 sollten in etwa eingehalten werden (so + - 20% machen aber nichts aus).&lt;br /&gt;
&lt;br /&gt;
CL, der im Datenblatt angegebene Wert, wird beim Abgleich des Quarzes während der Herstellung benutzt. &lt;br /&gt;
&lt;br /&gt;
Wenn CL nicht eingehalten wird, hat das keinen Einfluss auf das Schwingen des Oszillators (solange der Faktor2 nicht überschritten wird) sondern nur auf die Frequenz, aber das in einem Maße (max. 0,01%der Frequenz), das für die meisten Mikrokontrolleranwendungen bedeutungslos ist.&lt;br /&gt;
{{Warnung |&lt;br /&gt;
;Soll ein Uhrenquarz eine Real-Time-Clock versorgen, so sind die Kapazitäten von großer Wichtigkeit. Die Uhr läuft bei falsch dimensionierten Kapazitäten gleich im 3-Stelligen PPM-Bereich falsch. Das bedeutet praktisch gleich mehrere Minuten pro Tag!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Einstellung der Fuses =&lt;br /&gt;
{{Warnung |&lt;br /&gt;
;Hier ist besondere Vorsicht geboten. Fast immer liegt hier das Problem, wenn ein Mikrocontroller nicht mehr läuft!&lt;br /&gt;
}}&lt;br /&gt;
Ein Quarz ist &#039;&#039;&#039;keine&#039;&#039;&#039; &amp;quot;External Clock&amp;quot;, sondern ein &amp;quot;External Crystal/Ceramic Resonator&amp;quot;. &lt;br /&gt;
Wenn man wirklich auf Nummer sicher gehen will, sollte man:&lt;br /&gt;
*Das Datenblatt &#039;&#039;&#039;genau&#039;&#039;&#039; lesen (Abschnitt &amp;quot;Clock Source&amp;quot;)&lt;br /&gt;
*Beim Fuse Calculator [http://www.engbedded.com/fusecalc] die Fuses berechnen lassen&lt;br /&gt;
*Nochmals genau überprüfen&lt;br /&gt;
Siehe auch: [[AVR_Fuses#Taktquellen_Fuse_Einstellung]]&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
*AppNotes von Atmel zum Thema Quarze: [http://www.atmel.com/Images/doc2521.pdf][http://www.atmel.com/Images/doc8128.pdf]&lt;br /&gt;
*Fuse Calculator: [http://www.engbedded.com/fusecalc]&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Schwingquarz&amp;diff=66377</id>
		<title>Schwingquarz</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Schwingquarz&amp;diff=66377"/>
		<updated>2012-05-16T20:41:17Z</updated>

		<summary type="html">&lt;p&gt;Cmf: Bild hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Bild:Quarz_offen.jpg|right|framed|Zwei geöffnete Quarze]]&lt;br /&gt;
Dieser Artikel beinhaltet Informationen zu Quarzen im Allgemeinen. Für die Verwendung zusammen mit AVRs siehe [[Quarze und AVR]]&lt;br /&gt;
&lt;br /&gt;
Ein Quarz, eigentlich &amp;quot;Schwingquarz&amp;quot;, ist ein Bauteil zu Erzeugung einer bestimmten Frequenz. Die Genauigkeit von Quarzen liegt bei 10-100ppm	(1ppm = 0,0001 %) und wird somit nur noch vom [[Quarzoszillator]] überboten.&lt;br /&gt;
&lt;br /&gt;
= Verwendung =&lt;br /&gt;
Quarze sind in folgenden Situationen sinnvoll / notwendig:&lt;br /&gt;
&lt;br /&gt;
* Interner Oszillator des µC zu langsam / ungenau&lt;br /&gt;
* In der Funktechnik zur genauen und stabilen Fequenzerzeugung&lt;br /&gt;
* Als Quarzfilter in Empfängern?&lt;br /&gt;
&lt;br /&gt;
= Frequenzen =&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Runde&amp;quot; Frequenzen (4MHz, 8MHz, 10MHz....) sind meist leichter erhältlich und haben den Vorteil, dass man Verzögerungsschleifen und Rechendauern relativ leicht errechnen kann.&lt;br /&gt;
&lt;br /&gt;
12MHz: Aus dieser Frequenz erzeugen Software-USB Programme oft den für USB notwendigen Takt.&lt;br /&gt;
0,032768Mhz: Diese Quarze werden häufig als Uhrenquarze verwendet&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Baudraten&amp;quot;-Frequenzen (siehe [[Baudratenquarz]]e sind ganzzahlige Vielfache der bei RS232 üblichen Baudraten. Mit Baudraten-Frequenzen kann  man mit den im Kontroller enthaltenen Teilern exakte Baudraten erreichen, mit &amp;quot;runden&amp;quot; Frequenzen entstehen u.U. einige Prozent Fehler.&lt;br /&gt;
&lt;br /&gt;
= Quarze in Eagle =&lt;br /&gt;
 &lt;br /&gt;
In Eagle findet man Quarze in der Bibliothek &amp;quot;Crystal&amp;quot; in der Untergruppe &amp;quot;Crystal&amp;quot;.&lt;br /&gt;
Im Forum wurde eine Bibliothek mit mehreren SMD-Quarzen und Oszillatoren hochgeladen: http://www.mikrocontroller.net/articles/Eagle-Bibliotheken#Kristalle_und_Oszillatoren&lt;br /&gt;
&lt;br /&gt;
= Siehe auch = &lt;br /&gt;
Wikipedia: [http://de.wikipedia.org/wiki/Schwingquarz]&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:Quarz_offen.jpg&amp;diff=66376</id>
		<title>Datei:Quarz offen.jpg</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:Quarz_offen.jpg&amp;diff=66376"/>
		<updated>2012-05-16T20:39:00Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Quarze_und_AVR&amp;diff=66375</id>
		<title>Quarze und AVR</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Quarze_und_AVR&amp;diff=66375"/>
		<updated>2012-05-16T20:34:45Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Diese Seite behandelt Quarze im Zusammenhang mit AVRs. Für allgemeine Informationen zum Thema siehe [[Quarz]].&lt;br /&gt;
&lt;br /&gt;
Die Genauigkeit von Quarzen liegt bei 10-100ppm	(1ppm = 0,0001 %) und wird somit nur noch vom [[Oszillator#Quarzoszillator|Quarzoszillator]] überboten. Außerdem sind Quarze im Gegensatz zum internen RC-Oszillator weniger temperaturunabhängig.&lt;br /&gt;
&lt;br /&gt;
= Verwendung =&lt;br /&gt;
Quarze sind in folgenden Situationen sinnvoll / notwendig:&lt;br /&gt;
&lt;br /&gt;
* Interner Oszillator des µC zu langsam&lt;br /&gt;
* Interner Oszillator des µC zu ungenau&lt;br /&gt;
**Bei Verwendung des [[UART]]&lt;br /&gt;
**Bei zeitkritischen Anwendungen wie z.B. einer Uhr&lt;br /&gt;
&lt;br /&gt;
= Wahl der richtigen Frequenz =&lt;br /&gt;
Vor allem als Anfänger denkt man sich, &#039;&#039;ich kaufe einfach mal 10MHz, das ist eine so schön gerade Zahl&#039;&#039;. Allerdings sind diese Quarze nur in den seltensten Fällen sinnvoll. Viel sinnvoller sind [[Baudratenquarz]]e. &amp;quot;Baudraten&amp;quot;-Frequenzen sind ganzzahlige Vielfache der bei RS232 üblichen Baudraten. Mit Baudrate-Frequenz kann  man exakte Baudraten erreichen, mit &amp;quot;runden&amp;quot; Frequenzen entstehen Fehler, weshalb oft nur sehr niedrige Baudraten möglich sind.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Runde&amp;quot; Frequenzen (4MHz, 8MHz, 10MHz....) sind meist leichter erhältlich und haben den Vorteil, dass man Verzögerungsschleifen und Rechendauern relativ leicht errechnen kann.&lt;br /&gt;
&lt;br /&gt;
= Anschluss =&lt;br /&gt;
[[Bild:Quarz_Anschluss_AVR.png|right|framed]]&lt;br /&gt;
Die Kapazitäten von C1 und C2 entsprechen &#039;&#039;&#039;nicht&#039;&#039;&#039; der Lastkapazität des Quarzes!&lt;br /&gt;
Sie errechnen sich folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
C=2xCL-(CP+CI)&lt;br /&gt;
&lt;br /&gt;
*CP: Leiterbahnen bedingte Kapazität&lt;br /&gt;
*CI: Portbedingte Kapazität&lt;br /&gt;
*CL: Datenblatt des Quarzes&lt;br /&gt;
*CP+CI ca. 5pF&lt;br /&gt;
&lt;br /&gt;
Am Beispiel von CL = 32pF:&lt;br /&gt;
&lt;br /&gt;
C = 2x32pF-5pF = 59pF&lt;br /&gt;
&lt;br /&gt;
C1 und C2 sind die vom Hersteller des Kontrollers empfohlenen Werte, mit ihnen wird die Schwingsicherheit der Oszillatorschaltung gewährleistet. C1 und C2 sollten in etwa eingehalten werden (so + - 20% machen aber nichts aus).&lt;br /&gt;
&lt;br /&gt;
CL, der im Datenblatt angegebene Wert, wird beim Abgleich des Quarzes während der Herstellung benutzt. &lt;br /&gt;
&lt;br /&gt;
Wenn CL nicht eingehalten wird, hat das keinen Einfluss auf das Schwingen des Oszillators (solange der Faktor2 nicht überschritten wird) sondern nur auf die Frequenz, aber das in einem Maße (max. 0,01%der Frequenz), das für die meisten Mikrokontrolleranwendungen bedeutungslos ist.&lt;br /&gt;
{{Warnung |&lt;br /&gt;
;Soll ein Uhrenquarz eine Real-Time-Clock versorgen, so sind die Kapazitäten von großer Wichtigkeit. Die Uhr läuft bei falsch dimensionierten Kapazitäten gleich im 3-Stelligen PPM-Bereich falsch. Das bedeutet praktisch gleich mehrere Minuten pro Tag!&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
= Einstellung der Fuses =&lt;br /&gt;
{{Warnung |&lt;br /&gt;
;Hier ist besondere Vorsicht geboten. Fast immer liegt hier das Problem, wenn ein Mikrocontroller nicht mehr läuft!&lt;br /&gt;
}}&lt;br /&gt;
Ein Quarz ist &#039;&#039;&#039;keine&#039;&#039;&#039; &amp;quot;External Clock&amp;quot;, sondern ein &amp;quot;External Crystal/Ceramic Resonator&amp;quot;. &lt;br /&gt;
Wenn man wirklich auf Nummer sicher gehen will, sollte man:&lt;br /&gt;
*Das Datenblatt &#039;&#039;&#039;genau&#039;&#039;&#039; lesen (Abschnitt &amp;quot;Clock Source&amp;quot;)&lt;br /&gt;
*Beim Fuse Calculator [http://www.engbedded.com/fusecalc] die Fuses berechnen lassen&lt;br /&gt;
*Nochmals genau überprüfen&lt;br /&gt;
Siehe auch: [[AVR_Fuses#Taktquellen_Fuse_Einstellung]]&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
*AppNotes von Atmel zum Thema Quarze: [http://www.atmel.com/Images/doc2521.pdf][http://www.atmel.com/Images/doc8128.pdf]&lt;br /&gt;
*Fuse Calculator: [http://www.engbedded.com/fusecalc]&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66364</id>
		<title>Vorlage:Warnung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66364"/>
		<updated>2012-05-16T09:33:23Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;margin:1em; padding:1em; border:solid 2px #ee0040;&amp;quot;&amp;gt;&lt;br /&gt;
{{{1|}}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66362</id>
		<title>Vorlage:Warnung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66362"/>
		<updated>2012-05-16T09:31:57Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;min-height: 30px; margin:1em; padding:1em; border:solid 2px #ee0040;&amp;quot;&amp;gt;&lt;br /&gt;
{{{1|}}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer_Diskussion:Cmf&amp;diff=66361</id>
		<title>Benutzer Diskussion:Cmf</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer_Diskussion:Cmf&amp;diff=66361"/>
		<updated>2012-05-16T09:31:07Z</updated>

		<summary type="html">&lt;p&gt;Cmf: /* Vorlage:Warnung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Vorlage:Warnung ==&lt;br /&gt;
&lt;br /&gt;
Gut, ist wieder weg.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Hi, die letzten Änderungen zerbröseln etwas das Layout beim Verwenden der Vorlage, siehe zum Beispiel die falsche Einrückung von &amp;quot;Achtung&amp;quot; in http://www.mikrocontroller.net/wikisoftware/index.php?title=AVR_Fuses&amp;amp;oldid=65098#Ponyprog2000&lt;br /&gt;
&lt;br /&gt;
Eigentlich sehe ich nicht, warum die ein Bildchen eingebaut werden muss. Wer eine Warnung in fettem, rotem Rahmen nicht beachtet oder übersieht, wird sie auch nicht beachten oder übersehen, wenn ein fettes, rotes Ausrufezeichen darin ist... --[[Benutzer:Gjlayde|Gjlayde]] 05:41, 16. Mai 2012 (UTC)&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66353</id>
		<title>Vorlage:Warnung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66353"/>
		<updated>2012-05-15T22:54:08Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;min-height: 30px; margin:10px; padding:10px; border:solid 2px #ee0040;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;float:left; margin-right:20px; margin-bottom:10px&amp;quot;&amp;gt;[[Bild:Ausrufezeichen.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
{{{1|}}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Schwingquarz&amp;diff=66347</id>
		<title>Schwingquarz</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Schwingquarz&amp;diff=66347"/>
		<updated>2012-05-15T22:38:24Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dieser Artikel beinhaltet Informationen zu Quarzen im Allgemeinen. Für die Verwendung zusammen mit AVRs siehe [[Quarze und AVR]]&lt;br /&gt;
&lt;br /&gt;
Ein Quarz, eigentlich &amp;quot;Schwingquarz&amp;quot;, ist ein Bauteil zu Erzeugung einer bestimmten Frequenz. Die Genauigkeit von Quarzen liegt bei 10-100ppm	(1ppm = 0,0001 %) und wird somit nur noch vom [[Quarzoszillator]] überboten.&lt;br /&gt;
&lt;br /&gt;
= Verwendung =&lt;br /&gt;
Quarze sind in folgenden Situationen sinnvoll / notwendig:&lt;br /&gt;
&lt;br /&gt;
* Interner Oszillator des µC zu langsam / ungenau&lt;br /&gt;
* In der Funktechnik zur genauen und stabilen Fequenzerzeugung&lt;br /&gt;
* Als Quarzfilter in Empfängern?&lt;br /&gt;
&lt;br /&gt;
= Frequenzen =&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Runde&amp;quot; Frequenzen (4MHz, 8MHz, 10MHz....) sind meist leichter erhältlich und haben den Vorteil, dass man Verzögerungsschleifen und Rechendauern relativ leicht errechnen kann.&lt;br /&gt;
&lt;br /&gt;
12MHz: Aus dieser Frequenz erzeugen Software-USB Programme oft den für USB notwendigen Takt.&lt;br /&gt;
0,032768Mhz: Diese Quarze werden häufig als Uhrenquarze verwendet&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Baudraten&amp;quot;-Frequenzen (siehe [[Baudratenquarz]]e sind ganzzahlige Vielfache der bei RS232 üblichen Baudraten. Mit Baudraten-Frequenzen kann  man mit den im Kontroller enthaltenen Teilern exakte Baudraten erreichen, mit &amp;quot;runden&amp;quot; Frequenzen entstehen u.U. einige Prozent Fehler.&lt;br /&gt;
&lt;br /&gt;
= Quarze in Eagle =&lt;br /&gt;
 &lt;br /&gt;
In Eagle findet man Quarze in der Bibliothek &amp;quot;Crystal&amp;quot; in der Untergruppe &amp;quot;Crystal&amp;quot;.&lt;br /&gt;
Im Forum wurde eine Bibliothek mit mehreren SMD-Quarzen und Oszillatoren hochgeladen: http://www.mikrocontroller.net/articles/Eagle-Bibliotheken#Kristalle_und_Oszillatoren&lt;br /&gt;
&lt;br /&gt;
= Siehe auch = &lt;br /&gt;
Wikipedia: [http://de.wikipedia.org/wiki/Schwingquarz]&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66341</id>
		<title>Vorlage:Warnung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66341"/>
		<updated>2012-05-15T19:25:50Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;min-height: 30px; margin:1em; padding:1em; border:solid 2px #ee0040;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;!--&amp;lt;div style=&amp;quot;float:left; width:30px&amp;quot;&amp;gt;[[Datei:Ausrufezeichen.png]]&amp;lt;/div&amp;gt;--&amp;gt;&lt;br /&gt;
    &amp;lt;!--&amp;lt;div style=&amp;quot;float:right; width: 90%&amp;quot;&amp;gt;--&amp;gt;{{{1|}}}&amp;lt;!--&amp;lt;/div&amp;gt;--&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66340</id>
		<title>Vorlage:Warnung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66340"/>
		<updated>2012-05-15T19:25:21Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;min-height: 30px; margin:1em; padding:1em; border:solid 2px #ee0040;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;!--&amp;lt;div style=&amp;quot;float:left; width:30px&amp;quot;&amp;gt;[[Datei:Ausrufezeichen.png]]&amp;lt;/div&amp;gt;--&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;float:right; width: 90%&amp;quot;&amp;gt;{{{1|}}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66339</id>
		<title>Vorlage:Warnung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66339"/>
		<updated>2012-05-15T19:25:03Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;min-height: 30px; margin:1em; padding:1em; border:solid 2px #ee0040;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;float:left; width:30px&amp;quot;&amp;gt;[[Datei:Ausrufezeichen.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;!--&amp;lt;div style=&amp;quot;float:right; width: 90%&amp;quot;&amp;gt;{{{1|}}}&amp;lt;/div&amp;gt;--&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66338</id>
		<title>Vorlage:Warnung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66338"/>
		<updated>2012-05-15T19:24:24Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;min-height: 30px; margin:1em; padding:1em; border:solid 2px #ee0040;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;float:left; width:30px&amp;quot;&amp;gt;[[Datei:Ausrufezeichen.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;float:right; width: 90%&amp;quot;&amp;gt;{{{1|}}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66337</id>
		<title>Vorlage:Warnung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66337"/>
		<updated>2012-05-15T19:24:03Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;height: 100%; margin:1em; padding:1em; border:solid 2px #ee0040;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;float:left; width:30px&amp;quot;&amp;gt;[[Datei:Ausrufezeichen.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;float:right; width: 90%&amp;quot;&amp;gt;{{{1|}}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66336</id>
		<title>Vorlage:Warnung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66336"/>
		<updated>2012-05-15T19:23:30Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;min-height: 30px; margin:1em; padding:1em; border:solid 2px #ee0040;&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;float:left; width:30px&amp;quot;&amp;gt;[[Datei:Ausrufezeichen.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;float:right; width: 90%&amp;quot;&amp;gt;{{{1|}}}&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66335</id>
		<title>Vorlage:Warnung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66335"/>
		<updated>2012-05-15T19:22:40Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;min-height: 30px; margin:1em; padding:1em; border:solid 2px #ee0040;&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;float:left; width:30px&amp;quot;&amp;gt;[[Datei:Ausrufezeichen.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;float:right; width: 90%&amp;quot;&amp;gt;{{{1|}}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66333</id>
		<title>Vorlage:Warnung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66333"/>
		<updated>2012-05-15T19:22:20Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;min-height: 30px; margin:1em; padding:1em; border:solid 2px #ee0040;&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;float:left; width:30px&amp;quot;&amp;gt;[[Datei:Ausrufezeichen.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;float:right; width: 100%&amp;quot;&amp;gt;{{{1|}}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66331</id>
		<title>Vorlage:Warnung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66331"/>
		<updated>2012-05-15T19:21:38Z</updated>

		<summary type="html">&lt;p&gt;Cmf: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;min-height: 30px; margin:1em; padding:1em; border:solid 2px #ee0040;&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;float:left; width:30px&amp;quot;&amp;gt;[[Datei:Ausrufezeichen.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;float:right;&amp;quot;&amp;gt;{{{1|}}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66330</id>
		<title>Vorlage:Warnung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Vorlage:Warnung&amp;diff=66330"/>
		<updated>2012-05-15T19:20:56Z</updated>

		<summary type="html">&lt;p&gt;Cmf: Ausrufezeichen eingefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;min-height: 30px; margin:1em; padding:1em; border:solid 2px #ee0040;&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;float:left; width:10%&amp;quot;&amp;gt;[[Datei:Ausrufezeichen.png]]&amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div style=&amp;quot;float:right; width:10%&amp;quot;&amp;gt;{{{1|}}}&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Datei:Ausrufezeichen.png&amp;diff=66329</id>
		<title>Datei:Ausrufezeichen.png</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Datei:Ausrufezeichen.png&amp;diff=66329"/>
		<updated>2012-05-15T19:14:11Z</updated>

		<summary type="html">&lt;p&gt;Cmf: Selbst gezeichnet&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Selbst gezeichnet&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR_Checkliste&amp;diff=66328</id>
		<title>AVR Checkliste</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR_Checkliste&amp;diff=66328"/>
		<updated>2012-05-15T18:56:06Z</updated>

		<summary type="html">&lt;p&gt;Cmf: /* Quarz oder Quarzoszillator angeschlossen? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:AVR]]&lt;br /&gt;
Diese Seite soll als erste Anlaufstelle dienen, wenn der [[AVR]]-Mikrocontroller mal wieder nicht so will wie er soll. Es wird versucht, die Standardfehler und Probleme aufzulisten und zu erklären, was man dagegen tun kann.&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
&lt;br /&gt;
=== Anderen Controller benutzt als den im Schaltplan: Pinkompatibilität sichergestellt? ===&lt;br /&gt;
&lt;br /&gt;
Nur wenige AVR-Controller sind pinkompatibel und damit untereinander austauschbar. Manchmal liegen gar die am dringensten benötigten Funktionen (ISP-Programmierung) bei anderen Controllern auf anderen Pins. Unbedingt vorher die Belegungen anhand der Datenblätter vergleichen!&lt;br /&gt;
&lt;br /&gt;
=== Fuses richtig gesetzt? ===&lt;br /&gt;
&lt;br /&gt;
Die AVR-Controller haben &#039;Fuses&#039; (deutsch: &#039;Sicherungen&#039;), die das Verhalten des Prozessors auf grundlegender Ebene bestimmen. Ein häufiger Fehler ist beispielsweise, dass die falsche Taktquelle gewählt wurde (Fuse &amp;quot;CKSEL&amp;quot; etc.): einige AVRs können mit dem internen Oszillator (&amp;lt;i&amp;gt;internal R/C&amp;lt;/i&amp;gt;), mit einem externen Oszillator (&amp;lt;i&amp;gt;external clock&amp;lt;/i&amp;gt;), mit einem Quarz (&amp;lt;i&amp;gt;external crystal&amp;lt;/i&amp;gt;) oder mit einem Resonator (&amp;lt;i&amp;gt;external R/C&amp;lt;/i&amp;gt;) betrieben werden. Wenn die Einstellung über die Fusebits nicht dazu passt (z. B. &amp;lt;i&amp;gt;external clock&amp;lt;/i&amp;gt; statt &amp;lt;i&amp;gt;external crystal&amp;lt;/i&amp;gt;), fehlt dem Controller unter Umständen der Systemtakt und er läuft nicht an, oder man bekommt auf der seriellen Schnittstelle Nonsens, oder die Timer bzw. Zeitschleifen im Programm laufen zu langsam oder zu schnell.&lt;br /&gt;
&lt;br /&gt;
Eine andere Fuse (JTAGEN) schaltet auf einem Port (z.&amp;amp;nbsp;B. PORTC auf ATMega32) die JTAG-Unterstützung ein bzw. aus. Wenn sie eingeschaltet ist, funktionieren vier Bits dieses Ports nicht wie gewohnt, da sie für die JTAG-Schnittstelle reserviert werden.&lt;br /&gt;
&lt;br /&gt;
In dem zum STK500 gehörenden Entwicklungstool &#039;AVR Studio&#039; gibt es in der Programmer-Dialogbox einen Tab &#039;Fuses&#039;, der controllerabhängig den Status der Fusebits anzeigt und Änderungen ermöglicht.&lt;br /&gt;
Siehe auch: [[AVR Fuses]].&lt;br /&gt;
&lt;br /&gt;
=== ISP-Adapter ===&lt;br /&gt;
&lt;br /&gt;
Bei ISP-Programmieradaptern für den Parallelport kann es zu Inkompatibilitäten mit manchen Ports kommen. Tritt das Problem auch auf, wenn der ISP-Adapter an einem anderen Rechner angeschlossen ist? Funktioniert es vielleicht mit einer anderen Software? Siehe auch: [[AVR In System Programmer]]).&lt;br /&gt;
&lt;br /&gt;
Bei seriellem Programmer mit Controller (STK500, Atmel AVRISP etc.): Programmieren dauert sehr lange, es gibt Fehler. Abhilfe: ISP Taktrate richtig einstellen (&amp;lt;1/4 F_CPU).&lt;br /&gt;
&lt;br /&gt;
Beim Programmieren mit dem usbasp Programmieradapter muss die Geschwindigkeit richtig eingestellt werden. Bei einem AVR der auf den eingebauten 1 Mhz läuft muss mit langsamer Geschwindigkeit (Jumper zu) programmiert werden.&lt;br /&gt;
&lt;br /&gt;
=== Programmieren via SPI und angeschlossene SPI-Hardware ===&lt;br /&gt;
Wenn Peripherie über SPI angebunden ist, muss sich diese zum Programmierzeitpunkt auf dem Bus neutral verhalten. Normalerweise bedeutet dies, dass die Slave-Select/Chip-Select-Leitungen der Peripherie auf high gezogen werden müssen, wenn die Chips keinen internen Pull-Up haben. Werte von 10 kΩ bis 100 kΩ für normale Anwendungen haben sich bewährt.&lt;br /&gt;
&lt;br /&gt;
=== Spannungsversorgung richtig angeschlossen? ===&lt;br /&gt;
&lt;br /&gt;
Der AVCC-Pin ist der Versorgungsanschluss für den AD-Wandler und den zugehörigen Port. Er ist nicht an allen AVRs vorhanden; wenn er aber vorhanden ist, so muss er auf jeden Fall angeschlossen sein, auch wenn der AD-Wandler nicht benutzt wird. Wird der AD-Wandler verwendet, sollte zur Verbesserung der Genauigkeit der AVCC-Pin über einen Lowpass-Filter angeschlossen werden (siehe Datenblatt).&lt;br /&gt;
Oft funktioniert die Programmierung des Controllers auch, wenn Vcc oder GND nicht richtig angeschlossen ist. Zur Sicherheit kann man mit einem Messgerät direkt an den Anschlüssen des AVRs kontrollieren (VCC-GND, AVCC-GND) prüfen, ob die Verbindungen korrekt sind. Es empfiehlt sich, vor dem Einsetzen bzw. Einlöten des Controllers die Versorgungsanschlüsse nochmals zu prüfen, um sicherzustellen, dass man den IC nicht durch eine zu hohe Spannung aufgrund eines Fehlers in der Versorgung zerstört.&lt;br /&gt;
&lt;br /&gt;
=== Reset-Pin korrekt beschaltet? ===&lt;br /&gt;
&lt;br /&gt;
Der Reset-Anschluss am AVR ist &#039;active-low&#039;, d. h. wenn man den Pin mit GND (Masse) verbindet, wird der Controller zurückgesetzt gehalten. Zwar haben die meisten(!) AVRs einen internen Pullup-Widerstand, der den Reset-Pin gegen VCC &amp;quot;zieht&amp;quot;, dieser ist jedoch relativ hochohmig (ca. 50 kΩ, vgl. Datenblatt) und reicht in extrem stark gestörter Umgebung nicht aus, um den Reset-Pin sicher &amp;quot;hochzuhalten&amp;quot;. Als Mindestbeschaltung empfiehlt sich dringend, einen externen Pullup-Widerstand vorzusehen (typisch 10 kΩ), der den Reset-Pin mit VCC verbindet. Er sollte nicht kleiner als 4,7 kΩ sein, da der Programmieradapter sonst eventuell den Reset-Pin während des Programmiervorgangs nicht sicher auf &amp;quot;low&amp;quot; ziehen kann. Mit einem Oszilloskop kann man gut überprüfen, ob der Pegel am Reset-Pin sauber zwischen high und low wechselt. Zusätzlich sollte man auch noch einen Kondensator 47 nF oder 100 nF zwischen Reset-Pin und GND anordnen. Dieses RC-Glied sorgt dafür, dass der Controller beim Einschalten der Versorgungsspannung für eine definierte Zeitspanne im Reset gehalten wird. Im laufenden Betrieb sorgt der Kondensator dafür, dass der Reseteingang unempfindlich gegenüber Spikes und Glitches wird. Er sollte deshalb unmittelbar in Pin-Nähe beim Prozessor untergebracht werden. Dieser Kondensator darf jedoch nicht verwendet werden, wenn [[debugWIRE]] möglich sein soll.&lt;br /&gt;
&lt;br /&gt;
Atmel empfiehlt zusätzlich noch zum Schutz vor Überspannungen eine externe Diode nach VCC (&amp;quot;Clamp-Diode&amp;quot;), da für den Reset-Pin keine interne vorhanden ist. Diese Diode bereitet jedoch bei manchen Programmieradaptern Schwierigkeiten. Allerdings schützt die Diode den Controller davor, in den High-Voltage Programming Mode zu schalten, zum Beispiel als Folge von Störspannung wegen EMV, und dadurch den Programmspeicher zu überschreiben.&lt;br /&gt;
&lt;br /&gt;
=== Flashen / Lesen / Fuse nur ein mal möglich ===&lt;br /&gt;
&lt;br /&gt;
Es kann vorkommen das ein AVR nur ein mal programmiert werden kann, danach geht es nicht mehr (z.B. Typ wird nicht mehr erkannt). Erst nachdem die Versorgungsspannung getrennt / wider verbunden ist geht es erneut.&lt;br /&gt;
&lt;br /&gt;
In diesem Fall ist meistens der Resetpin kurzgeschlossen, daher lässt sich der AVR ein mal programmieren.&lt;br /&gt;
&lt;br /&gt;
Der Reset PIN müsste bei korrekter Beschaltung eine Spannung nahe VCC (z.B. 4.9V) aufweisen, ist die Spannung bei GND ist der Pin kurzgeschlossen, und verursacht dieses Problem.&lt;br /&gt;
&lt;br /&gt;
=== Abblockkondensator(en) ordnungsgemäß installiert? ===&lt;br /&gt;
&lt;br /&gt;
Abblockkondensatoren (&amp;quot;Bunker-Kondensatoren&amp;quot;) dienen dazu, sehr kurze Versorgungsspannungseinbrüche, die durch Schaltvorgänge verursacht werden können, zu kompensieren. Diesen Zweck erfüllen sie optimal, wenn folgende Regeln eingehalten werden: &lt;br /&gt;
&lt;br /&gt;
* Ein Abblockkondensator sollte möglichst dicht am IC sitzen.&lt;br /&gt;
&lt;br /&gt;
* Jedes IC in einer Schaltung sollte einen Abblockkondensator besitzen.&lt;br /&gt;
&lt;br /&gt;
* Bei ICs mit mehreren Anschlüssen für VCC und GND sollte jedes VCC-GND-Paar mit einem eigenen Abblockkondensator beschaltet werden (z. B. AVRs in SMD-Bauform wie dem ATmega16A also mit vier Kondensatoren).&lt;br /&gt;
&lt;br /&gt;
* Es sollten keramische Kondensatoren mit einer Kapazität von 100 nF verwendet werden. Größere Kondensatoren, etwa 10 µF-Elkos, sind für diese Aufgabe &#039;&#039;nicht&#039;&#039; geeignet, weil sie &amp;quot;zu langsam&amp;quot; sind!&lt;br /&gt;
&lt;br /&gt;
=== Quarz oder Quarzoszillator angeschlossen? ===&lt;br /&gt;
&lt;br /&gt;
Die neueren AVRs haben einen internen [[Oszillator]], der im Auslieferungszustand über die entsprechenden Fuses eingeschaltet ist. In diesem Fall muss kein externer [[Quarze und AVR|Quarz]] mehr angeschlossen werden. Man kann in den [[AVR Fuses|Fuse-Bits]] aber einstellen, dass man einen externen Taktgenerator (&#039;&#039;external clock&#039;&#039;, z. B. Quarzoszillator) oder externen Quarz (&#039;&#039;external crystal&#039;&#039;) verwenden möchte.&lt;br /&gt;
&lt;br /&gt;
Dann, oder wenn der AVR keinen internen Takt hat, wird an die entsprechenden Pins des Controllers ein Quarz (&#039;&#039;external crystal&#039;&#039;, Bauelement mit zwei &amp;quot;Beinchen&amp;quot;) oder Quarzoszillator (&#039;&#039;external clock&#039;&#039;, Bauelement mit vier &amp;quot;Beinchen&amp;quot;) angeschlossen. Im Falle eines Quarzes werden die XTAL-Pins mit den beiden Anschlüssen des Quarzes und jeweils mit einem Kondensator (ca. 12 bis 22 pF) (vgl. Datenblatt ATMega 8) gegen Masse angeschlossen. Im Falle eines Quarzoszillators reicht es aus, den Taktausgang mit dem XTAL1-Pin zu verbinden, und den XTAL2-Pin unbeschaltet zu lassen. Die Fuses sind entsprechend einzustellen.&lt;br /&gt;
&lt;br /&gt;
=== Alle Ground-Anschlüsse beschaltet? ===&lt;br /&gt;
&lt;br /&gt;
Bei AVRs mit mehreren Ground-Anschlüssen müssen alle Anschlüsse beschaltet werden. Siehe http://www.mikrocontroller.net/forum/read-1-107259.html&lt;br /&gt;
&lt;br /&gt;
=== Alle Lötstellen in Ordnung? ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Kalte&amp;quot;, d.h. schlechte Lötstellen erkennt man an ihrer matten Oberfläche (bei bleihaltigem Lot). Bei beschädigten Lötstellen erkennt man oft einen Riss, der sich kreisförmig um die Mitte des Lötpunktes herum gebildet hat. Solche Stellen verursachen oft erst bei mechanischer Beanspruchung Probleme.&lt;br /&gt;
&lt;br /&gt;
Bei kleinen Abständen (SMD-Bauteile) müssen besonders Verbindungen zwischen benachbarten Lötungen kontrolliert werden.&lt;br /&gt;
&lt;br /&gt;
Bei Lochrasterplatinen kann man mit einem spitzen Messer (Bastelmesser) die Zwischenräume von möglichen leitenden Verbindungen befreien. &lt;br /&gt;
&lt;br /&gt;
=== Eingänge ===&lt;br /&gt;
&lt;br /&gt;
Taster müssen:&lt;br /&gt;
&lt;br /&gt;
* entprellt werden ([[Entprellung]])&lt;br /&gt;
&lt;br /&gt;
* einen [[AVR-GCC-Tutorial#Tasten_und_Schalter|Pullup-Widerstand]] besitzen, so sie &#039;&#039;active-low&#039;&#039; betrieben werden, d.h. wenn beim Tastendruck der Pin mit GND (Masse) verbunden wird (dies ist die übliche Anschaltung). Man kann einen externen Pull-Up Widerstand (typ. 10 kOhm) benutzen oder den internen aktivieren (DDR als Eingang also &amp;quot;0&amp;quot;, PORT auf &amp;quot;1&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Will man einen Taster &#039;&#039;active-high&#039;&#039; betreiben, soll also bei Tastendruck eine &amp;quot;1&amp;quot; in PIN gelesen werden, ist ein externer Pull-Down-Widerstand (typ. 10 kOhm) gegen GND anzuschließen, denn interne Pull-Downs sind nicht verfügbar.&lt;br /&gt;
&lt;br /&gt;
Symptome: Aufgrund des Prellens bekommt man bei einem Tastendruck statt eines Signals mehrere, und beim fehlenden Pullup fängt man sich Störungen (z.&amp;amp;nbsp;B. das 50 Hz-Netzbrummen) ein, da der Pin nicht auf einem &amp;quot;definierten Pegel&amp;quot; liegt, wenn der Taster nicht geschlossen ist. Soll z.&amp;amp;nbsp;B. bei einem Tastendruck eine LED angehen, dann leuchtet die LED durch das Netzbrummen plötzlich mit 50 Hz anstatt aus zu sein.&lt;br /&gt;
&lt;br /&gt;
* active low: ein Anschluss des Tasters an den Port-Pin, den anderen Taster-Anschluss an GND; internen Pull-Up-Widerstand aktivieren oder externen Widerstand zwischen Port-Pin und VCC.&lt;br /&gt;
&lt;br /&gt;
* active high: Taster zwischen Port-Pin und VCC; externen Widerstand zwischen Port-Pin und GND.&lt;br /&gt;
&lt;br /&gt;
=== Ausgänge ===&lt;br /&gt;
&lt;br /&gt;
Man sollte darauf achten, das &amp;quot;kritische&amp;quot; Ausgänge, d.h. Ausgänge, über die nicht &amp;quot;nur&amp;quot; eine LED geschaltet wird, einen definierten Zustand haben, wenn der Portpin auf &amp;quot;Eingang&amp;quot; und damit hochohmig geschaltet ist. Dadurch wird sichergestellt, dass beim Einschalten nicht kurz ein Verbraucher geschaltet wird (z.&amp;amp;nbsp;B. &amp;quot;Zucken&amp;quot; eines Motors). Dies kann man bewerkstelligen, indem man extern Widerstände (auch hier Pull-Up bzw. Pull-Down genannt, typ. 10 kOhm) an den Ausgangs-Pins vorsieht, die den Ausgang auf den gewünschten Zustand ziehen.&lt;br /&gt;
&lt;br /&gt;
=== Besonderheiten bei ATmega128 und seinen Derivaten im 64-Pin-Gehäuse===&lt;br /&gt;
&lt;br /&gt;
[[Bild:isp.png|thumb|300px|right|ISP-Adapter]]&lt;br /&gt;
Der ATmega64 und der ATmega128 sowie alle vom ATMega128 abgeleiteten AVRs im 64-Pin-Gehäuse (ATMega641/1281/2561 sowie AT90CAN32/64/128, Ausnahmen sind nur AT90USB64/128, die eine ganz andere Pinbelegung haben) haben besondere Fallstricke, über die man bei nicht ausreichendem Datenblattstudium leicht stolpert. &lt;br /&gt;
&lt;br /&gt;
* Der erste betrifft den Anschluss der ISP-Signale (MISO, MOSI, SCK, RESET). Dieser erfolgt nicht wie bei den meisten anderen AVR-Controllern an den gleichnamigen Pins, sondern an PDI, PDO, SCK und RESET. Die Pinzuordnung ist:&lt;br /&gt;
:* MOSI → PE0 (Pin 2)&lt;br /&gt;
:* MISO → PE1 (Pin 3)&lt;br /&gt;
:* SCK → PB1 (Pin 11)&lt;br /&gt;
:* RESET → RESET (Pin 20)&lt;br /&gt;
: PEN (Pin 1) hat für normale ISP-Adapter keine Bedeutung und kann offen gelassen oder direkt mit Vcc verbunden werden. Die Benutzung der Pins PDI und PDO anstelle von MOSI und MISO gilt für praktisch alle ATmega128-Derivate im 64-Pin-TQFP-Gehäuse, darunter AT90CAN32/64/128 und ATmega641/1281/2561. Im Zweifelsfall im Datenblatt (Pin Configuration) nachsehen, ob PE0 und PE1 mit &amp;quot;PDI&amp;quot; bzw. &amp;quot;PDO&amp;quot; beschriftet sind.&lt;br /&gt;
&lt;br /&gt;
* Die zweite kleine Gemeinheit betrifft die M103C-Fuse (ATmega103 Compatibility Mode, nur bei den ATmega-Typen, nicht beim AT90CAN32/64/128). Diese ist bei fabrikneuen Atmega64/128 gesetzt und sorgt dafür, dass sich diese wie ein Atmega103 verhalten.&lt;br /&gt;
** Dies hat zur Folge, dass ein für den ATmega64 oder ATmega128 geschriebenes Programm beim ersten RET abstürzt, da der SRAM an einer anderen Stelle endet als erwartet und somit der Prozessor keine gültige Rücksprungadresse vom Stack holen kann. &lt;br /&gt;
** Außerdem funktionieren einige IO-Pins an PORTC, PORTF und PORTG anders.&lt;br /&gt;
** Für weitere Infos bzgl. [[TWI]], [[UART]], [[Timer]], [[Bootloader]] und Kalibrierung des internen RC-Oszillators unbedingt das Datenblatt lesen.&lt;br /&gt;
&lt;br /&gt;
== Software ==&lt;br /&gt;
&lt;br /&gt;
=== Alle Interruptvektoren definiert? ===&lt;br /&gt;
&lt;br /&gt;
Wenn man irgendwelche [[Interrupt]]vektoren verwendet, sollte man alle definieren, auch die nicht benutzten. Passiert es dann aufgrund eines Fehlers, dass ein Interrupt unbeabsichtigt ausgeführt wird, so führt der Controller dann eine definierte Aktion aus. Benutzt man eine Hochsprache wie C oder Basic, nimmt einem der Compiler diese Arbeit ab.&lt;br /&gt;
&lt;br /&gt;
Ausserdem sollte man immer im Datenblatt des Controllers nachsehen, wie die Interrupttabelle aufgebaut ist. Die kleinen AVRs verwenden ein RCALL zum Anspringen der Interrupts, welches 1 Wort lang ist. Die grossen AVRs mit mehr als 8 KiBi FLASH verwenden ein CALL, welches 2 Worte lang ist. Verwendet man nun  den falschen Befehl, verschieben sich die Einsprungadressen und das Chaos ist perfekt.&lt;br /&gt;
&lt;br /&gt;
In einem komplett interruptlosen Programm kann man auf die Interrupttabelle selbstverständlich verzichten (erkennbar daran, dass nirgendwo im Code Interrupts mittels Assembler-Befehl SEI eingeschaltet werden).&lt;br /&gt;
&lt;br /&gt;
Oft hilft es einen Catch All Interruptvektor zu definieren um herauszufinden ob ein Fehler (z.B. ein Neubeginn des Programms) vorliegt.&lt;br /&gt;
&amp;lt;c&amp;gt;#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ISR (BADISR_vect)&lt;br /&gt;
{&lt;br /&gt;
    // Hier eine Fehlerausgabe definieren.&lt;br /&gt;
    // Z.B. UART-Ausgabe oder ein PIN toggeln&lt;br /&gt;
}&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dann findet man solche Fehler recht schnell.&lt;br /&gt;
&lt;br /&gt;
=== Alle Konfigurationsregister korrekt initialisiert? ===&lt;br /&gt;
&lt;br /&gt;
Alle benötigten Konfigurationsregister (auch &amp;quot;I/O-Register&amp;quot; genannt) eines Mikrocontrollers müssen korrekt initialisiert werden. Bei Fehlfunktionen sollten diese Konfigurationen noch einmal mit dem Datenblatt abgeglichen werden. &lt;br /&gt;
Manchmal ist es auch sinnvoll, bestimmte Funktionen explizit abzuwählen. Ein Beispiel hierfür ist der [[Analog-Komparator]] des AVR: Schaltet man diesen ab, wenn man ihn nicht benötigt, kann man dadurch ein wenig Strom sparen. &lt;br /&gt;
Wenn man besonders &amp;quot;sauber&amp;quot; programmieren möchte, initialisiert man Konfigurationsregister immer, d.h. auch wenn sie nicht im Programm verwendet werden. Dies verhindert mögliche zufällige Fehlkonfigurationen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Stackpointer initialisiert? (Nur in Assembler relevant) ===&lt;br /&gt;
&lt;br /&gt;
Fehlerbeschreibung: &#039;&#039;Das Programm lief, bis ein &amp;quot;rcall&amp;quot; oder ein Interrupt eingefügt wurde. Danach ging plötzlich gar nichts mehr.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Wahrscheinliche Ursache: Der Stack ist ein spezieller Bereich im RAM, der von Sprungbefehlen und Interruptaufrufen dazu verwendet wird, die Rücksprungadresse ins Hauptprogramm zu speichern.  Da der Stack bei den AVRs nach &amp;quot;unten&amp;quot; wächst, d.h. in Richtung Anfang des RAMs, wird er üblicherweise ans Ende des RAMs gelegt. Der Stack muss vor der ersten Benutzung, am besten direkt am Anfang des Programms, initialisiert werden (sonst ist nach einem Sprung in ein Unterprogramm die Rücksprungadresse undefiniert und das Programm wird an einer unvorhersehbaren Stelle weiter ausgeführt, was in der Regel einen Absturz zur Folge hat). &amp;quot;Den Stack initialisieren&amp;quot; bedeutet, den Stackpointer auf den gewünschten &amp;quot;Startwert&amp;quot; zu setzen. Meistens wird dafür die letzte RAM-Adresse gewählt. &lt;br /&gt;
&lt;br /&gt;
Die Initialisierung unterscheidet sich geringfügig je nach verwendetem AVR. Bei den alten AT90xxxx und den ATtinys ist sie mit zwei Zeilen erledigt:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt;&lt;br /&gt;
       ldi r16, RAMEND   ;Die Adresse der letzten Stelle im RAM in r16 laden&lt;br /&gt;
       out SPL, r16      ;Die Adresse in das Register SPL ausgeben&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Da die ATmegas mehr RAM haben, reicht das 8 bit-Register SPL nicht mehr, und es ist ein zweites (SPH) dazugekommen.  Die Initialisierung des Stacks erfordert hier vier Zeilen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;avrasm&amp;gt;&lt;br /&gt;
       ldi r16, LOW(RAMEND)    ;Untere 8 bit des 16 bit-Wertes RAMEND laden&lt;br /&gt;
       out SPL, r16&lt;br /&gt;
       ldi r16, HIGH(RAMEND)   ;Obere 8 bit laden&lt;br /&gt;
       out SPH, r16&lt;br /&gt;
&amp;lt;/avrasm&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 16bit-Register in richtiger Reihenfolge geladen/gelesen? (Nur in Assembler relevant) ===&lt;br /&gt;
&lt;br /&gt;
Bei den 16-bit Registern (z.&amp;amp;nbsp;B. Timer1) genau die Hinweise im Kapitel &amp;quot;Accessing 16-bit Registers&amp;quot; beachten!&lt;br /&gt;
&lt;br /&gt;
So muss z.&amp;amp;nbsp;B. das High-Byte VOR dem Low-Byte geschrieben werden, weil mit dem Schreiben des Low Byte das gesamte Register &amp;quot;übernommen&amp;quot; wird.&lt;br /&gt;
Beim Lesen muss zuerst das Low-Byte gelesen werden, dann das High-Byte.&lt;br /&gt;
Es wird dadurch garantiert, dass sich zwischen den beiden einzelnen Befehlen nicht noch das Register weiter verändert, z.&amp;amp;nbsp;B. beim 16bit Counter.&lt;br /&gt;
Möglich wird das durch ein &amp;quot;temporary Register&amp;quot;, von dem es aber nur eines gibt - was beachtet werden muss, da zwischen diesen beiden einzelnen Lese-/Schreib-Befehlen kein Interrupt auftreten darf, der selber das temporary Rgegister benutzt.&lt;br /&gt;
&lt;br /&gt;
In C oder Basic kümmert sich der Compiler um das Problem - man liest oder beschreibt dann einfach z.&amp;amp;nbsp;B. TCNT1 anstatt TCNT1H und TCNT1L einzeln.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Flag richtig gelöscht? ===&lt;br /&gt;
&lt;br /&gt;
Ein beliebter Fehler ist, dass man überliest, dass gesetzte Flags (z.&amp;amp;nbsp;B. die Interrupt-Flags) durch beschreiben mit einer &#039;1&#039; und nicht mit einer &#039;0&#039; gelöscht werden! &lt;br /&gt;
&lt;br /&gt;
Beispiel: &lt;br /&gt;
* das Flag ist zuerst &#039;0&#039;&lt;br /&gt;
* das Ereignis (z.&amp;amp;nbsp;B. Zählerüberlauf, also Bit TOV0 in TIFR) tritt auf und setzt das jeweilige Bit im Register auf &#039;1&#039;&lt;br /&gt;
* wir haben auf die &#039;1&#039; gewartet und wollen das Bit nun wieder löschen und müssen dafür eine &#039;1&#039; (eins!) in das Register schreiben, &#039;&#039;&#039;keine&#039;&#039;&#039; &#039;0&#039;. Trotzdem wird das Bit dadurch &#039;0&#039; z.&amp;amp;nbsp;B.:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    TIFR = (1&amp;lt;&amp;lt;TOV0);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das ganze ist kein Fehler, sondern hat seine guten Gründe.&lt;br /&gt;
&lt;br /&gt;
Wenn Interrupts zugelassen sind (z.&amp;amp;nbsp;B. in TIMSK) und die Interruptroutine aufgerufen wird, werden diese Flags zumeist automatisch gelöscht.&lt;br /&gt;
&lt;br /&gt;
Der UART-Empfangs-Interrupt (RXC in UCSRA) jedoch nicht! Der wird gelöscht durch Auslesen des Empfangsregisters (UDR). Hier liegt wiederum ein beliebter Stolperstein: Man prüft oft zuerst in der Interruptroutine die Fehlerflags (z.&amp;amp;nbsp;B. Parity) und macht dann manchmal den Fehler das empfangene Zeichen im Fehlerfall nicht auszulesen. Das führt dann zum Absturz (der IRQ wird immer wieder aufgerufen) - man muss also immer das UDR lesen auch wenn etwas Fehlerhaftes drinsteht.&lt;br /&gt;
&lt;br /&gt;
Zusätzlich ist zu beachten, dass in C die Interrupt-Flags &#039;&#039;&#039;nicht&#039;&#039;&#039; mit einer Veroderung des Registers (z.&amp;amp;nbsp;B. TIFR |= (1 &amp;lt;&amp;lt; TOV0)) gelöscht werden sollten, da bei dieser Operation alle anderen evtl. gesetzten Flags im betreffenden Register ebenfalls gelöscht werden. Es ist die Schreibweise von oben zu benutzen (also TIFR = (1 &amp;lt;&amp;lt; TOV0))!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Alle Interrupt Variablen als volatile bezeichnet? ===&lt;br /&gt;
&lt;br /&gt;
Das Schlüsselwort volatile kann als Attribut an Variablen gehängt werden. Der Ausdruck „volatile int i“ versieht die Integervariable i mit dem Attribut volatile. Das Attribut weist den Compiler an, diese Variable nicht zu optimieren, sondern im Speicher abzulegen und zu beachten, dass diese Variable von anderen Prozessen geändert werden kann. Normale Variablen können durch den Compiler auf Register reduziert werden, oder die Daten werden einmalig aus dem Speicher geladen und erst am Ende des Programmes wieder zurückgeschrieben. Das kann Probleme bereiten, wenn beispielsweise in einer [[Interrupt]]routine die Variable verändert wird. Darum müssen alle globalen Variablen, die in einer Interruptroutine geändert werden, mit diesem Schlüsselwort versehen werden.&lt;br /&gt;
&lt;br /&gt;
=== Die Programmierfrequenz passend? ===&lt;br /&gt;
&lt;br /&gt;
Sollte ein Programmieren nicht möglich sein erst einmal die Programmiergeschwindigkeit bei AVR dude mit der Option&lt;br /&gt;
-B bitclock anpassen&lt;br /&gt;
wobei bitclock die Perioden dauer in Milisekunden (floating-point Zahl) ist. Normalerweise -B 1 für Controller mit &amp;gt;=4MHz daher ist bei der Erstprogrammierung ein höherer Wert zu versuchen.&lt;br /&gt;
&lt;br /&gt;
== Serielle Verbindungen ==&lt;br /&gt;
&lt;br /&gt;
=== [[I²C]]/[[TWI]] ===&lt;br /&gt;
&lt;br /&gt;
Sind die Leitungen SCL und SDA mit einem Pullup-Widerstand ausgestattet? Die I²C-Bus-Leitungen SCL und SDA müssen über einen Pullup-Widerstand mit einem Wert von 4,7 kΩ bis 10 kΩ mit der Versorgungsspannung (+5 V) verbunden sein.&lt;br /&gt;
&lt;br /&gt;
=== UART/USART ===&lt;br /&gt;
&lt;br /&gt;
==== Übertragungsprobleme durch falschen oder ungenauen Takt ====&lt;br /&gt;
&lt;br /&gt;
* Der interne [[Oszillator]] ist recht ungenau und nicht temperaturstabil. Daher kann die Umgebungstemperatur auch den [[UART|USART]]-Takt verändern. Für serielle, asynchrone Kommunikation per UART sollte man deshalb immer einen Quarz oder einen Oszillator verwenden, egal bei welcher Baudrate: 3% Fehler sind immer 3% Fehler, egal ob bei 1200 oder 9600 [[Baud]]. Falls doch der interne Oszillator verwendet wird: Wurde er für die richtige Frequenz und Betriebsspannung kalibriert?&lt;br /&gt;
&lt;br /&gt;
* Nicht mit allen Quarzen kann man alle Baudraten genau genug erzeugen. Deswegen gibt es [[Baudratenquarz]]e wie z.&amp;amp;nbsp;B. 3,6864 MHz. Näheres steht im Datenblatt.&lt;br /&gt;
&lt;br /&gt;
* Geschieht die Konfiguration des U(S)ART automatisch durch die Programmiersprache (z.&amp;amp;nbsp;B. in [[Bascom AVR|BASCOM]], [[C]]), dann muss dort der Takt &#039;&#039;genau&#039;&#039; angegeben werden. Setzt man z.&amp;amp;nbsp;B. einen 3,6864 MHz-Quarz ein, darf man dort nicht einfach &amp;quot;4 MHz&amp;quot; angeben, weil dann die Abweichung mit ca. 8% viel zu hoch wäre. Damit funktioniert die Übertragung nicht mehr.&lt;br /&gt;
&lt;br /&gt;
* Im AVR-Studio kann man die Taktfrequenz sowohl über ein &amp;lt;code&amp;gt;#define F_CPU&amp;lt;/code&amp;gt; im Quelltext als auch über das Optionsmenu oder das selbsterstellte Makefile einstellen. Es darf nur &#039;&#039;eine&#039;&#039; Variante verwendet werden!&lt;br /&gt;
&lt;br /&gt;
* Wenn ein externer Oszillator oder Quarz angeschlossen ist: Sind die [[AVR Fuses | Fuses]] des Controllers so gesetzt, dass er auch verwendet wird?&lt;br /&gt;
&lt;br /&gt;
* Ist die Fuse CLKDIV &#039;&#039;nicht&#039;&#039; programmiert?&lt;br /&gt;
&lt;br /&gt;
* Es taucht auch des öfteren das Missverständnis auf, dass man nur F_CPU verändern muss, um den µC mit einem anderen Takt laufen zu lassen. Dem ist nicht so. Der µC-Takt wird durch die Fuses bzw. den eventuell angeschlossenen Quarz oder Quarzoszillator bestimmt. F_CPU dient nur dazu, die dadurch festgelegte Frequenz im C-Programm zur Verfügung zu haben. F_CPU ist nur eine Information, mit der man bei der Programmierung arbeiten kann. Aber ein anderer F_CPU-Wert führt nicht dazu, dass der µC dann magisch auf diese Frequenz umgestellt wird.&lt;br /&gt;
&lt;br /&gt;
* Um zu prüfen, ob der externe Quarz auch wirklich verwendet wird, kann man  mittels _delay_ms() testweise eine LED im Sekundentakt blinken lassen. Den Unterschied zwischen Quarz und internem RC-Oszillator kann man bei grösseren Frequenzunterschieden leicht sehen. Ebenso sieht man, ob versehentlich die CLKDIV Fuse gesetzt ist: die Blinkfrequenz ist dann achtmal langsamer. Allerdings muss man auch hier aufpassen. Siehe [[AVR-GCC-Tutorial#Warteschleifen (delay.h)|AVR-GCC-Tutorial: Warteschleifen]].&lt;br /&gt;
&lt;br /&gt;
Im folgenden Programm muss angepasst werden:&lt;br /&gt;
*Die vermeintliche Taktfrequenz F_CPU&lt;br /&gt;
*der Port und der Pin, an dem eine LED angeschlossen ist.&lt;br /&gt;
&lt;br /&gt;
Wird das Programm laufen gelassen, muss die LED 1 Sekunde ein/1 Sekunde aus sein. Stimmen die Zeiten nicht, ist das ein deutlicher Hinweis darauf, dass die tatsächlich vom µC verwendete Taktfrequenz nicht mit der in F_CPU angegebenen übereinstimmt. Das Programm muss mit aktivierter Optimierung &amp;lt;code&amp;gt;-Os&amp;lt;/code&amp;gt; compiliert werden.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// Testprogramm für CPU Takt&lt;br /&gt;
// Hier die vermeintliche Taktrate des µC eintragen&lt;br /&gt;
// Im Beispiel hier: 1Mhz&lt;br /&gt;
&lt;br /&gt;
#define F_CPU 1000000&lt;br /&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;
&lt;br /&gt;
// Hier die tatsächlich verwendeten Parameter angeben&lt;br /&gt;
&lt;br /&gt;
#define LED_PORT    PORTB&lt;br /&gt;
#define LED_DDR     DDRB&lt;br /&gt;
#define LED_PIN     PB0&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
   LED_DDR |= 1 &amp;lt;&amp;lt; LED_PIN;&lt;br /&gt;
&lt;br /&gt;
   while (1)&lt;br /&gt;
   {&lt;br /&gt;
      LED_PORT ^= 1 &amp;lt;&amp;lt; LED_PIN;&lt;br /&gt;
      _delay_ms(1000);&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;
&lt;br /&gt;
* Erscheinen im Terminalprogramm kryptische Zeichen anstatt ordentlichen Buchstaben (z.&amp;amp;nbsp;B. ü statt A), liegt das zu 99,9% an einer falsch eingestellten/erzeugten Baudrate im Mikrocontroller. Meistens wiederum liegt dies daran, dass der µC nicht mit der vermeintlichen Taktrate läuft und daher die Baudratenparameter falsch berechnet werden.&lt;br /&gt;
&lt;br /&gt;
* URSEL-Bit in UCSRC: Bei der Initialisierung der UART beachtet, wenn das für den verwendeten AVR notwendig ist, siehe [[AVR-GCC-Tutorial/Der_UART#Die_UART-Register|AVR-GCC-Tutorial/Der UART: Die UART-Register]].&lt;br /&gt;
&lt;br /&gt;
* In den Tutorials für [[AVR-Tutorial: UART |Assembler]] und [http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Der_UART GCC] wird die Nutzung recht gut erklärt und mit Beispielen erläutert.&lt;br /&gt;
&lt;br /&gt;
==== Sonstige Fehlerquellen bei UART/USART ====&lt;br /&gt;
&lt;br /&gt;
* Funktioniert die Datenübertragung zum PC nur solange der Programmieradapter eingesteckt ist, deutet dies auf ein Problem mit der Masse hin (z.&amp;amp;nbsp;B. GND-Anschluss am RS232-Stecker nicht belegt oder dergleichen).&lt;br /&gt;
&lt;br /&gt;
* Der Pegelwandler/Inverter (z.&amp;amp;nbsp;B. MAX232) muss mit Kondensatoren für die internen Ladungspumpen beschaltet werden. Beim MAX232 sind dies mindestens vier Kondensatoren ≥ 1 µF (Polung beachten!), beim MAX202, MAX232A und MAX3232 vier Kondensatoren ≥ 100 nF. Hinzu kommt der obligatorische Abblockkondensator von 100 nF keramisch zwischen VCC und GND des ICs. Das jeweilige Datenblatt gibt Auskunft über die Beschaltung bei &amp;quot;typischer Anwendung&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* TX/RX vertauscht? Modem- oder Nullmodemkabel?&lt;br /&gt;
&lt;br /&gt;
* Bei Kommunikation mit PC: ist die serielle Schnittstelle richtig konfiguriert? Nicht nur Baudrate, Stopp- und Parity-Bits, sondern auch Handshakeverhalten muss stimmen (kein Hardwarehandshake bei ausschließlicher Verwendung der Pins RX/TX).&lt;br /&gt;
&lt;br /&gt;
* Wird das Signal eventuell durch zusätzliche Chips invertiert? (EEPROM von FT232 falsch Programmiert)&lt;br /&gt;
&lt;br /&gt;
* Die Hardware und Verkabelung kann man schnell prüfen, indem man den Pin R1OUT bzw. R2OUT mit T1IN bzw. T2IN am MAX232 miteinander verbindet (je nachdem welches Pinpaar verwendet wird). Dann sollte man auf dem PC ein Terminalprogramm wie Hyperterminal starten und nach dem Eingeben von Zeichen diese sofort angezeigt bekommen, egal mit welcher Baudrate. Lediglich die Flusssteuerung muss auf &amp;quot;Kein&amp;quot; eingestellt werden.&lt;br /&gt;
&lt;br /&gt;
: Man muss aber beachten, dass T1IN bzw. T2IN für diesen Test &#039;&#039;nicht&#039;&#039; mit dem Mikrocontroller verbunden sein darf, weil sonst zwei Ausgänge miteinander verbunden sind, siehe [[Ausgangsstufen Logik-ICs]]. Wenn der µC gesockelt ist, kann man ihn dafür einfach aus dem Sockel nehmen und die RX/TX Pins direkt im µC-Sockel mit einem Stück Draht verbinden.&lt;br /&gt;
&lt;br /&gt;
* UART Ausgabe-Pin als Output-Pin deklariert?&lt;br /&gt;
&lt;br /&gt;
* Spannung an Pin 15 und 16 liegt an? (Falsche Zeichen kommen an, aber in der richtigen Reihenfolge. Beim Test durch Kurzschluss von T1IN und R1OUT kommt nichts an)&lt;br /&gt;
&lt;br /&gt;
=== SPI (Hardware) ===&lt;br /&gt;
* Master Mode: SS Pin als Ausgang oder auf High gelegt? (siehe hier: [http://www.holger-klabunde.de/avr/avrhelp.htm] )&lt;br /&gt;
* SPI zu schnell&lt;br /&gt;
* Hängen andere SPI-Devices am Bus, die undefiniertes CS haben?&lt;br /&gt;
* Sind die DDR-Register der SPI-Ports richtig gesetzt?&lt;br /&gt;
&lt;br /&gt;
== Analog-Digital-Wandler ==&lt;br /&gt;
&lt;br /&gt;
* Sind die Pullup-Widerstände deaktiviert? (im allgemeinen)&lt;br /&gt;
* (im speziellen) Bei einige Controllern liegt der JTAG mit auf den ADC-Pins. Die betroffenen ADC-Kanäle werden erst richtig funktionieren, wenn der JTAG deaktiviert ist. Das geht per Fuse oder - wenn man an die Fuses nicht mehr herrankommen sollte, weil man mit einem Bootloader arbeitet - auch per Software.&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc2521.pdf Application Note AVR042: AVR Hardware Design Considerations]&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/doc1619.pdf Application Note AVR040: EMC Design Considerations]&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Quarze_und_AVR&amp;diff=66327</id>
		<title>Quarze und AVR</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Quarze_und_AVR&amp;diff=66327"/>
		<updated>2012-05-15T18:55:03Z</updated>

		<summary type="html">&lt;p&gt;Cmf: /* Einstellung der Fuses */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Diese Seite behandelt Quarze im Zusammenhang mit AVRs. Für allgemeine Informationen zum Thema siehe [[Quarz]].&lt;br /&gt;
&lt;br /&gt;
Die Genauigkeit von Quarzen liegt bei 10-100ppm	(1ppm = 0,0001 %) und wird somit nur noch vom [[Quarzoszillator]] überboten. Außerdem sind Quarze im Gegensatz zum internen RC-Oszillator weniger temperaturunabhängig.&lt;br /&gt;
&lt;br /&gt;
= Verwendung =&lt;br /&gt;
Quarze sind in folgenden Situationen sinnvoll / notwendig:&lt;br /&gt;
&lt;br /&gt;
* Interner Oszillator des µC zu langsam&lt;br /&gt;
* Interner Oszillator des µC zu ungenau&lt;br /&gt;
**Bei Verwendung des [[UART]]&lt;br /&gt;
**Bei zeitkritischen Anwendungen wie z.B. einer Uhr&lt;br /&gt;
&lt;br /&gt;
= Wahl der richtigen Frequenz =&lt;br /&gt;
Vor allem als Anfänger denkt man sich, &#039;&#039;ich kaufe einfach mal 10MHz, das ist eine so schön gerade Zahl&#039;&#039;. Allerdings sind diese Quarze nur in den seltensten Fällen sinnvoll. Viel sinnvoller sind [[Baudratenquarz]]e. &amp;quot;Baudraten&amp;quot;-Frequenzen sind ganzzahlige Vielfache der bei RS232 üblichen Baudraten. Mit Baudrate-Frequenz kann  man exakte Baudraten erreichen, mit &amp;quot;runden&amp;quot; Frequenzen entstehen Fehler, weshalb oft nur sehr niedrige Baudraten möglich sind.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Runde&amp;quot; Frequenzen (4MHz, 8MHz, 10MHz....) sind meist leichter erhältlich und haben den Vorteil, dass man Verzögerungsschleifen und Rechendauern relativ leicht errechnen kann.&lt;br /&gt;
&lt;br /&gt;
= Anschluss =&lt;br /&gt;
[[Bild:Quarz_Anschluss_AVR.png|right|framed]]&lt;br /&gt;
Die Kapazitäten von C1 und C2 entsprechen &#039;&#039;&#039;nicht&#039;&#039;&#039; der Lastkapazität des Quarzes!&lt;br /&gt;
Sie errechnen sich folgendermaßen:&lt;br /&gt;
&lt;br /&gt;
C=2xCL-(CP+CI)&lt;br /&gt;
&lt;br /&gt;
*CP: Leiterbahnen bedingte Kapazität&lt;br /&gt;
*CI: Portbedingte Kapazität&lt;br /&gt;
*CL: Datenblatt des Quarzes&lt;br /&gt;
*CP+CI ca. 5pF&lt;br /&gt;
&lt;br /&gt;
Am Beispiel von CL = 32pF:&lt;br /&gt;
&lt;br /&gt;
C = 2x32pF-5pF = 59pF&lt;br /&gt;
&lt;br /&gt;
C1 und C2 sind die vom Hersteller des Kontrollers empfohlenen Werte, mit ihnen wird die Schwingsicherheit der Oszillatorschaltung gewährleistet. C1 und C2 sollten in etwa eingehalten werden (so + - 20% machen aber nichts aus).&lt;br /&gt;
&lt;br /&gt;
CL, der im Datenblatt angegebene Wert, wird beim Abgleich des Quarzes während der Herstellung benutzt. &lt;br /&gt;
&lt;br /&gt;
Wenn CL nicht eingehalten wird, hat das keinen Einfluss auf das Schwingen des Oszillators (solange der Faktor2 nicht überschritten wird) sondern nur auf die Frequenz, aber das in einem Maße (max. 0,01%der Frequenz), das für die meisten Mikrokontrolleranwendungen bedeutungslos ist.&lt;br /&gt;
&lt;br /&gt;
= Einstellung der Fuses =&lt;br /&gt;
{{Warnung |&lt;br /&gt;
;Hier ist besondere Vorsicht geboten. Fast immer liegt hier das Problem, wenn ein Mikrocontroller nicht mehr läuft!&lt;br /&gt;
}}&lt;br /&gt;
Ein Quarz ist &#039;&#039;&#039;keine&#039;&#039;&#039; &amp;quot;External Clock&amp;quot;, sondern ein &amp;quot;External Crystal/Ceramic Resonator&amp;quot;. &lt;br /&gt;
Wenn man wirklich auf Nummer sicher gehen will, sollte man:&lt;br /&gt;
*Das Datenblatt &#039;&#039;&#039;genau&#039;&#039;&#039; lesen (Abschnitt &amp;quot;Clock Source&amp;quot;)&lt;br /&gt;
*Beim Fuse Calculator [http://www.engbedded.com/fusecalc] die Fuses berechnen lassen&lt;br /&gt;
*Nochmals genau überprüfen&lt;br /&gt;
Siehe auch: [[AVR_Fuses#Taktquellen_Fuse_Einstellung]]&lt;br /&gt;
&lt;br /&gt;
= Siehe auch =&lt;br /&gt;
*AppNotes von Atmel zum Thema Quarze: [http://www.atmel.com/Images/doc2521.pdf][http://www.atmel.com/Images/doc8128.pdf]&lt;br /&gt;
*Fuse Calculator: [http://www.engbedded.com/fusecalc]&lt;/div&gt;</summary>
		<author><name>Cmf</name></author>
	</entry>
</feed>